Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6

* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6:
  ACPI / PM: Do not save/restore NVS on Sony Vaio VGN-NW130D
  ACPI/HEST: adjust section selection
  ACPI: eliminate unused variable warning for !ACPI_SLEEP
  ACPI/PNP: avoid section mismatch warning
  ACPI thermal: remove two unused functions
  ACPI: fix a section mismatch
  ACPI, APEI, use raw spinlock in ERST
  ACPI: video: fix build for CONFIG_ACPI=n
  ACPI: video: fix build for VIDEO_OUTPUT_CONTROL=n
  ACPI: fix allowing to add/remove multiple _OSI strings
  acpi: fix _OSI string setup regression
  ACPI: EC: Add another dmi match entry for MSI hardware
  ACPI battery: update status upon sysfs query
  ACPI ac: update AC status upon sysfs query
  ACPI / PM: Do not refcount power resources that can't be turned on
  ACPI / PM: Check device state before refcounting power resources
This commit is contained in:
Linus Torvalds 2010-12-14 14:33:33 -08:00
commit 3907969596
13 changed files with 173 additions and 95 deletions

View File

@ -100,24 +100,7 @@ static const struct file_operations acpi_ac_fops = {
.release = single_release,
};
#endif
static int get_ac_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct acpi_ac *ac = to_acpi_ac(psy);
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
val->intval = ac->state;
break;
default:
return -EINVAL;
}
return 0;
}
static enum power_supply_property ac_props[] = {
POWER_SUPPLY_PROP_ONLINE,
};
/* --------------------------------------------------------------------------
AC Adapter Management
-------------------------------------------------------------------------- */
@ -140,6 +123,35 @@ static int acpi_ac_get_state(struct acpi_ac *ac)
return 0;
}
/* --------------------------------------------------------------------------
sysfs I/F
-------------------------------------------------------------------------- */
static int get_ac_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct acpi_ac *ac = to_acpi_ac(psy);
if (!ac)
return -ENODEV;
if (acpi_ac_get_state(ac))
return -ENODEV;
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
val->intval = ac->state;
break;
default:
return -EINVAL;
}
return 0;
}
static enum power_supply_property ac_props[] = {
POWER_SUPPLY_PROP_ONLINE,
};
#ifdef CONFIG_ACPI_PROCFS_POWER
/* --------------------------------------------------------------------------
FS Interface (/proc)

View File

@ -86,7 +86,7 @@ static struct erst_erange {
* It is used to provide exclusive accessing for ERST Error Log
* Address Range too.
*/
static DEFINE_SPINLOCK(erst_lock);
static DEFINE_RAW_SPINLOCK(erst_lock);
static inline int erst_errno(int command_status)
{
@ -421,9 +421,9 @@ ssize_t erst_get_record_count(void)
if (erst_disable)
return -ENODEV;
spin_lock_irqsave(&erst_lock, flags);
raw_spin_lock_irqsave(&erst_lock, flags);
count = __erst_get_record_count();
spin_unlock_irqrestore(&erst_lock, flags);
raw_spin_unlock_irqrestore(&erst_lock, flags);
return count;
}
@ -456,9 +456,9 @@ int erst_get_next_record_id(u64 *record_id)
if (erst_disable)
return -ENODEV;
spin_lock_irqsave(&erst_lock, flags);
raw_spin_lock_irqsave(&erst_lock, flags);
rc = __erst_get_next_record_id(record_id);
spin_unlock_irqrestore(&erst_lock, flags);
raw_spin_unlock_irqrestore(&erst_lock, flags);
return rc;
}
@ -624,17 +624,17 @@ int erst_write(const struct cper_record_header *record)
return -EINVAL;
if (erst_erange.attr & ERST_RANGE_NVRAM) {
if (!spin_trylock_irqsave(&erst_lock, flags))
if (!raw_spin_trylock_irqsave(&erst_lock, flags))
return -EBUSY;
rc = __erst_write_to_nvram(record);
spin_unlock_irqrestore(&erst_lock, flags);
raw_spin_unlock_irqrestore(&erst_lock, flags);
return rc;
}
if (record->record_length > erst_erange.size)
return -EINVAL;
if (!spin_trylock_irqsave(&erst_lock, flags))
if (!raw_spin_trylock_irqsave(&erst_lock, flags))
return -EBUSY;
memcpy(erst_erange.vaddr, record, record->record_length);
rcd_erange = erst_erange.vaddr;
@ -642,7 +642,7 @@ int erst_write(const struct cper_record_header *record)
memcpy(&rcd_erange->persistence_information, "ER", 2);
rc = __erst_write_to_storage(0);
spin_unlock_irqrestore(&erst_lock, flags);
raw_spin_unlock_irqrestore(&erst_lock, flags);
return rc;
}
@ -696,9 +696,9 @@ ssize_t erst_read(u64 record_id, struct cper_record_header *record,
if (erst_disable)
return -ENODEV;
spin_lock_irqsave(&erst_lock, flags);
raw_spin_lock_irqsave(&erst_lock, flags);
len = __erst_read(record_id, record, buflen);
spin_unlock_irqrestore(&erst_lock, flags);
raw_spin_unlock_irqrestore(&erst_lock, flags);
return len;
}
EXPORT_SYMBOL_GPL(erst_read);
@ -719,20 +719,20 @@ ssize_t erst_read_next(struct cper_record_header *record, size_t buflen)
if (erst_disable)
return -ENODEV;
spin_lock_irqsave(&erst_lock, flags);
raw_spin_lock_irqsave(&erst_lock, flags);
rc = __erst_get_next_record_id(&record_id);
if (rc) {
spin_unlock_irqrestore(&erst_lock, flags);
raw_spin_unlock_irqrestore(&erst_lock, flags);
return rc;
}
/* no more record */
if (record_id == APEI_ERST_INVALID_RECORD_ID) {
spin_unlock_irqrestore(&erst_lock, flags);
raw_spin_unlock_irqrestore(&erst_lock, flags);
return 0;
}
len = __erst_read(record_id, record, buflen);
spin_unlock_irqrestore(&erst_lock, flags);
raw_spin_unlock_irqrestore(&erst_lock, flags);
return len;
}
@ -746,12 +746,12 @@ int erst_clear(u64 record_id)
if (erst_disable)
return -ENODEV;
spin_lock_irqsave(&erst_lock, flags);
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);
spin_unlock_irqrestore(&erst_lock, flags);
raw_spin_unlock_irqrestore(&erst_lock, flags);
return rc;
}

View File

@ -46,9 +46,9 @@ EXPORT_SYMBOL_GPL(hest_disable);
/* HEST table parsing */
static struct acpi_table_hest *hest_tab;
static struct acpi_table_hest *__read_mostly hest_tab;
static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
[ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */
[ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1,
[ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi),
@ -126,7 +126,7 @@ struct ghes_arr {
unsigned int count;
};
static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
static int __init hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
{
int *count = data;
@ -135,7 +135,7 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
return 0;
}
static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
static int __init hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
{
struct platform_device *ghes_dev;
struct ghes_arr *ghes_arr = data;
@ -165,7 +165,7 @@ err:
return rc;
}
static int hest_ghes_dev_register(unsigned int ghes_count)
static int __init hest_ghes_dev_register(unsigned int ghes_count)
{
int rc, i;
struct ghes_arr ghes_arr;

View File

@ -130,6 +130,8 @@ struct acpi_battery {
unsigned long flags;
};
static int acpi_battery_update(struct acpi_battery *battery);
#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
inline int acpi_battery_present(struct acpi_battery *battery)
@ -184,6 +186,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
int ret = 0;
struct acpi_battery *battery = to_acpi_battery(psy);
if (acpi_battery_update(battery))
return -ENODEV;
if (acpi_battery_present(battery)) {
/* run battery update only if it is present */
acpi_battery_get_state(battery);

View File

@ -934,6 +934,9 @@ 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, "MSI hardware", {
DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL},
{
ec_validate_ecdt, "ASUS hardware", {
DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
{},

View File

@ -110,9 +110,6 @@ struct acpi_ioremap {
static LIST_HEAD(acpi_ioremaps);
static DEFINE_SPINLOCK(acpi_ioremap_lock);
#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
static char osi_setup_string[OSI_STRING_LENGTH_MAX];
static void __init acpi_osi_setup_late(void);
/*
@ -152,8 +149,7 @@ static struct osi_linux {
unsigned int enable:1;
unsigned int dmi:1;
unsigned int cmdline:1;
unsigned int known:1;
} osi_linux = { 0, 0, 0, 0};
} osi_linux = {0, 0, 0};
static u32 acpi_osi_handler(acpi_string interface, u32 supported)
{
@ -1055,13 +1051,53 @@ static int __init acpi_os_name_setup(char *str)
__setup("acpi_os_name=", acpi_os_name_setup);
#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
#define OSI_STRING_ENTRIES_MAX 16 /* arbitrary */
struct osi_setup_entry {
char string[OSI_STRING_LENGTH_MAX];
bool enable;
};
static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX];
void __init acpi_osi_setup(char *str)
{
struct osi_setup_entry *osi;
bool enable = true;
int i;
if (!acpi_gbl_create_osi_method)
return;
if (str == NULL || *str == '\0') {
printk(KERN_INFO PREFIX "_OSI method disabled\n");
acpi_gbl_create_osi_method = FALSE;
return;
}
if (*str == '!') {
str++;
enable = false;
}
for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
osi = &osi_setup_entries[i];
if (!strcmp(osi->string, str)) {
osi->enable = enable;
break;
} else if (osi->string[0] == '\0') {
osi->enable = enable;
strncpy(osi->string, str, OSI_STRING_LENGTH_MAX);
break;
}
}
}
static void __init set_osi_linux(unsigned int enable)
{
if (osi_linux.enable != enable) {
if (osi_linux.enable != enable)
osi_linux.enable = enable;
printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n",
enable ? "Add": "Delet");
}
if (osi_linux.enable)
acpi_osi_setup("Linux");
@ -1073,7 +1109,8 @@ static void __init set_osi_linux(unsigned int enable)
static void __init acpi_cmdline_osi_linux(unsigned int enable)
{
osi_linux.cmdline = 1; /* cmdline set the default */
osi_linux.cmdline = 1; /* cmdline set the default and override DMI */
osi_linux.dmi = 0;
set_osi_linux(enable);
return;
@ -1081,15 +1118,12 @@ static void __init acpi_cmdline_osi_linux(unsigned int enable)
void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
{
osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */
printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
if (enable == -1)
return;
osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */
osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */
set_osi_linux(enable);
return;
@ -1104,37 +1138,44 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
*/
static void __init acpi_osi_setup_late(void)
{
char *str = osi_setup_string;
struct osi_setup_entry *osi;
char *str;
int i;
acpi_status status;
if (*str == '\0')
return;
for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
osi = &osi_setup_entries[i];
str = osi->string;
if (!strcmp("!Linux", str)) {
acpi_cmdline_osi_linux(0); /* !enable */
} else if (*str == '!') {
if (acpi_remove_interface(++str) == AE_OK)
printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
} else if (!strcmp("Linux", str)) {
acpi_cmdline_osi_linux(1); /* enable */
} else {
if (acpi_install_interface(str) == AE_OK)
printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
if (*str == '\0')
break;
if (osi->enable) {
status = acpi_install_interface(str);
if (ACPI_SUCCESS(status))
printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
} else {
status = acpi_remove_interface(str);
if (ACPI_SUCCESS(status))
printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
}
}
}
int __init acpi_osi_setup(char *str)
static int __init osi_setup(char *str)
{
if (str == NULL || *str == '\0') {
printk(KERN_INFO PREFIX "_OSI method disabled\n");
acpi_gbl_create_osi_method = FALSE;
} else {
strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX);
}
if (str && !strcmp("Linux", str))
acpi_cmdline_osi_linux(1);
else if (str && !strcmp("!Linux", str))
acpi_cmdline_osi_linux(0);
else
acpi_osi_setup(str);
return 1;
}
__setup("acpi_osi=", acpi_osi_setup);
__setup("acpi_osi=", osi_setup);
/* enable serialization to combat AE_ALREADY_EXISTS errors */
static int __init acpi_serialize_setup(char *str)
@ -1530,7 +1571,7 @@ acpi_status __init acpi_os_initialize(void)
return AE_OK;
}
acpi_status acpi_os_initialize1(void)
acpi_status __init acpi_os_initialize1(void)
{
kacpid_wq = create_workqueue("kacpid");
kacpi_notify_wq = create_workqueue("kacpi_notify");

View File

@ -213,11 +213,13 @@ static int acpi_power_on(acpi_handle handle)
resource->name));
} else {
result = __acpi_power_on(resource);
if (result)
resource->ref_count--;
}
mutex_unlock(&resource->resource_lock);
return 0;
return result;
}
static int acpi_power_off_device(acpi_handle handle)
@ -465,10 +467,12 @@ int acpi_power_transition(struct acpi_device *device, int state)
struct acpi_handle_list *tl = NULL; /* Target Resources */
int i = 0;
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
return -EINVAL;
if (device->power.state == state)
return 0;
if ((device->power.state < ACPI_STATE_D0)
|| (device->power.state > ACPI_STATE_D3))
return -ENODEV;
@ -488,10 +492,6 @@ int acpi_power_transition(struct acpi_device *device, int state)
goto end;
}
if (device->power.state == state) {
goto end;
}
/*
* Then we dereference all power resources used in the current list.
*/

View File

@ -156,15 +156,6 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state)
return 0;
}
static int acpi_thermal_cpufreq_increase(unsigned int cpu)
{
return -ENODEV;
}
static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
{
return -ENODEV;
}
#endif
int acpi_processor_get_limit_info(struct acpi_processor *pr)

