#include <linux/jiffies.h>
#include <linux/async.h>
#include <linux/dmi.h>
++ +++++++#include <linux/slab.h>
#ifdef CONFIG_ACPI_PROCFS_POWER
#include <linux/proc_fs.h>
result = acpi_battery_get_status(battery);
if (result)
return result;
---------#ifdef CONFIG_ACPI_SYSFS_POWER
if (!acpi_battery_present(battery)) {
+++++++++#ifdef CONFIG_ACPI_SYSFS_POWER
sysfs_remove_battery(battery);
+++++++++#endif
battery->update_time = 0;
return 0;
}
---------#endif
if (!battery->update_time ||
old_present != acpi_battery_present(battery)) {
result = acpi_battery_get_info(battery);
#ifdef CONFIG_ACPI_SYSFS_POWER
/* acpi_battery_update could remove power_supply object */
if (battery->bat.dev)
--------- kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
+++++++++ power_supply_changed(&battery->bat);
#endif
}
#include <linux/kernel.h>
#include <linux/module.h>
++ +++++++#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/notifier.h>
static acpi_status
find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
{
---- ----- acpi_status status = AE_OK;
---- -----
if (is_dock(handle))
---- ----- if (dock_add(handle) >= 0)
---- ----- status = AE_CTRL_TERMINATE;
++++ +++++ dock_add(handle);
---- ----- return status;
++++ +++++ return AE_OK;
}
static acpi_status
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/spinlock.h>
++ +++++++#include <linux/slab.h>
#include <asm/io.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
static acpi_status
acpi_ec_space_handler(u32 function, acpi_physical_address address,
- -------- u32 bits, u64 *value,
+ ++++++++ u32 bits, u64 *value64,
void *handler_context, void *region_context)
{
struct acpi_ec *ec = handler_context;
- -------- int result = 0, i;
- -------- u8 temp = 0;
+ ++++++++ int result = 0, i, bytes = bits / 8;
+ ++++++++ u8 *value = (u8 *)value64;
if ((address > 0xFF) || !value || !handler_context)
return AE_BAD_PARAMETER;
if (function != ACPI_READ && function != ACPI_WRITE)
return AE_BAD_PARAMETER;
- -------- if (bits != 8 && acpi_strict)
- -------- return AE_BAD_PARAMETER;
- --------
- -------- if (EC_FLAGS_MSI)
+ ++++++++ if (EC_FLAGS_MSI || bits > 8)
acpi_ec_burst_enable(ec);
- -------- if (function == ACPI_READ) {
- -------- result = acpi_ec_read(ec, address, &temp);
- -------- *value = temp;
- -------- } else {
- -------- temp = 0xff & (*value);
- -------- result = acpi_ec_write(ec, address, temp);
- -------- }
- --------
- -------- for (i = 8; unlikely(bits - i > 0); i += 8) {
- -------- ++address;
- -------- if (function == ACPI_READ) {
- -------- result = acpi_ec_read(ec, address, &temp);
- -------- (*value) |= ((u64)temp) << i;
- -------- } else {
- -------- temp = 0xff & ((*value) >> i);
- -------- result = acpi_ec_write(ec, address, temp);
- -------- }
- -------- }
+ ++++++++ for (i = 0; i < bytes; ++i, ++address, ++value)
+ ++++++++ result = (function == ACPI_READ) ?
+ ++++++++ acpi_ec_read(ec, address, value) :
+ ++++++++ acpi_ec_write(ec, address, *value);
- -------- if (EC_FLAGS_MSI)
+ ++++++++ if (EC_FLAGS_MSI || bits > 8)
acpi_ec_burst_disable(ec);
switch (result) {
queue = hp ? kacpi_hotplug_wq :
(type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq);
dpc->wait = hp ? 1 : 0;
---- ----- INIT_WORK(&dpc->work, acpi_os_execute_deferred);
++++ +++++
++++ +++++ if (queue == kacpi_hotplug_wq)
++++ +++++ INIT_WORK(&dpc->work, acpi_os_execute_deferred);
++++ +++++ else if (queue == kacpi_notify_wq)
++++ +++++ INIT_WORK(&dpc->work, acpi_os_execute_deferred);
++++ +++++ else
++++ +++++ INIT_WORK(&dpc->work, acpi_os_execute_deferred);
++++ +++++
ret = queue_work(queue, &dpc->work);
if (!ret) {
if (clash) {
if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
------- -- printk("%sACPI: %s resource %s [0x%llx-0x%llx]"
------- -- " conflicts with ACPI region %s"
------- -- " [0x%llx-0x%llx]\n",
------- -- acpi_enforce_resources == ENFORCE_RESOURCES_LAX
------- -- ? KERN_WARNING : KERN_ERR,
------- -- ioport ? "I/O" : "Memory", res->name,
------- -- (long long) res->start, (long long) res->end,
------- -- res_list_elem->name,
------- -- (long long) res_list_elem->start,
------- -- (long long) res_list_elem->end);
+++++++ ++ printk(KERN_WARNING "ACPI: resource %s %pR"
+++++++ ++ " conflicts with ACPI region %s %pR\n",
+++++++ ++ res->name, res, res_list_elem->name,
+++++++ ++ res_list_elem);
if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX)
printk(KERN_NOTICE "ACPI: This conflict may"
" cause random problems and system"
#include <linux/module.h>
#include <linux/init.h>
++ +++++++#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/acpi.h>
#include <linux/signal.h>
#include <linux/kthread.h>
+ + + #include <linux/dmi.h>
#include <acpi/acpi_drivers.h>
list_add_tail(&id->list, &device->pnp.ids);
}
+ + + /*
+ + + * Old IBM workstations have a DSDT bug wherein the SMBus object
+ + + * lacks the SMBUS01 HID and the methods do not have the necessary "_"
+ + + * prefix. Work around this.
+ + + */
+ + + static int acpi_ibm_smbus_match(struct acpi_device *device)
+ + + {
+ + + acpi_handle h_dummy;
+ + + struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
+ + + int result;
+ + +
+ + + if (!dmi_name_in_vendors("IBM"))
+ + + return -ENODEV;
+ + +
+ + + /* Look for SMBS object */
+ + + result = acpi_get_name(device->handle, ACPI_SINGLE_NAME, &path);
+ + + if (result)
+ + + return result;
+ + +
+ + + if (strcmp("SMBS", path.pointer)) {
+ + + result = -ENODEV;
+ + + goto out;
+ + + }
+ + +
+ + + /* Does it have the necessary (but misnamed) methods? */
+ + + result = -ENODEV;
+ + + if (ACPI_SUCCESS(acpi_get_handle(device->handle, "SBI", &h_dummy)) &&
+ + + ACPI_SUCCESS(acpi_get_handle(device->handle, "SBR", &h_dummy)) &&
+ + + ACPI_SUCCESS(acpi_get_handle(device->handle, "SBW", &h_dummy)))
+ + + result = 0;
+ + + out:
+ + + kfree(path.pointer);
+ + + return result;
+ + + }
+ + +
static void acpi_device_set_id(struct acpi_device *device)
{
acpi_status status;
if (ACPI_IS_ROOT_DEVICE(device)) {
acpi_add_id(device, ACPI_SYSTEM_HID);
break;
----- ---- } else if (ACPI_IS_ROOT_DEVICE(device->parent)) {
----- ---- /* \_SB_, the only root-level namespace device */
----- ---- acpi_add_id(device, ACPI_BUS_HID);
----- ---- strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
----- ---- strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
----- ---- break;
}
status = acpi_get_object_info(device->handle, &info);
acpi_add_id(device, ACPI_BAY_HID);
else if (ACPI_SUCCESS(acpi_dock_match(device)))
acpi_add_id(device, ACPI_DOCK_HID);
+ + + else if (!acpi_ibm_smbus_match(device))
+ + + acpi_add_id(device, ACPI_SMBUS_IBM_HID);
+++++ ++++ else if (!acpi_device_hid(device) &&
+++++ ++++ ACPI_IS_ROOT_DEVICE(device->parent)) {
+++++ ++++ acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */
+++++ ++++ strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
+++++ ++++ strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
+++++ ++++ }
break;
case ACPI_BUS_TYPE_POWER:
#include <linux/sort.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
++ +++++++#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/dmi.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
++ +++++++#include <linux/suspend.h>
#define PREFIX "ACPI: "
static int register_count = 0;
static int acpi_video_bus_add(struct acpi_device *device);
static int acpi_video_bus_remove(struct acpi_device *device, int type);
-- -------static int acpi_video_resume(struct acpi_device *device);
static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id video_device_ids[] = {
.ops = {
.add = acpi_video_bus_add,
.remove = acpi_video_bus_remove,
-- ------- .resume = acpi_video_resume,
.notify = acpi_video_bus_notify,
},
};
struct proc_dir_entry *dir;
struct input_dev *input;
char phys[32]; /* for input device */
++ +++++++ struct notifier_block pm_nb;
};
struct acpi_video_device_flags {
}
if (acpi_video_backlight_support()) {
+ struct backlight_properties props;
int result;
static int count = 0;
char *name;
return;
sprintf(name, "acpi_video%d", count++);
- device->backlight = backlight_device_register(name,
- NULL, device, &acpi_backlight_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = device->brightness->count - 3;
+ device->backlight = backlight_device_register(name, NULL, device,
+ &acpi_backlight_ops,
+ &props);
kfree(name);
if (IS_ERR(device->backlight))
return;
- device->backlight->props.max_brightness = device->brightness->count-3;
+
++ +++++++ /*
++ +++++++ * Save current brightness level in case we have to restore it
++ +++++++ * before acpi_video_device_lcd_set_level() is called next time.
++ +++++++ */
++ +++++++ 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)
{
struct acpi_video_bus *video = acpi_driver_data(device);
struct input_dev *input;
--------- int keycode;
+++++++++ int keycode = 0;
if (!video)
return;
break;
default:
--------- keycode = KEY_UNKNOWN;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
break;
}
acpi_notifier_call_chain(device, event, 0);
--------- input_report_key(input, keycode, 1);
--------- input_sync(input);
--------- input_report_key(input, keycode, 0);
--------- input_sync(input);
+++++++++
+++++++++ if (keycode) {
+++++++++ input_report_key(input, keycode, 1);
+++++++++ input_sync(input);
+++++++++ input_report_key(input, keycode, 0);
+++++++++ input_sync(input);
+++++++++ }
return;
}
struct acpi_device *device = NULL;
struct acpi_video_bus *bus;
struct input_dev *input;
--------- int keycode;
+++++++++ int keycode = 0;
if (!video_device)
return;
keycode = KEY_DISPLAY_OFF;
break;
default:
--------- keycode = KEY_UNKNOWN;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
break;
}
acpi_notifier_call_chain(device, event, 0);
--------- input_report_key(input, keycode, 1);
--------- input_sync(input);
--------- input_report_key(input, keycode, 0);
--------- input_sync(input);
+++++++++
+++++++++ if (keycode) {
+++++++++ input_report_key(input, keycode, 1);
+++++++++ input_sync(input);
+++++++++ input_report_key(input, keycode, 0);
+++++++++ input_sync(input);
+++++++++ }
return;
}
-- -------static int instance;
-- -------static int acpi_video_resume(struct acpi_device *device)
++ +++++++static int acpi_video_resume(struct notifier_block *nb,
++ +++++++ unsigned long val, void *ign)
{
struct acpi_video_bus *video;
struct acpi_video_device *video_device;
int i;
-- ------- if (!device || !acpi_driver_data(device))
-- ------- return -EINVAL;
++ +++++++ switch (val) {
++ +++++++ case PM_HIBERNATION_PREPARE:
++ +++++++ case PM_SUSPEND_PREPARE:
++ +++++++ case PM_RESTORE_PREPARE:
++ +++++++ return NOTIFY_DONE;
++ +++++++ }
-- ------- video = acpi_driver_data(device);
++ +++++++ video = container_of(nb, struct acpi_video_bus, pm_nb);
++ +++++++
++ +++++++ dev_info(&video->device->dev, "Restoring backlight state\n");
for (i = 0; i < video->attached_count; i++) {
video_device = video->attached_array[i].bind_info;
if (video_device && video_device->backlight)
acpi_video_set_brightness(video_device->backlight);
}
-- ------- return AE_OK;
++ +++++++
++ +++++++ return NOTIFY_OK;
}
static acpi_status
return AE_OK;
}
++ +++++++static int instance;
++ +++++++
static int acpi_video_bus_add(struct acpi_device *device)
{
struct acpi_video_bus *video;
set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
set_bit(KEY_DISPLAY_OFF, input->keybit);
--------- set_bit(KEY_UNKNOWN, input->keybit);
error = input_register_device(input);
if (error)
video->flags.rom ? "yes" : "no",
video->flags.post ? "yes" : "no");
++ +++++++ video->pm_nb.notifier_call = acpi_video_resume;
++ +++++++ video->pm_nb.priority = 0;
++ +++++++ register_pm_notifier(&video->pm_nb);
++ +++++++
return 0;
err_free_input_dev:
video = acpi_driver_data(device);
++ +++++++ unregister_pm_notifier(&video->pm_nb);
++ +++++++
acpi_video_bus_stop_devices(video);
acpi_video_bus_put_devices(video);
acpi_video_bus_remove_fs(device);
#include <linux/acpi.h>
#include <linux/pci.h>
#include <linux/pnp.h>
++ +++++++#include <linux/slab.h>
#include "../base.h"
#include "pnpacpi.h"
pnp_add_bus_resource(dev, start, end);
}
+++ ++++++static u64 addr_space_length(struct pnp_dev *dev, u64 min, u64 max, u64 len)
+++ ++++++{
+++ ++++++ u64 max_len;
+++ ++++++
+++ ++++++ max_len = max - min + 1;
+++ ++++++ if (len <= max_len)
+++ ++++++ return len;
+++ ++++++
+++ ++++++ /*
+++ ++++++ * Per 6.4.3.5, _LEN cannot exceed _MAX - _MIN + 1, but some BIOSes
+++ ++++++ * don't do this correctly, e.g.,
+++ ++++++ * https://bugzilla.kernel.org/show_bug.cgi?id=15480
+++ ++++++ */
+++ ++++++ dev_info(&dev->dev,
+++ ++++++ "resource length %#llx doesn't fit in %#llx-%#llx, trimming\n",
+++ ++++++ (unsigned long long) len, (unsigned long long) min,
+++ ++++++ (unsigned long long) max);
+++ ++++++ return max_len;
+++ ++++++}
+++ ++++++
static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
struct acpi_resource *res)
{
struct acpi_resource_address64 addr, *p = &addr;
acpi_status status;
int window;
+++ ++++++ u64 len;
status = acpi_resource_to_address64(res, p);
if (!ACPI_SUCCESS(status)) {
return;
}
+++ ++++++ len = addr_space_length(dev, p->minimum, p->maximum, p->address_length);
window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
if (p->resource_type == ACPI_MEMORY_RANGE)
--- ------ pnpacpi_parse_allocated_memresource(dev,
--- ------ p->minimum, p->address_length,
+++ ++++++ pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
p->info.mem.write_protect, window);
else if (p->resource_type == ACPI_IO_RANGE)
--- ------ pnpacpi_parse_allocated_ioresource(dev,
--- ------ p->minimum, p->address_length,
+++ ++++++ pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
p->granularity == 0xfff ? ACPI_DECODE_10 :
ACPI_DECODE_16, window);
else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
--- ------ pnpacpi_parse_allocated_busresource(dev, p->minimum,
--- ------ p->address_length);
+++ ++++++ pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
}
static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
{
struct acpi_resource_extended_address64 *p = &res->data.ext_address64;
int window;
+++ ++++++ u64 len;
+++ ++++++ len = addr_space_length(dev, p->minimum, p->maximum, p->address_length);
window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
if (p->resource_type == ACPI_MEMORY_RANGE)
--- ------ pnpacpi_parse_allocated_memresource(dev,
--- ------ p->minimum, p->address_length,
+++ ++++++ pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
p->info.mem.write_protect, window);
else if (p->resource_type == ACPI_IO_RANGE)
--- ------ pnpacpi_parse_allocated_ioresource(dev,
--- ------ p->minimum, p->address_length,
+++ ++++++ pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
p->granularity == 0xfff ? ACPI_DECODE_10 :
ACPI_DECODE_16, window);
else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
--- ------ pnpacpi_parse_allocated_busresource(dev, p->minimum,
--- ------ p->address_length);
+++ ++++++ pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
}
static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,