From: Alexey Starikovskiy <aystarik@gmail.com>
To: lenb@kernel.org, linux-acpi@vger.kernel.org
Cc: astarikovskiy@suse.de
Subject: [PATCH 03/12] ACPI: Battery: simplify update scheme
Date: Thu, 16 Aug 2007 18:03:32 +0400 [thread overview]
Message-ID: <20070816140332.19441.45886.stgit@z61m> (raw)
In-Reply-To: <20070816140322.19441.63139.stgit@z61m>
From: Alexey Starikovskiy <astarikivskiy@suse.de>
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
---
drivers/acpi/battery.c | 274 +++++++++---------------------------------------
1 files changed, 52 insertions(+), 222 deletions(-)
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 14bdfad..eea4dd9 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -27,6 +27,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
+#include <linux/jiffies.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
@@ -41,27 +42,18 @@
#define ACPI_BATTERY_DEVICE_NAME "Battery"
#define ACPI_BATTERY_NOTIFY_STATUS 0x80
#define ACPI_BATTERY_NOTIFY_INFO 0x81
-#define ACPI_BATTERY_UNITS_WATTS "mW"
-#define ACPI_BATTERY_UNITS_AMPS "mA"
#define _COMPONENT ACPI_BATTERY_COMPONENT
-#define ACPI_BATTERY_UPDATE_TIME 0
-
-#define ACPI_BATTERY_NONE_UPDATE 0
-#define ACPI_BATTERY_EASY_UPDATE 1
-#define ACPI_BATTERY_INIT_UPDATE 2
-
ACPI_MODULE_NAME("battery");
MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION("ACPI Battery Driver");
MODULE_LICENSE("GPL");
-static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME;
-
-/* 0 - every time, > 0 - by update_time */
-module_param(update_time, uint, 0644);
+static unsigned int cache_time = 1000;
+module_param(cache_time, uint, 0644);
+MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
extern struct proc_dir_entry *acpi_lock_battery_dir(void);
extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
@@ -95,15 +87,12 @@ enum acpi_battery_files {
};
struct acpi_battery {
- struct acpi_device *device;
struct mutex lock;
- unsigned long alarm;
- unsigned long update_time[ACPI_BATTERY_NUMFILES];
- int state;
+ struct acpi_device *device;
+ unsigned long update_time;
int present_rate;
int remaining_capacity;
int present_voltage;
- int power_unit;
int design_capacity;
int last_full_capacity;
int technology;
@@ -112,14 +101,14 @@ struct acpi_battery {
int design_capacity_low;
int capacity_granularity_1;
int capacity_granularity_2;
+ int alarm;
char model_number[32];
char serial_number[32];
char type[32];
char oem_info[32];
- u8 present_prev;
+ int state;
+ int power_unit;
u8 alarm_present;
- u8 init_update;
- u8 update[ACPI_BATTERY_NUMFILES];
};
inline int acpi_battery_present(struct acpi_battery *battery)
@@ -127,33 +116,15 @@ inline int acpi_battery_present(struct acpi_battery *battery)
return battery->device->status.battery_present;
}
-inline char *acpi_battery_power_units(struct acpi_battery *battery)
+inline char *acpi_battery_units(struct acpi_battery *battery)
{
- if (battery->power_unit)
- return ACPI_BATTERY_UNITS_AMPS;
- else
- return ACPI_BATTERY_UNITS_WATTS;
-}
-
-inline acpi_handle acpi_battery_handle(struct acpi_battery *battery)
-{
- return battery->device->handle;
+ return (battery->power_unit)?"mA":"mW";
}
/* --------------------------------------------------------------------------
Battery Management
-------------------------------------------------------------------------- */
-static void acpi_battery_check_result(struct acpi_battery *battery, int result)
-{
- if (!battery)
- return;
-
- if (result) {
- battery->init_update = 1;
- }
-}
-
struct acpi_offsets {
size_t offset; /* offset inside struct acpi_sbs_battery */
u8 mode; /* int or string? */
@@ -228,11 +199,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
acpi_status status = 0;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- battery->update_time[ACPI_BATTERY_INFO] = get_seconds();
if (!acpi_battery_present(battery))
return 0;
mutex_lock(&battery->lock);
- status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF",
+ status = acpi_evaluate_object(battery->device->handle, "_BIF",
NULL, &buffer);
mutex_unlock(&battery->lock);
if (ACPI_FAILURE(status)) {
@@ -251,14 +221,17 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
acpi_status status = 0;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- battery->update_time[ACPI_BATTERY_STATE] = get_seconds();
-
if (!acpi_battery_present(battery))
return 0;
+ if (battery->update_time &&
+ time_before(jiffies, battery->update_time +
+ msecs_to_jiffies(cache_time)))
+ return 0;
+
/* Evaluate _BST */
mutex_lock(&battery->lock);
- status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST",
+ status = acpi_evaluate_object(battery->device->handle, "_BST",
NULL, &buffer);
mutex_unlock(&battery->lock);
if (ACPI_FAILURE(status)) {
@@ -267,14 +240,13 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
}
result = extract_package(battery, buffer.pointer,
state_offsets, ARRAY_SIZE(state_offsets));
+ battery->update_time = jiffies;
kfree(buffer.pointer);
return result;
}
static int acpi_battery_get_alarm(struct acpi_battery *battery)
{
- battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
-
return 0;
}
@@ -285,8 +257,6 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
struct acpi_object_list arg_list = { 1, &arg0 };
- battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
-
if (!acpi_battery_present(battery))
return -ENODEV;
@@ -296,7 +266,7 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
arg0.integer.value = alarm;
mutex_lock(&battery->lock);
- status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
+ status = acpi_evaluate_object(battery->device->handle, "_BTP",
&arg_list, NULL);
mutex_unlock(&battery->lock);
if (ACPI_FAILURE(status))
@@ -311,112 +281,36 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
static int acpi_battery_init_alarm(struct acpi_battery *battery)
{
- int result = 0;
acpi_status status = AE_OK;
acpi_handle handle = NULL;
- unsigned long alarm = battery->alarm;
/* See if alarms are supported, and if so, set default */
-
- status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle);
- if (ACPI_SUCCESS(status)) {
- battery->alarm_present = 1;
- if (!alarm) {
- alarm = battery->design_capacity_warning;
- }
- result = acpi_battery_set_alarm(battery, alarm);
- if (result)
- goto end;
- } else {
+ status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
+ if (ACPI_FAILURE(status)) {
battery->alarm_present = 0;
+ return 0;
}
-
- end:
-
- return result;
+ battery->alarm_present = 1;
+ if (!battery->alarm)
+ battery->alarm = battery->design_capacity_warning;
+ return acpi_battery_set_alarm(battery, battery->alarm);
}
-static int acpi_battery_init_update(struct acpi_battery *battery)
+static int acpi_battery_update(struct acpi_battery *battery)
{
- int result = 0;
-
- result = acpi_battery_get_status(battery);
- if (result)
+ int saved_present = acpi_battery_present(battery);
+ int result = acpi_battery_get_status(battery);
+ if (result || !acpi_battery_present(battery))
return result;
-
- battery->present_prev = acpi_battery_present(battery);
-
- if (acpi_battery_present(battery)) {
+ if (saved_present != acpi_battery_present(battery) ||
+ !battery->update_time) {
+ battery->update_time = 0;
result = acpi_battery_get_info(battery);
if (result)
return result;
- result = acpi_battery_get_state(battery);
- if (result)
- return result;
-
acpi_battery_init_alarm(battery);
}
-
- return result;
-}
-
-static int acpi_battery_update(struct acpi_battery *battery,
- int update, int *update_result_ptr)
-{
- int result = 0;
- int update_result = ACPI_BATTERY_NONE_UPDATE;
-
- if (!acpi_battery_present(battery)) {
- update = 1;
- }
-
- if (battery->init_update) {
- result = acpi_battery_init_update(battery);
- if (result)
- goto end;
- update_result = ACPI_BATTERY_INIT_UPDATE;
- } else if (update) {
- result = acpi_battery_get_status(battery);
- if (result)
- goto end;
- if ((!battery->present_prev & acpi_battery_present(battery))
- || (battery->present_prev & !acpi_battery_present(battery))) {
- result = acpi_battery_init_update(battery);
- if (result)
- goto end;
- update_result = ACPI_BATTERY_INIT_UPDATE;
- } else {
- update_result = ACPI_BATTERY_EASY_UPDATE;
- }
- }
-
- end:
-
- battery->init_update = (result != 0);
-
- *update_result_ptr = update_result;
-
- return result;
-}
-
-static void acpi_battery_notify_update(struct acpi_battery *battery)
-{
- acpi_battery_get_status(battery);
-
- if (battery->init_update) {
- return;
- }
-
- if ((!battery->present_prev &
- acpi_battery_present(battery)) ||
- (battery->present_prev &
- !acpi_battery_present(battery))) {
- battery->init_update = 1;
- } else {
- battery->update[ACPI_BATTERY_INFO] = 1;
- battery->update[ACPI_BATTERY_STATE] = 1;
- battery->update[ACPI_BATTERY_ALARM] = 1;
- }
+ return acpi_battery_get_state(battery);
}
/* --------------------------------------------------------------------------
@@ -442,7 +336,7 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)
/* Battery Units */
- units = acpi_battery_power_units(battery);
+ units = acpi_battery_units(battery);
if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "design capacity: unknown\n");
@@ -511,7 +405,7 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
/* Battery Units */
- units = acpi_battery_power_units(battery);
+ units = acpi_battery_units(battery);
if (!(battery->state & 0x04))
seq_printf(seq, "capacity state: ok\n");
@@ -571,13 +465,13 @@ static int acpi_battery_print_alarm(struct seq_file *seq, int result)
/* Battery Units */
- units = acpi_battery_power_units(battery);
+ units = acpi_battery_units(battery);
seq_printf(seq, "alarm: ");
if (!battery->alarm)
seq_printf(seq, "unsupported\n");
else
- seq_printf(seq, "%lu %sh\n", battery->alarm, units);
+ seq_printf(seq, "%u %sh\n", battery->alarm, units);
end:
@@ -587,50 +481,35 @@ static int acpi_battery_print_alarm(struct seq_file *seq, int result)
return result;
}
-static ssize_t
-acpi_battery_write_alarm(struct file *file,
- const char __user * buffer,
- size_t count, loff_t * ppos)
+static ssize_t acpi_battery_write_alarm(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * ppos)
{
int result = 0;
char alarm_string[12] = { '\0' };
struct seq_file *m = file->private_data;
struct acpi_battery *battery = m->private;
- int update_result = ACPI_BATTERY_NONE_UPDATE;
if (!battery || (count > sizeof(alarm_string) - 1))
return -EINVAL;
-
- result = acpi_battery_update(battery, 1, &update_result);
if (result) {
result = -ENODEV;
goto end;
}
-
if (!acpi_battery_present(battery)) {
result = -ENODEV;
goto end;
}
-
if (copy_from_user(alarm_string, buffer, count)) {
result = -EFAULT;
goto end;
}
-
alarm_string[count] = '\0';
-
- result = acpi_battery_set_alarm(battery,
- simple_strtoul(alarm_string, NULL, 0));
- if (result)
- goto end;
-
+ battery->alarm = simple_strtol(alarm_string, NULL, 0);
+ result = acpi_battery_set_alarm(battery, battery->alarm);
end:
-
- acpi_battery_check_result(battery, result);
-
if (!result)
return count;
-
return result;
}
@@ -649,28 +528,8 @@ static struct acpi_read_mux {
static int acpi_battery_read(int fid, struct seq_file *seq)
{
struct acpi_battery *battery = seq->private;
- int result = 0;
- int update_result = ACPI_BATTERY_NONE_UPDATE;
- int update = 0;
-
- update = (get_seconds() - battery->update_time[fid] >= update_time);
- update = (update | battery->update[fid]);
-
- result = acpi_battery_update(battery, update, &update_result);
- if (result)
- goto end;
-
- if (update_result == ACPI_BATTERY_EASY_UPDATE) {
- result = acpi_read_funcs[fid].get(battery);
- if (result)
- goto end;
- }
-
- end:
- result = acpi_read_funcs[fid].print(seq, result);
- acpi_battery_check_result(battery, result);
- battery->update[fid] = result;
- return result;
+ int result = acpi_battery_update(battery);
+ return acpi_read_funcs[fid].print(seq, result);
}
static int acpi_battery_read_info(struct seq_file *seq, void *offset)
@@ -794,30 +653,11 @@ static int acpi_battery_remove_fs(struct acpi_device *device)
static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
{
struct acpi_battery *battery = data;
- struct acpi_device *device = NULL;
-
if (!battery)
return;
-
- device = battery->device;
-
- switch (event) {
- case ACPI_BATTERY_NOTIFY_STATUS:
- case ACPI_BATTERY_NOTIFY_INFO:
- case ACPI_NOTIFY_BUS_CHECK:
- case ACPI_NOTIFY_DEVICE_CHECK:
- device = battery->device;
- acpi_battery_notify_update(battery);
- acpi_bus_generate_event(device, event,
- acpi_battery_present(battery));
- break;
- default:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
- break;
- }
-
- return;
+ acpi_battery_update(battery);
+ acpi_bus_generate_event(battery->device, event,
+ acpi_battery_present(battery));
}
static int acpi_battery_add(struct acpi_device *device)
@@ -838,13 +678,7 @@ static int acpi_battery_add(struct acpi_device *device)
strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
acpi_driver_data(device) = battery;
-
- result = acpi_battery_get_status(battery);
- if (result)
- goto end;
-
- battery->init_update = 1;
-
+ acpi_battery_update(battery);
result = acpi_battery_add_fs(device);
if (result)
goto end;
@@ -900,14 +734,10 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
static int acpi_battery_resume(struct acpi_device *device)
{
struct acpi_battery *battery;
-
if (!device)
return -EINVAL;
-
- battery = device->driver_data;
-
- battery->init_update = 1;
-
+ battery = acpi_driver_data(device);
+ battery->update_time = 0;
return 0;
}
next prev parent reply other threads:[~2007-08-16 14:34 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-08-16 14:03 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
2007-08-16 14:03 ` [PATCH 02/12] ACPI: Battery: don't use acpi_extract_package() Alexey Starikovskiy
2007-08-16 14:03 ` Alexey Starikovskiy [this message]
2007-08-16 14:03 ` [PATCH 04/12] ACPI: Battery: Misc clean-ups, no functional changes Alexey Starikovskiy
2007-08-16 14:03 ` [PATCH 05/12] ACPI: Battery: Add sysfs support Alexey Starikovskiy
2007-08-16 14:03 ` [PATCH 06/12] ACPI: Add acpi_bus_generate_event4() function Alexey Starikovskiy
2007-08-17 2:23 ` Zhang Rui
2007-08-17 5:11 ` Alexey Starikovskiy
2007-08-17 5:48 ` Alexey Starikovskiy
2007-08-17 6:25 ` Zhang Rui
2007-08-16 14:03 ` [PATCH 07/12] ACPI: EC: Add new query handler to list head Alexey Starikovskiy
2007-08-16 14:03 ` [PATCH 08/12] ACPI: SBS: Split host controller (ACPI0001) from SBS driver (ACPI0002) Alexey Starikovskiy
2007-08-16 14:04 ` [PATCH 09/12] ACPI: SBS: Simplify data structures in SBS Alexey Starikovskiy
2007-08-16 14:04 ` [PATCH 10/12] ACPI: SBS: Make SBS reads table-driven Alexey Starikovskiy
2007-08-16 14:04 ` [PATCH 11/12] ACPI: SBS: Add support for power_supply class (and sysfs) Alexey Starikovskiy
2007-08-16 14:04 ` [PATCH 12/12] ACPI: SBS: Add ACPI_PROCFS around procfs handling code Alexey Starikovskiy
-- strict thread matches above, loose matches on Subject: below --
2007-08-16 14:25 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
2007-08-16 14:26 ` [PATCH 03/12] ACPI: Battery: simplify update scheme Alexey Starikovskiy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070816140332.19441.45886.stgit@z61m \
--to=aystarik@gmail.com \
--cc=astarikovskiy@suse.de \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.