Skip to content

Commit

Permalink
Pull alexey-fixes into release branch
Browse files Browse the repository at this point in the history
  • Loading branch information
Len Brown committed Oct 29, 2007
2 parents 6a22c57 + 5527c8b commit 14f7d72
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 274 deletions.
5 changes: 0 additions & 5 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -586,11 +586,6 @@ and is between 256 and 4096 characters. It is defined in the file

eata= [HW,SCSI]

ec_intr= [HW,ACPI] ACPI Embedded Controller interrupt mode
Format: <int>
0: polling mode
non-0: interrupt mode (default)

edd= [EDD]
Format: {"of[f]" | "sk[ipmbr]"}
See comment in arch/i386/boot/edd.S
Expand Down
8 changes: 5 additions & 3 deletions drivers/acpi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ config ACPI_PROC_EVENT

config ACPI_AC
tristate "AC Adapter"
depends on X86 && POWER_SUPPLY
depends on X86
select POWER_SUPPLY
default y
help
This driver adds support for the AC Adapter object, which indicates
Expand All @@ -97,7 +98,8 @@ config ACPI_AC

config ACPI_BATTERY
tristate "Battery"
depends on X86 && POWER_SUPPLY
depends on X86
select POWER_SUPPLY
default y
help
This driver adds support for battery information through
Expand Down Expand Up @@ -352,7 +354,7 @@ config ACPI_HOTPLUG_MEMORY
config ACPI_SBS
tristate "Smart Battery System"
depends on X86
depends on POWER_SUPPLY
select POWER_SUPPLY
help
This driver adds support for the Smart Battery System, another
type of access to battery information, found on some laptops.
Expand Down
164 changes: 95 additions & 69 deletions drivers/acpi/battery.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,15 @@ static int acpi_battery_technology(struct acpi_battery *battery)
return POWER_SUPPLY_TECHNOLOGY_NiMH;
if (!strcasecmp("LION", battery->type))
return POWER_SUPPLY_TECHNOLOGY_LION;
if (!strcasecmp("LI-ION", battery->type))
return POWER_SUPPLY_TECHNOLOGY_LION;
if (!strcasecmp("LiP", battery->type))
return POWER_SUPPLY_TECHNOLOGY_LIPO;
return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
}

static int acpi_battery_update(struct acpi_battery *battery);

static int acpi_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
Expand All @@ -139,6 +143,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
if ((!acpi_battery_present(battery)) &&
psp != POWER_SUPPLY_PROP_PRESENT)
return -ENODEV;
acpi_battery_update(battery);
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
if (battery->state & 0x01)
Expand Down Expand Up @@ -257,7 +262,7 @@ static int extract_package(struct acpi_battery *battery,
union acpi_object *package,
struct acpi_offsets *offsets, int num)
{
int i, *x;
int i;
union acpi_object *element;
if (package->type != ACPI_TYPE_PACKAGE)
return -EFAULT;
Expand All @@ -266,16 +271,21 @@ static int extract_package(struct acpi_battery *battery,
return -EFAULT;
element = &package->package.elements[i];
if (offsets[i].mode) {
if (element->type != ACPI_TYPE_STRING &&
element->type != ACPI_TYPE_BUFFER)
return -EFAULT;
strncpy((u8 *)battery + offsets[i].offset,
element->string.pointer, 32);
u8 *ptr = (u8 *)battery + offsets[i].offset;
if (element->type == ACPI_TYPE_STRING ||
element->type == ACPI_TYPE_BUFFER)
strncpy(ptr, element->string.pointer, 32);
else if (element->type == ACPI_TYPE_INTEGER) {
strncpy(ptr, (u8 *)&element->integer.value,
sizeof(acpi_integer));
ptr[sizeof(acpi_integer)] = 0;
} else return -EFAULT;
} else {
if (element->type != ACPI_TYPE_INTEGER)
return -EFAULT;
x = (int *)((u8 *)battery + offsets[i].offset);
*x = element->integer.value;
if (element->type == ACPI_TYPE_INTEGER) {
int *x = (int *)((u8 *)battery +
offsets[i].offset);
*x = element->integer.value;
} else return -EFAULT;
}
}
return 0;
Expand Down Expand Up @@ -385,29 +395,81 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
return acpi_battery_set_alarm(battery);
}

static ssize_t acpi_battery_alarm_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
return sprintf(buf, "%d\n", battery->alarm * 1000);
}

static ssize_t acpi_battery_alarm_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
unsigned long x;
struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
if (sscanf(buf, "%ld\n", &x) == 1)
battery->alarm = x/1000;
if (acpi_battery_present(battery))
acpi_battery_set_alarm(battery);
return count;
}

static struct device_attribute alarm_attr = {
.attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
.show = acpi_battery_alarm_show,
.store = acpi_battery_alarm_store,
};

static int sysfs_add_battery(struct acpi_battery *battery)
{
int result;

battery->update_time = 0;
result = acpi_battery_get_info(battery);
acpi_battery_init_alarm(battery);
if (result)
return result;
if (battery->power_unit) {
battery->bat.properties = charge_battery_props;
battery->bat.num_properties =
ARRAY_SIZE(charge_battery_props);
} else {
battery->bat.properties = energy_battery_props;
battery->bat.num_properties =
ARRAY_SIZE(energy_battery_props);
}

battery->bat.name = acpi_device_bid(battery->device);
battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
battery->bat.get_property = acpi_battery_get_property;

result = power_supply_register(&battery->device->dev, &battery->bat);
if (result)
return result;
return device_create_file(battery->bat.dev, &alarm_attr);
}

static void sysfs_remove_battery(struct acpi_battery *battery)
{
if (!battery->bat.dev)
return;
device_remove_file(battery->bat.dev, &alarm_attr);
power_supply_unregister(&battery->bat);
}

static int acpi_battery_update(struct acpi_battery *battery)
{
int saved_present = acpi_battery_present(battery);
int result = acpi_battery_get_status(battery);
if (result || !acpi_battery_present(battery))
if (result)
return result;
if (saved_present != acpi_battery_present(battery) ||
!battery->update_time) {
battery->update_time = 0;
result = acpi_battery_get_info(battery);
if (result)
return result;
if (battery->power_unit) {
battery->bat.properties = charge_battery_props;
battery->bat.num_properties =
ARRAY_SIZE(charge_battery_props);
} else {
battery->bat.properties = energy_battery_props;
battery->bat.num_properties =
ARRAY_SIZE(energy_battery_props);
}
acpi_battery_init_alarm(battery);
if (!acpi_battery_present(battery)) {
sysfs_remove_battery(battery);
return 0;
}
if (!battery->bat.dev)
sysfs_add_battery(battery);
return acpi_battery_get_state(battery);
}

Expand Down Expand Up @@ -554,10 +616,6 @@ static ssize_t acpi_battery_write_alarm(struct file *file,

if (!battery || (count > sizeof(alarm_string) - 1))
return -EINVAL;
if (result) {
result = -ENODEV;
goto end;
}
if (!acpi_battery_present(battery)) {
result = -ENODEV;
goto end;
Expand Down Expand Up @@ -688,33 +746,6 @@ static void acpi_battery_remove_fs(struct acpi_device *device)

#endif

static ssize_t acpi_battery_alarm_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
return sprintf(buf, "%d\n", battery->alarm * 1000);
}

static ssize_t acpi_battery_alarm_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
unsigned long x;
struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
if (sscanf(buf, "%ld\n", &x) == 1)
battery->alarm = x/1000;
if (acpi_battery_present(battery))
acpi_battery_set_alarm(battery);
return count;
}

static struct device_attribute alarm_attr = {
.attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
.show = acpi_battery_alarm_show,
.store = acpi_battery_alarm_store,
};

/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
Expand All @@ -732,7 +763,9 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
acpi_bus_generate_netlink_event(device->pnp.device_class,
device->dev.bus_id, event,
acpi_battery_present(battery));
kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
/* acpi_batter_update could remove power_supply object */
if (battery->bat.dev)
kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
}

static int acpi_battery_add(struct acpi_device *device)
Expand All @@ -756,11 +789,6 @@ static int acpi_battery_add(struct acpi_device *device)
if (result)
goto end;
#endif
battery->bat.name = acpi_device_bid(device);
battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
battery->bat.get_property = acpi_battery_get_property;
result = power_supply_register(&battery->device->dev, &battery->bat);
result = device_create_file(battery->bat.dev, &alarm_attr);
status = acpi_install_notify_handler(device->handle,
ACPI_ALL_NOTIFY,
acpi_battery_notify, battery);
Expand Down Expand Up @@ -796,10 +824,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
#ifdef CONFIG_ACPI_PROCFS
acpi_battery_remove_fs(device);
#endif
if (battery->bat.dev) {
device_remove_file(battery->bat.dev, &alarm_attr);
power_supply_unregister(&battery->bat);
}
sysfs_remove_battery(battery);
mutex_destroy(&battery->lock);
kfree(battery);
return 0;
Expand All @@ -813,6 +838,7 @@ static int acpi_battery_resume(struct acpi_device *device)
return -EINVAL;
battery = acpi_driver_data(device);
battery->update_time = 0;
acpi_battery_update(battery);
return 0;
}

Expand Down
8 changes: 3 additions & 5 deletions drivers/acpi/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,10 @@ int acpi_bus_set_power(acpi_handle handle, int state)
return -ENODEV;
}
/*
* Get device's current power state if it's unknown
* This means device power state isn't initialized or previous setting failed
* Get device's current power state
*/
if ((device->power.state == ACPI_STATE_UNKNOWN) || device->flags.force_power_state)
acpi_bus_get_power(device->handle, &device->power.state);
if ((state == device->power.state) && !device->flags.force_power_state) {
acpi_bus_get_power(device->handle, &device->power.state);
if (state == device->power.state) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
state));
return 0;
Expand Down
37 changes: 29 additions & 8 deletions drivers/acpi/button.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids);

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 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);

Expand All @@ -87,6 +88,7 @@ static struct acpi_driver acpi_button_driver = {
.ids = button_device_ids,
.ops = {
.add = acpi_button_add,
.resume = acpi_button_resume,
.remove = acpi_button_remove,
},
};
Expand Down Expand Up @@ -253,6 +255,19 @@ static int acpi_button_remove_fs(struct acpi_device *device)
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
static int acpi_lid_send_state(struct acpi_button *button)
{
unsigned long state;
acpi_status status;

status = acpi_evaluate_integer(button->device->handle, "_LID", NULL,
&state);
if (ACPI_FAILURE(status))
return -ENODEV;
/* input layer checks if event is redundant */
input_report_switch(button->input, SW_LID, !state);
return 0;
}

static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
{
Expand All @@ -265,15 +280,8 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
switch (event) {
case ACPI_BUTTON_NOTIFY_STATUS:
input = button->input;

if (button->type == ACPI_BUTTON_TYPE_LID) {
struct acpi_handle *handle = button->device->handle;
unsigned long state;

if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID",
NULL, &state)))
input_report_switch(input, SW_LID, !state);

acpi_lid_send_state(button);
} else {
int keycode = test_bit(KEY_SLEEP, input->keybit) ?
KEY_SLEEP : KEY_POWER;
Expand Down Expand Up @@ -336,6 +344,17 @@ static int acpi_button_install_notify_handlers(struct acpi_button *button)
return ACPI_FAILURE(status) ? -ENODEV : 0;
}

static int acpi_button_resume(struct acpi_device *device)
{
struct acpi_button *button;
if (!device)
return -EINVAL;
button = acpi_driver_data(device);
if (button && button->type == ACPI_BUTTON_TYPE_LID)
return acpi_lid_send_state(button);
return 0;
}

static void acpi_button_remove_notify_handlers(struct acpi_button *button)
{
switch (button->type) {
Expand Down Expand Up @@ -453,6 +472,8 @@ static int acpi_button_add(struct acpi_device *device)
error = input_register_device(input);
if (error)
goto err_remove_handlers;
if (button->type == ACPI_BUTTON_TYPE_LID)
acpi_lid_send_state(button);

if (device->wakeup.flags.valid) {
/* Button's GPE is run-wake GPE */
Expand Down
Loading

0 comments on commit 14f7d72

Please sign in to comment.