mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
Merge branches 'acpica', 'aml-custom', 'bugzilla-16548', 'bugzilla-20242', 'd3-cold', 'ec-asus' and 'thermal-fix' into release
This commit is contained in:
commit
6288cf1e76
10697 changed files with 620646 additions and 295542 deletions
|
|
@ -7,7 +7,6 @@ menuconfig ACPI
|
|||
depends on !IA64_HP_SIM
|
||||
depends on IA64 || X86
|
||||
depends on PCI
|
||||
depends on PM
|
||||
select PNP
|
||||
default y
|
||||
help
|
||||
|
|
@ -381,6 +380,21 @@ config ACPI_HED
|
|||
which is used to report some hardware errors notified via
|
||||
SCI, mainly the corrected errors.
|
||||
|
||||
config ACPI_CUSTOM_METHOD
|
||||
tristate "Allow ACPI methods to be inserted/replaced at run time"
|
||||
depends on DEBUG_FS
|
||||
default n
|
||||
help
|
||||
This debug facility allows ACPI AML methods to me inserted and/or
|
||||
replaced without rebooting the system. For details refer to:
|
||||
Documentation/acpi/method-customizing.txt.
|
||||
|
||||
NOTE: This option is security sensitive, because it allows arbitrary
|
||||
kernel memory to be written to by root (uid=0) users, allowing them
|
||||
to bypass certain security measures (e.g. if root is not allowed to
|
||||
load additional kernel modules after boot, this feature may be used
|
||||
to override that restriction).
|
||||
|
||||
source "drivers/acpi/apei/Kconfig"
|
||||
|
||||
endif # ACPI
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ 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
|
||||
|
||||
# processor has its own "processor." module_param namespace
|
||||
processor-y := processor_driver.o processor_throttling.o
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ static ssize_t acpi_pad_rrtime_store(struct device *dev,
|
|||
static ssize_t acpi_pad_rrtime_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return scnprintf(buf, PAGE_SIZE, "%d", round_robin_time);
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", round_robin_time);
|
||||
}
|
||||
static DEVICE_ATTR(rrtime, S_IRUGO|S_IWUSR,
|
||||
acpi_pad_rrtime_show,
|
||||
|
|
@ -321,7 +321,7 @@ static ssize_t acpi_pad_idlepct_store(struct device *dev,
|
|||
static ssize_t acpi_pad_idlepct_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return scnprintf(buf, PAGE_SIZE, "%d", idle_pct);
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", idle_pct);
|
||||
}
|
||||
static DEVICE_ATTR(idlepct, S_IRUGO|S_IWUSR,
|
||||
acpi_pad_idlepct_show,
|
||||
|
|
@ -342,8 +342,11 @@ static ssize_t acpi_pad_idlecpus_store(struct device *dev,
|
|||
static ssize_t acpi_pad_idlecpus_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return cpumask_scnprintf(buf, PAGE_SIZE,
|
||||
to_cpumask(pad_busy_cpus_bits));
|
||||
int n = 0;
|
||||
n = cpumask_scnprintf(buf, PAGE_SIZE-2, to_cpumask(pad_busy_cpus_bits));
|
||||
buf[n++] = '\n';
|
||||
buf[n] = '\0';
|
||||
return n;
|
||||
}
|
||||
static DEVICE_ATTR(idlecpus, S_IRUGO|S_IWUSR,
|
||||
acpi_pad_idlecpus_show,
|
||||
|
|
@ -453,7 +456,7 @@ static void acpi_pad_notify(acpi_handle handle, u32 event,
|
|||
dev_name(&device->dev), event, 0);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_WARNING"Unsupported event [0x%x]\n", event);
|
||||
printk(KERN_WARNING "Unsupported event [0x%x]\n", event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -397,10 +397,15 @@ struct acpi_gpe_handler_info {
|
|||
u8 originally_enabled; /* True if GPE was originally enabled */
|
||||
};
|
||||
|
||||
struct acpi_gpe_notify_object {
|
||||
struct acpi_namespace_node *node;
|
||||
struct acpi_gpe_notify_object *next;
|
||||
};
|
||||
|
||||
union acpi_gpe_dispatch_info {
|
||||
struct acpi_namespace_node *method_node; /* Method node for this GPE level */
|
||||
struct acpi_gpe_handler_info *handler; /* Installed GPE handler */
|
||||
struct acpi_namespace_node *device_node; /* Parent _PRW device for implicit notify */
|
||||
struct acpi_gpe_notify_object device; /* List of _PRW devices for implicit notify */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -466,6 +466,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
|
|||
acpi_status status;
|
||||
struct acpi_gpe_event_info *local_gpe_event_info;
|
||||
struct acpi_evaluate_info *info;
|
||||
struct acpi_gpe_notify_object *notify_object;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);
|
||||
|
||||
|
|
@ -517,10 +518,18 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
|
|||
* from this thread -- because handlers may in turn run other
|
||||
* control methods.
|
||||
*/
|
||||
status =
|
||||
acpi_ev_queue_notify_request(local_gpe_event_info->dispatch.
|
||||
device_node,
|
||||
ACPI_NOTIFY_DEVICE_WAKE);
|
||||
status = acpi_ev_queue_notify_request(
|
||||
local_gpe_event_info->dispatch.device.node,
|
||||
ACPI_NOTIFY_DEVICE_WAKE);
|
||||
|
||||
notify_object = local_gpe_event_info->dispatch.device.next;
|
||||
while (ACPI_SUCCESS(status) && notify_object) {
|
||||
status = acpi_ev_queue_notify_request(
|
||||
notify_object->node,
|
||||
ACPI_NOTIFY_DEVICE_WAKE);
|
||||
notify_object = notify_object->next;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ACPI_GPE_DISPATCH_METHOD:
|
||||
|
|
|
|||
|
|
@ -198,7 +198,9 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,
|
|||
acpi_status status = AE_BAD_PARAMETER;
|
||||
struct acpi_gpe_event_info *gpe_event_info;
|
||||
struct acpi_namespace_node *device_node;
|
||||
struct acpi_gpe_notify_object *notify_object;
|
||||
acpi_cpu_flags flags;
|
||||
u8 gpe_dispatch_mask;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake);
|
||||
|
||||
|
|
@ -221,27 +223,49 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,
|
|||
goto unlock_and_exit;
|
||||
}
|
||||
|
||||
if (wake_device == ACPI_ROOT_OBJECT) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is no method or handler for this GPE, then the
|
||||
* wake_device will be notified whenever this GPE fires (aka
|
||||
* "implicit notify") Note: The GPE is assumed to be
|
||||
* level-triggered (for windows compatibility).
|
||||
*/
|
||||
if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
|
||||
ACPI_GPE_DISPATCH_NONE) && (wake_device != ACPI_ROOT_OBJECT)) {
|
||||
|
||||
/* Validate wake_device is of type Device */
|
||||
|
||||
device_node = ACPI_CAST_PTR(struct acpi_namespace_node,
|
||||
wake_device);
|
||||
if (device_node->type != ACPI_TYPE_DEVICE) {
|
||||
goto unlock_and_exit;
|
||||
}
|
||||
gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY |
|
||||
ACPI_GPE_LEVEL_TRIGGERED);
|
||||
gpe_event_info->dispatch.device_node = device_node;
|
||||
gpe_dispatch_mask = gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK;
|
||||
if (gpe_dispatch_mask != ACPI_GPE_DISPATCH_NONE
|
||||
&& gpe_dispatch_mask != ACPI_GPE_DISPATCH_NOTIFY) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Validate wake_device is of type Device */
|
||||
|
||||
device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
|
||||
if (device_node->type != ACPI_TYPE_DEVICE) {
|
||||
goto unlock_and_exit;
|
||||
}
|
||||
|
||||
if (gpe_dispatch_mask == ACPI_GPE_DISPATCH_NONE) {
|
||||
gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY |
|
||||
ACPI_GPE_LEVEL_TRIGGERED);
|
||||
gpe_event_info->dispatch.device.node = device_node;
|
||||
gpe_event_info->dispatch.device.next = NULL;
|
||||
} else {
|
||||
/* There are multiple devices to notify implicitly. */
|
||||
|
||||
notify_object = ACPI_ALLOCATE_ZEROED(sizeof(*notify_object));
|
||||
if (!notify_object) {
|
||||
status = AE_NO_MEMORY;
|
||||
goto unlock_and_exit;
|
||||
}
|
||||
|
||||
notify_object->node = device_node;
|
||||
notify_object->next = gpe_event_info->dispatch.device.next;
|
||||
gpe_event_info->dispatch.device.next = notify_object;
|
||||
}
|
||||
|
||||
out:
|
||||
gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
|
||||
status = AE_OK;
|
||||
|
||||
|
|
|
|||
|
|
@ -80,14 +80,14 @@ acpi_status acpi_reset(void)
|
|||
|
||||
if (reset_reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
|
||||
/*
|
||||
* For I/O space, write directly to the OSL. This bypasses the port
|
||||
* validation mechanism, which may block a valid write to the reset
|
||||
* register.
|
||||
* For I/O space, write directly to the OSL. This
|
||||
* bypasses the port validation mechanism, which may
|
||||
* block a valid write to the reset register. Spec
|
||||
* section 4.7.3.6 requires register width to be 8.
|
||||
*/
|
||||
status =
|
||||
acpi_os_write_port((acpi_io_address) reset_reg->address,
|
||||
acpi_gbl_FADT.reset_value,
|
||||
reset_reg->bit_width);
|
||||
acpi_gbl_FADT.reset_value, 8);
|
||||
} else {
|
||||
/* Write the reset value to the reset register */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
config ACPI_APEI
|
||||
bool "ACPI Platform Error Interface (APEI)"
|
||||
select PSTORE
|
||||
depends on X86
|
||||
help
|
||||
APEI allows to report errors (for example from the chipset)
|
||||
|
|
@ -21,6 +22,13 @@ config ACPI_APEI_GHES
|
|||
by firmware to produce more valuable hardware error
|
||||
information for Linux.
|
||||
|
||||
config ACPI_APEI_PCIEAER
|
||||
bool "APEI PCIe AER logging/recovering support"
|
||||
depends on ACPI_APEI && PCIEAER
|
||||
help
|
||||
PCIe AER errors may be reported via APEI firmware first mode.
|
||||
Turn on this option to enable the corresponding support.
|
||||
|
||||
config ACPI_APEI_EINJ
|
||||
tristate "APEI Error INJection (EINJ)"
|
||||
depends on ACPI_APEI && DEBUG_FS
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <linux/time.h>
|
||||
#include <linux/cper.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/aer.h>
|
||||
|
||||
/*
|
||||
* CPER record ID need to be unique even after reboot, because record
|
||||
|
|
@ -70,8 +71,8 @@ static const char *cper_severity_str(unsigned int severity)
|
|||
* If the output length is longer than 80, multiple line will be
|
||||
* printed, with @pfx is printed at the beginning of each line.
|
||||
*/
|
||||
static void cper_print_bits(const char *pfx, unsigned int bits,
|
||||
const char *strs[], unsigned int strs_size)
|
||||
void cper_print_bits(const char *pfx, unsigned int bits,
|
||||
const char *strs[], unsigned int strs_size)
|
||||
{
|
||||
int i, len = 0;
|
||||
const char *str;
|
||||
|
|
@ -81,6 +82,8 @@ static void cper_print_bits(const char *pfx, unsigned int bits,
|
|||
if (!(bits & (1U << i)))
|
||||
continue;
|
||||
str = strs[i];
|
||||
if (!str)
|
||||
continue;
|
||||
if (len && len + strlen(str) + 2 > 80) {
|
||||
printk("%s\n", buf);
|
||||
len = 0;
|
||||
|
|
@ -243,7 +246,8 @@ static const char *cper_pcie_port_type_strs[] = {
|
|||
"root complex event collector",
|
||||
};
|
||||
|
||||
static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie)
|
||||
static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
|
||||
const struct acpi_hest_generic_data *gdata)
|
||||
{
|
||||
if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)
|
||||
printk("%s""port_type: %d, %s\n", pfx, pcie->port_type,
|
||||
|
|
@ -276,6 +280,12 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie)
|
|||
printk(
|
||||
"%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n",
|
||||
pfx, pcie->bridge.secondary_status, pcie->bridge.control);
|
||||
#ifdef CONFIG_ACPI_APEI_PCIEAER
|
||||
if (pcie->validation_bits & CPER_PCIE_VALID_AER_INFO) {
|
||||
struct aer_capability_regs *aer_regs = (void *)pcie->aer_info;
|
||||
cper_print_aer(pfx, gdata->error_severity, aer_regs);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static const char *apei_estatus_section_flag_strs[] = {
|
||||
|
|
@ -322,7 +332,7 @@ static void apei_estatus_print_section(
|
|||
struct cper_sec_pcie *pcie = (void *)(gdata + 1);
|
||||
printk("%s""section_type: PCIe error\n", pfx);
|
||||
if (gdata->error_data_length >= sizeof(*pcie))
|
||||
cper_print_pcie(pfx, pcie);
|
||||
cper_print_pcie(pfx, pcie, gdata);
|
||||
else
|
||||
goto err_section_too_small;
|
||||
} else
|
||||
|
|
|
|||
|
|
@ -43,12 +43,27 @@ static DEFINE_MUTEX(erst_dbg_mutex);
|
|||
|
||||
static int erst_dbg_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int rc, *pos;
|
||||
|
||||
if (erst_disable)
|
||||
return -ENODEV;
|
||||
|
||||
pos = (int *)&file->private_data;
|
||||
|
||||
rc = erst_get_record_id_begin(pos);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return nonseekable_open(inode, file);
|
||||
}
|
||||
|
||||
static int erst_dbg_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
erst_get_record_id_end();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int rc;
|
||||
|
|
@ -79,18 +94,20 @@ static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
|
|||
static ssize_t erst_dbg_read(struct file *filp, char __user *ubuf,
|
||||
size_t usize, loff_t *off)
|
||||
{
|
||||
int rc;
|
||||
int rc, *pos;
|
||||
ssize_t len = 0;
|
||||
u64 id;
|
||||
|
||||
if (*off != 0)
|
||||
if (*off)
|
||||
return -EINVAL;
|
||||
|
||||
if (mutex_lock_interruptible(&erst_dbg_mutex) != 0)
|
||||
return -EINTR;
|
||||
|
||||
pos = (int *)&filp->private_data;
|
||||
|
||||
retry_next:
|
||||
rc = erst_get_next_record_id(&id);
|
||||
rc = erst_get_record_id_next(pos, &id);
|
||||
if (rc)
|
||||
goto out;
|
||||
/* no more record */
|
||||
|
|
@ -181,6 +198,7 @@ out:
|
|||
static const struct file_operations erst_dbg_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = erst_dbg_open,
|
||||
.release = erst_dbg_release,
|
||||
.read = erst_dbg_read,
|
||||
.write = erst_dbg_write,
|
||||
.unlocked_ioctl = erst_dbg_ioctl,
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <linux/cper.h>
|
||||
#include <linux/nmi.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/pstore.h>
|
||||
#include <acpi/apei.h>
|
||||
|
||||
#include "apei-internal.h"
|
||||
|
|
@ -429,6 +430,22 @@ ssize_t erst_get_record_count(void)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(erst_get_record_count);
|
||||
|
||||
#define ERST_RECORD_ID_CACHE_SIZE_MIN 16
|
||||
#define ERST_RECORD_ID_CACHE_SIZE_MAX 1024
|
||||
|
||||
struct erst_record_id_cache {
|
||||
struct mutex lock;
|
||||
u64 *entries;
|
||||
int len;
|
||||
int size;
|
||||
int refcount;
|
||||
};
|
||||
|
||||
static struct erst_record_id_cache erst_record_id_cache = {
|
||||
.lock = __MUTEX_INITIALIZER(erst_record_id_cache.lock),
|
||||
.refcount = 0,
|
||||
};
|
||||
|
||||
static int __erst_get_next_record_id(u64 *record_id)
|
||||
{
|
||||
struct apei_exec_context ctx;
|
||||
|
|
@ -443,26 +460,179 @@ static int __erst_get_next_record_id(u64 *record_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int erst_get_record_id_begin(int *pos)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (erst_disable)
|
||||
return -ENODEV;
|
||||
|
||||
rc = mutex_lock_interruptible(&erst_record_id_cache.lock);
|
||||
if (rc)
|
||||
return rc;
|
||||
erst_record_id_cache.refcount++;
|
||||
mutex_unlock(&erst_record_id_cache.lock);
|
||||
|
||||
*pos = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(erst_get_record_id_begin);
|
||||
|
||||
/* erst_record_id_cache.lock must be held by caller */
|
||||
static int __erst_record_id_cache_add_one(void)
|
||||
{
|
||||
u64 id, prev_id, first_id;
|
||||
int i, rc;
|
||||
u64 *entries;
|
||||
unsigned long flags;
|
||||
|
||||
id = prev_id = first_id = APEI_ERST_INVALID_RECORD_ID;
|
||||
retry:
|
||||
raw_spin_lock_irqsave(&erst_lock, flags);
|
||||
rc = __erst_get_next_record_id(&id);
|
||||
raw_spin_unlock_irqrestore(&erst_lock, flags);
|
||||
if (rc == -ENOENT)
|
||||
return 0;
|
||||
if (rc)
|
||||
return rc;
|
||||
if (id == APEI_ERST_INVALID_RECORD_ID)
|
||||
return 0;
|
||||
/* can not skip current ID, or loop back to first ID */
|
||||
if (id == prev_id || id == first_id)
|
||||
return 0;
|
||||
if (first_id == APEI_ERST_INVALID_RECORD_ID)
|
||||
first_id = id;
|
||||
prev_id = id;
|
||||
|
||||
entries = erst_record_id_cache.entries;
|
||||
for (i = 0; i < erst_record_id_cache.len; i++) {
|
||||
if (entries[i] == id)
|
||||
break;
|
||||
}
|
||||
/* record id already in cache, try next */
|
||||
if (i < erst_record_id_cache.len)
|
||||
goto retry;
|
||||
if (erst_record_id_cache.len >= erst_record_id_cache.size) {
|
||||
int new_size, alloc_size;
|
||||
u64 *new_entries;
|
||||
|
||||
new_size = erst_record_id_cache.size * 2;
|
||||
new_size = clamp_val(new_size, ERST_RECORD_ID_CACHE_SIZE_MIN,
|
||||
ERST_RECORD_ID_CACHE_SIZE_MAX);
|
||||
if (new_size <= erst_record_id_cache.size) {
|
||||
if (printk_ratelimit())
|
||||
pr_warning(FW_WARN ERST_PFX
|
||||
"too many record ID!\n");
|
||||
return 0;
|
||||
}
|
||||
alloc_size = new_size * sizeof(entries[0]);
|
||||
if (alloc_size < PAGE_SIZE)
|
||||
new_entries = kmalloc(alloc_size, GFP_KERNEL);
|
||||
else
|
||||
new_entries = vmalloc(alloc_size);
|
||||
if (!new_entries)
|
||||
return -ENOMEM;
|
||||
memcpy(new_entries, entries,
|
||||
erst_record_id_cache.len * sizeof(entries[0]));
|
||||
if (erst_record_id_cache.size < PAGE_SIZE)
|
||||
kfree(entries);
|
||||
else
|
||||
vfree(entries);
|
||||
erst_record_id_cache.entries = entries = new_entries;
|
||||
erst_record_id_cache.size = new_size;
|
||||
}
|
||||
entries[i] = id;
|
||||
erst_record_id_cache.len++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the record ID of an existing error record on the persistent
|
||||
* storage. If there is no error record on the persistent storage, the
|
||||
* returned record_id is APEI_ERST_INVALID_RECORD_ID.
|
||||
*/
|
||||
int erst_get_next_record_id(u64 *record_id)
|
||||
int erst_get_record_id_next(int *pos, u64 *record_id)
|
||||
{
|
||||
int rc;
|
||||
unsigned long flags;
|
||||
int rc = 0;
|
||||
u64 *entries;
|
||||
|
||||
if (erst_disable)
|
||||
return -ENODEV;
|
||||
|
||||
raw_spin_lock_irqsave(&erst_lock, flags);
|
||||
rc = __erst_get_next_record_id(record_id);
|
||||
raw_spin_unlock_irqrestore(&erst_lock, flags);
|
||||
/* must be enclosed by erst_get_record_id_begin/end */
|
||||
BUG_ON(!erst_record_id_cache.refcount);
|
||||
BUG_ON(*pos < 0 || *pos > erst_record_id_cache.len);
|
||||
|
||||
mutex_lock(&erst_record_id_cache.lock);
|
||||
entries = erst_record_id_cache.entries;
|
||||
for (; *pos < erst_record_id_cache.len; (*pos)++)
|
||||
if (entries[*pos] != APEI_ERST_INVALID_RECORD_ID)
|
||||
break;
|
||||
/* found next record id in cache */
|
||||
if (*pos < erst_record_id_cache.len) {
|
||||
*record_id = entries[*pos];
|
||||
(*pos)++;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* Try to add one more record ID to cache */
|
||||
rc = __erst_record_id_cache_add_one();
|
||||
if (rc < 0)
|
||||
goto out_unlock;
|
||||
/* successfully add one new ID */
|
||||
if (rc == 1) {
|
||||
*record_id = erst_record_id_cache.entries[*pos];
|
||||
(*pos)++;
|
||||
rc = 0;
|
||||
} else {
|
||||
*pos = -1;
|
||||
*record_id = APEI_ERST_INVALID_RECORD_ID;
|
||||
}
|
||||
out_unlock:
|
||||
mutex_unlock(&erst_record_id_cache.lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(erst_get_next_record_id);
|
||||
EXPORT_SYMBOL_GPL(erst_get_record_id_next);
|
||||
|
||||
/* erst_record_id_cache.lock must be held by caller */
|
||||
static void __erst_record_id_cache_compact(void)
|
||||
{
|
||||
int i, wpos = 0;
|
||||
u64 *entries;
|
||||
|
||||
if (erst_record_id_cache.refcount)
|
||||
return;
|
||||
|
||||
entries = erst_record_id_cache.entries;
|
||||
for (i = 0; i < erst_record_id_cache.len; i++) {
|
||||
if (entries[i] == APEI_ERST_INVALID_RECORD_ID)
|
||||
continue;
|
||||
if (wpos != i)
|
||||
memcpy(&entries[wpos], &entries[i], sizeof(entries[i]));
|
||||
wpos++;
|
||||
}
|
||||
erst_record_id_cache.len = wpos;
|
||||
}
|
||||
|
||||
void erst_get_record_id_end(void)
|
||||
{
|
||||
/*
|
||||
* erst_disable != 0 should be detected by invoker via the
|
||||
* return value of erst_get_record_id_begin/next, so this
|
||||
* function should not be called for erst_disable != 0.
|
||||
*/
|
||||
BUG_ON(erst_disable);
|
||||
|
||||
mutex_lock(&erst_record_id_cache.lock);
|
||||
erst_record_id_cache.refcount--;
|
||||
BUG_ON(erst_record_id_cache.refcount < 0);
|
||||
__erst_record_id_cache_compact();
|
||||
mutex_unlock(&erst_record_id_cache.lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(erst_get_record_id_end);
|
||||
|
||||
static int __erst_write_to_storage(u64 offset)
|
||||
{
|
||||
|
|
@ -703,56 +873,34 @@ ssize_t erst_read(u64 record_id, struct cper_record_header *record,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(erst_read);
|
||||
|
||||
/*
|
||||
* If return value > buflen, the buffer size is not big enough,
|
||||
* else if return value = 0, there is no more record to read,
|
||||
* else if return value < 0, something goes wrong,
|
||||
* else everything is OK, and return value is record length
|
||||
*/
|
||||
ssize_t erst_read_next(struct cper_record_header *record, size_t buflen)
|
||||
{
|
||||
int rc;
|
||||
ssize_t len;
|
||||
unsigned long flags;
|
||||
u64 record_id;
|
||||
|
||||
if (erst_disable)
|
||||
return -ENODEV;
|
||||
|
||||
raw_spin_lock_irqsave(&erst_lock, flags);
|
||||
rc = __erst_get_next_record_id(&record_id);
|
||||
if (rc) {
|
||||
raw_spin_unlock_irqrestore(&erst_lock, flags);
|
||||
return rc;
|
||||
}
|
||||
/* no more record */
|
||||
if (record_id == APEI_ERST_INVALID_RECORD_ID) {
|
||||
raw_spin_unlock_irqrestore(&erst_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = __erst_read(record_id, record, buflen);
|
||||
raw_spin_unlock_irqrestore(&erst_lock, flags);
|
||||
|
||||
return len;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(erst_read_next);
|
||||
|
||||
int erst_clear(u64 record_id)
|
||||
{
|
||||
int rc;
|
||||
int rc, i;
|
||||
unsigned long flags;
|
||||
u64 *entries;
|
||||
|
||||
if (erst_disable)
|
||||
return -ENODEV;
|
||||
|
||||
rc = mutex_lock_interruptible(&erst_record_id_cache.lock);
|
||||
if (rc)
|
||||
return rc;
|
||||
raw_spin_lock_irqsave(&erst_lock, flags);
|
||||
if (erst_erange.attr & ERST_RANGE_NVRAM)
|
||||
rc = __erst_clear_from_nvram(record_id);
|
||||
else
|
||||
rc = __erst_clear_from_storage(record_id);
|
||||
raw_spin_unlock_irqrestore(&erst_lock, flags);
|
||||
|
||||
if (rc)
|
||||
goto out;
|
||||
entries = erst_record_id_cache.entries;
|
||||
for (i = 0; i < erst_record_id_cache.len; i++) {
|
||||
if (entries[i] == record_id)
|
||||
entries[i] = APEI_ERST_INVALID_RECORD_ID;
|
||||
}
|
||||
__erst_record_id_cache_compact();
|
||||
out:
|
||||
mutex_unlock(&erst_record_id_cache.lock);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(erst_clear);
|
||||
|
|
@ -781,6 +929,128 @@ 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,
|
||||
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",
|
||||
.read = erst_reader,
|
||||
.write = erst_writer,
|
||||
.erase = erst_clear
|
||||
};
|
||||
|
||||
#define CPER_CREATOR_PSTORE \
|
||||
UUID_LE(0x75a574e3, 0x5052, 0x4b29, 0x8a, 0x8e, 0xbe, 0x2c, \
|
||||
0x64, 0x90, 0xb8, 0x9d)
|
||||
#define CPER_SECTION_TYPE_DMESG \
|
||||
UUID_LE(0xc197e04e, 0xd545, 0x4a70, 0x9c, 0x17, 0xa5, 0x54, \
|
||||
0x94, 0x19, 0xeb, 0x12)
|
||||
#define CPER_SECTION_TYPE_MCE \
|
||||
UUID_LE(0xfe08ffbe, 0x95e4, 0x4be7, 0xbc, 0x73, 0x40, 0x96, \
|
||||
0x04, 0x4a, 0x38, 0xfc)
|
||||
|
||||
struct cper_pstore_record {
|
||||
struct cper_record_header hdr;
|
||||
struct cper_section_descriptor sec_hdr;
|
||||
char data[];
|
||||
} __packed;
|
||||
|
||||
static size_t erst_reader(u64 *id, enum pstore_type_id *type,
|
||||
struct timespec *time)
|
||||
{
|
||||
int rc;
|
||||
ssize_t len;
|
||||
unsigned long flags;
|
||||
u64 record_id;
|
||||
struct cper_pstore_record *rcd = (struct cper_pstore_record *)
|
||||
(erst_info.buf - sizeof(*rcd));
|
||||
|
||||
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;
|
||||
}
|
||||
/* no more record */
|
||||
if (record_id == APEI_ERST_INVALID_RECORD_ID) {
|
||||
raw_spin_unlock_irqrestore(&erst_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = __erst_read(record_id, &rcd->hdr, sizeof(*rcd) +
|
||||
erst_erange.size);
|
||||
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,
|
||||
CPER_SECTION_TYPE_DMESG) == 0)
|
||||
*type = PSTORE_TYPE_DMESG;
|
||||
else if (uuid_le_cmp(rcd->sec_hdr.section_type,
|
||||
CPER_SECTION_TYPE_MCE) == 0)
|
||||
*type = PSTORE_TYPE_MCE;
|
||||
else
|
||||
*type = PSTORE_TYPE_UNKNOWN;
|
||||
|
||||
if (rcd->hdr.validation_bits & CPER_VALID_TIMESTAMP)
|
||||
time->tv_sec = rcd->hdr.timestamp;
|
||||
else
|
||||
time->tv_sec = 0;
|
||||
time->tv_nsec = 0;
|
||||
|
||||
return len - sizeof(*rcd);
|
||||
}
|
||||
|
||||
static u64 erst_writer(enum pstore_type_id type, size_t size)
|
||||
{
|
||||
struct cper_pstore_record *rcd = (struct cper_pstore_record *)
|
||||
(erst_info.buf - sizeof(*rcd));
|
||||
|
||||
memset(rcd, 0, sizeof(*rcd));
|
||||
memcpy(rcd->hdr.signature, CPER_SIG_RECORD, CPER_SIG_SIZE);
|
||||
rcd->hdr.revision = CPER_RECORD_REV;
|
||||
rcd->hdr.signature_end = CPER_SIG_END;
|
||||
rcd->hdr.section_count = 1;
|
||||
rcd->hdr.error_severity = CPER_SEV_FATAL;
|
||||
/* timestamp valid. platform_id, partition_id are invalid */
|
||||
rcd->hdr.validation_bits = CPER_VALID_TIMESTAMP;
|
||||
rcd->hdr.timestamp = get_seconds();
|
||||
rcd->hdr.record_length = sizeof(*rcd) + size;
|
||||
rcd->hdr.creator_id = CPER_CREATOR_PSTORE;
|
||||
rcd->hdr.notification_type = CPER_NOTIFY_MCE;
|
||||
rcd->hdr.record_id = cper_next_record_id();
|
||||
rcd->hdr.flags = CPER_HW_ERROR_FLAGS_PREVERR;
|
||||
|
||||
rcd->sec_hdr.section_offset = sizeof(*rcd);
|
||||
rcd->sec_hdr.section_length = size;
|
||||
rcd->sec_hdr.revision = CPER_SEC_REV;
|
||||
/* fru_id and fru_text is invalid */
|
||||
rcd->sec_hdr.validation_bits = 0;
|
||||
rcd->sec_hdr.flags = CPER_SEC_PRIMARY;
|
||||
switch (type) {
|
||||
case PSTORE_TYPE_DMESG:
|
||||
rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG;
|
||||
break;
|
||||
case PSTORE_TYPE_MCE:
|
||||
rcd->sec_hdr.section_type = CPER_SECTION_TYPE_MCE;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
rcd->sec_hdr.section_severity = CPER_SEV_FATAL;
|
||||
|
||||
erst_write(&rcd->hdr);
|
||||
|
||||
return rcd->hdr.record_id;
|
||||
}
|
||||
|
||||
static int __init erst_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -788,6 +1058,7 @@ static int __init erst_init(void)
|
|||
struct apei_exec_context ctx;
|
||||
struct apei_resources erst_resources;
|
||||
struct resource *r;
|
||||
char *buf;
|
||||
|
||||
if (acpi_disabled)
|
||||
goto err;
|
||||
|
|
@ -854,6 +1125,18 @@ static int __init erst_init(void)
|
|||
if (!erst_erange.vaddr)
|
||||
goto err_release_erange;
|
||||
|
||||
buf = kmalloc(erst_erange.size, GFP_KERNEL);
|
||||
mutex_init(&erst_info.buf_mutex);
|
||||
if (buf) {
|
||||
erst_info.buf = buf + sizeof(struct cper_pstore_record);
|
||||
erst_info.bufsize = erst_erange.size -
|
||||
sizeof(struct cper_pstore_record);
|
||||
if (pstore_register(&erst_info)) {
|
||||
pr_info(ERST_PFX "Could not register with persistent store\n");
|
||||
kfree(buf);
|
||||
}
|
||||
}
|
||||
|
||||
pr_info(ERST_PFX
|
||||
"Error Record Serialization Table (ERST) support is initialized.\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ static inline int ghes_severity(int severity)
|
|||
case CPER_SEV_FATAL:
|
||||
return GHES_SEV_PANIC;
|
||||
default:
|
||||
/* Unkown, go panic */
|
||||
/* Unknown, go panic */
|
||||
return GHES_SEV_PANIC;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include <linux/async.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
#include <linux/proc_fs.h>
|
||||
|
|
@ -102,6 +103,7 @@ struct acpi_battery {
|
|||
struct mutex lock;
|
||||
struct power_supply bat;
|
||||
struct acpi_device *device;
|
||||
struct notifier_block pm_nb;
|
||||
unsigned long update_time;
|
||||
int rate_now;
|
||||
int capacity_now;
|
||||
|
|
@ -940,6 +942,21 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
|
|||
power_supply_changed(&battery->bat);
|
||||
}
|
||||
|
||||
static int battery_notify(struct notifier_block *nb,
|
||||
unsigned long mode, void *_unused)
|
||||
{
|
||||
struct acpi_battery *battery = container_of(nb, struct acpi_battery,
|
||||
pm_nb);
|
||||
switch (mode) {
|
||||
case PM_POST_SUSPEND:
|
||||
sysfs_remove_battery(battery);
|
||||
sysfs_add_battery(battery);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_battery_add(struct acpi_device *device)
|
||||
{
|
||||
int result = 0;
|
||||
|
|
@ -972,6 +989,10 @@ static int acpi_battery_add(struct acpi_device *device)
|
|||
#endif
|
||||
kfree(battery);
|
||||
}
|
||||
|
||||
battery->pm_nb.notifier_call = battery_notify;
|
||||
register_pm_notifier(&battery->pm_nb);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -982,6 +1003,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
|
|||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
battery = acpi_driver_data(device);
|
||||
unregister_pm_notifier(&battery->pm_nb);
|
||||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
acpi_battery_remove_fs(device);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include <acpi/acpi_bus.h>
|
||||
#include <acpi/acpi_drivers.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
|
@ -226,7 +227,7 @@ static int __acpi_bus_set_power(struct acpi_device *device, int state)
|
|||
acpi_status status = AE_OK;
|
||||
char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' };
|
||||
|
||||
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
|
||||
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
|
||||
return -EINVAL;
|
||||
|
||||
/* Make sure this is a valid target state */
|
||||
|
|
@ -1006,8 +1007,7 @@ struct kobject *acpi_kobj;
|
|||
|
||||
static int __init acpi_init(void)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
int result;
|
||||
|
||||
if (acpi_disabled) {
|
||||
printk(KERN_INFO PREFIX "Interpreter disabled.\n");
|
||||
|
|
@ -1022,29 +1022,18 @@ static int __init acpi_init(void)
|
|||
|
||||
init_acpi_device_notify();
|
||||
result = acpi_bus_init();
|
||||
|
||||
if (!result) {
|
||||
pci_mmcfg_late_init();
|
||||
if (!(pm_flags & PM_APM))
|
||||
pm_flags |= PM_ACPI;
|
||||
else {
|
||||
printk(KERN_INFO PREFIX
|
||||
"APM is already active, exiting\n");
|
||||
disable_acpi();
|
||||
result = -ENODEV;
|
||||
}
|
||||
} else
|
||||
if (result) {
|
||||
disable_acpi();
|
||||
|
||||
if (acpi_disabled)
|
||||
return result;
|
||||
}
|
||||
|
||||
pci_mmcfg_late_init();
|
||||
acpi_scan_init();
|
||||
acpi_ec_init();
|
||||
acpi_debugfs_init();
|
||||
acpi_sleep_proc_init();
|
||||
acpi_wakeup_device_init();
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(acpi_init);
|
||||
|
|
|
|||
|
|
@ -78,8 +78,6 @@ static int acpi_button_add(struct acpi_device *device);
|
|||
static int acpi_button_remove(struct acpi_device *device, int type);
|
||||
static int acpi_button_resume(struct acpi_device *device);
|
||||
static void acpi_button_notify(struct acpi_device *device, u32 event);
|
||||
static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
|
||||
static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
|
||||
|
||||
static struct acpi_driver acpi_button_driver = {
|
||||
.name = "button",
|
||||
|
|
@ -98,22 +96,7 @@ struct acpi_button {
|
|||
struct input_dev *input;
|
||||
char phys[32]; /* for input device */
|
||||
unsigned long pushed;
|
||||
};
|
||||
|
||||
static const struct file_operations acpi_button_info_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_button_info_open_fs,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static const struct file_operations acpi_button_state_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_button_state_open_fs,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
bool wakeup_enabled;
|
||||
};
|
||||
|
||||
static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
|
||||
|
|
@ -124,20 +107,7 @@ static struct acpi_device *lid_device;
|
|||
-------------------------------------------------------------------------- */
|
||||
|
||||
static struct proc_dir_entry *acpi_button_dir;
|
||||
|
||||
static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_device *device = seq->private;
|
||||
|
||||
seq_printf(seq, "type: %s\n",
|
||||
acpi_device_name(device));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_button_info_open_fs(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, acpi_button_info_seq_show, PDE(inode)->data);
|
||||
}
|
||||
static struct proc_dir_entry *acpi_lid_dir;
|
||||
|
||||
static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
|
|
@ -157,77 +127,85 @@ static int acpi_button_state_open_fs(struct inode *inode, struct file *file)
|
|||
return single_open(file, acpi_button_state_seq_show, PDE(inode)->data);
|
||||
}
|
||||
|
||||
static struct proc_dir_entry *acpi_power_dir;
|
||||
static struct proc_dir_entry *acpi_sleep_dir;
|
||||
static struct proc_dir_entry *acpi_lid_dir;
|
||||
static const struct file_operations acpi_button_state_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = acpi_button_state_open_fs,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int acpi_button_add_fs(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_button *button = acpi_driver_data(device);
|
||||
struct proc_dir_entry *entry = NULL;
|
||||
int ret = 0;
|
||||
|
||||
switch (button->type) {
|
||||
case ACPI_BUTTON_TYPE_POWER:
|
||||
if (!acpi_power_dir)
|
||||
acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER,
|
||||
acpi_button_dir);
|
||||
entry = acpi_power_dir;
|
||||
break;
|
||||
case ACPI_BUTTON_TYPE_SLEEP:
|
||||
if (!acpi_sleep_dir)
|
||||
acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP,
|
||||
acpi_button_dir);
|
||||
entry = acpi_sleep_dir;
|
||||
break;
|
||||
case ACPI_BUTTON_TYPE_LID:
|
||||
if (!acpi_lid_dir)
|
||||
acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID,
|
||||
acpi_button_dir);
|
||||
entry = acpi_lid_dir;
|
||||
break;
|
||||
/* procfs I/F for ACPI lid device only */
|
||||
if (button->type != ACPI_BUTTON_TYPE_LID)
|
||||
return 0;
|
||||
|
||||
if (acpi_button_dir || acpi_lid_dir) {
|
||||
printk(KERN_ERR PREFIX "More than one Lid device found!\n");
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
if (!entry)
|
||||
/* create /proc/acpi/button */
|
||||
acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
|
||||
if (!acpi_button_dir)
|
||||
return -ENODEV;
|
||||
|
||||
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry);
|
||||
if (!acpi_device_dir(device))
|
||||
return -ENODEV;
|
||||
/* create /proc/acpi/button/lid */
|
||||
acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
|
||||
if (!acpi_lid_dir) {
|
||||
ret = -ENODEV;
|
||||
goto remove_button_dir;
|
||||
}
|
||||
|
||||
/* 'info' [R] */
|
||||
entry = proc_create_data(ACPI_BUTTON_FILE_INFO,
|
||||
/* create /proc/acpi/button/lid/LID/ */
|
||||
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), acpi_lid_dir);
|
||||
if (!acpi_device_dir(device)) {
|
||||
ret = -ENODEV;
|
||||
goto remove_lid_dir;
|
||||
}
|
||||
|
||||
/* create /proc/acpi/button/lid/LID/state */
|
||||
entry = proc_create_data(ACPI_BUTTON_FILE_STATE,
|
||||
S_IRUGO, acpi_device_dir(device),
|
||||
&acpi_button_info_fops, device);
|
||||
if (!entry)
|
||||
return -ENODEV;
|
||||
|
||||
/* show lid state [R] */
|
||||
if (button->type == ACPI_BUTTON_TYPE_LID) {
|
||||
entry = proc_create_data(ACPI_BUTTON_FILE_STATE,
|
||||
S_IRUGO, acpi_device_dir(device),
|
||||
&acpi_button_state_fops, device);
|
||||
if (!entry)
|
||||
return -ENODEV;
|
||||
&acpi_button_state_fops, device);
|
||||
if (!entry) {
|
||||
ret = -ENODEV;
|
||||
goto remove_dev_dir;
|
||||
}
|
||||
|
||||
return 0;
|
||||
done:
|
||||
return ret;
|
||||
|
||||
remove_dev_dir:
|
||||
remove_proc_entry(acpi_device_bid(device),
|
||||
acpi_lid_dir);
|
||||
acpi_device_dir(device) = NULL;
|
||||
remove_lid_dir:
|
||||
remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
|
||||
remove_button_dir:
|
||||
remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
|
||||
goto done;
|
||||
}
|
||||
|
||||
static int acpi_button_remove_fs(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_button *button = acpi_driver_data(device);
|
||||
|
||||
if (acpi_device_dir(device)) {
|
||||
if (button->type == ACPI_BUTTON_TYPE_LID)
|
||||
remove_proc_entry(ACPI_BUTTON_FILE_STATE,
|
||||
acpi_device_dir(device));
|
||||
remove_proc_entry(ACPI_BUTTON_FILE_INFO,
|
||||
acpi_device_dir(device));
|
||||
if (button->type != ACPI_BUTTON_TYPE_LID)
|
||||
return 0;
|
||||
|
||||
remove_proc_entry(acpi_device_bid(device),
|
||||
acpi_device_dir(device)->parent);
|
||||
acpi_device_dir(device) = NULL;
|
||||
}
|
||||
remove_proc_entry(ACPI_BUTTON_FILE_STATE,
|
||||
acpi_device_dir(device));
|
||||
remove_proc_entry(acpi_device_bid(device),
|
||||
acpi_lid_dir);
|
||||
acpi_device_dir(device) = NULL;
|
||||
remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
|
||||
remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -430,8 +408,10 @@ static int acpi_button_add(struct acpi_device *device)
|
|||
/* Button's GPE is run-wake GPE */
|
||||
acpi_enable_gpe(device->wakeup.gpe_device,
|
||||
device->wakeup.gpe_number);
|
||||
device->wakeup.run_wake_count++;
|
||||
device_set_wakeup_enable(&device->dev, true);
|
||||
if (!device_may_wakeup(&device->dev)) {
|
||||
device_set_wakeup_enable(&device->dev, true);
|
||||
button->wakeup_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
|
||||
|
|
@ -453,8 +433,8 @@ static int acpi_button_remove(struct acpi_device *device, int type)
|
|||
if (device->wakeup.flags.valid) {
|
||||
acpi_disable_gpe(device->wakeup.gpe_device,
|
||||
device->wakeup.gpe_number);
|
||||
device->wakeup.run_wake_count--;
|
||||
device_set_wakeup_enable(&device->dev, false);
|
||||
if (button->wakeup_enabled)
|
||||
device_set_wakeup_enable(&device->dev, false);
|
||||
}
|
||||
|
||||
acpi_button_remove_fs(device);
|
||||
|
|
@ -465,32 +445,12 @@ static int acpi_button_remove(struct acpi_device *device, int type)
|
|||
|
||||
static int __init acpi_button_init(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
|
||||
if (!acpi_button_dir)
|
||||
return -ENODEV;
|
||||
|
||||
result = acpi_bus_register_driver(&acpi_button_driver);
|
||||
if (result < 0) {
|
||||
remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return acpi_bus_register_driver(&acpi_button_driver);
|
||||
}
|
||||
|
||||
static void __exit acpi_button_exit(void)
|
||||
{
|
||||
acpi_bus_unregister_driver(&acpi_button_driver);
|
||||
|
||||
if (acpi_power_dir)
|
||||
remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER, acpi_button_dir);
|
||||
if (acpi_sleep_dir)
|
||||
remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP, acpi_button_dir);
|
||||
if (acpi_lid_dir)
|
||||
remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
|
||||
remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
|
||||
}
|
||||
|
||||
module_init(acpi_button_init);
|
||||
|
|
|
|||
100
drivers/acpi/custom_method.c
Normal file
100
drivers/acpi/custom_method.c
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* debugfs.c - ACPI debugfs interface to userspace.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <acpi/acpi_drivers.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#define _COMPONENT ACPI_SYSTEM_COMPONENT
|
||||
ACPI_MODULE_NAME("custom_method");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static struct dentry *cm_dentry;
|
||||
|
||||
/* /sys/kernel/debug/acpi/custom_method */
|
||||
|
||||
static ssize_t cm_write(struct file *file, const char __user * user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
static char *buf;
|
||||
static u32 max_size;
|
||||
static u32 uncopied_bytes;
|
||||
|
||||
struct acpi_table_header table;
|
||||
acpi_status status;
|
||||
|
||||
if (!(*ppos)) {
|
||||
/* parse the table header to get the table length */
|
||||
if (count <= sizeof(struct acpi_table_header))
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&table, user_buf,
|
||||
sizeof(struct acpi_table_header)))
|
||||
return -EFAULT;
|
||||
uncopied_bytes = max_size = table.length;
|
||||
buf = kzalloc(max_size, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (buf == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if ((*ppos > max_size) ||
|
||||
(*ppos + count > max_size) ||
|
||||
(*ppos + count < count) ||
|
||||
(count > uncopied_bytes))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(buf + (*ppos), user_buf, count)) {
|
||||
kfree(buf);
|
||||
buf = NULL;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
uncopied_bytes -= count;
|
||||
*ppos += count;
|
||||
|
||||
if (!uncopied_bytes) {
|
||||
status = acpi_install_method(buf);
|
||||
kfree(buf);
|
||||
buf = NULL;
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EINVAL;
|
||||
add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations cm_fops = {
|
||||
.write = cm_write,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static int __init acpi_custom_method_init(void)
|
||||
{
|
||||
if (acpi_debugfs_dir == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
cm_dentry = debugfs_create_file("custom_method", S_IWUSR,
|
||||
acpi_debugfs_dir, NULL, &cm_fops);
|
||||
if (cm_dentry == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit acpi_custom_method_exit(void)
|
||||
{
|
||||
if (cm_dentry)
|
||||
debugfs_remove(cm_dentry);
|
||||
}
|
||||
|
||||
module_init(acpi_custom_method_init);
|
||||
module_exit(acpi_custom_method_exit);
|
||||
|
|
@ -3,92 +3,16 @@
|
|||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <acpi/acpi_drivers.h>
|
||||
|
||||
#define _COMPONENT ACPI_SYSTEM_COMPONENT
|
||||
ACPI_MODULE_NAME("debugfs");
|
||||
|
||||
struct dentry *acpi_debugfs_dir;
|
||||
EXPORT_SYMBOL_GPL(acpi_debugfs_dir);
|
||||
|
||||
/* /sys/modules/acpi/parameters/aml_debug_output */
|
||||
|
||||
module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object,
|
||||
bool, 0644);
|
||||
MODULE_PARM_DESC(aml_debug_output,
|
||||
"To enable/disable the ACPI Debug Object output.");
|
||||
|
||||
/* /sys/kernel/debug/acpi/custom_method */
|
||||
|
||||
static ssize_t cm_write(struct file *file, const char __user * user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
void __init acpi_debugfs_init(void)
|
||||
{
|
||||
static char *buf;
|
||||
static int uncopied_bytes;
|
||||
struct acpi_table_header table;
|
||||
acpi_status status;
|
||||
|
||||
if (!(*ppos)) {
|
||||
/* parse the table header to get the table length */
|
||||
if (count <= sizeof(struct acpi_table_header))
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&table, user_buf,
|
||||
sizeof(struct acpi_table_header)))
|
||||
return -EFAULT;
|
||||
uncopied_bytes = table.length;
|
||||
buf = kzalloc(uncopied_bytes, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (uncopied_bytes < count) {
|
||||
kfree(buf);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (copy_from_user(buf + (*ppos), user_buf, count)) {
|
||||
kfree(buf);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
uncopied_bytes -= count;
|
||||
*ppos += count;
|
||||
|
||||
if (!uncopied_bytes) {
|
||||
status = acpi_install_method(buf);
|
||||
kfree(buf);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EINVAL;
|
||||
add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations cm_fops = {
|
||||
.write = cm_write,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
int __init acpi_debugfs_init(void)
|
||||
{
|
||||
struct dentry *acpi_dir, *cm_dentry;
|
||||
|
||||
acpi_dir = debugfs_create_dir("acpi", NULL);
|
||||
if (!acpi_dir)
|
||||
goto err;
|
||||
|
||||
cm_dentry = debugfs_create_file("custom_method", S_IWUSR,
|
||||
acpi_dir, NULL, &cm_fops);
|
||||
if (!cm_dentry)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (acpi_dir)
|
||||
debugfs_remove(acpi_dir);
|
||||
return -EINVAL;
|
||||
acpi_debugfs_dir = debugfs_create_dir("acpi", NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -938,8 +938,19 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
|
|||
ec_flag_msi, "MSI hardware", {
|
||||
DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL},
|
||||
{
|
||||
ec_flag_msi, "Quanta hardware", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Quanta"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "TW8/SW8/DW8"),}, NULL},
|
||||
{
|
||||
ec_flag_msi, "Quanta hardware", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Quanta"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "TW9/SW9"),}, NULL},
|
||||
{
|
||||
ec_validate_ecdt, "ASUS hardware", {
|
||||
DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
|
||||
{
|
||||
ec_validate_ecdt, "ASUS hardware", {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc.") }, NULL},
|
||||
{},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,6 @@ MODULE_PARM_DESC(write_support, "Dangerous, reboot and removal of battery may "
|
|||
|
||||
#define EC_SPACE_SIZE 256
|
||||
|
||||
struct sysdev_class acpi_ec_sysdev_class = {
|
||||
.name = "ec",
|
||||
};
|
||||
|
||||
static struct dentry *acpi_ec_debugfs_dir;
|
||||
|
||||
static int acpi_ec_open_io(struct inode *i, struct file *f)
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@
|
|||
#ifndef _ACPI_INTERNAL_H_
|
||||
#define _ACPI_INTERNAL_H_
|
||||
|
||||
#include <linux/sysdev.h>
|
||||
|
||||
#define PREFIX "ACPI: "
|
||||
|
||||
int init_acpi_device_notify(void);
|
||||
|
|
@ -30,9 +28,10 @@ int acpi_scan_init(void);
|
|||
int acpi_sysfs_init(void);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
extern struct dentry *acpi_debugfs_dir;
|
||||
int acpi_debugfs_init(void);
|
||||
#else
|
||||
static inline int acpi_debugfs_init(void) { return 0; }
|
||||
static inline void acpi_debugfs_init(void) { return; }
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
|
|
@ -64,7 +63,6 @@ struct acpi_ec {
|
|||
struct list_head list;
|
||||
struct transaction *curr;
|
||||
spinlock_t curr_lock;
|
||||
struct sys_device sysdev;
|
||||
};
|
||||
|
||||
extern struct acpi_ec *first_ec;
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ acpi_table_parse_srat(enum acpi_srat_type id,
|
|||
|
||||
int __init acpi_numa_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int cnt = 0;
|
||||
|
||||
/*
|
||||
* Should not limit number with cpu num that is from NR_CPUS or nr_cpus=
|
||||
|
|
@ -288,7 +288,7 @@ int __init acpi_numa_init(void)
|
|||
acpi_parse_x2apic_affinity, 0);
|
||||
acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
|
||||
acpi_parse_processor_affinity, 0);
|
||||
ret = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
|
||||
cnt = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
|
||||
acpi_parse_memory_affinity,
|
||||
NR_NODE_MEMBLKS);
|
||||
}
|
||||
|
|
@ -297,7 +297,10 @@ int __init acpi_numa_init(void)
|
|||
acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
|
||||
|
||||
acpi_numa_arch_fixup();
|
||||
return ret;
|
||||
|
||||
if (cnt <= 0)
|
||||
return cnt ?: -ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acpi_get_pxm(acpi_handle h)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ struct nvs_page {
|
|||
unsigned int size;
|
||||
void *kaddr;
|
||||
void *data;
|
||||
bool unmap;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
|
|
@ -44,6 +45,9 @@ int suspend_nvs_register(unsigned long start, unsigned long size)
|
|||
{
|
||||
struct nvs_page *entry, *next;
|
||||
|
||||
pr_info("PM: Registering ACPI NVS region at %lx (%ld bytes)\n",
|
||||
start, size);
|
||||
|
||||
while (size > 0) {
|
||||
unsigned int nr_bytes;
|
||||
|
||||
|
|
@ -81,7 +85,13 @@ void suspend_nvs_free(void)
|
|||
free_page((unsigned long)entry->data);
|
||||
entry->data = NULL;
|
||||
if (entry->kaddr) {
|
||||
iounmap(entry->kaddr);
|
||||
if (entry->unmap) {
|
||||
iounmap(entry->kaddr);
|
||||
entry->unmap = false;
|
||||
} else {
|
||||
acpi_os_unmap_memory(entry->kaddr,
|
||||
entry->size);
|
||||
}
|
||||
entry->kaddr = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -115,8 +125,14 @@ int suspend_nvs_save(void)
|
|||
|
||||
list_for_each_entry(entry, &nvs_list, node)
|
||||
if (entry->data) {
|
||||
entry->kaddr = acpi_os_ioremap(entry->phys_start,
|
||||
entry->size);
|
||||
unsigned long phys = entry->phys_start;
|
||||
unsigned int size = entry->size;
|
||||
|
||||
entry->kaddr = acpi_os_get_iomem(phys, size);
|
||||
if (!entry->kaddr) {
|
||||
entry->kaddr = acpi_os_ioremap(phys, size);
|
||||
entry->unmap = !!entry->kaddr;
|
||||
}
|
||||
if (!entry->kaddr) {
|
||||
suspend_nvs_free();
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@ EXPORT_SYMBOL(acpi_in_debugger);
|
|||
extern char line_buf[80];
|
||||
#endif /*ENABLE_DEBUGGER */
|
||||
|
||||
static unsigned int acpi_irq_irq;
|
||||
static acpi_osd_handler acpi_irq_handler;
|
||||
static void *acpi_irq_context;
|
||||
static struct workqueue_struct *kacpid_wq;
|
||||
|
|
@ -105,11 +104,11 @@ struct acpi_ioremap {
|
|||
void __iomem *virt;
|
||||
acpi_physical_address phys;
|
||||
acpi_size size;
|
||||
struct kref ref;
|
||||
unsigned long refcount;
|
||||
};
|
||||
|
||||
static LIST_HEAD(acpi_ioremaps);
|
||||
static DEFINE_SPINLOCK(acpi_ioremap_lock);
|
||||
static DEFINE_MUTEX(acpi_ioremap_lock);
|
||||
|
||||
static void __init acpi_osi_setup_late(void);
|
||||
|
||||
|
|
@ -285,6 +284,22 @@ acpi_map_vaddr_lookup(acpi_physical_address phys, unsigned int size)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size)
|
||||
{
|
||||
struct acpi_ioremap *map;
|
||||
void __iomem *virt = NULL;
|
||||
|
||||
mutex_lock(&acpi_ioremap_lock);
|
||||
map = acpi_map_lookup(phys, size);
|
||||
if (map) {
|
||||
virt = map->virt + (phys - map->phys);
|
||||
map->refcount++;
|
||||
}
|
||||
mutex_unlock(&acpi_ioremap_lock);
|
||||
return virt;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_os_get_iomem);
|
||||
|
||||
/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
|
||||
static struct acpi_ioremap *
|
||||
acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
|
||||
|
|
@ -302,8 +317,7 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
|
|||
void __iomem *__init_refok
|
||||
acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
|
||||
{
|
||||
struct acpi_ioremap *map, *tmp_map;
|
||||
unsigned long flags;
|
||||
struct acpi_ioremap *map;
|
||||
void __iomem *virt;
|
||||
acpi_physical_address pg_off;
|
||||
acpi_size pg_sz;
|
||||
|
|
@ -316,14 +330,25 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
|
|||
if (!acpi_gbl_permanent_mmap)
|
||||
return __acpi_map_table((unsigned long)phys, size);
|
||||
|
||||
mutex_lock(&acpi_ioremap_lock);
|
||||
/* Check if there's a suitable mapping already. */
|
||||
map = acpi_map_lookup(phys, size);
|
||||
if (map) {
|
||||
map->refcount++;
|
||||
goto out;
|
||||
}
|
||||
|
||||
map = kzalloc(sizeof(*map), GFP_KERNEL);
|
||||
if (!map)
|
||||
if (!map) {
|
||||
mutex_unlock(&acpi_ioremap_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pg_off = round_down(phys, PAGE_SIZE);
|
||||
pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
|
||||
virt = acpi_os_ioremap(pg_off, pg_sz);
|
||||
if (!virt) {
|
||||
mutex_unlock(&acpi_ioremap_lock);
|
||||
kfree(map);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -332,62 +357,51 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
|
|||
map->virt = virt;
|
||||
map->phys = pg_off;
|
||||
map->size = pg_sz;
|
||||
kref_init(&map->ref);
|
||||
map->refcount = 1;
|
||||
|
||||
spin_lock_irqsave(&acpi_ioremap_lock, flags);
|
||||
/* Check if page has already been mapped. */
|
||||
tmp_map = acpi_map_lookup(phys, size);
|
||||
if (tmp_map) {
|
||||
kref_get(&tmp_map->ref);
|
||||
spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
|
||||
iounmap(map->virt);
|
||||
kfree(map);
|
||||
return tmp_map->virt + (phys - tmp_map->phys);
|
||||
}
|
||||
list_add_tail_rcu(&map->list, &acpi_ioremaps);
|
||||
spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
|
||||
|
||||
out:
|
||||
mutex_unlock(&acpi_ioremap_lock);
|
||||
return map->virt + (phys - map->phys);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_os_map_memory);
|
||||
|
||||
static void acpi_kref_del_iomap(struct kref *ref)
|
||||
static void acpi_os_drop_map_ref(struct acpi_ioremap *map)
|
||||
{
|
||||
struct acpi_ioremap *map;
|
||||
if (!--map->refcount)
|
||||
list_del_rcu(&map->list);
|
||||
}
|
||||
|
||||
map = container_of(ref, struct acpi_ioremap, ref);
|
||||
list_del_rcu(&map->list);
|
||||
static void acpi_os_map_cleanup(struct acpi_ioremap *map)
|
||||
{
|
||||
if (!map->refcount) {
|
||||
synchronize_rcu();
|
||||
iounmap(map->virt);
|
||||
kfree(map);
|
||||
}
|
||||
}
|
||||
|
||||
void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
|
||||
{
|
||||
struct acpi_ioremap *map;
|
||||
unsigned long flags;
|
||||
int del;
|
||||
|
||||
if (!acpi_gbl_permanent_mmap) {
|
||||
__acpi_unmap_table(virt, size);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&acpi_ioremap_lock, flags);
|
||||
mutex_lock(&acpi_ioremap_lock);
|
||||
map = acpi_map_lookup_virt(virt, size);
|
||||
if (!map) {
|
||||
spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
|
||||
printk(KERN_ERR PREFIX "%s: bad address %p\n", __func__, virt);
|
||||
dump_stack();
|
||||
mutex_unlock(&acpi_ioremap_lock);
|
||||
WARN(true, PREFIX "%s: bad address %p\n", __func__, virt);
|
||||
return;
|
||||
}
|
||||
acpi_os_drop_map_ref(map);
|
||||
mutex_unlock(&acpi_ioremap_lock);
|
||||
|
||||
del = kref_put(&map->ref, acpi_kref_del_iomap);
|
||||
spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
|
||||
|
||||
if (!del)
|
||||
return;
|
||||
|
||||
synchronize_rcu();
|
||||
iounmap(map->virt);
|
||||
kfree(map);
|
||||
acpi_os_map_cleanup(map);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
|
||||
|
||||
|
|
@ -397,7 +411,7 @@ void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
|
|||
__acpi_unmap_table(virt, size);
|
||||
}
|
||||
|
||||
int acpi_os_map_generic_address(struct acpi_generic_address *addr)
|
||||
static int acpi_os_map_generic_address(struct acpi_generic_address *addr)
|
||||
{
|
||||
void __iomem *virt;
|
||||
|
||||
|
|
@ -413,13 +427,10 @@ int acpi_os_map_generic_address(struct acpi_generic_address *addr)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_os_map_generic_address);
|
||||
|
||||
void acpi_os_unmap_generic_address(struct acpi_generic_address *addr)
|
||||
static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr)
|
||||
{
|
||||
void __iomem *virt;
|
||||
unsigned long flags;
|
||||
acpi_size size = addr->bit_width / 8;
|
||||
struct acpi_ioremap *map;
|
||||
|
||||
if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
|
||||
return;
|
||||
|
|
@ -427,13 +438,17 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *addr)
|
|||
if (!addr->address || !addr->bit_width)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&acpi_ioremap_lock, flags);
|
||||
virt = acpi_map_vaddr_lookup(addr->address, size);
|
||||
spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
|
||||
mutex_lock(&acpi_ioremap_lock);
|
||||
map = acpi_map_lookup(addr->address, addr->bit_width / 8);
|
||||
if (!map) {
|
||||
mutex_unlock(&acpi_ioremap_lock);
|
||||
return;
|
||||
}
|
||||
acpi_os_drop_map_ref(map);
|
||||
mutex_unlock(&acpi_ioremap_lock);
|
||||
|
||||
acpi_os_unmap_memory(virt, size);
|
||||
acpi_os_map_cleanup(map);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_os_unmap_generic_address);
|
||||
|
||||
#ifdef ACPI_FUTURE_USAGE
|
||||
acpi_status
|
||||
|
|
@ -516,11 +531,15 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
|
|||
acpi_irq_stats_init();
|
||||
|
||||
/*
|
||||
* Ignore the GSI from the core, and use the value in our copy of the
|
||||
* FADT. It may not be the same if an interrupt source override exists
|
||||
* for the SCI.
|
||||
* ACPI interrupts different from the SCI in our copy of the FADT are
|
||||
* not supported.
|
||||
*/
|
||||
gsi = acpi_gbl_FADT.sci_interrupt;
|
||||
if (gsi != acpi_gbl_FADT.sci_interrupt)
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
if (acpi_irq_handler)
|
||||
return AE_ALREADY_ACQUIRED;
|
||||
|
||||
if (acpi_gsi_to_irq(gsi, &irq) < 0) {
|
||||
printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n",
|
||||
gsi);
|
||||
|
|
@ -531,20 +550,20 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
|
|||
acpi_irq_context = context;
|
||||
if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
|
||||
printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
|
||||
acpi_irq_handler = NULL;
|
||||
return AE_NOT_ACQUIRED;
|
||||
}
|
||||
acpi_irq_irq = irq;
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
|
||||
{
|
||||
if (irq) {
|
||||
free_irq(irq, acpi_irq);
|
||||
acpi_irq_handler = NULL;
|
||||
acpi_irq_irq = 0;
|
||||
}
|
||||
if (irq != acpi_gbl_FADT.sci_interrupt)
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
free_irq(irq, acpi_irq);
|
||||
acpi_irq_handler = NULL;
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
|
@ -1606,9 +1625,9 @@ acpi_status __init acpi_os_initialize(void)
|
|||
|
||||
acpi_status __init acpi_os_initialize1(void)
|
||||
{
|
||||
kacpid_wq = create_workqueue("kacpid");
|
||||
kacpi_notify_wq = create_workqueue("kacpi_notify");
|
||||
kacpi_hotplug_wq = create_workqueue("kacpi_hotplug");
|
||||
kacpid_wq = alloc_workqueue("kacpid", 0, 1);
|
||||
kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
|
||||
kacpi_hotplug_wq = alloc_workqueue("kacpi_hotplug", 0, 1);
|
||||
BUG_ON(!kacpid_wq);
|
||||
BUG_ON(!kacpi_notify_wq);
|
||||
BUG_ON(!kacpi_hotplug_wq);
|
||||
|
|
@ -1620,7 +1639,7 @@ acpi_status __init acpi_os_initialize1(void)
|
|||
acpi_status acpi_os_terminate(void)
|
||||
{
|
||||
if (acpi_irq_handler) {
|
||||
acpi_os_remove_interrupt_handler(acpi_irq_irq,
|
||||
acpi_os_remove_interrupt_handler(acpi_gbl_FADT.sci_interrupt,
|
||||
acpi_irq_handler);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
* for IRQ management (e.g. start()->_SRS).
|
||||
*/
|
||||
|
||||
#include <linux/sysdev.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
|
|
@ -757,14 +757,13 @@ static int acpi_pci_link_resume(struct acpi_pci_link *link)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int irqrouter_resume(struct sys_device *dev)
|
||||
static void irqrouter_resume(void)
|
||||
{
|
||||
struct acpi_pci_link *link;
|
||||
|
||||
list_for_each_entry(link, &acpi_link_list, list) {
|
||||
acpi_pci_link_resume(link);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_pci_link_remove(struct acpi_device *device, int type)
|
||||
|
|
@ -871,32 +870,19 @@ static int __init acpi_irq_balance_set(char *str)
|
|||
|
||||
__setup("acpi_irq_balance", acpi_irq_balance_set);
|
||||
|
||||
/* FIXME: we will remove this interface after all drivers call pci_disable_device */
|
||||
static struct sysdev_class irqrouter_sysdev_class = {
|
||||
.name = "irqrouter",
|
||||
static struct syscore_ops irqrouter_syscore_ops = {
|
||||
.resume = irqrouter_resume,
|
||||
};
|
||||
|
||||
static struct sys_device device_irqrouter = {
|
||||
.id = 0,
|
||||
.cls = &irqrouter_sysdev_class,
|
||||
};
|
||||
|
||||
static int __init irqrouter_init_sysfs(void)
|
||||
static int __init irqrouter_init_ops(void)
|
||||
{
|
||||
int error;
|
||||
if (!acpi_disabled && !acpi_noirq)
|
||||
register_syscore_ops(&irqrouter_syscore_ops);
|
||||
|
||||
if (acpi_disabled || acpi_noirq)
|
||||
return 0;
|
||||
|
||||
error = sysdev_class_register(&irqrouter_sysdev_class);
|
||||
if (!error)
|
||||
error = sysdev_register(&device_irqrouter);
|
||||
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_initcall(irqrouter_init_sysfs);
|
||||
device_initcall(irqrouter_init_ops);
|
||||
|
||||
static int __init acpi_pci_link_init(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/pm_runtime.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci-acpi.h>
|
||||
#include <linux/pci-aspm.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/slab.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
|
|
@ -564,7 +565,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
|||
/* Indicate support for various _OSC capabilities. */
|
||||
if (pci_ext_cfg_avail(root->bus->self))
|
||||
flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
|
||||
if (pcie_aspm_enabled())
|
||||
if (pcie_aspm_support_enabled())
|
||||
flags |= OSC_ACTIVE_STATE_PWR_SUPPORT |
|
||||
OSC_CLOCK_PWR_CAPABILITY_SUPPORT;
|
||||
if (pci_msi_enabled())
|
||||
|
|
@ -591,12 +592,16 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
|||
|
||||
status = acpi_pci_osc_control_set(device->handle, &flags,
|
||||
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
|
||||
if (ACPI_SUCCESS(status))
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
dev_info(root->bus->bridge,
|
||||
"ACPI _OSC control (0x%02x) granted\n", flags);
|
||||
else
|
||||
} 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");
|
||||
pcie_no_aspm();
|
||||
}
|
||||
}
|
||||
|
||||
pci_acpi_add_bus_pm_notifier(device, root->bus);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
|
||||
ACPI_MODULE_NAME("processor_core");
|
||||
|
||||
static int set_no_mwait(const struct dmi_system_id *id)
|
||||
static int __init set_no_mwait(const struct dmi_system_id *id)
|
||||
{
|
||||
printk(KERN_NOTICE PREFIX "%s detected - "
|
||||
"disabling mwait for CPU C-states\n", id->ident);
|
||||
|
|
@ -27,7 +27,7 @@ static int set_no_mwait(const struct dmi_system_id *id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
|
||||
static struct dmi_system_id __initdata processor_idle_dmi_table[] = {
|
||||
{
|
||||
set_no_mwait, "Extensa 5220", {
|
||||
DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
|
||||
|
|
@ -37,7 +37,6 @@ static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
|
|||
{},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static int map_lapic_id(struct acpi_subtable_header *entry,
|
||||
u32 acpi_id, int *apic_id)
|
||||
{
|
||||
|
|
@ -165,7 +164,9 @@ exit:
|
|||
|
||||
int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
int i;
|
||||
#endif
|
||||
int apic_id = -1;
|
||||
|
||||
apic_id = map_mat_entry(handle, type, acpi_id);
|
||||
|
|
@ -174,16 +175,21 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
|
|||
if (apic_id == -1)
|
||||
return apic_id;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
for_each_possible_cpu(i) {
|
||||
if (cpu_physical_id(i) == apic_id)
|
||||
return i;
|
||||
}
|
||||
#else
|
||||
/* In UP kernel, only processor 0 is valid */
|
||||
if (apic_id == 0)
|
||||
return apic_id;
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_get_cpuid);
|
||||
#endif
|
||||
|
||||
static bool processor_physically_present(acpi_handle handle)
|
||||
static bool __init processor_physically_present(acpi_handle handle)
|
||||
{
|
||||
int cpuid, type;
|
||||
u32 acpi_id;
|
||||
|
|
@ -217,13 +223,13 @@ static bool processor_physically_present(acpi_handle handle)
|
|||
type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
|
||||
cpuid = acpi_get_cpuid(handle, type, acpi_id);
|
||||
|
||||
if ((cpuid == -1) && (num_possible_cpus() > 1))
|
||||
if (cpuid == -1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void acpi_set_pdc_bits(u32 *buf)
|
||||
static void __cpuinit acpi_set_pdc_bits(u32 *buf)
|
||||
{
|
||||
buf[0] = ACPI_PDC_REVISION_ID;
|
||||
buf[1] = 1;
|
||||
|
|
@ -235,7 +241,7 @@ static void acpi_set_pdc_bits(u32 *buf)
|
|||
arch_acpi_set_pdc_bits(buf);
|
||||
}
|
||||
|
||||
static struct acpi_object_list *acpi_processor_alloc_pdc(void)
|
||||
static struct acpi_object_list *__cpuinit acpi_processor_alloc_pdc(void)
|
||||
{
|
||||
struct acpi_object_list *obj_list;
|
||||
union acpi_object *obj;
|
||||
|
|
@ -278,7 +284,7 @@ static struct acpi_object_list *acpi_processor_alloc_pdc(void)
|
|||
* _PDC is required for a BIOS-OS handshake for most of the newer
|
||||
* ACPI processor features.
|
||||
*/
|
||||
static int
|
||||
static int __cpuinit
|
||||
acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
|
|
@ -306,7 +312,7 @@ acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
|
|||
return status;
|
||||
}
|
||||
|
||||
void acpi_processor_set_pdc(acpi_handle handle)
|
||||
void __cpuinit acpi_processor_set_pdc(acpi_handle handle)
|
||||
{
|
||||
struct acpi_object_list *obj_list;
|
||||
|
||||
|
|
@ -323,9 +329,8 @@ void acpi_processor_set_pdc(acpi_handle handle)
|
|||
kfree(obj_list->pointer);
|
||||
kfree(obj_list);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_processor_set_pdc);
|
||||
|
||||
static acpi_status
|
||||
static acpi_status __init
|
||||
early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
|
||||
{
|
||||
if (processor_physically_present(handle) == false)
|
||||
|
|
|
|||
|
|
@ -635,8 +635,8 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void __ref acpi_processor_hotplug_notify(acpi_handle handle,
|
||||
u32 event, void *data)
|
||||
static void acpi_processor_hotplug_notify(acpi_handle handle,
|
||||
u32 event, void *data)
|
||||
{
|
||||
struct acpi_processor *pr;
|
||||
struct acpi_device *device = NULL;
|
||||
|
|
|
|||
|
|
@ -1164,7 +1164,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
|
|||
*/
|
||||
if (!match_pr->flags.throttling) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Throttling Controll is unsupported "
|
||||
"Throttling Control is unsupported "
|
||||
"on CPU %d\n", i));
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,9 +15,15 @@ void acpi_reboot(void)
|
|||
|
||||
rr = &acpi_gbl_FADT.reset_register;
|
||||
|
||||
/* Is the reset register supported? */
|
||||
if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
|
||||
rr->bit_width != 8 || rr->bit_offset != 0)
|
||||
/* ACPI reset register was only introduced with v2 of the FADT */
|
||||
|
||||
if (acpi_gbl_FADT.header.revision < 2)
|
||||
return;
|
||||
|
||||
/* Is the reset register supported? The spec says we should be
|
||||
* checking the bit width and bit offset, but Windows ignores
|
||||
* these fields */
|
||||
if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER))
|
||||
return;
|
||||
|
||||
reset_value = acpi_gbl_FADT.reset_value;
|
||||
|
|
@ -45,6 +51,4 @@ void acpi_reboot(void)
|
|||
acpi_reset();
|
||||
break;
|
||||
}
|
||||
/* Wait ten seconds */
|
||||
acpi_os_stall(10000000);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -797,7 +797,6 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
|
|||
acpi_status status;
|
||||
acpi_event_status event_status;
|
||||
|
||||
device->wakeup.run_wake_count = 0;
|
||||
device->wakeup.flags.notifier_present = 0;
|
||||
|
||||
/* Power button, Lid switch always enable wakeup */
|
||||
|
|
@ -944,6 +943,10 @@ static int acpi_bus_get_flags(struct acpi_device *device)
|
|||
if (ACPI_SUCCESS(status))
|
||||
device->flags.lockable = 1;
|
||||
|
||||
/* Power resources cannot be power manageable. */
|
||||
if (device->device_type == ACPI_BUS_TYPE_POWER)
|
||||
return 0;
|
||||
|
||||
/* Presence of _PS0|_PR0 indicates 'power manageable' */
|
||||
status = acpi_get_handle(device->handle, "_PS0", &temp);
|
||||
if (ACPI_FAILURE(status))
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
|
|
@ -199,8 +200,6 @@ static void acpi_pm_end(void)
|
|||
#endif /* CONFIG_ACPI_SLEEP */
|
||||
|
||||
#ifdef CONFIG_SUSPEND
|
||||
extern void do_suspend_lowlevel(void);
|
||||
|
||||
static u32 acpi_suspend_states[] = {
|
||||
[PM_SUSPEND_ON] = ACPI_STATE_S0,
|
||||
[PM_SUSPEND_STANDBY] = ACPI_STATE_S1,
|
||||
|
|
@ -243,20 +242,11 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
|
|||
static int acpi_suspend_enter(suspend_state_t pm_state)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
unsigned long flags = 0;
|
||||
u32 acpi_state = acpi_target_sleep_state;
|
||||
int error;
|
||||
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
||||
/* Do arch specific saving of state. */
|
||||
if (acpi_state == ACPI_STATE_S3) {
|
||||
int error = acpi_save_state_mem();
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
switch (acpi_state) {
|
||||
case ACPI_STATE_S1:
|
||||
barrier();
|
||||
|
|
@ -264,7 +254,10 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
|
|||
break;
|
||||
|
||||
case ACPI_STATE_S3:
|
||||
do_suspend_lowlevel();
|
||||
error = acpi_suspend_lowlevel();
|
||||
if (error)
|
||||
return error;
|
||||
pr_info(PREFIX "Low-level resume complete\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -290,13 +283,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
|
|||
/* Allow EC transactions to happen. */
|
||||
acpi_ec_unblock_transactions_early();
|
||||
|
||||
local_irq_restore(flags);
|
||||
printk(KERN_DEBUG "Back to C!\n");
|
||||
|
||||
/* restore processor state */
|
||||
if (acpi_state == ACPI_STATE_S3)
|
||||
acpi_restore_state_mem();
|
||||
|
||||
suspend_nvs_restore();
|
||||
|
||||
return ACPI_SUCCESS(status) ? 0 : -EFAULT;
|
||||
|
|
@ -472,16 +458,13 @@ static int acpi_hibernation_begin(void)
|
|||
static int acpi_hibernation_enter(void)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
unsigned long flags = 0;
|
||||
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
||||
local_irq_save(flags);
|
||||
/* This shouldn't return. If it returns, we have a problem */
|
||||
status = acpi_enter_sleep_state(ACPI_STATE_S4);
|
||||
/* Reprogram control registers and execute _BFS */
|
||||
acpi_leave_sleep_state_prep(ACPI_STATE_S4);
|
||||
local_irq_restore(flags);
|
||||
|
||||
return ACPI_SUCCESS(status) ? 0 : -EFAULT;
|
||||
}
|
||||
|
|
@ -585,7 +568,7 @@ int acpi_suspend(u32 acpi_state)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_OPS
|
||||
#ifdef CONFIG_PM
|
||||
/**
|
||||
* acpi_pm_device_sleep_state - return preferred power state of ACPI device
|
||||
* in the system sleep state given by %acpi_target_sleep_state
|
||||
|
|
@ -671,7 +654,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
|
|||
*d_min_p = d_min;
|
||||
return d_max;
|
||||
}
|
||||
#endif /* CONFIG_PM_OPS */
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -220,6 +220,14 @@ module_param_call(trace_state, param_set_trace_state, param_get_trace_state,
|
|||
NULL, 0644);
|
||||
#endif /* CONFIG_ACPI_DEBUG */
|
||||
|
||||
|
||||
/* /sys/modules/acpi/parameters/aml_debug_output */
|
||||
|
||||
module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object,
|
||||
bool, 0644);
|
||||
MODULE_PARM_DESC(aml_debug_output,
|
||||
"To enable/disable the ACPI Debug Object output.");
|
||||
|
||||
/* /sys/module/acpi/parameters/acpica_version */
|
||||
static int param_get_acpica_version(char *buffer, struct kernel_param *kp)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -782,6 +782,9 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
|
|||
|
||||
if (acpi_video_backlight_support()) {
|
||||
struct backlight_properties props;
|
||||
struct pci_dev *pdev;
|
||||
acpi_handle acpi_parent;
|
||||
struct device *parent = NULL;
|
||||
int result;
|
||||
static int count = 0;
|
||||
char *name;
|
||||
|
|
@ -794,9 +797,20 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
|
|||
return;
|
||||
count++;
|
||||
|
||||
acpi_get_parent(device->dev->handle, &acpi_parent);
|
||||
|
||||
pdev = acpi_get_pci_dev(acpi_parent);
|
||||
if (pdev) {
|
||||
parent = &pdev->dev;
|
||||
pci_dev_put(pdev);
|
||||
}
|
||||
|
||||
memset(&props, 0, sizeof(struct backlight_properties));
|
||||
props.type = BACKLIGHT_FIRMWARE;
|
||||
props.max_brightness = device->brightness->count - 3;
|
||||
device->backlight = backlight_device_register(name, NULL, device,
|
||||
device->backlight = backlight_device_register(name,
|
||||
parent,
|
||||
device,
|
||||
&acpi_backlight_ops,
|
||||
&props);
|
||||
kfree(name);
|
||||
|
|
@ -810,11 +824,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
|
|||
device->backlight->props.brightness =
|
||||
acpi_video_get_brightness(device->backlight);
|
||||
|
||||
result = sysfs_create_link(&device->backlight->dev.kobj,
|
||||
&device->dev->dev.kobj, "device");
|
||||
if (result)
|
||||
printk(KERN_ERR PREFIX "Create sysfs link\n");
|
||||
|
||||
device->cooling_dev = thermal_cooling_device_register("LCD",
|
||||
device->dev, &video_cooling_ops);
|
||||
if (IS_ERR(device->cooling_dev)) {
|
||||
|
|
@ -1345,7 +1354,7 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
|
|||
status = acpi_video_bus_get_one_device(dev, video);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
printk(KERN_WARNING PREFIX
|
||||
"Cant attach device\n");
|
||||
"Can't attach device\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -1364,10 +1373,9 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
|
|||
acpi_video_device_notify);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
printk(KERN_WARNING PREFIX
|
||||
"Cant remove video notify handler\n");
|
||||
"Can't remove video notify handler\n");
|
||||
}
|
||||
if (device->backlight) {
|
||||
sysfs_remove_link(&device->backlight->dev.kobj, "device");
|
||||
backlight_device_unregister(device->backlight);
|
||||
device->backlight = NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue