Commit c940c8ce authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branch 'acpi-assorted'

* acpi-assorted: (21 commits)
  ACPI / thermal: do not always return THERMAL_TREND_RAISING for active trip points
  ACPI: video: correct acpi_video_bus_add error processing
  ACPI: Fix wrong parameter passed to memblock_reserve
  acpi: video: enhance the quirk detect logic of _BQC
  ACPI: update comments for acpi_event_status
  ACPI: remove "config ACPI_DEBUG_FUNC_TRACE"
  PCI / ACPI: Don't query OSC support with all possible controls
  ACPI / processor_thermal: avoid null pointer deference error
  ACPI / fan: avoid null pointer deference error
  ACPI / video: Fix applying indexed initial brightness value.
  ACPI / video: Make logic a little easier to understand.
  ACPI / video: Fix brightness control initialization for some laptops.
  ACPI: Use resource_size() in osl.c
  ACPI / acpi_pad: Used PTR_RET
  ACPI: suppress compiler warning in container.c
  ACPI: suppress compiler warning in battery.c
  ACPI: suppress compiler warnings in processor_throttling.c
  ACPI: suppress compiler warnings in button.c
  ACPI: replace kmalloc+memcpy with kmemdup
  ACPI: Remove acpi_pci_bind_root() definition
  ...
