ACPI: AC: Add sysfs interface
Subsystems (2)
PATCH 1/12 ACPI: AC: Add sysfs interface
Refer to Documentation/power_supply_class.txt for interface description.
---
drivers/acpi/ac.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 47 insertions(+), 2 deletions(-)
drivers/acpi/ac.c +47 -2
@@ -29,6 +29,12 @@#include <linux/types.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> + +#if defined(CONFIG_POWER_SUPPLY ) || defined(CONFIG_POWER_SUPPLY_MODULE ) +#define ENABLE_POWER_SUPPLY +#include <linux/power_supply.h> +#endif +#include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h>
@@ -72,16 +78,42 @@ static struct acpi_driver acpi_ac_driver = { };struct acpi_ac { +#ifdef ENABLE_POWER_SUPPLY +struct power_supply charger; +#endif struct acpi_device * device;unsigned long state; }; +#define to_acpi_ac (x) container_of(x, struct acpi_ac, charger); +static const struct file_operations acpi_ac_fops = { .open = acpi_ac_open_fs, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; +#ifdef ENABLE_POWER_SUPPLY +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 , +}; + +#endif /* -------------------------------------------------------------------------- AC Adapter Management
@@ -205,6 +237,9 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)case ACPI_NOTIFY_DEVICE_CHECK :acpi_ac_get_state (ac);acpi_bus_generate_event (device, event, (u32 ) ac->state); +#ifdef ENABLE_POWER_SUPPLY +kobject_uevent (&ac->charger.dev->kobj,KOBJ_CHANGE ); +#endif break ;default : ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -241,7 +276,14 @@ static int acpi_ac_add(struct acpi_device *device) result =acpi_ac_add_fs (device);if (result) goto end; - +#ifdef ENABLE_POWER_SUPPLY + ac->charger.name =acpi_device_bid (device); + ac->charger.type =POWER_SUPPLY_TYPE_MAINS ; + ac->charger.properties = ac_props; + ac->charger.num_properties =ARRAY_SIZE (ac_props); + ac->charger.get_property = get_ac_property; +power_supply_register (&ac->device->dev, &ac->charger); +#endif status =acpi_install_notify_handler (device->handle,ACPI_ALL_NOTIFY , acpi_ac_notify, ac);
@@ -276,7 +318,10 @@ static int acpi_ac_remove(struct acpi_device *device, int type) status =acpi_remove_notify_handler (device->handle,ACPI_ALL_NOTIFY , acpi_ac_notify); - +#ifdef ENABLE_POWER_SUPPLY +if (ac->charger.dev) +power_supply_unregister (&ac->charger); +#endif acpi_ac_remove_fs (device);kfree (ac);
PATCH 2/12 ACPI: Battery: don't use acpi_extract_package()
acpi_extract_package() creates more problems with memory management than solves as helper for package handling.
---
drivers/acpi/battery.c | 309 +++++++++++++++++++----------------------------- 1 files changed, 123 insertions(+), 186 deletions(-)
drivers/acpi/battery.c +123 -186
@@ -36,9 +36,6 @@#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF -#define ACPI_BATTERY_FORMAT_BIF "NNNNNNNNNSSSS" -#define ACPI_BATTERY_FORMAT_BST "NNNN" -#define ACPI_BATTERY_COMPONENT 0x00040000#define ACPI_BATTERY_CLASS "battery"#define ACPI_BATTERY_DEVICE_NAME "Battery"
@@ -90,29 +87,6 @@ static struct acpi_driver acpi_battery_driver = { }, }; -struct acpi_battery_state { -acpi_integer state; -acpi_integer present_rate; -acpi_integer remaining_capacity; -acpi_integer present_voltage; -}; - -struct acpi_battery_info { -acpi_integer power_unit; -acpi_integer design_capacity; -acpi_integer last_full_capacity; -acpi_integer battery_technology; -acpi_integer design_voltage; -acpi_integer design_capacity_warning; -acpi_integer design_capacity_low; -acpi_integer battery_capacity_granularity_1; -acpi_integer battery_capacity_granularity_2; -acpi_string model_number; -acpi_string serial_number; -acpi_string battery_type; -acpi_string oem_info; -}; -enum acpi_battery_files {ACPI_BATTERY_INFO =0 ,ACPI_BATTERY_STATE ,
@@ -120,32 +94,42 @@ enum acpi_battery_files { ACPI_BATTERY_NUMFILES, }; -struct acpi_battery_flags { -u8 battery_present_prev; -u8 alarm_present; -u8 init_update; -u8 update[ACPI_BATTERY_NUMFILES ]; -u8 power_unit; -}; -struct acpi_battery {struct acpi_device *device; -struct acpi_battery_flags flags; -struct acpi_buffer bif_data; -struct acpi_buffer bst_data;struct mutex lock;unsigned long alarm;unsigned long update_time[ACPI_BATTERY_NUMFILES ]; - +int state; +int present_rate; +int remaining_capacity; +int present_voltage; +int power_unit; +int design_capacity; +int last_full_capacity; +int technology; +int design_voltage; +int design_capacity_warning; +int design_capacity_low; +int capacity_granularity_1; +int capacity_granularity_2; +char model_number[32 ]; +char serial_number[32 ]; +char type[32 ]; +char oem_info[32 ]; +u8 present_prev; +u8 alarm_present; +u8 init_update; +u8 update[ACPI_BATTERY_NUMFILES ]; };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) { -if (battery->flags.power_unit) +if (battery->power_unit)return ACPI_BATTERY_UNITS_AMPS ;else return ACPI_BATTERY_UNITS_WATTS ;
@@ -166,43 +150,63 @@ static void acpi_battery_check_result(struct acpi_battery *battery, int result)return ;if (result) { - battery->flags.init_update =1 ; + battery->init_update =1 ; } } -static int acpi_battery_extract_package (struct acpi_battery *battery, -union acpi_object *package, -struct acpi_buffer *format, -struct acpi_buffer *data, -char *package_name) -{ -acpi_status status =AE_OK ; -struct acpi_buffer data_null = {0 ,NULL }; +struct acpi_offsets { +size_t offset;/* offset inside struct acpi_sbs_battery */ +u8 mode;/* int or string? */ +}; - status =acpi_extract_package (package, format, &data_null); -if (status !=AE_BUFFER_OVERFLOW ) { -ACPI_EXCEPTION ((AE_INFO , status,"Extracting size %s" , - package_name)); -return -ENODEV ; - } +static struct acpi_offsets state_offsets[] = { + {offsetof(struct acpi_battery , state),0 }, + {offsetof(struct acpi_battery , present_rate),0 }, + {offsetof(struct acpi_battery , remaining_capacity),0 }, + {offsetof(struct acpi_battery , present_voltage),0 }, +}; -if (data_null.length != data->length) { -kfree (data->pointer); - data->pointer =kzalloc (data_null.length,GFP_KERNEL ); -if (!data->pointer) { -ACPI_EXCEPTION ((AE_INFO ,AE_NO_MEMORY ,"kzalloc()" )); -return -ENOMEM ; - } - data->length = data_null.length; - } +static struct acpi_offsets info_offsets[] = { + {offsetof(struct acpi_battery , power_unit),0 }, + {offsetof(struct acpi_battery , design_capacity),0 }, + {offsetof(struct acpi_battery , last_full_capacity),0 }, + {offsetof(struct acpi_battery , technology),0 }, + {offsetof(struct acpi_battery , design_voltage),0 }, + {offsetof(struct acpi_battery , design_capacity_warning),0 }, + {offsetof(struct acpi_battery , design_capacity_low),0 }, + {offsetof(struct acpi_battery , capacity_granularity_1),0 }, + {offsetof(struct acpi_battery , capacity_granularity_2),0 }, + {offsetof(struct acpi_battery , model_number),1 }, + {offsetof(struct acpi_battery , serial_number),1 }, + {offsetof(struct acpi_battery , type),1 }, + {offsetof(struct acpi_battery , oem_info),1 }, +}; - status =acpi_extract_package (package, format, data); -if (ACPI_FAILURE (status)) { -ACPI_EXCEPTION ((AE_INFO , status,"Extracting %s" , - package_name)); -return -ENODEV ; +static int extract_package (struct acpi_battery *battery, +union acpi_object *package, +struct acpi_offsets *offsets,int num) +{ +int i, *x; +union acpi_object *element; +if (package->type !=ACPI_TYPE_PACKAGE ) +return -EFAULT ; +for (i =0 ; i < num; ++i) { +if (package->package.count <= i) +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 ); + }else { +if (element->type !=ACPI_TYPE_INTEGER ) +return -EFAULT ; + x = (int *)((u8 *)battery + offsets[i].offset); + *x = element->integer.value; + } } -return 0 ; }
@@ -223,19 +227,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery)int result =0 ;acpi_status status =0 ;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL }; -struct acpi_buffer format = {sizeof (ACPI_BATTERY_FORMAT_BIF ), -ACPI_BATTERY_FORMAT_BIF - }; -union acpi_object *package =NULL ; -struct acpi_buffer *data =NULL ; -struct acpi_battery_info *bif =NULL ; battery->update_time[ACPI_BATTERY_INFO ] =get_seconds (); -if (!acpi_battery_present (battery))return 0 ; - -/* Evaluate _BIF */ mutex_lock (&battery->lock); status =acpi_evaluate_object (acpi_battery_handle (battery),"_BIF" ,NULL , &buffer);
@@ -244,28 +239,9 @@ static int acpi_battery_get_info(struct acpi_battery *battery)ACPI_EXCEPTION ((AE_INFO , status,"Evaluating _BIF" ));return -ENODEV ; } - - package = buffer.pointer; - - data = &battery->bif_data; - -/* Extract Package Data */ - - result = -acpi_battery_extract_package (battery, package, &format, data, -"_BIF" ); -if (result) - goto end; - - end: - + result =extract_package (battery, buffer.pointer, + info_offsets,ARRAY_SIZE (info_offsets));kfree (buffer.pointer); - -if (!result) { - bif = data->pointer; - battery->flags.power_unit = bif->power_unit; - } -return result; }
@@ -274,11 +250,6 @@ static int acpi_battery_get_state(struct acpi_battery *battery)int result =0 ;acpi_status status =0 ;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL }; -struct acpi_buffer format = {sizeof (ACPI_BATTERY_FORMAT_BST ), -ACPI_BATTERY_FORMAT_BST - }; -union acpi_object *package =NULL ; -struct acpi_buffer *data =NULL ; battery->update_time[ACPI_BATTERY_STATE ] =get_seconds ();
@@ -294,22 +265,9 @@ static int acpi_battery_get_state(struct acpi_battery *battery)ACPI_EXCEPTION ((AE_INFO , status,"Evaluating _BST" ));return -ENODEV ; } - - package = buffer.pointer; - - data = &battery->bst_data; - -/* Extract Package Data */ - - result = -acpi_battery_extract_package (battery, package, &format, data, -"_BST" ); -if (result) - goto end; - - end: + result =extract_package (battery, buffer.pointer, + state_offsets,ARRAY_SIZE (state_offsets));kfree (buffer.pointer); -return result; }
@@ -332,7 +290,7 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,if (!acpi_battery_present (battery))return -ENODEV ; -if (!battery->flags.alarm_present) +if (!battery->alarm_present)return -ENODEV ; arg0.integer.value = alarm;
@@ -356,22 +314,21 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)int result =0 ;acpi_status status =AE_OK ;acpi_handle handle =NULL ; -struct acpi_battery_info *bif = battery->bif_data.pointer;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->flags.alarm_present =1 ; -if (!alarm && bif) { - alarm = bif->design_capacity_warning; + battery->alarm_present =1 ; +if (!alarm) { + alarm = battery->design_capacity_warning; } result =acpi_battery_set_alarm (battery, alarm);if (result) goto end; }else { - battery->flags.alarm_present =0 ; + battery->alarm_present =0 ; } end:
@@ -387,7 +344,7 @@ static int acpi_battery_init_update(struct acpi_battery *battery)if (result)return result; - battery->flags.battery_present_prev =acpi_battery_present (battery); + battery->present_prev =acpi_battery_present (battery);if (acpi_battery_present (battery)) { result =acpi_battery_get_info (battery);
@@ -413,7 +370,7 @@ static int acpi_battery_update(struct acpi_battery *battery, update =1 ; } -if (battery->flags.init_update) { +if (battery->init_update) { result =acpi_battery_init_update (battery);if (result) goto end;
@@ -422,8 +379,8 @@ static int acpi_battery_update(struct acpi_battery *battery, result =acpi_battery_get_status (battery);if (result) goto end; -if ((!battery->flags.battery_present_prev &acpi_battery_present (battery)) - || (battery->flags.battery_present_prev & !acpi_battery_present (battery))) { +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;
@@ -435,7 +392,7 @@ static int acpi_battery_update(struct acpi_battery *battery, end: - battery->flags.init_update = (result !=0 ); + battery->init_update = (result !=0 ); *update_result_ptr = update_result;
@@ -446,19 +403,19 @@ static void acpi_battery_notify_update(struct acpi_battery *battery) {acpi_battery_get_status (battery); -if (battery->flags.init_update) { +if (battery->init_update) {return ; } -if ((!battery->flags.battery_present_prev & +if ((!battery->present_prev &acpi_battery_present (battery)) || - (battery->flags.battery_present_prev & + (battery->present_prev & !acpi_battery_present (battery))) { - battery->flags.init_update =1 ; + battery->init_update =1 ; }else { - battery->flags.update[ACPI_BATTERY_INFO ] =1 ; - battery->flags.update[ACPI_BATTERY_STATE ] =1 ; - battery->flags.update[ACPI_BATTERY_ALARM ] =1 ; + battery->update[ACPI_BATTERY_INFO ] =1 ; + battery->update[ACPI_BATTERY_STATE ] =1 ; + battery->update[ACPI_BATTERY_ALARM ] =1 ; } }
@@ -471,7 +428,6 @@ static struct proc_dir_entry *acpi_battery_dir;static int acpi_battery_print_info (struct seq_file *seq,int result) {struct acpi_battery *battery = seq->private; -struct acpi_battery_info *bif =NULL ;char *units ="?" ;if (result)
@@ -484,30 +440,23 @@ static int acpi_battery_print_info(struct seq_file *seq, int result) goto end; } - bif = battery->bif_data.pointer; -if (!bif) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"BIF buffer is NULL" )); - result = -ENODEV ; - goto end; - } -/* Battery Units */ units =acpi_battery_power_units (battery); -if (bif->design_capacity ==ACPI_BATTERY_VALUE_UNKNOWN ) +if (battery->design_capacity ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"design capacity: unknown\n" );else seq_printf (seq,"design capacity: %d %sh\n" , - (u32 ) bif->design_capacity, units); + (u32 ) battery->design_capacity, units); -if (bif->last_full_capacity ==ACPI_BATTERY_VALUE_UNKNOWN ) +if (battery->last_full_capacity ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"last full capacity: unknown\n" );else seq_printf (seq,"last full capacity: %d %sh\n" , - (u32 ) bif->last_full_capacity, units); + (u32 ) battery->last_full_capacity, units); -switch ((u32 ) bif->battery_technology) { +switch ((u32 ) battery->technology) {case 0 :seq_printf (seq,"battery technology: non-rechargeable\n" );break ;
@@ -519,23 +468,23 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)break ; } -if (bif->design_voltage ==ACPI_BATTERY_VALUE_UNKNOWN ) +if (battery->design_voltage ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"design voltage: unknown\n" );else seq_printf (seq,"design voltage: %d mV\n" , - (u32 ) bif->design_voltage); + (u32 ) battery->design_voltage);seq_printf (seq,"design capacity warning: %d %sh\n" , - (u32 ) bif->design_capacity_warning, units); + (u32 ) battery->design_capacity_warning, units);seq_printf (seq,"design capacity low: %d %sh\n" , - (u32 ) bif->design_capacity_low, units); + (u32 ) battery->design_capacity_low, units);seq_printf (seq,"capacity granularity 1: %d %sh\n" , - (u32 ) bif->battery_capacity_granularity_1, units); + (u32 ) battery->capacity_granularity_1, units);seq_printf (seq,"capacity granularity 2: %d %sh\n" , - (u32 ) bif->battery_capacity_granularity_2, units); -seq_printf (seq,"model number: %s\n" , bif->model_number); -seq_printf (seq,"serial number: %s\n" , bif->serial_number); -seq_printf (seq,"battery type: %s\n" , bif->battery_type); -seq_printf (seq,"OEM info: %s\n" , bif->oem_info); + (u32 ) battery->capacity_granularity_2, units); +seq_printf (seq,"model number: %s\n" , battery->model_number); +seq_printf (seq,"serial number: %s\n" , battery->serial_number); +seq_printf (seq,"battery type: %s\n" , battery->type); +seq_printf (seq,"OEM info: %s\n" , battery->oem_info); end:
@@ -548,7 +497,6 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)static int acpi_battery_print_state (struct seq_file *seq,int result) {struct acpi_battery *battery = seq->private; -struct acpi_battery_state *bst =NULL ;char *units ="?" ;if (result)
@@ -561,50 +509,43 @@ static int acpi_battery_print_state(struct seq_file *seq, int result) goto end; } - bst = battery->bst_data.pointer; -if (!bst) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"BST buffer is NULL" )); - result = -ENODEV ; - goto end; - } -/* Battery Units */ units =acpi_battery_power_units (battery); -if (!(bst->state &0x04 )) +if (!(battery->state &0x04 ))seq_printf (seq,"capacity state: ok\n" );else seq_printf (seq,"capacity state: critical\n" ); -if ((bst->state &0x01 ) && (bst->state &0x02 )) { +if ((battery->state &0x01 ) && (battery->state &0x02 )) {seq_printf (seq,"charging state: charging/discharging\n" ); - }else if (bst->state &0x01 ) + }else if (battery->state &0x01 )seq_printf (seq,"charging state: discharging\n" ); -else if (bst->state &0x02 ) +else if (battery->state &0x02 )seq_printf (seq,"charging state: charging\n" );else {seq_printf (seq,"charging state: charged\n" ); } -if (bst->present_rate ==ACPI_BATTERY_VALUE_UNKNOWN ) +if (battery->present_rate ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"present rate: unknown\n" );else seq_printf (seq,"present rate: %d %s\n" , - (u32 ) bst->present_rate, units); + (u32 ) battery->present_rate, units); -if (bst->remaining_capacity ==ACPI_BATTERY_VALUE_UNKNOWN ) +if (battery->remaining_capacity ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"remaining capacity: unknown\n" );else seq_printf (seq,"remaining capacity: %d %sh\n" , - (u32 ) bst->remaining_capacity, units); + (u32 ) battery->remaining_capacity, units); -if (bst->present_voltage ==ACPI_BATTERY_VALUE_UNKNOWN ) +if (battery->present_voltage ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"present voltage: unknown\n" );else seq_printf (seq,"present voltage: %d mV\n" , - (u32 ) bst->present_voltage); + (u32 ) battery->present_voltage); end:
@@ -713,7 +654,7 @@ static int acpi_battery_read(int fid, struct seq_file *seq)int update =0 ; update = (get_seconds () - battery->update_time[fid] >= update_time); - update = (update | battery->flags.update[fid]); + update = (update | battery->update[fid]); result =acpi_battery_update (battery, update, &update_result);if (result)
@@ -728,7 +669,7 @@ static int acpi_battery_read(int fid, struct seq_file *seq) end: result = acpi_read_funcs[fid].acpi_battery_check_result (battery, result); - battery->flags.update[fid] = result; + battery->update[fid] = result;return result; }
@@ -902,7 +843,7 @@ static int acpi_battery_add(struct acpi_device *device)if (result) goto end; - battery->flags.init_update =1 ; + battery->init_update =1 ; result =acpi_battery_add_fs (device);if (result)
@@ -948,10 +889,6 @@ static int acpi_battery_remove(struct acpi_device *device, int type)acpi_battery_remove_fs (device); -kfree (battery->bif_data.pointer); - -kfree (battery->bst_data.pointer); -mutex_destroy (&battery->lock);kfree (battery);
@@ -969,7 +906,7 @@ static int acpi_battery_resume(struct acpi_device *device) battery = device->driver_data; - battery->flags.init_update =1 ; + battery->init_update =1 ;return 0 ; }
PATCH 3/12 ACPI: Battery: simplify update scheme
In reply to Alexey Starikovskiy---
drivers/acpi/battery.c | 274 +++++++++--------------------------------------- 1 files changed, 52 insertions(+), 222 deletions(-)
drivers/acpi/battery.c +52 -222
@@ -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].acpi_battery_check_result (battery, result); - battery->update[fid] = result; -return result; +int result =acpi_battery_update (battery); +return acpi_read_funcs[fid].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 ; }
PATCH 4/12 ACPI: Battery: Misc clean-ups, no functional changes
In reply to Alexey Starikovskiy---
drivers/acpi/battery.c | 346 +++++++++++++++++------------------------------- 1 files changed, 126 insertions(+), 220 deletions(-)
drivers/acpi/battery.c +126 -220
@@ -1,6 +1,8 @@/* -* acpi_battery.c - ACPI Battery Driver ($Revision: 37 $) +* battery.c - ACPI Battery Driver (Revision: 2.0) * +* Copyright (C) 2007 Alexey Starikovskiy <[email protected]> +* Copyright (C) 2004-2007 Vladimir Lebedev <[email protected]> * Copyright (C) 2001, 2002 Andy Grover <[email protected]> * Copyright (C) 2001, 2002 Paul Diefenbaugh <[email protected]> *
@@ -48,6 +50,7 @@ACPI_MODULE_NAME ("battery" );MODULE_AUTHOR ("Paul Diefenbaugh" ); +MODULE_AUTHOR ("Alexey Starikovskiy <[email protected]>" );MODULE_DESCRIPTION ("ACPI Battery Driver" );MODULE_LICENSE ("GPL" );
@@ -58,31 +61,17 @@ 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); -static int acpi_battery_add (struct acpi_device *device); -static int acpi_battery_remove (struct acpi_device *device,int type); -static int acpi_battery_resume (struct acpi_device *device); -static const struct acpi_device_id battery_device_ids[] = { {"PNP0C0A" ,0 }, {"" ,0 }, }; -MODULE_DEVICE_TABLE (acpi, battery_device_ids); -static struct acpi_driver acpi_battery_driver = { - .name ="battery" , - .class =ACPI_BATTERY_CLASS , - .ids = battery_device_ids, - .ops = { - .add = acpi_battery_add, - .resume = acpi_battery_resume, - .remove = acpi_battery_remove, - }, -}; +MODULE_DEVICE_TABLE (acpi, battery_device_ids);enum acpi_battery_files { -ACPI_BATTERY_INFO =0 , -ACPI_BATTERY_STATE , -ACPI_BATTERY_ALARM , + info_tag =0 , + state_tag, + alarm_tag,ACPI_BATTERY_NUMFILES , };
@@ -124,7 +113,6 @@ inline char *acpi_battery_units(struct acpi_battery *battery)/* -------------------------------------------------------------------------- Battery Management -------------------------------------------------------------------------- */ -struct acpi_offsets {size_t offset;/* offset inside struct acpi_sbs_battery */ u8 mode;/* int or string? */
@@ -183,19 +171,16 @@ static int extract_package(struct acpi_battery *battery,static int acpi_battery_get_status (struct acpi_battery *battery) { -int result =0 ; - - result =acpi_bus_get_status (battery->device); -if (result) { +if (acpi_bus_get_status (battery->device)) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"Evaluating _STA" ));return -ENODEV ; } -return result; +return 0 ; }static int acpi_battery_get_info (struct acpi_battery *battery) { -int result =0 ; +int result = -EFAULT ;acpi_status status =0 ;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL };
@@ -205,10 +190,12 @@ static int acpi_battery_get_info(struct acpi_battery *battery) status =acpi_evaluate_object (battery->device->handle,"_BIF" ,NULL , &buffer);mutex_unlock (&battery->lock); +if (ACPI_FAILURE (status)) {ACPI_EXCEPTION ((AE_INFO , status,"Evaluating _BIF" ));return -ENODEV ; } + result =extract_package (battery, buffer.pointer, info_offsets,ARRAY_SIZE (info_offsets));kfree (buffer.pointer);
@@ -234,10 +221,12 @@ static int acpi_battery_get_state(struct acpi_battery *battery) status =acpi_evaluate_object (battery->device->handle,"_BST" ,NULL , &buffer);mutex_unlock (&battery->lock); +if (ACPI_FAILURE (status)) {ACPI_EXCEPTION ((AE_INFO , status,"Evaluating _BST" ));return -ENODEV ; } + result =extract_package (battery, buffer.pointer, state_offsets,ARRAY_SIZE (state_offsets)); battery->update_time = jiffies;
@@ -245,37 +234,26 @@ static int acpi_battery_get_state(struct acpi_battery *battery)return result; } -static int acpi_battery_get_alarm (struct acpi_battery *battery) -{ -return 0 ; -} - -static int acpi_battery_set_alarm (struct acpi_battery *battery, -unsigned long alarm) +static int acpi_battery_set_alarm (struct acpi_battery *battery) {acpi_status status =0 ; -union acpi_object arg0 = {ACPI_TYPE_INTEGER }; +union acpi_object arg0 = { .type =ACPI_TYPE_INTEGER };struct acpi_object_list arg_list = {1 , &arg0 }; -if (!acpi_battery_present (battery)) -return -ENODEV ; - -if (!battery->alarm_present) +if (!acpi_battery_present (battery)|| !battery->alarm_present)return -ENODEV ; - arg0.integer.value = alarm; + arg0.integer.value = battery->alarm;mutex_lock (&battery->lock); status =acpi_evaluate_object (battery->device->handle,"_BTP" , &arg_list,NULL );mutex_unlock (&battery->lock); +if (ACPI_FAILURE (status))return -ENODEV ; -ACPI_DEBUG_PRINT ((ACPI_DB_INFO ,"Alarm set to %d\n" , (u32 ) alarm)); - - battery->alarm = alarm; - +ACPI_DEBUG_PRINT ((ACPI_DB_INFO ,"Alarm set to %d\n" , battery->alarm));return 0 ; }
@@ -293,7 +271,7 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery) battery->alarm_present =1 ;if (!battery->alarm) battery->alarm = battery->design_capacity_warning; -return acpi_battery_set_alarm (battery, battery->alarm); +return acpi_battery_set_alarm (battery); }static int acpi_battery_update (struct acpi_battery *battery)
@@ -322,130 +300,101 @@ static struct proc_dir_entry *acpi_battery_dir;static int acpi_battery_print_info (struct seq_file *seq,int result) {struct acpi_battery *battery = seq->private; -char *units ="?" ;if (result) goto end; -if (acpi_battery_present (battery)) -seq_printf (seq,"present: yes\n" ); -else { -seq_printf (seq,"present: no\n" ); +seq_printf (seq,"present: %s\n" , +acpi_battery_present (battery)?"yes" :"no" ); +if (!acpi_battery_present (battery)) goto end; - } - -/* Battery Units */ - - units =acpi_battery_units (battery); -if (battery->design_capacity ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"design capacity: unknown\n" );else seq_printf (seq,"design capacity: %d %sh\n" , - (u32 ) battery->design_capacity, units); + battery->design_capacity, +acpi_battery_units (battery));if (battery->last_full_capacity ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"last full capacity: unknown\n" );else seq_printf (seq,"last full capacity: %d %sh\n" , - (u32 ) battery->last_full_capacity, units); - -switch ((u32 ) battery->technology) { -case 0 : -seq_printf (seq,"battery technology: non-rechargeable\n" ); -break ; -case 1 : -seq_printf (seq,"battery technology: rechargeable\n" ); -break ; -default : -seq_printf (seq,"battery technology: unknown\n" ); -break ; - } + battery->last_full_capacity, +acpi_battery_units (battery)); + +seq_printf (seq,"battery technology: %srechargeable\n" , + (!battery->technology)?"non-" :"" );if (battery->design_voltage ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"design voltage: unknown\n" );else seq_printf (seq,"design voltage: %d mV\n" , - (u32 ) battery->design_voltage); + battery->design_voltage);seq_printf (seq,"design capacity warning: %d %sh\n" , - (u32 ) battery->design_capacity_warning, units); + battery->design_capacity_warning, +acpi_battery_units (battery));seq_printf (seq,"design capacity low: %d %sh\n" , - (u32 ) battery->design_capacity_low, units); + battery->design_capacity_low, +acpi_battery_units (battery));seq_printf (seq,"capacity granularity 1: %d %sh\n" , - (u32 ) battery->capacity_granularity_1, units); + battery->capacity_granularity_1, +acpi_battery_units (battery));seq_printf (seq,"capacity granularity 2: %d %sh\n" , - (u32 ) battery->capacity_granularity_2, units); + battery->capacity_granularity_2, +acpi_battery_units (battery));seq_printf (seq,"model number: %s\n" , battery->model_number);seq_printf (seq,"serial number: %s\n" , battery->serial_number);seq_printf (seq,"battery type: %s\n" , battery->type);seq_printf (seq,"OEM info: %s\n" , battery->oem_info); - end: -if (result)seq_printf (seq,"ERROR: Unable to read battery info\n" ); -return result; }static int acpi_battery_print_state (struct seq_file *seq,int result) {struct acpi_battery *battery = seq->private; -char *units ="?" ;if (result) goto end; -if (acpi_battery_present (battery)) -seq_printf (seq,"present: yes\n" ); -else { -seq_printf (seq,"present: no\n" ); +seq_printf (seq,"present: %s\n" , +acpi_battery_present (battery)?"yes" :"no" ); +if (!acpi_battery_present (battery)) goto end; - } - -/* Battery Units */ - - units =acpi_battery_units (battery); - -if (!(battery->state &0x04 )) -seq_printf (seq,"capacity state: ok\n" ); -else -seq_printf (seq,"capacity state: critical\n" ); -if ((battery->state &0x01 ) && (battery->state &0x02 )) { +seq_printf (seq,"capacity state: %s\n" , + (battery->state &0x04 )?"critical" :"ok" ); +if ((battery->state &0x01 ) && (battery->state &0x02 ))seq_printf (seq,"charging state: charging/discharging\n" ); - }else if (battery->state &0x01 ) +else if (battery->state &0x01 )seq_printf (seq,"charging state: discharging\n" );else if (battery->state &0x02 )seq_printf (seq,"charging state: charging\n" ); -else { +else seq_printf (seq,"charging state: charged\n" ); - }if (battery->present_rate ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"present rate: unknown\n" );else seq_printf (seq,"present rate: %d %s\n" , - (u32 ) battery->present_rate, units); + battery->present_rate,acpi_battery_units (battery));if (battery->remaining_capacity ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"remaining capacity: unknown\n" );else seq_printf (seq,"remaining capacity: %d %sh\n" , - (u32 ) battery->remaining_capacity, units); - + battery->remaining_capacity,acpi_battery_units (battery));if (battery->present_voltage ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"present voltage: unknown\n" );else seq_printf (seq,"present voltage: %d mV\n" , - (u32 ) battery->present_voltage); - + battery->present_voltage); end: - -if (result) { +if (result)seq_printf (seq,"ERROR: Unable to read battery state\n" ); - }return result; }
@@ -453,7 +402,6 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)static int acpi_battery_print_alarm (struct seq_file *seq,int result) {struct acpi_battery *battery = seq->private; -char *units ="?" ;if (result) goto end;
@@ -462,22 +410,15 @@ static int acpi_battery_print_alarm(struct seq_file *seq, int result)seq_printf (seq,"present: no\n" ); goto end; } - -/* Battery Units */ - - units =acpi_battery_units (battery); -seq_printf (seq,"alarm: " );if (!battery->alarm)seq_printf (seq,"unsupported\n" );else -seq_printf (seq,"%u %sh\n" , battery->alarm, units); - +seq_printf (seq,"%u %sh\n" , battery->alarm, +acpi_battery_units (battery)); end: -if (result)seq_printf (seq,"ERROR: Unable to read battery alarm\n" ); -return result; }
@@ -506,7 +447,7 @@ static ssize_t acpi_battery_write_alarm(struct file *file, } alarm_string[count] ='\0' ; battery->alarm =simple_strtol (alarm_string,NULL ,0 ); - result =acpi_battery_set_alarm (battery, battery->alarm); + result =acpi_battery_set_alarm (battery); end:if (!result)return count;
@@ -514,95 +455,76 @@ static ssize_t acpi_battery_write_alarm(struct file *file, }typedef int (*print_func )(struct seq_file *seq,int result); -typedef int (*get_func )(struct acpi_battery *battery); - -static struct acpi_read_mux { -print_func print; -get_func get; -} acpi_read_funcs[ACPI_BATTERY_NUMFILES ] = { - {.get = acpi_battery_get_info, .print = acpi_battery_print_info}, - {.get = acpi_battery_get_state, .print = acpi_battery_print_state}, - {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm}, + +static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES ] = { + acpi_battery_print_info, + acpi_battery_print_state, + acpi_battery_print_alarm, };static int acpi_battery_read (int fid,struct seq_file *seq) {struct acpi_battery *battery = seq->private;int result =acpi_battery_update (battery); -return acpi_read_funcs[fid].static int acpi_battery_read_info (struct seq_file *seq,void *offset) -{ -return acpi_battery_read (ACPI_BATTERY_INFO , seq); +return acpi_print_funcs[fid](seq, result); } -static int acpi_battery_read_state (struct seq_file *seq,void *offset) -{ -return acpi_battery_read (ACPI_BATTERY_STATE , seq); -} - -static int acpi_battery_read_alarm (struct seq_file *seq,void *offset) -{ -return acpi_battery_read (ACPI_BATTERY_ALARM , seq); +#define DECLARE_FILE_FUNCTIONS (_name) \ +static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \ +{ \ + return acpi_battery_read(_name##_tag, seq); \ +} \ +static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \ +{ \ + return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \ } -static int acpi_battery_info_open_fs (struct inode *inode,struct file *file) -{ -return single_open (file, acpi_battery_read_info,PDE (inode)->data); -} - -static int acpi_battery_state_open_fs (struct inode *inode,struct file *file) -{ -return single_open (file, acpi_battery_read_state,PDE (inode)->data); -} +DECLARE_FILE_FUNCTIONS (info); +DECLARE_FILE_FUNCTIONS (state); +DECLARE_FILE_FUNCTIONS (alarm); + +#undef DECLARE_FILE_FUNCTIONS + +#define FILE_DESCRIPTION_RO (_name) \ + { \ + .name = __stringify(_name), \ + .mode = S_IRUGO, \ + .ops = { \ + .open = acpi_battery_##_name##_open_fs, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .release = single_release, \ + .owner = THIS_MODULE, \ + }, \ + } -static int acpi_battery_alarm_open_fs (struct inode *inode,struct file *file) -{ -return single_open (file, acpi_battery_read_alarm,PDE (inode)->data); -} +#define FILE_DESCRIPTION_RW (_name) \ + { \ + .name = __stringify(_name), \ + .mode = S_IFREG | S_IRUGO | S_IWUSR, \ + .ops = { \ + .open = acpi_battery_##_name##_open_fs, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .write = acpi_battery_write_##_name, \ + .release = single_release, \ + .owner = THIS_MODULE, \ + }, \ + }static struct battery_file {struct file_operations ops;mode_t mode;char *name; } acpi_battery_file[] = { - { - .name ="info" , - .mode =S_IRUGO , - .ops = { - .open = acpi_battery_info_open_fs, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner =THIS_MODULE , - }, - }, - { - .name ="state" , - .mode =S_IRUGO , - .ops = { - .open = acpi_battery_state_open_fs, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner =THIS_MODULE , - }, - }, - { - .name ="alarm" , - .mode =S_IFREG |S_IRUGO |S_IWUSR , - .ops = { - .open = acpi_battery_alarm_open_fs, - .read = seq_read, - .write = acpi_battery_write_alarm, - .llseek = seq_lseek, - .release = single_release, - .owner =THIS_MODULE , - }, - }, +FILE_DESCRIPTION_RO (info), +FILE_DESCRIPTION_RO (state), +FILE_DESCRIPTION_RW (alarm), }; +#undef FILE_DESCRIPTION_RO +#undef FILE_DESCRIPTION_RW +static int acpi_battery_add_fs (struct acpi_device *device) {struct proc_dir_entry *entry =NULL ;
@@ -627,23 +549,20 @@ static int acpi_battery_add_fs(struct acpi_device *device) entry->owner =THIS_MODULE ; } } -return 0 ; } -static int acpi_battery_remove_fs (struct acpi_device *device) +static void acpi_battery_remove_fs (struct acpi_device *device) {int i; -if (acpi_device_dir (device)) { -for (i =0 ; i <ACPI_BATTERY_NUMFILES ; ++i) { -remove_proc_entry (acpi_battery_file[i].name, +if (!acpi_device_dir (device)) +return ; +for (i =0 ; i <ACPI_BATTERY_NUMFILES ; ++i) +remove_proc_entry (acpi_battery_file[i].name,acpi_device_dir (device)); - } -remove_proc_entry (acpi_device_bid (device), acpi_battery_dir); -acpi_device_dir (device) =NULL ; - } -return 0 ; +remove_proc_entry (acpi_device_bid (device), acpi_battery_dir); +acpi_device_dir (device) =NULL ; }/* --------------------------------------------------------------------------
@@ -665,14 +584,11 @@ static int acpi_battery_add(struct acpi_device *device)int result =0 ;acpi_status status =0 ;struct acpi_battery *battery =NULL ; -if (!device)return -EINVAL ; - battery =kzalloc (sizeof (struct acpi_battery ),GFP_KERNEL );if (!battery)return -ENOMEM ; -mutex_init (&battery->lock); battery->device = device;strcpy (acpi_device_name (device),ACPI_BATTERY_DEVICE_NAME );
@@ -682,7 +598,6 @@ static int acpi_battery_add(struct acpi_device *device) result =acpi_battery_add_fs (device);if (result) goto end; - status =acpi_install_notify_handler (device->handle,ACPI_ALL_NOTIFY , acpi_battery_notify, battery);
@@ -691,19 +606,14 @@ static int acpi_battery_add(struct acpi_device *device) result = -ENODEV ; goto end; } - printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",ACPI_BATTERY_DEVICE_NAME ,acpi_device_bid (device), device->status.battery_present ? "present" : "absent"); - end: -if (result) {acpi_battery_remove_fs (device);kfree (battery); } - -return result; }
@@ -714,19 +624,13 @@ static int acpi_battery_remove(struct acpi_device *device, int type)if (!device || !acpi_driver_data (device))return -EINVAL ; - battery =acpi_driver_data (device); - status =acpi_remove_notify_handler (device->handle,ACPI_ALL_NOTIFY , acpi_battery_notify); -acpi_battery_remove_fs (device); -mutex_destroy (&battery->lock); -kfree (battery); -return 0 ; }
@@ -741,33 +645,35 @@ static int acpi_battery_resume(struct acpi_device *device)return 0 ; } +static struct acpi_driver acpi_battery_driver = { + .name ="battery" , + .class =ACPI_BATTERY_CLASS , + .ids = battery_device_ids, + .ops = { + .add = acpi_battery_add, + .resume = acpi_battery_resume, + .remove = acpi_battery_remove, + }, +}; +static int __init acpi_battery_init (void ) { -int result; -if (acpi_disabled)return -ENODEV ; - acpi_battery_dir =acpi_lock_battery_dir ();if (!acpi_battery_dir)return -ENODEV ; - - result =acpi_bus_register_driver (&acpi_battery_driver); -if (result <0 ) { +if (acpi_bus_register_driver (&acpi_battery_driver) <0 ) {acpi_unlock_battery_dir (acpi_battery_dir);return -ENODEV ; } -return 0 ; } static void __exit acpi_battery_exit(void) {acpi_bus_unregister_driver (&acpi_battery_driver); -acpi_unlock_battery_dir (acpi_battery_dir); - -return ; }module_init (acpi_battery_init);
PATCH 5/12 ACPI: Battery: Add sysfs support
In reply to Alexey StarikovskiyRefer to Documentation/power_supply_class.txt for interface description.
---
drivers/acpi/battery.c | 201 +++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 179 insertions(+), 22 deletions(-)
drivers/acpi/battery.c +179 -22
@@ -30,13 +30,21 @@#include <linux/init.h> #include <linux/types.h> #include <linux/jiffies.h> + +#ifdef CONFIG_ACPI_PROC #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <asm/uaccess.h> +#endif #include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h> +#if defined(CONFIG_POWER_SUPPLY ) || defined(CONFIG_POWER_SUPPLY_MODULE ) +#define ENABLE_POWER_SUPPLY +#include <linux/power_supply.h> +#endif +#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF#define ACPI_BATTERY_COMPONENT 0x00040000
@@ -58,9 +66,19 @@ static unsigned int cache_time = 1000;module_param (cache_time, uint,0644 );MODULE_PARM_DESC (cache_time,"cache time in milliseconds" ); +#ifdef CONFIG_ACPI_PROC extern struct proc_dir_entry *acpi_lock_battery_dir (void );extern void *acpi_unlock_battery_dir (struct proc_dir_entry *acpi_battery_dir); +enum acpi_battery_files { + info_tag =0 , + state_tag, + alarm_tag, +ACPI_BATTERY_NUMFILES , +}; + +#endif +static const struct acpi_device_id battery_device_ids[] = { {"PNP0C0A" ,0 }, {"" ,0 },
@@ -68,22 +86,19 @@ static const struct acpi_device_id battery_device_ids[] = {MODULE_DEVICE_TABLE (acpi, battery_device_ids); -enum acpi_battery_files { - info_tag =0 , - state_tag, - alarm_tag, -ACPI_BATTERY_NUMFILES , -};struct acpi_battery {struct mutex lock; +#ifdef ENABLE_POWER_SUPPLY +struct power_supply bat; +#endif struct acpi_device *device;unsigned long update_time; -int present_rate; -int remaining_capacity; -int present_voltage; +int current_now; +int capacity_now; +int voltage_now;int design_capacity; -int last_full_capacity; +int full_charge_capacity;int technology;int design_voltage;int design_capacity_warning;
@@ -100,15 +115,119 @@ struct acpi_battery {u8 alarm_present; }; +#define to_acpi_battery (x) container_of(x, struct acpi_battery, bat); +inline int acpi_battery_present (struct acpi_battery *battery) {return battery->device->status.battery_present; } +#ifdef ENABLE_POWER_SUPPLY +static int acpi_battery_technology (struct acpi_battery *battery) +{ +if (!strcasecmp ("NiCd" , battery->type)) +return POWER_SUPPLY_TECHNOLOGY_NiCd; +if (!strcasecmp ("NiMH" , battery->type)) +return POWER_SUPPLY_TECHNOLOGY_NiMH; +if (!strcasecmp ("LION" , 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_get_property (struct power_supply *psy, +enum power_supply_property psp, +union power_supply_propval *val) +{ +struct acpi_battery *battery =to_acpi_battery (psy); + +if ((!acpi_battery_present (battery)) && + psp !=POWER_SUPPLY_PROP_PRESENT ) +return -ENODEV ; +switch (psp) { +case POWER_SUPPLY_PROP_STATUS : +if (battery->state &0x01 ) + val->intval =POWER_SUPPLY_STATUS_DISCHARGING ; +else if (battery->state &0x02 ) + val->intval =POWER_SUPPLY_STATUS_CHARGING ; +else if (battery->state ==0 ) + val->intval =POWER_SUPPLY_STATUS_FULL ; +break ; +case POWER_SUPPLY_PROP_PRESENT : + val->intval =acpi_battery_present (battery); +break ; +case POWER_SUPPLY_PROP_TECHNOLOGY : + val->intval =acpi_battery_technology (battery); +break ; +case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN : + val->intval = battery->design_voltage *1000 ; +break ; +case POWER_SUPPLY_PROP_VOLTAGE_NOW : + val->intval = battery->voltage_now *1000 ; +break ; +case POWER_SUPPLY_PROP_CURRENT_NOW : + val->intval = battery->current_now *1000 ; +break ; +case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN : +case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN : + val->intval = battery->design_capacity *1000 ; +break ; +case POWER_SUPPLY_PROP_CHARGE_FULL : +case POWER_SUPPLY_PROP_ENERGY_FULL : + val->intval = battery->full_charge_capacity *1000 ; +break ; +case POWER_SUPPLY_PROP_CHARGE_NOW : +case POWER_SUPPLY_PROP_ENERGY_NOW : + val->intval = battery->capacity_now *1000 ; +break ; +case POWER_SUPPLY_PROP_MODEL_NAME : + val->strval = battery->model_number; +break ; +case POWER_SUPPLY_PROP_MANUFACTURER : + val->strval = battery->oem_info; +break ; +default : +return -EINVAL ; + } +return 0 ; +} + +static enum power_supply_property charge_battery_props[] = { +POWER_SUPPLY_PROP_STATUS , +POWER_SUPPLY_PROP_PRESENT , +POWER_SUPPLY_PROP_TECHNOLOGY , +POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN , +POWER_SUPPLY_PROP_VOLTAGE_NOW , +POWER_SUPPLY_PROP_CURRENT_NOW , +POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN , +POWER_SUPPLY_PROP_CHARGE_FULL , +POWER_SUPPLY_PROP_CHARGE_NOW , +POWER_SUPPLY_PROP_MODEL_NAME , +POWER_SUPPLY_PROP_MANUFACTURER , +}; + +static enum power_supply_property energy_battery_props[] = { +POWER_SUPPLY_PROP_STATUS , +POWER_SUPPLY_PROP_PRESENT , +POWER_SUPPLY_PROP_TECHNOLOGY , +POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN , +POWER_SUPPLY_PROP_VOLTAGE_NOW , +POWER_SUPPLY_PROP_CURRENT_NOW , +POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN , +POWER_SUPPLY_PROP_ENERGY_FULL , +POWER_SUPPLY_PROP_ENERGY_NOW , +POWER_SUPPLY_PROP_MODEL_NAME , +POWER_SUPPLY_PROP_MANUFACTURER , +}; +#endif + +#ifdef CONFIG_ACPI_PROC inline char *acpi_battery_units (struct acpi_battery *battery) {return (battery->power_unit)?"mA" :"mW" ; } +#endif /* -------------------------------------------------------------------------- Battery Management
@@ -120,15 +239,15 @@ struct acpi_offsets {static struct acpi_offsets state_offsets[] = { {offsetof(struct acpi_battery , state),0 }, - {offsetof(struct acpi_battery , present_rate),0 }, - {offsetof(struct acpi_battery , remaining_capacity),0 }, - {offsetof(struct acpi_battery , present_voltage),0 }, + {offsetof(struct acpi_battery , current_now),0 }, + {offsetof(struct acpi_battery , capacity_now),0 }, + {offsetof(struct acpi_battery , voltage_now),0 }, };static struct acpi_offsets info_offsets[] = { {offsetof(struct acpi_battery , power_unit),0 }, {offsetof(struct acpi_battery , design_capacity),0 }, - {offsetof(struct acpi_battery , last_full_capacity),0 }, + {offsetof(struct acpi_battery , full_charge_capacity),0 }, {offsetof(struct acpi_battery , technology),0 }, {offsetof(struct acpi_battery , design_voltage),0 }, {offsetof(struct acpi_battery , design_capacity_warning),0 },
@@ -286,6 +405,17 @@ static int acpi_battery_update(struct acpi_battery *battery) result =acpi_battery_get_info (battery);if (result)return result; +#ifdef ENABLE_POWER_SUPPLY +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); + } +#endif acpi_battery_init_alarm (battery); }return acpi_battery_get_state (battery);
@@ -295,6 +425,7 @@ static int acpi_battery_update(struct acpi_battery *battery)FS Interface (/proc) -------------------------------------------------------------------------- */ +#ifdef CONFIG_ACPI_PROC static struct proc_dir_entry *acpi_battery_dir;static int acpi_battery_print_info (struct seq_file *seq,int result)
@@ -315,11 +446,11 @@ static int acpi_battery_print_info(struct seq_file *seq, int result) battery->design_capacity, acpi_battery_units(battery)); -if (battery->last_full_capacity ==ACPI_BATTERY_VALUE_UNKNOWN ) +if (battery->full_charge_capacity ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"last full capacity: unknown\n" );else seq_printf (seq,"last full capacity: %d %sh\n" , - battery->last_full_capacity, + battery->full_charge_capacity,acpi_battery_units (battery)); seq_printf(seq, "battery technology: %srechargeable\n",
@@ -376,22 +507,22 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)else seq_printf (seq,"charging state: charged\n" ); -if (battery->present_rate ==ACPI_BATTERY_VALUE_UNKNOWN ) +if (battery->current_now ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"present rate: unknown\n" );else seq_printf (seq,"present rate: %d %s\n" , - battery->present_rate,acpi_battery_units (battery)); + battery->current_now,acpi_battery_units (battery)); -if (battery->remaining_capacity ==ACPI_BATTERY_VALUE_UNKNOWN ) +if (battery->capacity_now ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"remaining capacity: unknown\n" );else seq_printf (seq,"remaining capacity: %d %sh\n" , - battery->remaining_capacity,acpi_battery_units (battery)); -if (battery->present_voltage ==ACPI_BATTERY_VALUE_UNKNOWN ) + battery->capacity_now,acpi_battery_units (battery)); +if (battery->voltage_now ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"present voltage: unknown\n" );else seq_printf (seq,"present voltage: %d mV\n" , - battery->present_voltage); + battery->voltage_now); end:if (result)seq_printf (seq,"ERROR: Unable to read battery state\n" );
@@ -565,6 +696,7 @@ static void acpi_battery_remove_fs(struct acpi_device *device) acpi_device_dir(device) = NULL; } +#endif /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */
@@ -577,6 +709,9 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)acpi_battery_update (battery);acpi_bus_generate_event (battery->device, event,acpi_battery_present (battery)); +#ifdef ENABLE_POWER_SUPPLY +kobject_uevent (&battery->bat.dev->kobj,KOBJ_CHANGE ); +#endif }static int acpi_battery_add (struct acpi_device *device)
@@ -595,9 +730,17 @@ static int acpi_battery_add(struct acpi_device *device)strcpy (acpi_device_class (device),ACPI_BATTERY_CLASS );acpi_driver_data (device) = battery;acpi_battery_update (battery); +#ifdef CONFIG_ACPI_PROC result =acpi_battery_add_fs (device);if (result) goto end; +#endif +#ifdef ENABLE_POWER_SUPPLY + 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); +#endif status =acpi_install_notify_handler (device->handle,ACPI_ALL_NOTIFY , acpi_battery_notify, battery);
@@ -611,7 +754,9 @@ static int acpi_battery_add(struct acpi_device *device) device->status.battery_present ? "present" : "absent"); end:if (result) { +#ifdef CONFIG_ACPI_PROC acpi_battery_remove_fs (device); +#endif kfree (battery); }return result;
@@ -628,7 +773,13 @@ static int acpi_battery_remove(struct acpi_device *device, int type) status =acpi_remove_notify_handler (device->handle,ACPI_ALL_NOTIFY , acpi_battery_notify); +#ifdef CONFIG_ACPI_PROC acpi_battery_remove_fs (device); +#endif +#ifdef ENABLE_POWER_SUPPLY +if (battery->bat.dev) +power_supply_unregister (&battery->bat); +#endif mutex_destroy (&battery->lock);kfree (battery);return 0 ;
@@ -660,11 +811,15 @@ static int __init acpi_battery_init(void) {if (acpi_disabled)return -ENODEV ; +#ifdef CONFIG_ACPI_PROC acpi_battery_dir =acpi_lock_battery_dir ();if (!acpi_battery_dir)return -ENODEV ; +#endif if (acpi_bus_register_driver (&acpi_battery_driver) <0 ) { +#ifdef CONFIG_ACPI_PROC acpi_unlock_battery_dir (acpi_battery_dir); +#endif return -ENODEV ; }return 0 ;
@@ -673,7 +828,9 @@ static int __init acpi_battery_init(void) static void __exit acpi_battery_exit(void) {acpi_bus_unregister_driver (&acpi_battery_driver); +#ifdef CONFIG_ACPI_PROC acpi_unlock_battery_dir (acpi_battery_dir); +#endif }module_init (acpi_battery_init);
PATCH 6/12 ACPI: Add acpi_bus_generate_event4() function
In reply to Alexey StarikovskiyFrom: Alexey Starikovskiy <[email protected]>
acpi_bus_generate_event() takes two strings out of passed device object. SBS needs to supply these strings directly.
---
drivers/acpi/bus.c | 25 ++++++++++++++++--------- drivers/acpi/event.c | 7 ++++--- drivers/acpi/sbs.c | 39 ++++++++------------------------------- include/acpi/acpi_bus.h | 6 ++++-- 4 files changed, 32 insertions(+), 45 deletions(-)
drivers/acpi/bus.c +16 -9
@@ -283,16 +283,12 @@ DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);extern int event_is_open; -int acpi_bus_generate_event (struct acpi_device *device,u8 type,int data) +int acpi_bus_generate_event4 (const char *device_class,const char *bus_id,u8 type,int data) { -struct acpi_bus_event *event =NULL ; +struct acpi_bus_event *event;unsigned long flags =0 ; - -if (!device) -return -EINVAL ; - -if (acpi_bus_generate_genetlink_event (device, type, data)) +if (acpi_bus_generate_genetlink_event (device_class, bus_id, type, data)) printk(KERN_WARNING PREFIX"Failed to generate an ACPI event via genetlink!\n" );
@@ -304,8 +300,8 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)if (!event)return -ENOMEM ; -strcpy (event->device_class, device->pnp.device_class); -strcpy (event->bus_id, device->pnp.bus_id); +strcpy (event->device_class, device_class); +strcpy (event->bus_id, bus_id); event->type = type; event->data = data;
@@ -316,6 +312,17 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)wake_up_interruptible (&acpi_bus_event_queue);return 0 ; + +} + +EXPORT_SYMBOL_GPL (acpi_bus_generate_event4); + +int acpi_bus_generate_event (struct acpi_device *device,u8 type,int data) +{ +if (!device) +return -EINVAL ; +return acpi_bus_generate_event4 (device->pnp.device_class, + device->pnp.bus_id, type, data); }EXPORT_SYMBOL (acpi_bus_generate_event);
drivers/acpi/event.c +4 -3
@@ -147,7 +147,8 @@ static struct genl_multicast_group acpi_event_mcgrp = { .name = ACPI_GENL_MCAST_GROUP_NAME, }; -int acpi_bus_generate_genetlink_event (struct acpi_device *device, +int acpi_bus_generate_genetlink_event (const char *device_class, +const char *bus_id,u8 type,int data) {struct sk_buff *skb;
@@ -191,8 +192,8 @@ int acpi_bus_generate_genetlink_event(struct acpi_device *device,memset (event,0 ,sizeof (struct acpi_genl_event )); -strcpy (event->device_class, device->pnp.device_class); -strcpy (event->bus_id, device->dev.bus_id); +strcpy (event->device_class, device_class); +strcpy (event->bus_id, bus_id); event->type = type; event->data = data;
drivers/acpi/sbs.c +8 -31
@@ -427,27 +427,6 @@ static int acpi_check_update_proc(struct acpi_sbs *sbs)return 0 ; } -static int acpi_sbs_generate_event (struct acpi_device *device, -int event,int state,char *bid,char *class) -{ -char bid_saved[5 ]; -char class_saved[20 ]; -int result =0 ; - -strcpy (bid_saved,acpi_device_bid (device)); -strcpy (class_saved,acpi_device_class (device)); - -strcpy (acpi_device_bid (device), bid); -strcpy (acpi_device_class (device), class); - - result =acpi_bus_generate_event (device, event, state); - -strcpy (acpi_device_bid (device), bid_saved); -strcpy (acpi_device_class (device), class_saved); - -return result; -} -static int acpi_battery_get_present (struct acpi_battery *battery) {s16 state;
@@ -1451,14 +1430,13 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type) }if (do_ac_init) { - result =acpi_sbs_generate_event (sbs->device, -ACPI_SBS_AC_NOTIFY_STATUS , - new_ac_present, + result =acpi_bus_generate_event4 (ACPI_AC_CLASS ,ACPI_AC_DIR_NAME , -ACPI_AC_CLASS ); +ACPI_SBS_AC_NOTIFY_STATUS , + new_ac_present);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_generate_event() failed" )); +"acpi_bus_generate_event4() failed" )); } }
@@ -1567,14 +1545,13 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type) old_remaining_capacity != battery->state.remaining_capacity) {sprintf (dir_name,ACPI_BATTERY_DIR_NAME , id); - result =acpi_sbs_generate_event (sbs->device, -ACPI_SBS_BATTERY_NOTIFY_STATUS , - new_battery_present, + result =acpi_bus_generate_event4 (ACPI_BATTERY_CLASS , dir_name, -ACPI_BATTERY_CLASS ); +ACPI_SBS_BATTERY_NOTIFY_STATUS , + new_battery_present);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_generate_event() " +"acpi_bus_generate_event4() " "failed" )); } }
include/acpi/acpi_bus.h +4 -2
@@ -321,8 +321,9 @@ struct acpi_bus_event { };extern struct kset acpi_subsys; -extern int acpi_bus_generate_genetlink_event (struct acpi_device *device, -u8 type,int data); +extern int acpi_bus_generate_genetlink_event (const char *device_class, +const char *bus_id, +u8 type,int data);/* * External Functions */
@@ -333,6 +334,7 @@ int acpi_bus_get_status(struct acpi_device *device);int acpi_bus_get_power (acpi_handle handle,int *state);int acpi_bus_set_power (acpi_handle handle,int state);int acpi_bus_generate_event (struct acpi_device *device,u8 type,int data); +int acpi_bus_generate_event4 (const char *class,const char *bid,u8 type,int data);int acpi_bus_receive_event (struct acpi_bus_event *event);int acpi_bus_register_driver (struct acpi_driver *driver);void acpi_bus_unregister_driver (struct acpi_driver *driver);
PATCH 7/12 ACPI: EC: Add new query handler to list head.
In reply to Alexey StarikovskiyFrom: Alexey Starikovskiy <[email protected]>
---
drivers/acpi/ec.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
drivers/acpi/ec.c +1 -2
@@ -425,7 +425,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, handler->func = func; handler->data = data;mutex_lock (&ec->lock); -list_add_tail (&handler->node, &ec->list); +list_add (&handler->node, &ec->list);mutex_unlock (&ec->lock);return 0 ; }
@@ -440,7 +440,6 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)if (query_bit == handler->query_bit) {list_del (&handler->node);kfree (handler); -break ; } }mutex_unlock (&ec->lock);
PATCH 8/12 ACPI: SBS: Split host controller (ACPI0001) from SBS driver (ACPI0002)
In reply to Alexey StarikovskiyFrom: Alexey Starikovskiy <[email protected]>
Replace poll-based host controller driver with the notify-based one. Split it out of sbs.c.
---
drivers/acpi/Makefile | 1 drivers/acpi/sbs.c | 374 ++++++++++--------------------------------------- drivers/acpi/sbshc.c | 309 ++++++++++++++++++++++++++++++++++++++++ drivers/acpi/sbshc.h | 27 ++++ 4 files changed, 412 insertions(+), 299 deletions(-)
drivers/acpi/Makefile +1 -0
@@ -60,3 +60,4 @@ obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o obj-y += cm_sbs.o obj-$(CONFIG_ACPI_SBS) += sbs.o +obj-$(CONFIG_ACPI_SBS) += sbshc.o
drivers/acpi/sbs.c +75 -299
610 lines not on this page · raw message
drivers/acpi/sbshc.c new file +309 -0
309 lines not on this page · raw message
drivers/acpi/sbshc.h new file +27 -0
@@ -0,0 +1,27 @@ +struct acpi_smb_hc ; +enum acpi_smb_protocol { +SMBUS_WRITE_QUICK =2 , +SMBUS_READ_QUICK =3 , +SMBUS_SEND_BYTE =4 , +SMBUS_RECEIVE_BYTE =5 , +SMBUS_WRITE_BYTE =6 , +SMBUS_READ_BYTE =7 , +SMBUS_WRITE_WORD =8 , +SMBUS_READ_WORD =9 , +SMBUS_WRITE_BLOCK =0xa , +SMBUS_READ_BLOCK =0xb , +SMBUS_PROCESS_CALL =0xc , +SMBUS_BLOCK_PROCESS_CALL =0xd , +}; + +static const u8 SMBUS_PEC =0x80 ; + +typedef void (*smbus_alarm_callback )(void *context); + +extern int acpi_smbus_read (struct acpi_smb_hc *hc,u8 protocol,u8 address, +u8 command,u8 * data); +extern int acpi_smbus_write (struct acpi_smb_hc *hc,u8 protocol,u8 slave_address, +u8 command,u8 * data,u8 length); +extern int acpi_smbus_register_callback (struct acpi_smb_hc *hc, +smbus_alarm_callback callback,void *context); +extern int acpi_smbus_unregister_callback (struct acpi_smb_hc *hc);
PATCH 9/12 ACPI: SBS: Simplify data structures in SBS
In reply to Alexey StarikovskiyFrom: Alexey Starikovskiy <[email protected]>
---
drivers/acpi/sbs.c | 280 +++++++++++++++++++++++++--------------------------- 1 files changed, 134 insertions(+), 146 deletions(-)
drivers/acpi/sbs.c +134 -146
@@ -88,10 +88,10 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);/* 0 - every time, > 0 - by update_time */ static unsigned int update_time =120 ; -static unsigned int capacity_mode =CAPACITY_UNIT ; +static unsigned int mode =CAPACITY_UNIT ;module_param (update_time, uint,0644 ); -module_param (capacity_mode, uint,0444 ); +module_param (mode, uint,0444 );static int acpi_sbs_add (struct acpi_device *device);static int acpi_sbs_remove (struct acpi_device *device,int type);
@@ -114,59 +114,43 @@ static struct acpi_driver acpi_sbs_driver = { }, }; -struct acpi_ac { -int ac_present; -}; - -struct acpi_battery_info { -int capacity_mode; -s16 full_charge_capacity; -s16 design_capacity; -s16 design_voltage; -int vscale; -int ipscale; -s16 serial_number; -char manufacturer_name[ACPI_SBS_BLOCK_MAX +3 ]; -char device_name[ACPI_SBS_BLOCK_MAX +3 ]; -char device_chemistry[ACPI_SBS_BLOCK_MAX +3 ]; -}; - -struct acpi_battery_state { -s16 voltage; -s16 amperage; -s16 remaining_capacity; -s16 battery_state; -}; - -struct acpi_battery_alarm { -s16 remaining_capacity; -}; -struct acpi_battery { -int alive; -int id; -int init_state; -int battery_present;struct acpi_sbs *sbs; -struct acpi_battery_info info; -struct acpi_battery_state state; -struct acpi_battery_alarm alarm; -struct proc_dir_entry *battery_entry; +struct proc_dir_entry *proc_entry; +int vscale; +int ipscale; +char manufacturer_name[ACPI_SBS_BLOCK_MAX ]; +char device_name[ACPI_SBS_BLOCK_MAX ]; +char device_chemistry[ACPI_SBS_BLOCK_MAX ]; +u16 full_charge_capacity; +u16 design_capacity; +u16 design_voltage; +u16 serial_number; +u16 voltage_now; +s16 current_now; +u16 capacity_now; +u16 state; +u16 alarm_capacity; +u16 mode; +u8 id; +u8 alive:1 ; +u8 init_state:1 ; +u8 present:1 ; };struct acpi_sbs {struct acpi_device *device;struct acpi_smb_hc *hc;struct mutex mutex; -int sbsm_present; -int sbsm_batteries_supported;struct proc_dir_entry *ac_entry; -struct acpi_ac ac;struct acpi_battery battery[MAX_SBS_BAT ];int zombie;struct timer_list update_timer;int run_cnt;int update_proc_flg; +u8 batteries_supported; +u8 manager_present:1 ; +u8 charger_present:1 ; };static int acpi_sbs_update_run (struct acpi_sbs *sbs,int id,int data_type);
@@ -231,7 +215,7 @@ static int acpi_battery_get_present(struct acpi_battery *battery)if (!result) { is_present = (state &0x000f ) & (1 << battery->id); } - battery->battery_present = is_present; + battery->present = is_present;return result; }
@@ -243,14 +227,14 @@ static int acpi_battery_select(struct acpi_battery *battery)s16 state;int foo; -if (sbs->sbsm_present) { +if (sbs->manager_present) {/* Take special care not to knobble other nibbles of * state (aka selector_state), since * it causes charging to halt on SBSELs */ - result = -acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SBSM_SMBUS_ADDR ,0x01 , (u8 *)&state); + result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , +ACPI_SBSM_SMBUS_ADDR ,0x01 , (u8 *)&state);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -258,8 +242,8 @@ static int acpi_battery_select(struct acpi_battery *battery) } foo = (state &0x0fff ) | (1 << (battery->id +12 )); - result = -acpi_smbus_write (battery->sbs->hc,SMBUS_WRITE_WORD ,ACPI_SBSM_SMBUS_ADDR ,0x01 , (u8 *)&foo,2 ); + result =acpi_smbus_write (battery->sbs->hc,SMBUS_WRITE_WORD , +ACPI_SBSM_SMBUS_ADDR ,0x01 , (u8 *)&foo,2 );if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_write() failed" ));
@@ -283,8 +267,7 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs) "acpi_smbus_read() failed")); goto end; } - sbs->sbsm_present =1 ; - sbs->sbsm_batteries_supported = battery_system_info &0x000f ; + sbs->manager_present =1 ; end:
@@ -304,10 +287,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery) "acpi_smbus_read() failed")); goto end; } - battery->info.capacity_mode = (battery_mode &0x8000 ) >>15 ; + battery->mode = (battery_mode &0x8000 ) >>15 ; result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x10 , - (u8 *)&battery->info.full_charge_capacity); + (u8 *)&battery->full_charge_capacity);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -315,7 +298,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x18 , - (u8 *)&battery->info.design_capacity); + (u8 *)&battery->design_capacity);if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -324,7 +307,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x19 , - (u8 *)&battery->info.design_voltage); + (u8 *)&battery->design_voltage);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -341,34 +324,34 @@ static int acpi_battery_get_info(struct acpi_battery *battery)switch ((specification_info &0x0f00 ) >>8 ) {case 1 : - battery->info.vscale =10 ; + battery->vscale =10 ;break ;case 2 : - battery->info.vscale =100 ; + battery->vscale =100 ;break ;case 3 : - battery->info.vscale =1000 ; + battery->vscale =1000 ;break ;default : - battery->info.vscale =1 ; + battery->vscale =1 ; }switch ((specification_info &0xf000 ) >>12 ) {case 1 : - battery->info.ipscale =10 ; + battery->ipscale =10 ;break ;case 2 : - battery->info.ipscale =100 ; + battery->ipscale =100 ;break ;case 3 : - battery->info.ipscale =1000 ; + battery->ipscale =1000 ;break ;default : - battery->info.ipscale =1 ; + battery->ipscale =1 ; } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x1c , - (u8 *)&battery->info.serial_number); + (u8 *)&battery->serial_number);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -376,7 +359,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_BLOCK ,ACPI_SB_SMBUS_ADDR ,0x20 , - (u8 *)battery->info.manufacturer_name); + (u8 *)battery->manufacturer_name);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_sbs_read_str() failed" ));
@@ -384,7 +367,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_BLOCK ,ACPI_SB_SMBUS_ADDR ,0x21 , - (u8 *)battery->info.device_name); + (u8 *)battery->device_name);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_sbs_read_str() failed" ));
@@ -392,7 +375,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_BLOCK ,ACPI_SB_SMBUS_ADDR ,0x22 , - (u8 *)battery->info.device_chemistry); + (u8 *)battery->device_chemistry);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_sbs_read_str() failed" ));
@@ -408,7 +391,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery)int result =0 ; result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x09 , - (u8 *)&battery->state.voltage); + (u8 *)&battery->voltage_now);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -416,7 +399,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x0a , - (u8 *)&battery->state.amperage); + (u8 *)&battery->current_now);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -424,7 +407,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x0f , - (u8 *)&battery->state.remaining_capacity); + (u8 *)&battery->capacity_now);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -432,7 +415,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x16 , - (u8 *)&battery->state.battery_state); + (u8 *)&battery->state);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -448,7 +431,7 @@ static int acpi_battery_get_alarm(struct acpi_battery *battery)int result =0 ; result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x01 , - (u8 *)&battery->alarm.remaining_capacity); + (u8 *)&battery->alarm_capacity);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -497,8 +480,9 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery, } } - foo = alarm / (battery->info.capacity_mode ?10 :1 ); - result =acpi_smbus_write (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x01 , (u8 *)&foo,2 ); + foo = alarm / (battery->mode ?10 :1 ); + result =acpi_smbus_write (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x01 , + (u8 *)&foo,2 );if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_write() failed" ));
@@ -515,25 +499,25 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)int result =0 ;s16 battery_mode; -if (capacity_mode ==DEF_CAPACITY_UNIT ) { +if (mode ==DEF_CAPACITY_UNIT ) { goto end; } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode); +ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" )); goto end; } -if (capacity_mode ==MAH_CAPACITY_UNIT ) { +if (mode ==MAH_CAPACITY_UNIT ) { battery_mode &=0x7fff ; }else { battery_mode |=0x8000 ; } result =acpi_smbus_write (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode,2 ); +ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode,2 );if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_write() failed" ));
@@ -541,7 +525,7 @@ static int acpi_battery_set_mode(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode); +ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -601,7 +585,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)s16 charger_status; result =acpi_smbus_read (sbs->hc,SMBUS_READ_WORD ,ACPI_SBC_SMBUS_ADDR ,0x13 , - (u8 *)&charger_status); + (u8 *)&charger_status);if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -609,7 +593,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs) goto end; } - sbs->ac.ac_present = (charger_status &0x8000 ) >>15 ; + sbs->charger_present = (charger_status &0x8000 ) >>15 ; end:
@@ -726,30 +710,30 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset) } } -if (battery->battery_present) { +if (battery->present) {seq_printf (seq,"present: yes\n" ); }else {seq_printf (seq,"present: no\n" ); goto end; } -if (battery->info.capacity_mode) { - cscale = battery->info.vscale * battery->info.ipscale; +if (battery->mode) { + cscale = battery->vscale * battery->ipscale; }else { - cscale = battery->info.ipscale; + cscale = battery->ipscale; }seq_printf (seq,"design capacity: %i%s\n" , - battery->info.design_capacity * cscale, - battery->info.capacity_mode ?"0 mWh" :" mAh" ); + battery->design_capacity * cscale, + battery->mode ?"0 mWh" :" mAh" );seq_printf (seq,"last full capacity: %i%s\n" , - battery->info.full_charge_capacity * cscale, - battery->info.capacity_mode ?"0 mWh" :" mAh" ); + battery->full_charge_capacity * cscale, + battery->mode ?"0 mWh" :" mAh" );seq_printf (seq,"battery technology: rechargeable\n" );seq_printf (seq,"design voltage: %i mV\n" , - battery->info.design_voltage * battery->info.vscale); + battery->design_voltage * battery->vscale);seq_printf (seq,"design capacity warning: unknown\n" );seq_printf (seq,"design capacity low: unknown\n" );
@@ -757,16 +741,16 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)seq_printf (seq,"capacity granularity 2: unknown\n" );seq_printf (seq,"model number: %s\n" , - battery->info.device_name); + battery->device_name);seq_printf (seq,"serial number: %i\n" , - battery->info.serial_number); + battery->serial_number);seq_printf (seq,"battery type: %s\n" , - battery->info.device_chemistry); + battery->device_chemistry);seq_printf (seq,"OEM info: %s\n" , - battery->info.manufacturer_name); + battery->manufacturer_name); end:
@@ -804,49 +788,49 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset) } } -if (battery->battery_present) { +if (battery->present) {seq_printf (seq,"present: yes\n" ); }else {seq_printf (seq,"present: no\n" ); goto end; } -if (battery->info.capacity_mode) { - cscale = battery->info.vscale * battery->info.ipscale; +if (battery->mode) { + cscale = battery->vscale * battery->ipscale; }else { - cscale = battery->info.ipscale; + cscale = battery->ipscale; } -if (battery->state.battery_state &0x0010 ) { +if (battery->state &0x0010 ) {seq_printf (seq,"capacity state: critical\n" ); }else {seq_printf (seq,"capacity state: ok\n" ); } - foo = (s16 ) battery->state.amperage * battery->info.ipscale; -if (battery->info.capacity_mode) { - foo = foo * battery->info.design_voltage /1000 ; + foo = (s16 ) battery->current_now * battery->ipscale; +if (battery->mode) { + foo = foo * battery->design_voltage /1000 ; } -if (battery->state.amperage <0 ) { +if (battery->current_now <0 ) {seq_printf (seq,"charging state: discharging\n" );seq_printf (seq,"present rate: %d %s\n" , - -foo, battery->info.capacity_mode ?"mW" :"mA" ); - }else if (battery->state.amperage >0 ) { + -foo, battery->mode ?"mW" :"mA" ); + }else if (battery->current_now >0 ) {seq_printf (seq,"charging state: charging\n" );seq_printf (seq,"present rate: %d %s\n" , - foo, battery->info.capacity_mode ?"mW" :"mA" ); + foo, battery->mode ?"mW" :"mA" ); }else {seq_printf (seq,"charging state: charged\n" );seq_printf (seq,"present rate: 0 %s\n" , - battery->info.capacity_mode ?"mW" :"mA" ); + battery->mode ?"mW" :"mA" ); }seq_printf (seq,"remaining capacity: %i%s\n" , - battery->state.remaining_capacity * cscale, - battery->info.capacity_mode ?"0 mWh" :" mAh" ); + battery->capacity_now * cscale, + battery->mode ?"0 mWh" :" mAh" );seq_printf (seq,"present voltage: %i mV\n" , - battery->state.voltage * battery->info.vscale); + battery->voltage_now * battery->vscale); end:
@@ -883,22 +867,22 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) } } -if (!battery->battery_present) { +if (!battery->present) {seq_printf (seq,"present: no\n" ); goto end; } -if (battery->info.capacity_mode) { - cscale = battery->info.vscale * battery->info.ipscale; +if (battery->mode) { + cscale = battery->vscale * battery->ipscale; }else { - cscale = battery->info.ipscale; + cscale = battery->ipscale; }seq_printf (seq,"alarm: " ); -if (battery->alarm.remaining_capacity) { +if (battery->alarm_capacity) {seq_printf (seq,"%i%s\n" , - battery->alarm.remaining_capacity * cscale, - battery->info.capacity_mode ?"0 mWh" :" mAh" ); + battery->alarm_capacity * cscale, + battery->mode ?"0 mWh" :" mAh" ); }else {seq_printf (seq,"disabled\n" ); }
@@ -928,7 +912,7 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,if (result) goto end; -if (!battery->battery_present) { +if (!battery->present) { result = -ENODEV ; goto end; }
@@ -945,7 +929,7 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer, alarm_string[count] =0 ; - old_alarm = battery->alarm.remaining_capacity; + old_alarm = battery->alarm_capacity; new_alarm =simple_strtoul (alarm_string,NULL ,0 ); result =acpi_battery_set_alarm (battery, new_alarm);
@@ -1025,7 +1009,7 @@ static int acpi_ac_read_state(struct seq_file *seq, void *offset) }seq_printf (seq,"state: %s\n" , - sbs->ac.ac_present ?"on-line" :"off-line" ); + sbs->charger_present ?"on-line" :"off-line" );sbs_mutex_unlock (sbs);
@@ -1080,7 +1064,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) goto end; } - is_present = battery->battery_present; + is_present = battery->present;if (is_present) { result =acpi_battery_init (battery);
@@ -1094,7 +1078,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)sprintf (dir_name,ACPI_BATTERY_DIR_NAME , id); - result = acpi_sbs_generic_add_fs(&battery->battery_entry, + result = acpi_sbs_generic_add_fs(&battery->proc_entry, acpi_battery_dir, dir_name, &acpi_battery_info_fops,
@@ -1109,7 +1093,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",ACPI_SBS_DEVICE_NAME ,acpi_device_bid (sbs->device), dir_name, - sbs->battery->battery_present ? "present" : "absent"); + sbs->battery->present ? "present" : "absent"); end:return result;
@@ -1118,8 +1102,8 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)static void acpi_battery_remove (struct acpi_sbs *sbs,int id) { -if (sbs->battery[id].battery_entry) { -acpi_sbs_generic_remove_fs (&(sbs->battery[id].battery_entry), +if (sbs->battery[id].proc_entry) { +acpi_sbs_generic_remove_fs (&(sbs->battery[id].proc_entry), acpi_battery_dir); } }
@@ -1147,7 +1131,7 @@ static int acpi_ac_add(struct acpi_sbs *sbs) printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",ACPI_SBS_DEVICE_NAME ,acpi_device_bid (sbs->device), - ACPI_AC_DIR_NAME, sbs->ac.ac_present ? "on-line" : "off-line"); + ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line"); end:
@@ -1172,9 +1156,9 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)struct acpi_battery *battery;int result =0 , cnt;int old_ac_present =-1 ; -int old_battery_present =-1 ; +int old_present =-1 ;int new_ac_present =-1 ; -int new_battery_present =-1 ; +int new_present =-1 ;int id_min =0 , id_max =MAX_SBS_BAT -1 ;char dir_name[32 ];int do_battery_init =0 , do_ac_init =0 ;
@@ -1199,7 +1183,11 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type) sbs->run_cnt++; - old_ac_present = sbs->ac.ac_present; +if (!update_battery) { + goto end; + } + + old_ac_present = sbs->charger_present; result =acpi_ac_get_present (sbs);if (result) {
@@ -1207,7 +1195,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type) "acpi_ac_get_present() failed")); } - new_ac_present = sbs->ac.ac_present; + new_ac_present = sbs->charger_present; do_ac_init = (old_ac_present != new_ac_present);if (sbs->run_cnt ==1 && data_type ==DATA_TYPE_COMMON ) {
@@ -1241,9 +1229,9 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)continue ; } - old_remaining_capacity = battery->state.remaining_capacity; + old_remaining_capacity = battery->capacity_now; - old_battery_present = battery->battery_present; + old_present = battery->present; result =acpi_battery_select (battery);if (result) {
@@ -1257,11 +1245,11 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type) "acpi_battery_get_present() failed")); } - new_battery_present = battery->battery_present; + new_present = battery->present; - do_battery_init = ((old_battery_present != new_battery_present) - && new_battery_present); -if (!new_battery_present) + do_battery_init = ((old_present != new_present) + && new_present); +if (!new_present) goto event;if (do_ac_init || do_battery_init) { result =acpi_battery_init (battery);
@@ -1277,7 +1265,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)if ((data_type ==DATA_TYPE_COMMON || data_type ==DATA_TYPE_INFO ) - && new_battery_present) { + && new_present) { result =acpi_battery_get_info (battery);if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1293,7 +1281,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)if ((data_type ==DATA_TYPE_COMMON || data_type ==DATA_TYPE_STATE ) - && new_battery_present) { + && new_present) { result =acpi_battery_get_state (battery);if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1309,7 +1297,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)if ((data_type ==DATA_TYPE_COMMON || data_type ==DATA_TYPE_ALARM ) - && new_battery_present) { + && new_present) { result =acpi_battery_get_alarm (battery);if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1326,14 +1314,14 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type) event: -if (old_battery_present != new_battery_present || do_ac_init || +if (old_present != new_present || do_ac_init || old_remaining_capacity != - battery->state.remaining_capacity) { + battery->capacity_now) {sprintf (dir_name,ACPI_BATTERY_DIR_NAME , id); result =acpi_bus_generate_event4 (ACPI_BATTERY_CLASS , dir_name,ACPI_SBS_BATTERY_NOTIFY_STATUS , - new_battery_present); + new_present);if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_bus_generate_event4() "
@@ -1420,7 +1408,7 @@ static int acpi_sbs_add(struct acpi_device *device)acpi_sbsm_get_info (sbs); -if (!sbs->sbsm_present) { +if (!sbs->manager_present) { result =acpi_battery_add (sbs,0 );if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1429,7 +1417,7 @@ static int acpi_sbs_add(struct acpi_device *device) } }else {for (id =0 ; id <MAX_SBS_BAT ; id++) { -if ((sbs->sbsm_batteries_supported & (1 << id))) { +if ((sbs->batteries_supported & (1 << id))) { result =acpi_battery_add (sbs, id);if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1529,11 +1517,11 @@ static int __init acpi_sbs_init(void)if (acpi_disabled)return -ENODEV ; -if (capacity_mode !=DEF_CAPACITY_UNIT - && capacity_mode !=MAH_CAPACITY_UNIT - && capacity_mode !=MWH_CAPACITY_UNIT ) { +if (mode !=DEF_CAPACITY_UNIT + && mode !=MAH_CAPACITY_UNIT + && mode !=MWH_CAPACITY_UNIT ) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"invalid capacity_mode = %d" , capacity_mode)); +"invalid mode = %d" , mode));return -EINVAL ; }
PATCH 10/12 ACPI: SBS: Make SBS reads table-driven.
In reply to Alexey StarikovskiyFrom: Alexey Starikovskiy <[email protected]>
Re-factor SBS functions to use tables and cycles for repeated operations.
---
drivers/acpi/sbs.c | 1286 +++++++++++----------------------------------------- 1 files changed, 275 insertions(+), 1011 deletions(-)
drivers/acpi/sbs.c +275 -1011
@@ -1,6 +1,8 @@/* -* acpi_sbs.c - ACPI Smart Battery System Driver ($Revision: 1.16 $) +* sbs.c - ACPI Smart Battery System Driver ($Revision: 2.0 $) * +* Copyright (c) 2007 Alexey Starikovskiy <[email protected]> +* Copyright (c) 2005-2007 Vladimir Lebedev <[email protected]> * Copyright (c) 2005 Rich Townsend <[email protected]> * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -46,53 +48,34 @@#define ACPI_SBS_FILE_ALARM "alarm"#define ACPI_BATTERY_DIR_NAME "BAT%i"#define ACPI_AC_DIR_NAME "AC0" -#define ACPI_SBC_SMBUS_ADDR 0x9 -#define ACPI_SBSM_SMBUS_ADDR 0xa -#define ACPI_SB_SMBUS_ADDR 0xb -#define ACPI_SBS_AC_NOTIFY_STATUS 0x80 -#define ACPI_SBS_BATTERY_NOTIFY_STATUS 0x80 -#define ACPI_SBS_BATTERY_NOTIFY_INFO 0x81 -#define _COMPONENT ACPI_SBS_COMPONENT +enum acpi_sbs_device_addr { +ACPI_SBS_CHARGER =0x9 , +ACPI_SBS_MANAGER =0xa , +ACPI_SBS_BATTERY =0xb , +}; + +#define ACPI_SBS_NOTIFY_STATUS 0x80 +#define ACPI_SBS_NOTIFY_INFO 0x81ACPI_MODULE_NAME ("sbs" ); -MODULE_AUTHOR ("Rich Townsend" ); +MODULE_AUTHOR ("Alexey Starikovskiy <[email protected]>" );MODULE_DESCRIPTION ("Smart Battery System ACPI interface driver" );MODULE_LICENSE ("GPL" ); -#define DEF_CAPACITY_UNIT 3 -#define MAH_CAPACITY_UNIT 1 -#define MWH_CAPACITY_UNIT 2 -#define CAPACITY_UNIT DEF_CAPACITY_UNIT - -#define REQUEST_UPDATE_MODE 1 -#define QUEUE_UPDATE_MODE 2 - -#define DATA_TYPE_COMMON 0 -#define DATA_TYPE_INFO 1 -#define DATA_TYPE_STATE 2 -#define DATA_TYPE_ALARM 3 -#define DATA_TYPE_AC_STATE 4 +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_ac_dir (void );extern struct proc_dir_entry *acpi_lock_battery_dir (void );extern void acpi_unlock_ac_dir (struct proc_dir_entry *acpi_ac_dir);extern void acpi_unlock_battery_dir (struct proc_dir_entry *acpi_battery_dir); -#define MAX_SBS_BAT 4 +#define MAX_SBS_BAT 4#define ACPI_SBS_BLOCK_MAX 32 -#define UPDATE_DELAY 10 - -/* 0 - every time, > 0 - by update_time */ -static unsigned int update_time =120 ; - -static unsigned int mode =CAPACITY_UNIT ; - -module_param (update_time, uint,0644 ); -module_param (mode, uint,0444 ); -static int acpi_sbs_add (struct acpi_device *device);static int acpi_sbs_remove (struct acpi_device *device,int type);static int acpi_sbs_resume (struct acpi_device *device);
@@ -117,486 +100,187 @@ static struct acpi_driver acpi_sbs_driver = {struct acpi_battery {struct acpi_sbs *sbs;struct proc_dir_entry *proc_entry; -int vscale; -int ipscale; +unsigned long update_time; +char name[8 ];char manufacturer_name[ACPI_SBS_BLOCK_MAX ];char device_name[ACPI_SBS_BLOCK_MAX ];char device_chemistry[ACPI_SBS_BLOCK_MAX ]; +u32 alarm_capacity;u16 full_charge_capacity;u16 design_capacity;u16 design_voltage;u16 serial_number; +u16 cycle_count; +u16 temp_now;u16 voltage_now;s16 current_now; +s16 current_avg;u16 capacity_now; +u16 state_of_charge;u16 state; -u16 alarm_capacity;u16 mode; +u16 spec;u8 id; -u8 alive:1 ; -u8 init_state:1 ;u8 present:1 ; };struct acpi_sbs {struct acpi_device *device;struct acpi_smb_hc *hc; -struct mutex mutex; -struct proc_dir_entry *ac_entry; +struct mutex lock; +struct proc_dir_entry *charger_entry;struct acpi_battery battery[MAX_SBS_BAT ]; -int zombie; -struct timer_list update_timer; -int run_cnt; -int update_proc_flg; -u8 batteries_supported; +u8 batteries_supported:4 ;u8 manager_present:1 ;u8 charger_present:1 ; }; -static int acpi_sbs_update_run (struct acpi_sbs *sbs,int id,int data_type); -static void acpi_sbs_update_time (void *data); - -static int sbs_zombie (struct acpi_sbs *sbs) +static inline int battery_scale (int log) { -return (sbs->zombie); +int scale =1 ; +while (log--) + scale *=10 ; +return scale; } -static int sbs_mutex_lock (struct acpi_sbs *sbs) +static inline int acpi_battery_vscale (struct acpi_battery *battery) { -if (sbs_zombie (sbs)) { -return -ENODEV ; - } -mutex_lock (&sbs->mutex); -return 0 ; +return battery_scale ((battery->spec &0x0f00 ) >>8 ); } -static void sbs_mutex_unlock (struct acpi_sbs *sbs) +static inline int acpi_battery_ipscale (struct acpi_battery *battery) { -mutex_unlock (&sbs->mutex); +return battery_scale ((battery->spec &0xf000 ) >>12 ); } -/* -------------------------------------------------------------------------- -Smart Battery System Management --------------------------------------------------------------------------- */ - -static int acpi_check_update_proc (struct acpi_sbs *sbs) +static inline int acpi_battery_mode (struct acpi_battery *battery) { -acpi_status status =AE_OK ; - -if (update_time ==0 ) { - sbs->update_proc_flg =0 ; -return 0 ; - } -if (sbs->update_proc_flg ==0 ) { - status =acpi_os_execute (OSL_GPE_HANDLER , - acpi_sbs_update_time, sbs); -if (status !=AE_OK ) { -ACPI_EXCEPTION ((AE_INFO , status, -"acpi_os_execute() failed" )); -return 1 ; - } - sbs->update_proc_flg =1 ; - } -return 0 ; +return (battery->mode &0x8000 ); } -static int acpi_battery_get_present (struct acpi_battery *battery) +static inline int acpi_battery_scale (struct acpi_battery *battery) { -s16 state; -int result =0 ; -int is_present =0 ; - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SBSM_SMBUS_ADDR ,0x01 , (u8 *)&state); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - } -if (!result) { - is_present = (state &0x000f ) & (1 << battery->id); - } - battery->present = is_present; - -return result; +return (acpi_battery_mode (battery) ?10 :1 ) * +acpi_battery_ipscale (battery); } -static int acpi_battery_select (struct acpi_battery *battery) -{ -struct acpi_sbs *sbs = battery->sbs; -int result =0 ; -s16 state; -int foo; - -if (sbs->manager_present) { - -/* Take special care not to knobble other nibbles of -* state (aka selector_state), since -* it causes charging to halt on SBSELs */ +/* -------------------------------------------------------------------------- +Smart Battery System Management +-------------------------------------------------------------------------- */ - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SBSM_SMBUS_ADDR ,0x01 , (u8 *)&state); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } +struct acpi_battery_reader { +u8 command;/* command for battery */ +u8 mode;/* word or block? */ +size_t offset;/* offset inside struct acpi_sbs_battery */ +}; - foo = (state &0x0fff ) | (1 << (battery->id +12 )); - result =acpi_smbus_write (battery->sbs->hc,SMBUS_WRITE_WORD , -ACPI_SBSM_SMBUS_ADDR ,0x01 , (u8 *)&foo,2 ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_write() failed" )); - goto end; - } - } +static struct acpi_battery_reader info_readers[] = { + {0x01 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , alarm_capacity)}, + {0x03 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , mode)}, + {0x10 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , full_charge_capacity)}, + {0x17 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , cycle_count)}, + {0x18 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , design_capacity)}, + {0x19 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , design_voltage)}, + {0x1a ,SMBUS_READ_WORD , offsetof(struct acpi_battery , spec)}, + {0x1c ,SMBUS_READ_WORD , offsetof(struct acpi_battery , serial_number)}, + {0x20 ,SMBUS_READ_BLOCK , offsetof(struct acpi_battery , manufacturer_name)}, + {0x21 ,SMBUS_READ_BLOCK , offsetof(struct acpi_battery , device_name)}, + {0x22 ,SMBUS_READ_BLOCK , offsetof(struct acpi_battery , device_chemistry)}, +}; - end: -return result; -} +static struct acpi_battery_reader state_readers[] = { + {0x08 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , temp_now)}, + {0x09 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , voltage_now)}, + {0x0a ,SMBUS_READ_WORD , offsetof(struct acpi_battery , current_now)}, + {0x0b ,SMBUS_READ_WORD , offsetof(struct acpi_battery , current_avg)}, + {0x0f ,SMBUS_READ_WORD , offsetof(struct acpi_battery , capacity_now)}, + {0x0e ,SMBUS_READ_WORD , offsetof(struct acpi_battery , state_of_charge)}, + {0x16 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , state)}, +}; -static int acpi_sbsm_get_info (struct acpi_sbs *sbs) +static int acpi_manager_get_info (struct acpi_sbs *sbs) {int result =0 ; -s16 battery_system_info; - - result =acpi_smbus_read (sbs->hc,SMBUS_READ_WORD ,ACPI_SBSM_SMBUS_ADDR ,0x04 , - (u8 *)&battery_system_info); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - sbs->manager_present =1 ; - - end: +u16 battery_system_info; + result =acpi_smbus_read (sbs->hc,SMBUS_READ_WORD ,ACPI_SBS_MANAGER , +0x04 , (u8 *) & battery_system_info); +if (!result) + sbs->batteries_supported = battery_system_info &0x000f ;return result; }static int acpi_battery_get_info (struct acpi_battery *battery) { -int result =0 ; -s16 battery_mode; -s16 specification_info; - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x03 , - (u8 *)&battery_mode); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - battery->mode = (battery_mode &0x8000 ) >>15 ; - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x10 , - (u8 *)&battery->full_charge_capacity); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x18 , - (u8 *)&battery->design_capacity); +int i, result =0 ; -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x19 , - (u8 *)&battery->design_voltage); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; +for (i =0 ; i <ARRAY_SIZE (info_readers); ++i) { + result =acpi_smbus_read (battery->sbs->hc, info_readers[i].mode, +ACPI_SBS_BATTERY , info_readers[i].command, + (u8 *) battery + info_readers[i].offset); +if (result) +break ; } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x1a , - (u8 *)&specification_info); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - -switch ((specification_info &0x0f00 ) >>8 ) { -case 1 : - battery->vscale =10 ; -break ; -case 2 : - battery->vscale =100 ; -break ; -case 3 : - battery->vscale =1000 ; -break ; -default : - battery->vscale =1 ; - } - -switch ((specification_info &0xf000 ) >>12 ) { -case 1 : - battery->ipscale =10 ; -break ; -case 2 : - battery->ipscale =100 ; -break ; -case 3 : - battery->ipscale =1000 ; -break ; -default : - battery->ipscale =1 ; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x1c , - (u8 *)&battery->serial_number); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_BLOCK ,ACPI_SB_SMBUS_ADDR ,0x20 , - (u8 *)battery->manufacturer_name); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_read_str() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_BLOCK ,ACPI_SB_SMBUS_ADDR ,0x21 , - (u8 *)battery->device_name); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_read_str() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_BLOCK ,ACPI_SB_SMBUS_ADDR ,0x22 , - (u8 *)battery->device_chemistry); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_read_str() failed" )); - goto end; - } - - end:return result; }static int acpi_battery_get_state (struct acpi_battery *battery) { -int result =0 ; - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x09 , - (u8 *)&battery->voltage_now); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x0a , - (u8 *)&battery->current_now); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x0f , - (u8 *)&battery->capacity_now); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x16 , - (u8 *)&battery->state); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - end: -return result; -} - -static int acpi_battery_get_alarm (struct acpi_battery *battery) -{ -int result =0 ; - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x01 , - (u8 *)&battery->alarm_capacity); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - end: - -return result; -} - -static int acpi_battery_set_alarm (struct acpi_battery *battery, -unsigned long alarm) -{ -int result =0 ; -s16 battery_mode; -int foo; +int i, result =0 ; - result =acpi_battery_select (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_select() failed" )); - goto end; - } - -/* If necessary, enable the alarm */ - -if (alarm >0 ) { - result = -acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x03 , - (u8 *)&battery_mode); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - battery_mode &=0xbfff ; - result = -acpi_smbus_write (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x01 , - (u8 *)&battery_mode,2 ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_write() failed" )); +if (time_before (jiffies, battery->update_time + +msecs_to_jiffies (cache_time))) +return 0 ; +for (i =0 ; i <ARRAY_SIZE (state_readers); ++i) { + result =acpi_smbus_read (battery->sbs->hc, + state_readers[i].mode, +ACPI_SBS_BATTERY , + state_readers[i].command, + (u8 *)battery + + state_readers[i].offset); +if (result) goto end; - } } - - foo = alarm / (battery->mode ?10 :1 ); - result =acpi_smbus_write (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x01 , - (u8 *)&foo,2 ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_write() failed" )); - goto end; - } - end: - + battery->update_time = jiffies;return result; } -static int acpi_battery_set_mode (struct acpi_battery *battery) +static int acpi_battery_get_alarm (struct acpi_battery *battery) { -int result =0 ; -s16 battery_mode; - -if (mode ==DEF_CAPACITY_UNIT ) { - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - -if (mode ==MAH_CAPACITY_UNIT ) { - battery_mode &=0x7fff ; - }else { - battery_mode |=0x8000 ; - } - result =acpi_smbus_write (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode,2 ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_write() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - end: -return result; +return acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , +ACPI_SBS_BATTERY ,0x01 , + (u8 *) & battery->alarm_capacity); } -static int acpi_battery_init (struct acpi_battery *battery) +static int acpi_battery_set_alarm (struct acpi_battery *battery) { -int result =0 ; - - result =acpi_battery_select (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_select() failed" )); - goto end; - } - - result =acpi_battery_set_mode (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_set_mode() failed" )); - goto end; - } - - result =acpi_battery_get_info (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_info() failed" )); - goto end; - } - - result =acpi_battery_get_state (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_state() failed" )); - goto end; - } +struct acpi_sbs *sbs = battery->sbs; +u16 value; +return 0 ; - result =acpi_battery_get_alarm (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_alarm() failed" )); - goto end; +if (sbs->manager_present) { +acpi_smbus_read (sbs->hc,SMBUS_READ_WORD ,ACPI_SBS_MANAGER , +0x01 , (u8 *)&value); + value &=0x0fff ; + value |=1 << (battery->id +12 ); +acpi_smbus_write (sbs->hc,SMBUS_WRITE_WORD ,ACPI_SBS_MANAGER , +0x01 , (u8 *)&value,2 ); } - - end: -return result; + value = battery->alarm_capacity / (acpi_battery_mode (battery) ?10 :1 ); +return acpi_smbus_write (sbs->hc,SMBUS_WRITE_WORD ,ACPI_SBS_BATTERY , +0x01 , (u8 *)&value,2 ); }static int acpi_ac_get_present (struct acpi_sbs *sbs) { -int result =0 ; -s16 charger_status; - - result =acpi_smbus_read (sbs->hc,SMBUS_READ_WORD ,ACPI_SBC_SMBUS_ADDR ,0x13 , - (u8 *)&charger_status); - -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - sbs->charger_present = (charger_status &0x8000 ) >>15 ; - - end: +int result; +u16 status; + result =acpi_smbus_read (sbs->hc,SMBUS_READ_WORD ,ACPI_SBS_CHARGER , +0x13 , (u8 *) & status); +if (!result) + sbs->charger_present = (status >>15 ) &0x1 ;return result; }
@@ -607,7 +291,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)/* Generic Routines */ static int -acpi_sbs_generic_add_fs(struct proc_dir_entry **dir, +acpi_sbs_add_fs(struct proc_dir_entry **dir, struct proc_dir_entry *parent_dir, char *dir_name, struct file_operations *info_fops,
@@ -669,7 +353,7 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir, }static void -acpi_sbs_generic_remove_fs (struct proc_dir_entry **dir, +acpi_sbs_remove_fs (struct proc_dir_entry **dir,struct proc_dir_entry *parent_dir) {
@@ -687,75 +371,47 @@ acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir,static struct proc_dir_entry *acpi_battery_dir =NULL ; +static inline char *acpi_battery_units (struct acpi_battery *battery) +{ +return acpi_battery_mode (battery) ?" mWh" :" mAh" ; +} + +static int acpi_battery_read_info (struct seq_file *seq,void *offset) {struct acpi_battery *battery = seq->private;struct acpi_sbs *sbs = battery->sbs; -int cscale;int result =0 ; -if (sbs_mutex_lock (sbs)) { -return -ENODEV ; - } +mutex_lock (&sbs->lock); - result =acpi_check_update_proc (sbs); -if (result) +seq_printf (seq,"present: %s\n" , + (battery->present) ?"yes" :"no" ); +if (!battery->present) goto end; -if (update_time ==0 ) { - result =acpi_sbs_update_run (sbs, battery->id,DATA_TYPE_INFO ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_update_run() failed" )); - } - } - -if (battery->present) { -seq_printf (seq,"present: yes\n" ); - }else { -seq_printf (seq,"present: no\n" ); - goto end; - } - -if (battery->mode) { - cscale = battery->vscale * battery->ipscale; - }else { - cscale = battery->ipscale; - }seq_printf (seq,"design capacity: %i%s\n" , - battery->design_capacity * cscale, - battery->mode ?"0 mWh" :" mAh" ); - + battery->design_capacity *acpi_battery_scale (battery), +acpi_battery_units (battery));seq_printf (seq,"last full capacity: %i%s\n" , - battery->full_charge_capacity * cscale, - battery->mode ?"0 mWh" :" mAh" ); - + battery->full_charge_capacity *acpi_battery_scale (battery), +acpi_battery_units (battery));seq_printf (seq,"battery technology: rechargeable\n" ); -seq_printf (seq,"design voltage: %i mV\n" , - battery->design_voltage * battery->vscale); - + battery->design_voltage *acpi_battery_vscale (battery));seq_printf (seq,"design capacity warning: unknown\n" );seq_printf (seq,"design capacity low: unknown\n" );seq_printf (seq,"capacity granularity 1: unknown\n" );seq_printf (seq,"capacity granularity 2: unknown\n" ); - -seq_printf (seq,"model number: %s\n" , - battery->device_name); - +seq_printf (seq,"model number: %s\n" , battery->device_name);seq_printf (seq,"serial number: %i\n" , battery->serial_number); -seq_printf (seq,"battery type: %s\n" , battery->device_chemistry); -seq_printf (seq,"OEM info: %s\n" , battery->manufacturer_name); - end: - -sbs_mutex_unlock (sbs); - +mutex_unlock (&sbs->lock);return result; }
@@ -769,73 +425,29 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)struct acpi_battery *battery = seq->private;struct acpi_sbs *sbs = battery->sbs;int result =0 ; -int cscale; -int foo; - -if (sbs_mutex_lock (sbs)) { -return -ENODEV ; - } - - result =acpi_check_update_proc (sbs); -if (result) - goto end; - -if (update_time ==0 ) { - result =acpi_sbs_update_run (sbs, battery->id,DATA_TYPE_STATE ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_update_run() failed" )); - } - } -if (battery->present) { -seq_printf (seq,"present: yes\n" ); - }else { -seq_printf (seq,"present: no\n" ); +mutex_lock (&sbs->lock); +seq_printf (seq,"present: %s\n" , + (battery->present) ?"yes" :"no" ); +if (!battery->present) goto end; - } - -if (battery->mode) { - cscale = battery->vscale * battery->ipscale; - }else { - cscale = battery->ipscale; - } - -if (battery->state &0x0010 ) { -seq_printf (seq,"capacity state: critical\n" ); - }else { -seq_printf (seq,"capacity state: ok\n" ); - } - - foo = (s16 ) battery->current_now * battery->ipscale; -if (battery->mode) { - foo = foo * battery->design_voltage /1000 ; - } -if (battery->current_now <0 ) { -seq_printf (seq,"charging state: discharging\n" ); -seq_printf (seq,"present rate: %d %s\n" , - -foo, battery->mode ?"mW" :"mA" ); - }else if (battery->current_now >0 ) { -seq_printf (seq,"charging state: charging\n" ); -seq_printf (seq,"present rate: %d %s\n" , - foo, battery->mode ?"mW" :"mA" ); - }else { -seq_printf (seq,"charging state: charged\n" ); -seq_printf (seq,"present rate: 0 %s\n" , - battery->mode ?"mW" :"mA" ); - } +acpi_battery_get_state (battery); +seq_printf (seq,"capacity state: %s\n" , + (battery->state &0x0010 ) ?"critical" :"ok" ); +seq_printf (seq,"charging state: %s\n" , + (battery->current_now <0 ) ?"discharging" : + ((battery->current_now >0 ) ?"charging" :"charged" )); +seq_printf (seq,"present rate: %d mA\n" , +abs (battery->current_now) *acpi_battery_ipscale (battery));seq_printf (seq,"remaining capacity: %i%s\n" , - battery->capacity_now * cscale, - battery->mode ?"0 mWh" :" mAh" ); - + battery->capacity_now *acpi_battery_scale (battery), +acpi_battery_units (battery));seq_printf (seq,"present voltage: %i mV\n" , - battery->voltage_now * battery->vscale); + battery->voltage_now *acpi_battery_vscale (battery)); end: - -sbs_mutex_unlock (sbs); - +mutex_unlock (&sbs->lock);return result; }
@@ -849,48 +461,25 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)struct acpi_battery *battery = seq->private;struct acpi_sbs *sbs = battery->sbs;int result =0 ; -int cscale; - -if (sbs_mutex_lock (sbs)) { -return -ENODEV ; - } - result =acpi_check_update_proc (sbs); -if (result) - goto end; - -if (update_time ==0 ) { - result =acpi_sbs_update_run (sbs, battery->id,DATA_TYPE_ALARM ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_update_run() failed" )); - } - } +mutex_lock (&sbs->lock);if (!battery->present) {seq_printf (seq,"present: no\n" ); goto end; } -if (battery->mode) { - cscale = battery->vscale * battery->ipscale; - }else { - cscale = battery->ipscale; - } - +acpi_battery_get_alarm (battery);seq_printf (seq,"alarm: " ); -if (battery->alarm_capacity) { +if (battery->alarm_capacity)seq_printf (seq,"%i%s\n" , - battery->alarm_capacity * cscale, - battery->mode ?"0 mWh" :" mAh" ); - }else { + battery->alarm_capacity * +acpi_battery_scale (battery), +acpi_battery_units (battery)); +else seq_printf (seq,"disabled\n" ); - } - end: - -sbs_mutex_unlock (sbs); - +mutex_unlock (&sbs->lock);return result; }
@@ -902,59 +491,28 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,struct acpi_battery *battery = seq->private;struct acpi_sbs *sbs = battery->sbs;char alarm_string[12 ] = {'\0' }; -int result, old_alarm, new_alarm; - -if (sbs_mutex_lock (sbs)) { -return -ENODEV ; - } - - result =acpi_check_update_proc (sbs); -if (result) - goto end; - +int result =0 ; +mutex_lock (&sbs->lock);if (!battery->present) { result = -ENODEV ; goto end; } -if (count >sizeof (alarm_string) -1 ) { result = -EINVAL ; goto end; } -if (copy_from_user (alarm_string, buffer, count)) { result = -EFAULT ; goto end; } - alarm_string[count] =0 ; - - old_alarm = battery->alarm_capacity; - new_alarm =simple_strtoul (alarm_string,NULL ,0 ); - - result =acpi_battery_set_alarm (battery, new_alarm); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_set_alarm() failed" )); -acpi_battery_set_alarm (battery, old_alarm); - goto end; - } - result =acpi_battery_get_alarm (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_alarm() failed" )); -acpi_battery_set_alarm (battery, old_alarm); - goto end; - } - + battery->alarm_capacity =simple_strtoul (alarm_string,NULL ,0 ); +acpi_battery_set_alarm (battery); end: -sbs_mutex_unlock (sbs); - -if (result) { +mutex_unlock (&sbs->lock); +if (result)return result; - }else { -return count; - } +return count; }static int acpi_battery_alarm_open_fs (struct inode *inode,struct file *file)
@@ -993,26 +551,15 @@ static struct proc_dir_entry *acpi_ac_dir = NULL;static int acpi_ac_read_state (struct seq_file *seq,void *offset) { -struct acpi_sbs *sbs = seq->private; -int result; -if (sbs_mutex_lock (sbs)) { -return -ENODEV ; - } +struct acpi_sbs *sbs = seq->private; -if (update_time ==0 ) { - result =acpi_sbs_update_run (sbs,-1 ,DATA_TYPE_AC_STATE ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_update_run() failed" )); - } - } +mutex_lock (&sbs->lock);seq_printf (seq,"state: %s\n" , sbs->charger_present ?"on-line" :"off-line" ); -sbs_mutex_unlock (sbs); - +mutex_unlock (&sbs->lock);return 0 ; }
@@ -1035,67 +582,54 @@ static struct file_operations acpi_ac_state_fops = {/* Smart Battery */ -static int acpi_battery_add (struct acpi_sbs *sbs,int id) +static int acpi_battery_read (struct acpi_battery *battery) { -int is_present; -int result; -char dir_name[32 ]; -struct acpi_battery *battery; +int result =0 , saved_present = battery->present; +u16 state; - battery = &sbs->battery[id]; +if (battery->sbs->manager_present) { + result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , +ACPI_SBS_MANAGER ,0x01 , (u8 *)&state); +if (!result) + battery->present = state & (1 << battery->id); + state &=0x0fff ; + state |=1 << (battery->id +12 ); +acpi_smbus_write (battery->sbs->hc,SMBUS_WRITE_WORD , +ACPI_SBS_MANAGER ,0x01 , (u8 *)&state,2 ); + }else if (battery->id ==0 ) + battery->present =1 ; +if (result || !battery->present) +return result; - battery->alive =0 ; +if (saved_present != battery->present) { + battery->update_time =0 ; + result =acpi_battery_get_info (battery); +if (result) +return result; + } + result =acpi_battery_get_state (battery); +return result; +} - battery->init_state =0 ; +static int acpi_battery_add (struct acpi_sbs *sbs,int id) +{ +int result; +struct acpi_battery *battery = &sbs->battery[id]; battery->id = id; battery->sbs = sbs; + battery->update_time =0 ; + result =acpi_battery_read (battery); +if (result) +return result; - result =acpi_battery_select (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_select() failed" )); - goto end; - } - - result =acpi_battery_get_present (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_present() failed" )); - goto end; - } - - is_present = battery->present; - -if (is_present) { - result =acpi_battery_init (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_init() failed" )); - goto end; - } - battery->init_state =1 ; - } - -sprintf (dir_name,ACPI_BATTERY_DIR_NAME , id); - - result =acpi_sbs_generic_add_fs (&battery->proc_entry, - acpi_battery_dir, - dir_name, - &acpi_battery_info_fops, - &acpi_battery_state_fops, - &acpi_battery_alarm_fops, battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_generic_add_fs() failed" )); - goto end; - } - battery->alive =1 ; - +sprintf (battery->name,ACPI_BATTERY_DIR_NAME , id); +acpi_sbs_add_fs (&battery->proc_entry, acpi_battery_dir, + battery->name, &acpi_battery_info_fops, + &acpi_battery_state_fops, &acpi_battery_alarm_fops, + battery); printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", -ACPI_SBS_DEVICE_NAME ,acpi_device_bid (sbs->device), dir_name, - sbs->battery->present ? "present" : "absent"); - - end: +ACPI_SBS_DEVICE_NAME ,acpi_device_bid (sbs->device), + battery->name, sbs->battery->present ? "present" : "absent");return result; }
@@ -1103,348 +637,105 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id) {if (sbs->battery[id].proc_entry) { -acpi_sbs_generic_remove_fs (&(sbs->battery[id].proc_entry), - acpi_battery_dir); +acpi_sbs_remove_fs (&(sbs->battery[id].proc_entry), + acpi_battery_dir); } } -static int acpi_ac_add (struct acpi_sbs *sbs) +static int acpi_charger_add (struct acpi_sbs *sbs) {int result; result =acpi_ac_get_present (sbs); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_ac_get_present() failed" )); +if (result) goto end; - } - - result =acpi_sbs_generic_add_fs (&sbs->ac_entry, - acpi_ac_dir, -ACPI_AC_DIR_NAME , -NULL , &acpi_ac_state_fops,NULL , sbs); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_generic_add_fs() failed" )); + result =acpi_sbs_add_fs (&sbs->charger_entry, acpi_ac_dir, +ACPI_AC_DIR_NAME ,NULL , + &acpi_ac_state_fops,NULL , sbs); +if (result) goto end; - } - printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",ACPI_SBS_DEVICE_NAME ,acpi_device_bid (sbs->device), ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line"); - end: -return result; } -static void acpi_ac_remove (struct acpi_sbs *sbs) +static void acpi_charger_remove (struct acpi_sbs *sbs) { -if (sbs->ac_entry) { -acpi_sbs_generic_remove_fs (&sbs->ac_entry, acpi_ac_dir); - } -} - -static void acpi_sbs_update_time_run (unsigned long data) -{ -acpi_os_execute (OSL_GPE_HANDLER , acpi_sbs_update_time, (void *)data); +if (sbs->charger_entry) +acpi_sbs_remove_fs (&sbs->charger_entry, acpi_ac_dir); } -static int acpi_sbs_update_run (struct acpi_sbs *sbs,int id,int data_type) +void acpi_sbs_callback (void *context) { -struct acpi_battery *battery; -int result =0 , cnt; -int old_ac_present =-1 ; -int old_present =-1 ; -int new_ac_present =-1 ; -int new_present =-1 ; -int id_min =0 , id_max =MAX_SBS_BAT -1 ; -char dir_name[32 ]; -int do_battery_init =0 , do_ac_init =0 ; -int old_remaining_capacity =0 ; -int update_battery =1 ; -int up_tm = update_time; - -if (sbs_zombie (sbs)) { - goto end; - } - -if (id >=0 ) { - id_min = id_max = id; - } - -if (data_type ==DATA_TYPE_COMMON && up_tm >0 ) { - cnt = up_tm / (up_tm >UPDATE_DELAY ?UPDATE_DELAY : up_tm); -if (sbs->run_cnt % cnt !=0 ) { - update_battery =0 ; - } - } - - sbs->run_cnt++; - -if (!update_battery) { - goto end; - } - - old_ac_present = sbs->charger_present; - - result =acpi_ac_get_present (sbs); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_ac_get_present() failed" )); - } - - new_ac_present = sbs->charger_present; - - do_ac_init = (old_ac_present != new_ac_present); -if (sbs->run_cnt ==1 && data_type ==DATA_TYPE_COMMON ) { - do_ac_init =1 ; - } - -if (do_ac_init) { - result =acpi_bus_generate_event4 (ACPI_AC_CLASS , -ACPI_AC_DIR_NAME , -ACPI_SBS_AC_NOTIFY_STATUS , - new_ac_present); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_bus_generate_event4() failed" )); - } - } - -if (data_type ==DATA_TYPE_COMMON ) { -if (!do_ac_init && !update_battery) { - goto end; - } - } - -if (data_type ==DATA_TYPE_AC_STATE && !do_ac_init) { - goto end; +int id; +struct acpi_sbs *sbs = context; +struct acpi_battery *bat; +u8 saved_charger_state = sbs->charger_present; +u8 saved_battery_state; +acpi_ac_get_present (sbs); +if (sbs->charger_present != saved_charger_state) { +acpi_bus_generate_event4 (ACPI_AC_CLASS ,ACPI_AC_DIR_NAME , +ACPI_SBS_NOTIFY_STATUS , + sbs->charger_present); } - -for (id = id_min; id <= id_max; id++) { - battery = &sbs->battery[id]; -if (battery->alive ==0 ) { -continue ; - } - - old_remaining_capacity = battery->capacity_now; - - old_present = battery->present; - - result =acpi_battery_select (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_select() failed" )); - } - - result =acpi_battery_get_present (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_present() failed" )); - } - - new_present = battery->present; - - do_battery_init = ((old_present != new_present) - && new_present); -if (!new_present) - goto event; -if (do_ac_init || do_battery_init) { - result =acpi_battery_init (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_init() " -"failed" )); - } - } -if (sbs_zombie (sbs)) { - goto end; - } - -if ((data_type ==DATA_TYPE_COMMON - || data_type ==DATA_TYPE_INFO ) - && new_present) { - result =acpi_battery_get_info (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_info() failed" )); - } - } -if (data_type ==DATA_TYPE_INFO ) { -continue ; - } -if (sbs_zombie (sbs)) { - goto end; - } - -if ((data_type ==DATA_TYPE_COMMON - || data_type ==DATA_TYPE_STATE ) - && new_present) { - result =acpi_battery_get_state (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_state() failed" )); - } - } -if (data_type ==DATA_TYPE_STATE ) { - goto event; - } -if (sbs_zombie (sbs)) { - goto end; - } - -if ((data_type ==DATA_TYPE_COMMON - || data_type ==DATA_TYPE_ALARM ) - && new_present) { - result =acpi_battery_get_alarm (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_alarm() " -"failed" )); - } - } -if (data_type ==DATA_TYPE_ALARM ) { -continue ; - } -if (sbs_zombie (sbs)) { - goto end; - } - - event: - -if (old_present != new_present || do_ac_init || - old_remaining_capacity != - battery->capacity_now) { -sprintf (dir_name,ACPI_BATTERY_DIR_NAME , id); - result =acpi_bus_generate_event4 (ACPI_BATTERY_CLASS , - dir_name, -ACPI_SBS_BATTERY_NOTIFY_STATUS , - new_present); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_bus_generate_event4() " -"failed" )); - } +if (sbs->manager_present) { +for (id =0 ; id <MAX_SBS_BAT ; ++id) { +if (!(sbs->batteries_supported & (1 << id))) +continue ; + bat = &sbs->battery[id]; + saved_battery_state = bat->present; +acpi_battery_read (bat); +if (saved_battery_state == bat->present) +continue ; +acpi_bus_generate_event4 (ACPI_BATTERY_CLASS , + bat->name, +ACPI_SBS_NOTIFY_STATUS , + bat->present); } } - - end: - -return result; } -static void acpi_sbs_update_time (void *data) -{ -struct acpi_sbs *sbs = data; -unsigned long delay =-1 ; -int result; -unsigned int up_tm = update_time; - -if (sbs_mutex_lock (sbs)) -return ; - - result =acpi_sbs_update_run (sbs,-1 ,DATA_TYPE_COMMON ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_update_run() failed" )); - } - -if (sbs_zombie (sbs)) { - goto end; - } - -if (!up_tm) { -if (timer_pending (&sbs->update_timer)) -del_timer (&sbs->update_timer); - }else { - delay = (up_tm >UPDATE_DELAY ?UPDATE_DELAY : up_tm); - delay = jiffies +HZ * delay; -if (timer_pending (&sbs->update_timer)) { -mod_timer (&sbs->update_timer, delay); - }else { - sbs->update_timer.data = (unsigned long )data; - sbs->update_timer.function = acpi_sbs_update_time_run; - sbs->update_timer.expires = delay; -add_timer (&sbs->update_timer); - } - } - - end: - -sbs_mutex_unlock (sbs); -} +static int acpi_sbs_remove (struct acpi_device *device,int type);static int acpi_sbs_add (struct acpi_device *device) { -struct acpi_sbs *sbs =NULL ; -int result =0 , remove_result =0 ; +struct acpi_sbs *sbs; +int result =0 ;int id; sbs =kzalloc (sizeof (struct acpi_sbs ),GFP_KERNEL );if (!sbs) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"kzalloc() failed" )); result = -ENOMEM ; goto end; } -mutex_init (&sbs->mutex); - -sbs_mutex_lock (sbs); +mutex_init (&sbs->lock); - sbs->device = device; sbs->hc =acpi_driver_data (device->parent); - + sbs->device = device;strcpy (acpi_device_name (device),ACPI_SBS_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_SBS_CLASS );acpi_driver_data (device) = sbs; - result =acpi_ac_add (sbs); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_ac_add() failed" )); - goto end; - } - -acpi_sbsm_get_info (sbs); - -if (!sbs->manager_present) { - result =acpi_battery_add (sbs,0 ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_add() failed" )); - goto end; - } - }else { -for (id =0 ; id <MAX_SBS_BAT ; id++) { -if ((sbs->batteries_supported & (1 << id))) { - result =acpi_battery_add (sbs, id); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_add() failed" )); - goto end; - } - } - } - } - -init_timer (&sbs->update_timer); - result =acpi_check_update_proc (sbs); + result =acpi_charger_add (sbs);if (result) goto end; + result =acpi_manager_get_info (sbs); +if (!result) { + sbs->manager_present =1 ; +for (id =0 ; id <MAX_SBS_BAT ; ++id) +if ((sbs->batteries_supported & (1 << id))) +acpi_battery_add (sbs, id); + }else +acpi_battery_add (sbs,0 ); +acpi_smbus_register_callback (sbs->hc, acpi_sbs_callback, sbs); end: - -sbs_mutex_unlock (sbs); - -if (result) { - remove_result =acpi_sbs_remove (device,0 ); -if (remove_result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_remove() failed" )); - } - } - +if (result) +acpi_sbs_remove (device,0 );return result; }
@@ -1453,34 +744,19 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)struct acpi_sbs *sbs;int id; -if (!device) { +if (!device)return -EINVAL ; - } - sbs =acpi_driver_data (device); -if (!sbs) { +if (!sbs)return -EINVAL ; - } - -sbs_mutex_lock (sbs); - - sbs->zombie =1 ; -del_timer_sync (&sbs->update_timer); -acpi_os_wait_events_complete (NULL ); -del_timer_sync (&sbs->update_timer); - -for (id =0 ; id <MAX_SBS_BAT ; id++) { +mutex_lock (&sbs->lock); +acpi_smbus_unregister_callback (sbs->hc); +for (id =0 ; id <MAX_SBS_BAT ; ++id)acpi_battery_remove (sbs, id); - } - -acpi_ac_remove (sbs); - -sbs_mutex_unlock (sbs); - -mutex_destroy (&sbs->mutex); - +acpi_charger_remove (sbs); +mutex_unlock (&sbs->lock); +mutex_destroy (&sbs->lock);kfree (sbs); -return 0 ; }
@@ -1499,14 +775,10 @@ static void acpi_sbs_rmdirs(void)static int acpi_sbs_resume (struct acpi_device *device) {struct acpi_sbs *sbs; -if (!device)return -EINVAL ; - sbs = device->driver_data; - - sbs->run_cnt =0 ; - +acpi_sbs_callback (sbs);return 0 ; }
@@ -1517,14 +789,6 @@ static int __init acpi_sbs_init(void)if (acpi_disabled)return -ENODEV ; -if (mode !=DEF_CAPACITY_UNIT - && mode !=MAH_CAPACITY_UNIT - && mode !=MWH_CAPACITY_UNIT ) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"invalid mode = %d" , mode)); -return -EINVAL ; - } - acpi_ac_dir =acpi_lock_ac_dir ();if (!acpi_ac_dir) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
PATCH 11/12 ACPI: SBS: Add support for power_supply class (and sysfs)
In reply to Alexey StarikovskiyFrom: Alexey Starikovskiy <[email protected]>
Add support for power_supply class and sysfs interface of it. Refer to Documentation/power_supply_class.txt for interface description.
---
drivers/acpi/sbs.c | 331 +++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 250 insertions(+), 81 deletions(-)
drivers/acpi/sbs.c +250 -81
@@ -28,17 +28,23 @@#include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> +#include <linux/proc_fs.h> #include <linux/seq_file.h> #include <asm/uaccess.h> +#include <linux/acpi.h> #include <linux/timer.h> #include <linux/jiffies.h> #include <linux/delay.h> +#if defined(CONFIG_POWER_SUPPLY ) || defined (CONFIG_POWER_SUPPLY_MODULE ) +#define ENABLE_POWER_SUPPLY +#include <linux/power_supply.h> +#endif +#include "sbshc.h" -#define ACPI_SBS_COMPONENT 0x00080000#define ACPI_SBS_CLASS "sbs"#define ACPI_AC_CLASS "ac_adapter"#define ACPI_BATTERY_CLASS "battery"
@@ -58,8 +64,6 @@ enum acpi_sbs_device_addr {#define ACPI_SBS_NOTIFY_STATUS 0x80#define ACPI_SBS_NOTIFY_INFO 0x81 -ACPI_MODULE_NAME ("sbs" ); -MODULE_AUTHOR ("Alexey Starikovskiy <[email protected]>" );MODULE_DESCRIPTION ("Smart Battery System ACPI interface driver" );MODULE_LICENSE ("GPL" );
@@ -76,28 +80,16 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);#define MAX_SBS_BAT 4#define ACPI_SBS_BLOCK_MAX 32 -static int acpi_sbs_add (struct acpi_device *device); -static int acpi_sbs_remove (struct acpi_device *device,int type); -static int acpi_sbs_resume (struct acpi_device *device); -static const struct acpi_device_id sbs_device_ids[] = { {"ACPI0002" ,0 }, {"" ,0 }, };MODULE_DEVICE_TABLE (acpi, sbs_device_ids); -static struct acpi_driver acpi_sbs_driver = { - .name ="sbs" , - .class =ACPI_SBS_CLASS , - .ids = sbs_device_ids, - .ops = { - .add = acpi_sbs_add, - .remove = acpi_sbs_remove, - .resume = acpi_sbs_resume, - }, -}; -struct acpi_battery { +#ifdef ENABLE_POWER_SUPPLY +struct power_supply bat; +#endif struct acpi_sbs *sbs;struct proc_dir_entry *proc_entry;unsigned long update_time;
@@ -105,7 +97,7 @@ struct acpi_battery {char manufacturer_name[ACPI_SBS_BLOCK_MAX ];char device_name[ACPI_SBS_BLOCK_MAX ];char device_chemistry[ACPI_SBS_BLOCK_MAX ]; -u32 alarm_capacity; +u16 alarm_capacity;u16 full_charge_capacity;u16 design_capacity;u16 design_voltage;
@@ -124,7 +116,12 @@ struct acpi_battery { u8 present:1; }; +#define to_acpi_battery (x) container_of(x, struct acpi_battery, bat); +struct acpi_sbs { +#ifdef ENABLE_POWER_SUPPLY +struct power_supply charger; +#endif struct acpi_device *device;struct acpi_smb_hc *hc;struct mutex lock;
@@ -135,6 +132,8 @@ struct acpi_sbs { u8 charger_present:1; }; +#define to_acpi_sbs (x) container_of(x, struct acpi_sbs, charger) +static inline int battery_scale (int log) {int scale =1 ;
@@ -164,6 +163,146 @@ static inline int acpi_battery_scale(struct acpi_battery *battery)acpi_battery_ipscale (battery); } +#ifdef ENABLE_POWER_SUPPLY +static int sbs_get_ac_property (struct power_supply *psy, +enum power_supply_property psp, +union power_supply_propval *val) +{ +struct acpi_sbs *sbs =to_acpi_sbs (psy); +switch (psp) { +case POWER_SUPPLY_PROP_ONLINE : + val->intval = sbs->charger_present; +break ; +default : +return -EINVAL ; + } +return 0 ; +} + +static int acpi_battery_technology (struct acpi_battery *battery) +{ +if (!strcasecmp ("NiCd" , battery->device_chemistry)) +return POWER_SUPPLY_TECHNOLOGY_NiCd; +if (!strcasecmp ("NiMH" , battery->device_chemistry)) +return POWER_SUPPLY_TECHNOLOGY_NiMH; +if (!strcasecmp ("LION" , battery->device_chemistry)) +return POWER_SUPPLY_TECHNOLOGY_LION ; +if (!strcasecmp ("LiP" , battery->device_chemistry)) +return POWER_SUPPLY_TECHNOLOGY_LIPO ; +return POWER_SUPPLY_TECHNOLOGY_UNKNOWN ; +} + +static int acpi_sbs_battery_get_property (struct power_supply *psy, +enum power_supply_property psp, +union power_supply_propval *val) +{ +struct acpi_battery *battery =to_acpi_battery (psy); + +if ((!battery->present) && psp !=POWER_SUPPLY_PROP_PRESENT ) +return -ENODEV ; +switch (psp) { +case POWER_SUPPLY_PROP_STATUS : +if (battery->current_now <0 ) + val->intval =POWER_SUPPLY_STATUS_DISCHARGING ; +else if (battery->current_now >0 ) + val->intval =POWER_SUPPLY_STATUS_CHARGING ; +else + val->intval =POWER_SUPPLY_STATUS_FULL ; +break ; +case POWER_SUPPLY_PROP_PRESENT : + val->intval = battery->present; +break ; +case POWER_SUPPLY_PROP_TECHNOLOGY : + val->intval =acpi_battery_technology (battery); +break ; +case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN : + val->intval = battery->design_voltage * +acpi_battery_vscale (battery) *1000 ; +break ; +case POWER_SUPPLY_PROP_VOLTAGE_NOW : + val->intval = battery->voltage_now * +acpi_battery_vscale (battery) *1000 ; +break ; +case POWER_SUPPLY_PROP_CURRENT_NOW : + val->intval =abs (battery->current_now) * +acpi_battery_ipscale (battery) *1000 ; +break ; +case POWER_SUPPLY_PROP_CURRENT_AVG : + val->intval =abs (battery->current_avg) * +acpi_battery_ipscale (battery) *1000 ; +break ; +case POWER_SUPPLY_PROP_CAPACITY : + val->intval = battery->state_of_charge; +break ; +case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN : +case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN : + val->intval = battery->design_capacity * +acpi_battery_scale (battery) *1000 ; +break ; +case POWER_SUPPLY_PROP_CHARGE_FULL : +case POWER_SUPPLY_PROP_ENERGY_FULL : + val->intval = battery->full_charge_capacity * +acpi_battery_scale (battery) *1000 ; +break ; +case POWER_SUPPLY_PROP_CHARGE_NOW : +case POWER_SUPPLY_PROP_ENERGY_NOW : + val->intval = battery->capacity_now * +acpi_battery_scale (battery) *1000 ; +break ; +case POWER_SUPPLY_PROP_TEMP : + val->intval = battery->temp_now -2730 ;// dK -> dC +break ; +case POWER_SUPPLY_PROP_MODEL_NAME : + val->strval = battery->device_name; +break ; +case POWER_SUPPLY_PROP_MANUFACTURER : + val->strval = battery->manufacturer_name; +break ; +default : +return -EINVAL ; + } +return 0 ; +} + +static enum power_supply_property sbs_ac_props[] = { +POWER_SUPPLY_PROP_ONLINE , +}; + +static enum power_supply_property sbs_charge_battery_props[] = { +POWER_SUPPLY_PROP_STATUS , +POWER_SUPPLY_PROP_PRESENT , +POWER_SUPPLY_PROP_TECHNOLOGY , +POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN , +POWER_SUPPLY_PROP_VOLTAGE_NOW , +POWER_SUPPLY_PROP_CURRENT_NOW , +POWER_SUPPLY_PROP_CURRENT_AVG , +POWER_SUPPLY_PROP_CAPACITY , +POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN , +POWER_SUPPLY_PROP_CHARGE_FULL , +POWER_SUPPLY_PROP_CHARGE_NOW , +POWER_SUPPLY_PROP_TEMP , +POWER_SUPPLY_PROP_MODEL_NAME , +POWER_SUPPLY_PROP_MANUFACTURER , +}; + +static enum power_supply_property sbs_energy_battery_props[] = { +POWER_SUPPLY_PROP_STATUS , +POWER_SUPPLY_PROP_PRESENT , +POWER_SUPPLY_PROP_TECHNOLOGY , +POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN , +POWER_SUPPLY_PROP_VOLTAGE_NOW , +POWER_SUPPLY_PROP_CURRENT_NOW , +POWER_SUPPLY_PROP_CURRENT_AVG , +POWER_SUPPLY_PROP_CAPACITY , +POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN , +POWER_SUPPLY_PROP_ENERGY_FULL , +POWER_SUPPLY_PROP_ENERGY_NOW , +POWER_SUPPLY_PROP_TEMP , +POWER_SUPPLY_PROP_MODEL_NAME , +POWER_SUPPLY_PROP_MANUFACTURER , +}; +#endif +/* -------------------------------------------------------------------------- Smart Battery System Management -------------------------------------------------------------------------- */
@@ -204,7 +343,7 @@ static int acpi_manager_get_info(struct acpi_sbs *sbs)u16 battery_system_info; result =acpi_smbus_read (sbs->hc,SMBUS_READ_WORD ,ACPI_SBS_MANAGER , -0x04 , (u8 *) & battery_system_info); +0x04 , (u8 *)&battery_system_info);if (!result) sbs->batteries_supported = battery_system_info &0x000f ;return result;
@@ -215,9 +354,12 @@ static int acpi_battery_get_info(struct acpi_battery *battery)int i, result =0 ;for (i =0 ; i <ARRAY_SIZE (info_readers); ++i) { - result =acpi_smbus_read (battery->sbs->hc, info_readers[i].mode, -ACPI_SBS_BATTERY , info_readers[i].command, - (u8 *) battery + info_readers[i].offset); + result =acpi_smbus_read (battery->sbs->hc, + info_readers[i].mode, +ACPI_SBS_BATTERY , + info_readers[i].command, + (u8 *) battery + + info_readers[i].offset);if (result)break ; }
@@ -228,7 +370,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery) {int i, result =0 ; -if (time_before (jiffies, battery->update_time + +if (battery->update_time && +time_before (jiffies, battery->update_time +msecs_to_jiffies (cache_time)))return 0 ;for (i =0 ; i <ARRAY_SIZE (state_readers); ++i) {
@@ -250,26 +393,36 @@ static int acpi_battery_get_alarm(struct acpi_battery *battery) {return acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SBS_BATTERY ,0x01 , - (u8 *) & battery->alarm_capacity); + (u8 *)&battery->alarm_capacity); }static int acpi_battery_set_alarm (struct acpi_battery *battery) {struct acpi_sbs *sbs = battery->sbs; -u16 value; -return 0 ; +u16 value, sel =1 << (battery->id +12 ); + +int ret; +if (sbs->manager_present) { -acpi_smbus_read (sbs->hc,SMBUS_READ_WORD ,ACPI_SBS_MANAGER , + ret =acpi_smbus_read (sbs->hc,SMBUS_READ_WORD ,ACPI_SBS_MANAGER ,0x01 , (u8 *)&value); - value &=0x0fff ; - value |=1 << (battery->id +12 ); -acpi_smbus_write (sbs->hc,SMBUS_WRITE_WORD ,ACPI_SBS_MANAGER , -0x01 , (u8 *)&value,2 ); +if (ret) + goto end; +if ((value &0xf000 ) != sel) { + value &=0x0fff ; + value |= sel; + ret =acpi_smbus_write (sbs->hc,SMBUS_WRITE_WORD , +ACPI_SBS_MANAGER , +0x01 , (u8 *)&value,2 ); +if (ret) + goto end; + } } - value = battery->alarm_capacity / (acpi_battery_mode (battery) ?10 :1 ); -return acpi_smbus_write (sbs->hc,SMBUS_WRITE_WORD ,ACPI_SBS_BATTERY , -0x01 , (u8 *)&value,2 ); + ret =acpi_smbus_write (sbs->hc,SMBUS_WRITE_WORD ,ACPI_SBS_BATTERY , +0x01 , (u8 *)&battery->alarm_capacity,2 ); + end: +return ret; }static int acpi_ac_get_present (struct acpi_sbs *sbs)
@@ -289,22 +442,19 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)-------------------------------------------------------------------------- */ /* Generic Routines */ -static int acpi_sbs_add_fs (struct proc_dir_entry **dir, -struct proc_dir_entry *parent_dir, -char *dir_name, -struct file_operations *info_fops, -struct file_operations *state_fops, -struct file_operations *alarm_fops,void *data) +struct proc_dir_entry *parent_dir, +char *dir_name, +struct file_operations *info_fops, +struct file_operations *state_fops, +struct file_operations *alarm_fops,void *data) {struct proc_dir_entry *entry =NULL ;if (!*dir) { *dir =proc_mkdir (dir_name, parent_dir);if (!*dir) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"proc_mkdir() failed" ));return -ENODEV ; } (*dir)->owner =THIS_MODULE ;
@@ -313,10 +463,7 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir,/* 'info' [R] */ if (info_fops) { entry =create_proc_entry (ACPI_SBS_FILE_INFO ,S_IRUGO , *dir); -if (!entry) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"create_proc_entry() failed" )); - }else { +if (entry) { entry->proc_fops = info_fops; entry->data = data; entry->owner =THIS_MODULE ;
@@ -326,10 +473,7 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir,/* 'state' [R] */ if (state_fops) { entry =create_proc_entry (ACPI_SBS_FILE_STATE ,S_IRUGO , *dir); -if (!entry) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"create_proc_entry() failed" )); - }else { +if (entry) { entry->proc_fops = state_fops; entry->data = data; entry->owner =THIS_MODULE ;
@@ -339,16 +483,12 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir,/* 'alarm' [R/W] */ if (alarm_fops) { entry =create_proc_entry (ACPI_SBS_FILE_ALARM ,S_IRUGO , *dir); -if (!entry) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"create_proc_entry() failed" )); - }else { +if (entry) { entry->proc_fops = alarm_fops; entry->data = data; entry->owner =THIS_MODULE ; } } -return 0 ; }
@@ -356,7 +496,6 @@ static void acpi_sbs_remove_fs(struct proc_dir_entry **dir, struct proc_dir_entry *parent_dir) { -if (*dir) {remove_proc_entry (ACPI_SBS_FILE_INFO , *dir);remove_proc_entry (ACPI_SBS_FILE_STATE , *dir);
@@ -364,11 +503,9 @@ acpi_sbs_remove_fs(struct proc_dir_entry **dir,remove_proc_entry ((*dir)->name, parent_dir); *dir =NULL ; } - }/* Smart Battery Interface */ -static struct proc_dir_entry *acpi_battery_dir =NULL ;static inline char *acpi_battery_units (struct acpi_battery *battery)
@@ -506,7 +643,8 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer, goto end; } alarm_string[count] =0 ; - battery->alarm_capacity =simple_strtoul (alarm_string,NULL ,0 ); + battery->alarm_capacity =simple_strtoul (alarm_string,NULL ,0 ) / +acpi_battery_scale (battery);acpi_battery_set_alarm (battery); end:mutex_unlock (&sbs->lock);
@@ -579,9 +717,6 @@ static struct file_operations acpi_ac_state_fops = {/* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ - -/* Smart Battery */ -static int acpi_battery_read (struct acpi_battery *battery) {int result =0 , saved_present = battery->present;
@@ -611,13 +746,14 @@ static int acpi_battery_read(struct acpi_battery *battery)return result; } +/* Smart Battery */ static int acpi_battery_add (struct acpi_sbs *sbs,int id) { -int result;struct acpi_battery *battery = &sbs->battery[id]; +int result; + battery->id = id; battery->sbs = sbs; - battery->update_time =0 ; result =acpi_battery_read (battery);if (result)return result;
@@ -627,6 +763,21 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) battery->name, &acpi_battery_info_fops, &acpi_battery_state_fops, &acpi_battery_alarm_fops, battery); +#ifdef ENABLE_POWER_SUPPLY + battery->bat.name = battery->name; + battery->bat.type =POWER_SUPPLY_TYPE_BATTERY ; +if (!acpi_battery_mode (battery)) { + battery->bat.properties = sbs_charge_battery_props; + battery->bat.num_properties = +ARRAY_SIZE (sbs_charge_battery_props); + }else { + battery->bat.properties = sbs_energy_battery_props; + battery->bat.num_properties = +ARRAY_SIZE (sbs_energy_battery_props); + } + battery->bat.get_property = acpi_sbs_battery_get_property; + result =power_supply_register (&sbs->device->dev, &battery->bat); +#endif printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",ACPI_SBS_DEVICE_NAME ,acpi_device_bid (sbs->device), battery->name, sbs->battery->present ? "present" : "absent");
@@ -635,7 +786,10 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)static void acpi_battery_remove (struct acpi_sbs *sbs,int id) { - +#ifdef ENABLE_POWER_SUPPLY +if (sbs->battery[id].bat.dev) +power_supply_unregister (&sbs->battery[id].bat); +#endif if (sbs->battery[id].proc_entry) {acpi_sbs_remove_fs (&(sbs->battery[id].proc_entry), acpi_battery_dir);
@@ -654,6 +808,14 @@ static int acpi_charger_add(struct acpi_sbs *sbs) &acpi_ac_state_fops, NULL, sbs);if (result) goto end; +#ifdef ENABLE_POWER_SUPPLY + sbs->charger.name ="sbs-charger" ; + sbs->charger.type =POWER_SUPPLY_TYPE_MAINS ; + sbs->charger.properties = sbs_ac_props; + sbs->charger.num_properties =ARRAY_SIZE (sbs_ac_props); + sbs->charger.get_property = sbs_get_ac_property; +power_supply_register (&sbs->device->dev, &sbs->charger); +#endif printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",ACPI_SBS_DEVICE_NAME ,acpi_device_bid (sbs->device), ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
@@ -663,7 +825,10 @@ static int acpi_charger_add(struct acpi_sbs *sbs)static void acpi_charger_remove (struct acpi_sbs *sbs) { - +#ifdef ENABLE_POWER_SUPPLY +if (sbs->charger.dev) +power_supply_unregister (&sbs->charger); +#endif if (sbs->charger_entry)acpi_sbs_remove_fs (&sbs->charger_entry, acpi_ac_dir); }
@@ -680,6 +845,9 @@ void acpi_sbs_callback(void *context)acpi_bus_generate_event4 (ACPI_AC_CLASS ,ACPI_AC_DIR_NAME ,ACPI_SBS_NOTIFY_STATUS , sbs->charger_present); +#ifdef ENABLE_POWER_SUPPLY +kobject_uevent (&sbs->charger.dev->kobj,KOBJ_CHANGE ); +#endif }if (sbs->manager_present) {for (id =0 ; id <MAX_SBS_BAT ; ++id) {
@@ -694,6 +862,9 @@ void acpi_sbs_callback(void *context) bat->name,ACPI_SBS_NOTIFY_STATUS , bat->present); +#ifdef ENABLE_POWER_SUPPLY +kobject_uevent (&bat->bat.dev->kobj,KOBJ_CHANGE ); +#endif } } }
@@ -782,45 +953,43 @@ static int acpi_sbs_resume(struct acpi_device *device)return 0 ; } +static struct acpi_driver acpi_sbs_driver = { + .name ="sbs" , + .class =ACPI_SBS_CLASS , + .ids = sbs_device_ids, + .ops = { + .add = acpi_sbs_add, + .remove = acpi_sbs_remove, + .resume = acpi_sbs_resume, + }, +}; +static int __init acpi_sbs_init (void ) {int result =0 ;if (acpi_disabled)return -ENODEV ; - acpi_ac_dir =acpi_lock_ac_dir (); -if (!acpi_ac_dir) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_lock_ac_dir() failed" )); +if (!acpi_ac_dir)return -ENODEV ; - } - acpi_battery_dir =acpi_lock_battery_dir ();if (!acpi_battery_dir) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_lock_battery_dir() failed" ));acpi_sbs_rmdirs ();return -ENODEV ; } - result =acpi_bus_register_driver (&acpi_sbs_driver);if (result <0 ) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_bus_register_driver() failed" ));acpi_sbs_rmdirs ();return -ENODEV ; } -return 0 ; } static void __exit acpi_sbs_exit(void) {acpi_bus_unregister_driver (&acpi_sbs_driver); -acpi_sbs_rmdirs (); -return ; }
PATCH 12/12 ACPI: SBS: Add ACPI_PROCFS around procfs handling code.
In reply to Alexey StarikovskiyFrom: Alexey Starikovskiy <[email protected]>
Make procfs support optional under ACPI_PROCFS
---
drivers/acpi/sbs.c | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+), 0 deletions(-)
drivers/acpi/sbs.c +21 -0
@@ -29,9 +29,11 @@#include <linux/moduleparam.h> #include <linux/kernel.h> +#ifdef CONFIG_ACPI_PROCFS #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <asm/uaccess.h> +#endif #include <linux/acpi.h> #include <linux/timer.h>
@@ -91,7 +93,9 @@ struct acpi_battery {struct power_supply bat;#endif struct acpi_sbs *sbs; +#ifdef CONFIG_ACPI_PROCFS struct proc_dir_entry *proc_entry; +#endif unsigned long update_time;char name[8 ];char manufacturer_name[ACPI_SBS_BLOCK_MAX ];
@@ -125,7 +129,9 @@ struct acpi_sbs {struct acpi_device *device;struct acpi_smb_hc *hc;struct mutex lock; +#ifdef CONFIG_ACPI_PROCFS struct proc_dir_entry *charger_entry; +#endif struct acpi_battery battery[MAX_SBS_BAT ]; u8 batteries_supported:4; u8 manager_present:1;
@@ -389,6 +395,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery)return result; } +#ifdef CONFIG_ACPI_PROCFS +static int acpi_battery_get_alarm (struct acpi_battery *battery) { return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
@@ -424,6 +432,7 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery) end: return ret; } +#endif static int acpi_ac_get_present (struct acpi_sbs *sbs) {
@@ -759,10 +768,12 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)return result;sprintf (battery->name,ACPI_BATTERY_DIR_NAME , id); +#ifdef CONFIG_ACPI_PROCFS acpi_sbs_add_fs (&battery->proc_entry, acpi_battery_dir, battery->name, &acpi_battery_info_fops, &acpi_battery_state_fops, &acpi_battery_alarm_fops, battery); +#endif #ifdef ENABLE_POWER_SUPPLY battery->bat.name = battery->name; battery->bat.type =POWER_SUPPLY_TYPE_BATTERY ;
@@ -790,10 +801,12 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id)if (sbs->battery[id].bat.dev)power_supply_unregister (&sbs->battery[id].bat);#endif +#ifdef CONFIG_ACPI_PROCFS if (sbs->battery[id].proc_entry) {acpi_sbs_remove_fs (&(sbs->battery[id].proc_entry), acpi_battery_dir); } +#endif }static int acpi_charger_add (struct acpi_sbs *sbs)
@@ -803,11 +816,13 @@ static int acpi_charger_add(struct acpi_sbs *sbs) result =acpi_ac_get_present (sbs);if (result) goto end; +#ifdef CONFIG_ACPI_PROCFS result =acpi_sbs_add_fs (&sbs->charger_entry, acpi_ac_dir,ACPI_AC_DIR_NAME ,NULL , &acpi_ac_state_fops,NULL , sbs);if (result) goto end; +#endif #ifdef ENABLE_POWER_SUPPLY sbs->charger.name ="sbs-charger" ; sbs->charger.type =POWER_SUPPLY_TYPE_MAINS ;
@@ -829,8 +844,10 @@ static void acpi_charger_remove(struct acpi_sbs *sbs)if (sbs->charger.dev)power_supply_unregister (&sbs->charger);#endif +#ifdef CONFIG_ACPI_PROCFS if (sbs->charger_entry)acpi_sbs_remove_fs (&sbs->charger_entry, acpi_ac_dir); +#endif }void acpi_sbs_callback (void *context)
@@ -933,6 +950,7 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)static void acpi_sbs_rmdirs (void ) { +#ifdef CONFIG_ACPI_PROCFS if (acpi_ac_dir) {acpi_unlock_ac_dir (acpi_ac_dir); acpi_ac_dir =NULL ;
@@ -941,6 +959,7 @@ static void acpi_sbs_rmdirs(void)acpi_unlock_battery_dir (acpi_battery_dir); acpi_battery_dir = NULL; } +#endif }static int acpi_sbs_resume (struct acpi_device *device)
@@ -970,6 +989,7 @@ static int __init acpi_sbs_init(void)if (acpi_disabled)return -ENODEV ; +#ifdef CONFIG_ACPI_PROCFS acpi_ac_dir =acpi_lock_ac_dir ();if (!acpi_ac_dir)return -ENODEV ;
@@ -978,6 +998,7 @@ static int __init acpi_sbs_init(void)acpi_sbs_rmdirs (); return -ENODEV; } +#endif result =acpi_bus_register_driver (&acpi_sbs_driver);if (result <0 ) {acpi_sbs_rmdirs ();
PATCH 12/12 ACPI: SBS: Add ACPI_PROCFS around procfs handling code.
Make procfs support optional under ACPI_PROCFS
---
drivers/acpi/sbs.c | 25 +++++++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-)
drivers/acpi/sbs.c +25 -0
@@ -29,9 +29,11 @@#include <linux/moduleparam.h> #include <linux/kernel.h> +#ifdef CONFIG_ACPI_PROCFS #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <asm/uaccess.h> +#endif #include <linux/acpi.h> #include <linux/timer.h>
@@ -91,7 +93,9 @@ struct acpi_battery {struct power_supply bat;#endif struct acpi_sbs *sbs; +#ifdef CONFIG_ACPI_PROCFS struct proc_dir_entry *proc_entry; +#endif unsigned long update_time;char name[8 ];char manufacturer_name[ACPI_SBS_BLOCK_MAX ];
@@ -125,7 +129,9 @@ struct acpi_sbs {struct acpi_device *device;struct acpi_smb_hc *hc;struct mutex lock; +#ifdef CONFIG_ACPI_PROCFS struct proc_dir_entry *charger_entry; +#endif struct acpi_battery battery[MAX_SBS_BAT ]; u8 batteries_supported:4; u8 manager_present:1;
@@ -389,6 +395,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery)return result; } +#ifdef CONFIG_ACPI_PROCFS +static int acpi_battery_get_alarm (struct acpi_battery *battery) { return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
@@ -425,6 +433,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery) return ret; } +#endif +static int acpi_ac_get_present (struct acpi_sbs *sbs) {int result;
@@ -441,6 +451,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)FS Interface (/proc/acpi) -------------------------------------------------------------------------- */ +#ifdef CONFIG_ACPI_PROCFS /* Generic Routines */ static int acpi_sbs_add_fs(struct proc_dir_entry **dir,
@@ -714,6 +725,8 @@ static struct file_operations acpi_ac_state_fops = { .owner = THIS_MODULE, }; +#endif +/* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */
@@ -759,10 +772,12 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)return result;sprintf (battery->name,ACPI_BATTERY_DIR_NAME , id); +#ifdef CONFIG_ACPI_PROCFS acpi_sbs_add_fs (&battery->proc_entry, acpi_battery_dir, battery->name, &acpi_battery_info_fops, &acpi_battery_state_fops, &acpi_battery_alarm_fops, battery); +#endif #ifdef ENABLE_POWER_SUPPLY battery->bat.name = battery->name; battery->bat.type =POWER_SUPPLY_TYPE_BATTERY ;
@@ -790,10 +805,12 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id)if (sbs->battery[id].bat.dev)power_supply_unregister (&sbs->battery[id].bat);#endif +#ifdef CONFIG_ACPI_PROCFS if (sbs->battery[id].proc_entry) {acpi_sbs_remove_fs (&(sbs->battery[id].proc_entry), acpi_battery_dir); } +#endif }static int acpi_charger_add (struct acpi_sbs *sbs)
@@ -803,11 +820,13 @@ static int acpi_charger_add(struct acpi_sbs *sbs) result =acpi_ac_get_present (sbs);if (result) goto end; +#ifdef CONFIG_ACPI_PROCFS result =acpi_sbs_add_fs (&sbs->charger_entry, acpi_ac_dir,ACPI_AC_DIR_NAME ,NULL , &acpi_ac_state_fops,NULL , sbs);if (result) goto end; +#endif #ifdef ENABLE_POWER_SUPPLY sbs->charger.name ="sbs-charger" ; sbs->charger.type =POWER_SUPPLY_TYPE_MAINS ;
@@ -829,8 +848,10 @@ static void acpi_charger_remove(struct acpi_sbs *sbs)if (sbs->charger.dev)power_supply_unregister (&sbs->charger);#endif +#ifdef CONFIG_ACPI_PROCFS if (sbs->charger_entry)acpi_sbs_remove_fs (&sbs->charger_entry, acpi_ac_dir); +#endif }void acpi_sbs_callback (void *context)
@@ -933,6 +954,7 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)static void acpi_sbs_rmdirs (void ) { +#ifdef CONFIG_ACPI_PROCFS if (acpi_ac_dir) {acpi_unlock_ac_dir (acpi_ac_dir); acpi_ac_dir =NULL ;
@@ -941,6 +963,7 @@ static void acpi_sbs_rmdirs(void)acpi_unlock_battery_dir (acpi_battery_dir); acpi_battery_dir = NULL; } +#endif }static int acpi_sbs_resume (struct acpi_device *device)
@@ -970,6 +993,7 @@ static int __init acpi_sbs_init(void)if (acpi_disabled)return -ENODEV ; +#ifdef CONFIG_ACPI_PROCFS acpi_ac_dir =acpi_lock_ac_dir ();if (!acpi_ac_dir)return -ENODEV ;
@@ -978,6 +1002,7 @@ static int __init acpi_sbs_init(void)acpi_sbs_rmdirs (); return -ENODEV; } +#endif result =acpi_bus_register_driver (&acpi_sbs_driver);if (result <0 ) {acpi_sbs_rmdirs ();