View File

@ -27,8 +27,6 @@
static u8 sleep_states[ACPI_S_STATE_COUNT];
static u32 acpi_target_sleep_state = ACPI_STATE_S0;
static void acpi_sleep_tts_switch(u32 acpi_state)
{
union acpi_object in_arg = { ACPI_TYPE_INTEGER };
@ -81,6 +79,8 @@ static int acpi_sleep_prepare(u32 acpi_state)
}
#ifdef CONFIG_ACPI_SLEEP
static u32 acpi_target_sleep_state = ACPI_STATE_S0;
/*
* The ACPI specification wants us to save NVS memory regions during hibernation
* and to restore them during the subsequent resume. Windows does that also for
@ -427,6 +427,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),
},
},
{
.callback = init_nvs_nosave,
.ident = "Sony Vaio VGN-NW130D",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
},
},
{},
};
#endif /* CONFIG_SUSPEND */

View File

@ -180,7 +180,7 @@ struct pnp_protocol pnpacpi_protocol = {
};
EXPORT_SYMBOL(pnpacpi_protocol);
static char *pnpacpi_get_id(struct acpi_device *device)
static char *__init pnpacpi_get_id(struct acpi_device *device)
{
struct acpi_hardware_id *id;

View File

@ -1,6 +1,10 @@
#ifndef __ACPI_VIDEO_H
#define __ACPI_VIDEO_H
#include <linux/errno.h> /* for ENODEV */
struct acpi_device;
#define ACPI_VIDEO_DISPLAY_CRT 1
#define ACPI_VIDEO_DISPLAY_TV 2
#define ACPI_VIDEO_DISPLAY_DVI 3
@ -26,4 +30,3 @@ static inline int acpi_video_get_edid(struct acpi_device *device, int type,
#endif
#endif

View File

@ -219,7 +219,7 @@ static inline int acpi_video_display_switch_support(void)
extern int acpi_blacklisted(void);
extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d);
extern int acpi_osi_setup(char *str);
extern void acpi_osi_setup(char *str);
#ifdef CONFIG_ACPI_NUMA
int acpi_get_pxm(acpi_handle handle);

View File

@ -23,6 +23,7 @@
#ifndef _LINUX_VIDEO_OUTPUT_H
#define _LINUX_VIDEO_OUTPUT_H
#include <linux/device.h>
#include <linux/err.h>
struct output_device;
struct output_properties {
int (*set_state)(struct output_device *);
@ -34,9 +35,23 @@ struct output_device {
struct device dev;
};
#define to_output_device(obj) container_of(obj, struct output_device, dev)
#if defined(CONFIG_VIDEO_OUTPUT_CONTROL) || defined(CONFIG_VIDEO_OUTPUT_CONTROL_MODULE)
struct output_device *video_output_register(const char *name,
struct device *dev,
void *devdata,
struct output_properties *op);
void video_output_unregister(struct output_device *dev);
#else
static struct output_device *video_output_register(const char *name,
struct device *dev,
void *devdata,
struct output_properties *op)
{
return ERR_PTR(-ENODEV);
}
static void video_output_unregister(struct output_device *dev)
{
return;
}
#endif
#endif