parents 34bdb1a4 94a40931
...@@ -298,14 +298,6 @@ config ACPI_DEBUG ...@@ -298,14 +298,6 @@ config ACPI_DEBUG
Documentation/kernel-parameters.txt to control the type and Documentation/kernel-parameters.txt to control the type and
amount of debug output. amount of debug output.
config ACPI_DEBUG_FUNC_TRACE
bool "Additionally enable ACPI function tracing"
default n
depends on ACPI_DEBUG
help
ACPI Debug Statements slow down ACPI processing. Function trace
is about half of the penalty and is rarely useful.
config ACPI_PCI_SLOT config ACPI_PCI_SLOT
bool "PCI slot detection driver" bool "PCI slot detection driver"
depends on SYSFS depends on SYSFS
......
...@@ -236,7 +236,7 @@ static int create_power_saving_task(void) ...@@ -236,7 +236,7 @@ static int create_power_saving_task(void)
ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread, ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread,
(void *)(unsigned long)ps_tsk_num, (void *)(unsigned long)ps_tsk_num,
"acpi_pad/%d", ps_tsk_num); "acpi_pad/%d", ps_tsk_num);
rc = IS_ERR(ps_tsks[ps_tsk_num]) ? PTR_ERR(ps_tsks[ps_tsk_num]) : 0; rc = PTR_RET(ps_tsks[ps_tsk_num]);
if (!rc) if (!rc)
ps_tsk_num++; ps_tsk_num++;
else else
......
...@@ -146,7 +146,7 @@ struct acpi_battery { ...@@ -146,7 +146,7 @@ struct acpi_battery {
#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat) #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat)
inline int acpi_battery_present(struct acpi_battery *battery) static inline int acpi_battery_present(struct acpi_battery *battery)
{ {
return battery->device->status.battery_present; return battery->device->status.battery_present;
} }
......
...@@ -288,13 +288,12 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context) ...@@ -288,13 +288,12 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
} }
out_success: out_success:
context->ret.length = out_obj->buffer.length; context->ret.length = out_obj->buffer.length;
context->ret.pointer = kmalloc(context->ret.length, GFP_KERNEL); context->ret.pointer = kmemdup(out_obj->buffer.pointer,
context->ret.length, GFP_KERNEL);
if (!context->ret.pointer) { if (!context->ret.pointer) {
status = AE_NO_MEMORY; status = AE_NO_MEMORY;
goto out_kfree; goto out_kfree;
} }
memcpy(context->ret.pointer, out_obj->buffer.pointer,
context->ret.length);
status = AE_OK; status = AE_OK;
out_kfree: out_kfree:
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h> #include <acpi/acpi_drivers.h>
#include <acpi/button.h>
#define PREFIX "ACPI: " #define PREFIX "ACPI: "
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include "internal.h" #include "internal.h"
#include "internal.h"
#define PREFIX "ACPI: " #define PREFIX "ACPI: "
#define _COMPONENT ACPI_CONTAINER_COMPONENT #define _COMPONENT ACPI_CONTAINER_COMPONENT
......
...@@ -174,9 +174,13 @@ static int acpi_fan_add(struct acpi_device *device) ...@@ -174,9 +174,13 @@ static int acpi_fan_add(struct acpi_device *device)
static int acpi_fan_remove(struct acpi_device *device) static int acpi_fan_remove(struct acpi_device *device)
{ {
struct thermal_cooling_device *cdev = acpi_driver_data(device); struct thermal_cooling_device *cdev;
if (!device)
return -EINVAL;
if (!device || !cdev) cdev = acpi_driver_data(device);
if (!cdev)
return -EINVAL; return -EINVAL;
sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
......
...@@ -641,7 +641,7 @@ void __init acpi_initrd_override(void *data, size_t size) ...@@ -641,7 +641,7 @@ void __init acpi_initrd_override(void *data, size_t size)
* Both memblock_reserve and e820_add_region (via arch_reserve_mem_area) * Both memblock_reserve and e820_add_region (via arch_reserve_mem_area)
* works fine. * works fine.
*/ */
memblock_reserve(acpi_tables_addr, acpi_tables_addr + all_tables_size); memblock_reserve(acpi_tables_addr, all_tables_size);
arch_reserve_mem_area(acpi_tables_addr, all_tables_size); arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
p = early_ioremap(acpi_tables_addr, all_tables_size); p = early_ioremap(acpi_tables_addr, all_tables_size);
...@@ -1555,7 +1555,7 @@ int acpi_check_resource_conflict(const struct resource *res) ...@@ -1555,7 +1555,7 @@ int acpi_check_resource_conflict(const struct resource *res)
else else
space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY; space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY;
length = res->end - res->start + 1; length = resource_size(res);
if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) if (acpi_enforce_resources != ENFORCE_RESOURCES_NO)
warn = 1; warn = 1;
clash = acpi_check_address_range(space_id, res->start, length, warn); clash = acpi_check_address_range(space_id, res->start, length, warn);
......
...@@ -201,8 +201,8 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, ...@@ -201,8 +201,8 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root,
*control &= OSC_PCI_CONTROL_MASKS; *control &= OSC_PCI_CONTROL_MASKS;
capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set; capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set;
} else { } else {
/* Run _OSC query for all possible controls. */ /* Run _OSC query only with existing controls. */
capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS; capbuf[OSC_CONTROL_TYPE] = root->osc_control_set;
} }
status = acpi_pci_run_osc(root->device->handle, capbuf, &result); status = acpi_pci_run_osc(root->device->handle, capbuf, &result);
......
...@@ -218,9 +218,13 @@ processor_get_max_state(struct thermal_cooling_device *cdev, ...@@ -218,9 +218,13 @@ processor_get_max_state(struct thermal_cooling_device *cdev,
unsigned long *state) unsigned long *state)
{ {
struct acpi_device *device = cdev->devdata; struct acpi_device *device = cdev->devdata;
struct acpi_processor *pr = acpi_driver_data(device); struct acpi_processor *pr;
if (!device || !pr) if (!device)
return -EINVAL;
pr = acpi_driver_data(device);
if (!pr)
return -EINVAL; return -EINVAL;
*state = acpi_processor_max_state(pr); *state = acpi_processor_max_state(pr);
...@@ -232,9 +236,13 @@ processor_get_cur_state(struct thermal_cooling_device *cdev, ...@@ -232,9 +236,13 @@ processor_get_cur_state(struct thermal_cooling_device *cdev,
unsigned long *cur_state) unsigned long *cur_state)
{ {
struct acpi_device *device = cdev->devdata; struct acpi_device *device = cdev->devdata;
struct acpi_processor *pr = acpi_driver_data(device); struct acpi_processor *pr;
if (!device || !pr) if (!device)
return -EINVAL;
pr = acpi_driver_data(device);
if (!pr)
return -EINVAL; return -EINVAL;
*cur_state = cpufreq_get_cur_state(pr->id); *cur_state = cpufreq_get_cur_state(pr->id);
...@@ -248,11 +256,15 @@ processor_set_cur_state(struct thermal_cooling_device *cdev, ...@@ -248,11 +256,15 @@ processor_set_cur_state(struct thermal_cooling_device *cdev,
unsigned long state) unsigned long state)
{ {
struct acpi_device *device = cdev->devdata; struct acpi_device *device = cdev->devdata;
struct acpi_processor *pr = acpi_driver_data(device); struct acpi_processor *pr;
int result = 0; int result = 0;
int max_pstate; int max_pstate;
if (!device || !pr) if (!device)
return -EINVAL;
pr = acpi_driver_data(device);
if (!pr)
return -EINVAL; return -EINVAL;
max_pstate = cpufreq_get_max_state(pr->id); max_pstate = cpufreq_get_max_state(pr->id);
......
...@@ -211,9 +211,10 @@ static int acpi_processor_update_tsd_coord(void) ...@@ -211,9 +211,10 @@ static int acpi_processor_update_tsd_coord(void)
*/ */
void acpi_processor_throttling_init(void) void acpi_processor_throttling_init(void)
{ {
if (acpi_processor_update_tsd_coord()) if (acpi_processor_update_tsd_coord()) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Assume no T-state coordination\n")); "Assume no T-state coordination\n"));
}
return; return;
} }
......
...@@ -723,9 +723,19 @@ static int thermal_get_trend(struct thermal_zone_device *thermal, ...@@ -723,9 +723,19 @@ static int thermal_get_trend(struct thermal_zone_device *thermal,
return -EINVAL; return -EINVAL;
if (type == THERMAL_TRIP_ACTIVE) { if (type == THERMAL_TRIP_ACTIVE) {
/* aggressive active cooling */ unsigned long trip_temp;
*trend = THERMAL_TREND_RAISING; unsigned long temp = KELVIN_TO_MILLICELSIUS(tz->temperature,
return 0; tz->kelvin_offset);
if (thermal_get_trip_temp(thermal, trip, &trip_temp))
return -EINVAL;
if (temp > trip_temp) {
*trend = THERMAL_TREND_RAISING;
return 0;
} else {
/* Fall back on default trend */
return -EINVAL;
}
} }
/* /*
......
...@@ -167,7 +167,8 @@ struct acpi_video_device_flags { ...@@ -167,7 +167,8 @@ struct acpi_video_device_flags {
u8 dvi:1; u8 dvi:1;
u8 bios:1; u8 bios:1;
u8 unknown:1; u8 unknown:1;
u8 reserved:2; u8 notify:1;
u8 reserved:1;
}; };
struct acpi_video_device_cap { struct acpi_video_device_cap {
...@@ -222,7 +223,7 @@ static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, ...@@ -222,7 +223,7 @@ static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
int level); int level);
static int acpi_video_device_lcd_get_level_current( static int acpi_video_device_lcd_get_level_current(
struct acpi_video_device *device, struct acpi_video_device *device,
unsigned long long *level, int init); unsigned long long *level, bool raw);
static int acpi_video_get_next_level(struct acpi_video_device *device, static int acpi_video_get_next_level(struct acpi_video_device *device,
u32 level_current, u32 event); u32 level_current, u32 event);
static int acpi_video_switch_brightness(struct acpi_video_device *device, static int acpi_video_switch_brightness(struct acpi_video_device *device,
...@@ -236,7 +237,7 @@ static int acpi_video_get_brightness(struct backlight_device *bd) ...@@ -236,7 +237,7 @@ static int acpi_video_get_brightness(struct backlight_device *bd)
struct acpi_video_device *vd = struct acpi_video_device *vd =
(struct acpi_video_device *)bl_get_data(bd); (struct acpi_video_device *)bl_get_data(bd);
if (acpi_video_device_lcd_get_level_current(vd, &cur_level, 0)) if (acpi_video_device_lcd_get_level_current(vd, &cur_level, false))
return -EINVAL; return -EINVAL;
for (i = 2; i < vd->brightness->count; i++) { for (i = 2; i < vd->brightness->count; i++) {
if (vd->brightness->levels[i] == cur_level) if (vd->brightness->levels[i] == cur_level)
...@@ -281,7 +282,7 @@ static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsig ...@@ -281,7 +282,7 @@ static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsig
unsigned long long level; unsigned long long level;
int offset; int offset;
if (acpi_video_device_lcd_get_level_current(video, &level, 0)) if (acpi_video_device_lcd_get_level_current(video, &level, false))
return -EINVAL; return -EINVAL;
for (offset = 2; offset < video->brightness->count; offset++) for (offset = 2; offset < video->brightness->count; offset++)
if (level == video->brightness->levels[offset]) { if (level == video->brightness->levels[offset]) {
...@@ -447,12 +448,45 @@ static struct dmi_system_id video_dmi_table[] __initdata = { ...@@ -447,12 +448,45 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13 - 2000 Notebook PC"), DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13 - 2000 Notebook PC"),
}, },
}, },
{
.callback = video_ignore_initial_backlight,
.ident = "HP Pavilion dm4",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dm4 Notebook PC"),
},
},
{} {}
}; };
static unsigned long long
acpi_video_bqc_value_to_level(struct acpi_video_device *device,
unsigned long long bqc_value)
{
unsigned long long level;
if (device->brightness->flags._BQC_use_index) {
/*
* _BQC returns an index that doesn't account for
* the first 2 items with special meaning, so we need
* to compensate for that by offsetting ourselves
*/
if (device->brightness->flags._BCL_reversed)
bqc_value = device->brightness->count - 3 - bqc_value;
level = device->brightness->levels[bqc_value + 2];
} else {
level = bqc_value;
}
level += bqc_offset_aml_bug_workaround;
return level;
}
static int static int
acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
unsigned long long *level, int init) unsigned long long *level, bool raw)
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
int i; int i;
...@@ -463,29 +497,30 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, ...@@ -463,29 +497,30 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
status = acpi_evaluate_integer(device->dev->handle, buf, status = acpi_evaluate_integer(device->dev->handle, buf,
NULL, level); NULL, level);
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
if (device->brightness->flags._BQC_use_index) { if (raw) {
if (device->brightness->flags._BCL_reversed) /*
*level = device->brightness->count * Caller has indicated he wants the raw
- 3 - (*level); * value returned by _BQC, so don't furtherly
*level = device->brightness->levels[*level + 2]; * mess with the value.
*/
return 0;
} }
*level += bqc_offset_aml_bug_workaround;
*level = acpi_video_bqc_value_to_level(device, *level);
for (i = 2; i < device->brightness->count; i++) for (i = 2; i < device->brightness->count; i++)
if (device->brightness->levels[i] == *level) { if (device->brightness->levels[i] == *level) {
device->brightness->curr = *level; device->brightness->curr = *level;
return 0; return 0;
} }
if (!init) { /*
/* * BQC returned an invalid level.
* BQC returned an invalid level. * Stop using it.
* Stop using it. */
*/ ACPI_WARNING((AE_INFO,
ACPI_WARNING((AE_INFO, "%s returned an invalid level",
"%s returned an invalid level", buf));
buf)); device->cap._BQC = device->cap._BCQ = 0;
device->cap._BQC = device->cap._BCQ = 0;
}
} else { } else {
/* Fixme: /* Fixme:
* should we return an error or ignore this failure? * should we return an error or ignore this failure?
...@@ -597,6 +632,56 @@ acpi_video_cmp_level(const void *a, const void *b) ...@@ -597,6 +632,56 @@ acpi_video_cmp_level(const void *a, const void *b)
return *(int *)a - *(int *)b; return *(int *)a - *(int *)b;
} }
/*
* Decides if _BQC/_BCQ for this system is usable
*
* We do this by changing the level first and then read out the current
* brightness level, if the value does not match, find out if it is using
* index. If not, clear the _BQC/_BCQ capability.
*/
static int acpi_video_bqc_quirk(struct acpi_video_device *device,
int max_level, int current_level)
{
struct acpi_video_device_brightness *br = device->brightness;
int result;
unsigned long long level;
int test_level;
/* don't mess with existing known broken systems */
if (bqc_offset_aml_bug_workaround)
return 0;
/*
* Some systems always report current brightness level as maximum
* through _BQC, we need to test another value for them.
*/
test_level = current_level == max_level ? br->levels[2] : max_level;
result = acpi_video_device_lcd_set_level(device, test_level);
if (result)
return result;
result = acpi_video_device_lcd_get_level_current(device, &level, true);
if (result)
return result;
if (level != test_level) {
/* buggy _BQC found, need to find out if it uses index */
if (level < br->count) {
if (br->flags._BCL_reversed)
level = br->count - 3 - level;
if (br->levels[level + 2] == test_level)
br->flags._BQC_use_index = 1;
}
if (!br->flags._BQC_use_index)
device->cap._BQC = device->cap._BCQ = 0;
}
return 0;
}
/* /*
* Arg: * Arg:
* device : video output device (LCD, CRT, ..) * device : video output device (LCD, CRT, ..)
...@@ -703,42 +788,36 @@ acpi_video_init_brightness(struct acpi_video_device *device) ...@@ -703,42 +788,36 @@ acpi_video_init_brightness(struct acpi_video_device *device)
if (!device->cap._BQC) if (!device->cap._BQC)
goto set_level; goto set_level;
result = acpi_video_device_lcd_get_level_current(device, &level_old, 1); result = acpi_video_device_lcd_get_level_current(device,
if (result) &level_old, true);
goto out_free_levels;
/*
* Set the level to maximum and check if _BQC uses indexed value
*/
result = acpi_video_device_lcd_set_level(device, max_level);
if (result) if (result)
goto out_free_levels; goto out_free_levels;
result = acpi_video_device_lcd_get_level_current(device, &level, 0); result = acpi_video_bqc_quirk(device, max_level, level_old);
if (result) if (result)
goto out_free_levels; goto out_free_levels;
/*
* cap._BQC may get cleared due to _BQC is found to be broken
* in acpi_video_bqc_quirk, so check again here.
*/
if (!device->cap._BQC)
goto set_level;
br->flags._BQC_use_index = (level == max_level ? 0 : 1); if (use_bios_initial_backlight) {
level = acpi_video_bqc_value_to_level(device, level_old);
if (!br->flags._BQC_use_index) {
/* /*
* Set the backlight to the initial state. * On some buggy laptops, _BQC returns an uninitialized
* On some buggy laptops, _BQC returns an uninitialized value * value when invoked for the first time, i.e.
* when invoked for the first time, i.e. level_old is invalid. * level_old is invalid (no matter whether it's a level
* set the backlight to max_level in this case * or an index). Set the backlight to max_level in this case.
*/ */
if (use_bios_initial_backlight) { for (i = 2; i < br->count; i++)
for (i = 2; i < br->count; i++) if (level_old == br->levels[i])
if (level_old == br->levels[i]) break;
level = level_old; if (i == br->count)
} level = max_level;
goto set_level;
} }
if (br->flags._BCL_reversed)
level_old = (br->count - 1) - level_old;
level = br->levels[level_old];
set_level: set_level:
result = acpi_video_device_lcd_set_level(device, level); result = acpi_video_device_lcd_set_level(device, level);
if (result) if (result)
...@@ -996,53 +1075,51 @@ acpi_video_bus_get_one_device(struct acpi_device *device, ...@@ -996,53 +1075,51 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
struct acpi_video_device *data; struct acpi_video_device *data;
struct acpi_video_device_attrib* attribute; struct acpi_video_device_attrib* attribute;
if (!device || !video)
return -EINVAL;
status = status =
acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
if (ACPI_SUCCESS(status)) { /* Some device omits _ADR, we skip them instead of fail */
if (ACPI_FAILURE(status))
data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL); return 0;
if (!data)
return -ENOMEM;
strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
device->driver_data = data;
data->device_id = device_id;
data->video = video;
data->dev = device;
attribute = acpi_video_get_device_attr(video, device_id); data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
if (!data)
return -ENOMEM;
if((attribute != NULL) && attribute->device_id_scheme) { strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
switch (attribute->display_type) { strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
case ACPI_VIDEO_DISPLAY_CRT: device->driver_data = data;
data->flags.crt = 1;
break; data->device_id = device_id;
case ACPI_VIDEO_DISPLAY_TV: data->video = video;
data->flags.tvout = 1; data->dev = device;
break;
case ACPI_VIDEO_DISPLAY_DVI: attribute = acpi_video_get_device_attr(video, device_id);
data->flags.dvi = 1;
break; if((attribute != NULL) && attribute->device_id_scheme) {
case ACPI_VIDEO_DISPLAY_LCD: switch (attribute->display_type) {
data->flags.lcd = 1; case ACPI_VIDEO_DISPLAY_CRT:
break; data->flags.crt = 1;
default: break;
data->flags.unknown = 1; case ACPI_VIDEO_DISPLAY_TV:
break; data->flags.tvout = 1;
} break;
if(attribute->bios_can_detect) case ACPI_VIDEO_DISPLAY_DVI:
data->flags.bios = 1; data->flags.dvi = 1;
} else { break;
/* Check for legacy IDs */ case ACPI_VIDEO_DISPLAY_LCD:
device_type = acpi_video_get_device_type(video, data->flags.lcd = 1;
device_id); break;
/* Ignore bits 16 and 18-20 */ default:
switch (device_type & 0xffe2ffff) { data->flags.unknown = 1;
break;
}
if(attribute->bios_can_detect)
data->flags.bios = 1;
} else {
/* Check for legacy IDs */
device_type = acpi_video_get_device_type(video, device_id);
/* Ignore bits 16 and 18-20 */
switch (device_type & 0xffe2ffff) {
case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR: case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR:
data->flags.crt = 1; data->flags.crt = 1;
break; break;
...@@ -1054,34 +1131,24 @@ acpi_video_bus_get_one_device(struct acpi_device *device, ...@@ -1054,34 +1131,24 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
break; break;
default: default:
data->flags.unknown = 1; data->flags.unknown = 1;
}
} }
}
acpi_video_device_bind(video, data); acpi_video_device_bind(video, data);
acpi_video_device_find_cap(data); acpi_video_device_find_cap(data);
status = acpi_install_notify_handler(device->handle,
ACPI_DEVICE_NOTIFY,
acpi_video_device_notify,
data);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX
"Error installing notify handler\n");
if(data->brightness)
kfree(data->brightness->levels);
kfree(data->brightness);
kfree(data);
return -ENODEV;
}
mutex_lock(&video->device_list_lock); status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
list_add_tail(&data->entry, &video->video_device_list); acpi_video_device_notify, data);
mutex_unlock(&video->device_list_lock); if (ACPI_FAILURE(status))
dev_err(&device->dev, "Error installing notify handler\n");
else
data->flags.notify = 1;
return 0; mutex_lock(&video->device_list_lock);
} list_add_tail(&data->entry, &video->video_device_list);
mutex_unlock(&video->device_list_lock);
return -ENOENT; return status;
} }
/* /*
...@@ -1268,7 +1335,8 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event) ...@@ -1268,7 +1335,8 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event)
goto out; goto out;
result = acpi_video_device_lcd_get_level_current(device, result = acpi_video_device_lcd_get_level_current(device,
&level_current, 0); &level_current,
false);
if (result) if (result)
goto out; goto out;
...@@ -1373,9 +1441,8 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, ...@@ -1373,9 +1441,8 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
status = acpi_video_bus_get_one_device(dev, video); status = acpi_video_bus_get_one_device(dev, video);
if (status) { if (status) {
printk(KERN_WARNING PREFIX dev_err(&dev->dev, "Can't attach device\n");
"Can't attach device\n"); break;
continue;
} }
} }
return status; return status;
...@@ -1388,13 +1455,14 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) ...@@ -1388,13 +1455,14 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
if (!device || !device->video) if (!device || !device->video)
return -ENOENT; return -ENOENT;
status = acpi_remove_notify_handler(device->dev->handle, if (device->flags.notify) {
ACPI_DEVICE_NOTIFY, status = acpi_remove_notify_handler(device->dev->handle,
acpi_video_device_notify); ACPI_DEVICE_NOTIFY, acpi_video_device_notify);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status))
printk(KERN_WARNING PREFIX dev_err(&device->dev->dev,
"Can't remove video notify handler\n"); "Can't remove video notify handler\n");
} }
if (device->backlight) { if (device->backlight) {
backlight_device_unregister(device->backlight); backlight_device_unregister(device->backlight);
device->backlight = NULL; device->backlight = NULL;
...@@ -1676,7 +1744,7 @@ static int acpi_video_bus_add(struct acpi_device *device) ...@@ -1676,7 +1744,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
error = acpi_video_bus_get_devices(video, device); error = acpi_video_bus_get_devices(video, device);
if (error) if (error)
goto err_free_video; goto err_put_video;
video->input = input = input_allocate_device(); video->input = input = input_allocate_device();
if (!input) { if (!input) {
......
...@@ -95,7 +95,6 @@ int acpi_pci_link_free_irq(acpi_handle handle); ...@@ -95,7 +95,6 @@ int acpi_pci_link_free_irq(acpi_handle handle);
struct pci_bus; struct pci_bus;
struct pci_dev *acpi_get_pci_dev(acpi_handle); struct pci_dev *acpi_get_pci_dev(acpi_handle);
int acpi_pci_bind_root(struct acpi_device *device);
/* Arch-defined function to add a bus to the system */ /* Arch-defined function to add a bus to the system */
......
...@@ -650,13 +650,14 @@ typedef u32 acpi_event_type; ...@@ -650,13 +650,14 @@ typedef u32 acpi_event_type;
* The encoding of acpi_event_status is illustrated below. * The encoding of acpi_event_status is illustrated below.
* Note that a set bit (1) indicates the property is TRUE * Note that a set bit (1) indicates the property is TRUE
* (e.g. if bit 0 is set then the event is enabled). * (e.g. if bit 0 is set then the event is enabled).
* +-------------+-+-+-+ * +-------------+-+-+-+-+
* | Bits 31:3 |2|1|0| * | Bits 31:4 |3|2|1|0|
* +-------------+-+-+-+ * +-------------+-+-+-+-+
* | | | | * | | | | |
* | | | +- Enabled? * | | | | +- Enabled?
* | | +--- Enabled for wake? * | | | +--- Enabled for wake?
* | +----- Set? * | | +----- Set?
* | +------- Has a handler?
* +----------- <Reserved> * +----------- <Reserved>
*/ */
typedef u32 acpi_event_status; typedef u32 acpi_event_status;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment