From 8db85d4c9a0cc131242c80ef8456362d66561dc2 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Wed, 26 Sep 2007 19:43:16 +0400 Subject: ACPI: Add acpi_bus_generate_event4() function acpi_bus_generate_event() takes two strings out of passed device object. SBS needs to supply these strings directly. Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/sbs.c | 46 ++++++++++++++-------------------------------- 1 file changed, 14 insertions(+), 32 deletions(-) (limited to 'drivers/acpi/sbs.c') diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index a578986..33ba4bf 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -427,28 +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_proc_event(device, event, state); - - strcpy(acpi_device_bid(device), bid_saved); - strcpy(acpi_device_class(device), class_saved); - - acpi_bus_generate_netlink_event(class, bid, event, state); - return result; -} - static int acpi_battery_get_present(struct acpi_battery *battery) { s16 state; @@ -1452,15 +1430,17 @@ 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_proc_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")); } + acpi_bus_generate_netlink_event(ACPI_AC_CLASS, ACPI_AC_DIR_NAME, + ACPI_SBS_AC_NOTIFY_STATUS, + new_ac_present); } if (data_type == DATA_TYPE_COMMON) { @@ -1568,14 +1548,16 @@ 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_proc_event4(ACPI_BATTERY_CLASS, dir_name, - ACPI_BATTERY_CLASS); + ACPI_SBS_BATTERY_NOTIFY_STATUS, + new_battery_present); + acpi_bus_generate_netlink_event(ACPI_BATTERY_CLASS, dir_name, + ACPI_SBS_BATTERY_NOTIFY_STATUS, + new_battery_present); if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "acpi_sbs_generate_event() " + "acpi_bus_generate_proc_event4() " "failed")); } } -- cgit v1.1 From 91087dfa51a29b3c190e99339c4c32eb13646c51 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Wed, 26 Sep 2007 19:43:28 +0400 Subject: ACPI: SBS: Split host controller (ACPI0001) from SBS driver (ACPI0002) Replace poll-based host controller driver with the notify-based one. Split it out of sbs.c. Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/sbs.c | 374 +++++++++++------------------------------------------ 1 file changed, 75 insertions(+), 299 deletions(-) (limited to 'drivers/acpi/sbs.c') diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 33ba4bf..7bb8c62 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -34,6 +34,8 @@ #include #include +#include "sbshc.h" + #define ACPI_SBS_COMPONENT 0x00080000 #define ACPI_SBS_CLASS "sbs" #define ACPI_AC_CLASS "ac_adapter" @@ -59,28 +61,6 @@ MODULE_AUTHOR("Rich Townsend"); MODULE_DESCRIPTION("Smart Battery System ACPI interface driver"); MODULE_LICENSE("GPL"); -#define xmsleep(t) msleep(t) - -#define ACPI_EC_SMB_PRTCL 0x00 /* protocol, PEC */ - -#define ACPI_EC_SMB_STS 0x01 /* status */ -#define ACPI_EC_SMB_ADDR 0x02 /* address */ -#define ACPI_EC_SMB_CMD 0x03 /* command */ -#define ACPI_EC_SMB_DATA 0x04 /* 32 data registers */ -#define ACPI_EC_SMB_BCNT 0x24 /* number of data bytes */ - -#define ACPI_EC_SMB_STS_DONE 0x80 -#define ACPI_EC_SMB_STS_STATUS 0x1f - -#define ACPI_EC_SMB_PRTCL_WRITE 0x00 -#define ACPI_EC_SMB_PRTCL_READ 0x01 -#define ACPI_EC_SMB_PRTCL_WORD_DATA 0x08 -#define ACPI_EC_SMB_PRTCL_BLOCK_DATA 0x0a - -#define ACPI_EC_SMB_TRANSACTION_SLEEP 1 -#define ACPI_EC_SMB_ACCESS_SLEEP1 1 -#define ACPI_EC_SMB_ACCESS_SLEEP2 10 - #define DEF_CAPACITY_UNIT 3 #define MAH_CAPACITY_UNIT 1 #define MWH_CAPACITY_UNIT 2 @@ -103,12 +83,6 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); #define MAX_SBS_BAT 4 #define ACPI_SBS_BLOCK_MAX 32 -#define ACPI_SBS_SMBUS_READ 1 -#define ACPI_SBS_SMBUS_WRITE 2 - -#define ACPI_SBS_WORD_DATA 1 -#define ACPI_SBS_BLOCK_DATA 2 - #define UPDATE_DELAY 10 /* 0 - every time, > 0 - by update_time */ @@ -124,8 +98,7 @@ 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[] = { - {"ACPI0001", 0}, - {"ACPI0005", 0}, + {"ACPI0002", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, sbs_device_ids); @@ -182,8 +155,8 @@ struct acpi_battery { }; struct acpi_sbs { - int base; struct acpi_device *device; + struct acpi_smb_hc *hc; struct mutex mutex; int sbsm_present; int sbsm_batteries_supported; @@ -199,190 +172,6 @@ struct acpi_sbs { static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type); static void acpi_sbs_update_time(void *data); -union sbs_rw_data { - u16 word; - u8 block[ACPI_SBS_BLOCK_MAX + 2]; -}; - -static int acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr, - char read_write, u8 command, int size, - union sbs_rw_data *data); - -/* -------------------------------------------------------------------------- - SMBus Communication - -------------------------------------------------------------------------- */ - -static int acpi_ec_sbs_read(struct acpi_sbs *sbs, u8 address, u8 * data) -{ - u8 val; - int err; - - err = ec_read(sbs->base + address, &val); - if (!err) { - *data = val; - } - xmsleep(ACPI_EC_SMB_TRANSACTION_SLEEP); - return (err); -} - -static int acpi_ec_sbs_write(struct acpi_sbs *sbs, u8 address, u8 data) -{ - int err; - - err = ec_write(sbs->base + address, data); - return (err); -} - -static int -acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr, - char read_write, u8 command, int size, - union sbs_rw_data *data) -{ - unsigned char protocol, len = 0, temp[2] = { 0, 0 }; - int i; - - if (read_write == ACPI_SBS_SMBUS_READ) { - protocol = ACPI_EC_SMB_PRTCL_READ; - } else { - protocol = ACPI_EC_SMB_PRTCL_WRITE; - } - - switch (size) { - - case ACPI_SBS_WORD_DATA: - acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command); - if (read_write == ACPI_SBS_SMBUS_WRITE) { - acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA, data->word); - acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + 1, - data->word >> 8); - } - protocol |= ACPI_EC_SMB_PRTCL_WORD_DATA; - break; - case ACPI_SBS_BLOCK_DATA: - acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command); - if (read_write == ACPI_SBS_SMBUS_WRITE) { - len = min_t(u8, data->block[0], 32); - acpi_ec_sbs_write(sbs, ACPI_EC_SMB_BCNT, len); - for (i = 0; i < len; i++) - acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + i, - data->block[i + 1]); - } - protocol |= ACPI_EC_SMB_PRTCL_BLOCK_DATA; - break; - default: - ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "unsupported transaction %d", size)); - return (-1); - } - - acpi_ec_sbs_write(sbs, ACPI_EC_SMB_ADDR, addr << 1); - acpi_ec_sbs_write(sbs, ACPI_EC_SMB_PRTCL, protocol); - - acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp); - - if (~temp[0] & ACPI_EC_SMB_STS_DONE) { - xmsleep(ACPI_EC_SMB_ACCESS_SLEEP1); - acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp); - } - if (~temp[0] & ACPI_EC_SMB_STS_DONE) { - xmsleep(ACPI_EC_SMB_ACCESS_SLEEP2); - acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp); - } - if ((~temp[0] & ACPI_EC_SMB_STS_DONE) - || (temp[0] & ACPI_EC_SMB_STS_STATUS)) { - ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "transaction %d error", size)); - return (-1); - } - - if (read_write == ACPI_SBS_SMBUS_WRITE) { - return (0); - } - - switch (size) { - - case ACPI_SBS_WORD_DATA: - acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA, temp); - acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + 1, temp + 1); - data->word = (temp[1] << 8) | temp[0]; - break; - - case ACPI_SBS_BLOCK_DATA: - len = 0; - acpi_ec_sbs_read(sbs, ACPI_EC_SMB_BCNT, &len); - len = min_t(u8, len, 32); - for (i = 0; i < len; i++) - acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + i, - data->block + i + 1); - data->block[0] = len; - break; - default: - ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "unsupported transaction %d", size)); - return (-1); - } - - return (0); -} - -static int -acpi_sbs_read_word(struct acpi_sbs *sbs, int addr, int func, u16 * word) -{ - union sbs_rw_data data; - int result = 0; - - result = acpi_ec_sbs_access(sbs, addr, - ACPI_SBS_SMBUS_READ, func, - ACPI_SBS_WORD_DATA, &data); - if (result) { - ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "acpi_ec_sbs_access() failed")); - } else { - *word = data.word; - } - - return result; -} - -static int -acpi_sbs_read_str(struct acpi_sbs *sbs, int addr, int func, char *str) -{ - union sbs_rw_data data; - int result = 0; - - result = acpi_ec_sbs_access(sbs, addr, - ACPI_SBS_SMBUS_READ, func, - ACPI_SBS_BLOCK_DATA, &data); - if (result) { - ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "acpi_ec_sbs_access() failed")); - } else { - strncpy(str, (const char *)data.block + 1, data.block[0]); - str[data.block[0]] = 0; - } - - return result; -} - -static int -acpi_sbs_write_word(struct acpi_sbs *sbs, int addr, int func, int word) -{ - union sbs_rw_data data; - int result = 0; - - data.word = word; - - result = acpi_ec_sbs_access(sbs, addr, - ACPI_SBS_SMBUS_WRITE, func, - ACPI_SBS_WORD_DATA, &data); - if (result) { - ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "acpi_ec_sbs_access() failed")); - } - - return result; -} - static int sbs_zombie(struct acpi_sbs *sbs) { return (sbs->zombie); @@ -433,11 +222,11 @@ static int acpi_battery_get_present(struct acpi_battery *battery) int result = 0; int is_present = 0; - result = acpi_sbs_read_word(battery->sbs, - ACPI_SBSM_SMBUS_ADDR, 0x01, &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_sbs_read_word() failed")); + "acpi_smbus_read() failed")); } if (!result) { is_present = (state & 0x000f) & (1 << battery->id); @@ -461,19 +250,19 @@ static int acpi_battery_select(struct acpi_battery *battery) * it causes charging to halt on SBSELs */ result = - acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, &state); + 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_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } foo = (state & 0x0fff) | (1 << (battery->id + 12)); result = - acpi_sbs_write_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, foo); + 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_sbs_write_word() failed")); + "acpi_smbus_write() failed")); goto end; } } @@ -487,11 +276,11 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs) int result = 0; s16 battery_system_info; - result = acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x04, - &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_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } sbs->sbsm_present = 1; @@ -504,50 +293,49 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs) static int acpi_battery_get_info(struct acpi_battery *battery) { - struct acpi_sbs *sbs = battery->sbs; int result = 0; s16 battery_mode; s16 specification_info; - result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03, - &battery_mode); + 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_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } battery->info.capacity_mode = (battery_mode & 0x8000) >> 15; - result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x10, - &battery->info.full_charge_capacity); + result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x10, + (u8 *)&battery->info.full_charge_capacity); if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "acpi_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } - result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x18, - &battery->info.design_capacity); + result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x18, + (u8 *)&battery->info.design_capacity); if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "acpi_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } - result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x19, - &battery->info.design_voltage); + result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x19, + (u8 *)&battery->info.design_voltage); if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "acpi_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } - result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1a, - &specification_info); + 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_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } @@ -579,32 +367,32 @@ static int acpi_battery_get_info(struct acpi_battery *battery) battery->info.ipscale = 1; } - result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1c, - &battery->info.serial_number); + result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x1c, + (u8 *)&battery->info.serial_number); if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "acpi_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } - result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x20, - battery->info.manufacturer_name); + result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x20, + (u8 *)battery->info.manufacturer_name); if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_sbs_read_str() failed")); goto end; } - result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x21, - battery->info.device_name); + result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x21, + (u8 *)battery->info.device_name); if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_sbs_read_str() failed")); goto end; } - result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x22, - battery->info.device_chemistry); + result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x22, + (u8 *)battery->info.device_chemistry); if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_sbs_read_str() failed")); @@ -617,38 +405,37 @@ static int acpi_battery_get_info(struct acpi_battery *battery) static int acpi_battery_get_state(struct acpi_battery *battery) { - struct acpi_sbs *sbs = battery->sbs; int result = 0; - result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x09, - &battery->state.voltage); + result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x09, + (u8 *)&battery->state.voltage); if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "acpi_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } - result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0a, - &battery->state.amperage); + result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x0a, + (u8 *)&battery->state.amperage); if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "acpi_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } - result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0f, - &battery->state.remaining_capacity); + result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x0f, + (u8 *)&battery->state.remaining_capacity); if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "acpi_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } - result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x16, - &battery->state.battery_state); + result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x16, + (u8 *)&battery->state.battery_state); if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "acpi_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } @@ -658,14 +445,13 @@ static int acpi_battery_get_state(struct acpi_battery *battery) static int acpi_battery_get_alarm(struct acpi_battery *battery) { - struct acpi_sbs *sbs = battery->sbs; int result = 0; - result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01, - &battery->alarm.remaining_capacity); + result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01, + (u8 *)&battery->alarm.remaining_capacity); if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "acpi_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } @@ -677,7 +463,6 @@ static int acpi_battery_get_alarm(struct acpi_battery *battery) static int acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm) { - struct acpi_sbs *sbs = battery->sbs; int result = 0; s16 battery_mode; int foo; @@ -693,29 +478,30 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery, if (alarm > 0) { result = - acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03, - &battery_mode); + 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_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } + battery_mode &= 0xbfff; result = - acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01, - battery_mode & 0xbfff); + 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_sbs_write_word() failed")); + "acpi_smbus_write() failed")); goto end; } } foo = alarm / (battery->info.capacity_mode ? 10 : 1); - result = acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01, foo); + 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_sbs_write_word() failed")); + "acpi_smbus_write() failed")); goto end; } @@ -726,7 +512,6 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery, static int acpi_battery_set_mode(struct acpi_battery *battery) { - struct acpi_sbs *sbs = battery->sbs; int result = 0; s16 battery_mode; @@ -734,11 +519,11 @@ static int acpi_battery_set_mode(struct acpi_battery *battery) goto end; } - result = acpi_sbs_read_word(sbs, - ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode); + 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_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } @@ -747,19 +532,19 @@ static int acpi_battery_set_mode(struct acpi_battery *battery) } else { battery_mode |= 0x8000; } - result = acpi_sbs_write_word(sbs, - ACPI_SB_SMBUS_ADDR, 0x03, battery_mode); + 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_sbs_write_word() failed")); + "acpi_smbus_write() failed")); goto end; } - result = acpi_sbs_read_word(sbs, - ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode); + 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_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } @@ -815,12 +600,12 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs) int result = 0; s16 charger_status; - result = acpi_sbs_read_word(sbs, ACPI_SBC_SMBUS_ADDR, 0x13, - &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_sbs_read_word() failed")); + "acpi_smbus_read() failed")); goto end; } @@ -1614,15 +1399,6 @@ static int acpi_sbs_add(struct acpi_device *device) struct acpi_sbs *sbs = NULL; int result = 0, remove_result = 0; int id; - acpi_status status = AE_OK; - unsigned long val; - - status = - acpi_evaluate_integer(device->handle, "_EC", NULL, &val); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC")); - return -EIO; - } sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL); if (!sbs) { @@ -1635,8 +1411,8 @@ static int acpi_sbs_add(struct acpi_device *device) sbs_mutex_lock(sbs); - sbs->base = 0xff & (val >> 8); sbs->device = device; + sbs->hc = acpi_driver_data(device->parent); strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_SBS_CLASS); -- cgit v1.1 From 89862e3be1ba387c738fc2c3a5875cfd7e51c5a8 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Wed, 26 Sep 2007 19:43:35 +0400 Subject: ACPI: SBS: Simplify data structures in SBS Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/sbs.c | 282 +++++++++++++++++++++++++---------------------------- 1 file changed, 135 insertions(+), 147 deletions(-) (limited to 'drivers/acpi/sbs.c') diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 7bb8c62..f35fe63 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -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) { @@ -1244,9 +1232,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) { @@ -1260,11 +1248,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); @@ -1280,7 +1268,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, @@ -1296,7 +1284,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, @@ -1312,7 +1300,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, @@ -1329,17 +1317,17 @@ 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_proc_event4(ACPI_BATTERY_CLASS, dir_name, ACPI_SBS_BATTERY_NOTIFY_STATUS, - new_battery_present); + new_present); acpi_bus_generate_netlink_event(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_proc_event4() " @@ -1426,7 +1414,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, @@ -1435,7 +1423,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, @@ -1535,11 +1523,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; } -- cgit v1.1 From db1c291af7ad748777371f25b9ff92e3e5aba38e Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Wed, 26 Sep 2007 19:43:41 +0400 Subject: ACPI: SBS: Make SBS reads table-driven. Re-factor SBS functions to use tables and cycles for repeated operations. Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/sbs.c | 1292 +++++++++++----------------------------------------- 1 file changed, 275 insertions(+), 1017 deletions(-) (limited to 'drivers/acpi/sbs.c') diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index f35fe63..3351dea 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -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 + * Copyright (c) 2005-2007 Vladimir Lebedev * Copyright (c) 2005 Rich Townsend * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -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 0x81 ACPI_MODULE_NAME("sbs"); -MODULE_AUTHOR("Rich Townsend"); +MODULE_AUTHOR("Alexey Starikovskiy "); 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,354 +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_proc_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")); - } - acpi_bus_generate_netlink_event(ACPI_AC_CLASS, ACPI_AC_DIR_NAME, - ACPI_SBS_AC_NOTIFY_STATUS, - new_ac_present); - } - - 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_proc_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_proc_event4(ACPI_BATTERY_CLASS, - dir_name, - ACPI_SBS_BATTERY_NOTIFY_STATUS, - new_present); - acpi_bus_generate_netlink_event(ACPI_BATTERY_CLASS, dir_name, - ACPI_SBS_BATTERY_NOTIFY_STATUS, - new_present); - if (result) { - ACPI_EXCEPTION((AE_INFO, AE_ERROR, - "acpi_bus_generate_proc_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_proc_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; } @@ -1459,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; } @@ -1505,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; } @@ -1523,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, -- cgit v1.1 From 94f6c0860139da9219255b8ff45ad42117dda859 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Wed, 26 Sep 2007 19:43:48 +0400 Subject: ACPI: SBS: Add support for power_supply class (and sysfs) Add support for power_supply class and sysfs interface of it. Refer to Documentation/power_supply_class.txt for interface description. Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/sbs.c | 314 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 233 insertions(+), 81 deletions(-) (limited to 'drivers/acpi/sbs.c') diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 3351dea..c4f9641 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -28,17 +28,20 @@ #include #include #include + #include #include #include + #include #include #include #include +#include + #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 +61,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 "); MODULE_DESCRIPTION("Smart Battery System ACPI interface driver"); MODULE_LICENSE("GPL"); @@ -76,28 +77,14 @@ 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 { + struct power_supply bat; struct acpi_sbs *sbs; struct proc_dir_entry *proc_entry; unsigned long update_time; @@ -105,7 +92,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 +111,10 @@ struct acpi_battery { u8 present:1; }; +#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); + struct acpi_sbs { + struct power_supply charger; struct acpi_device *device; struct acpi_smb_hc *hc; struct mutex lock; @@ -135,6 +125,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 +156,144 @@ static inline int acpi_battery_scale(struct acpi_battery *battery) acpi_battery_ipscale(battery); } +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, +}; + /* -------------------------------------------------------------------------- Smart Battery System Management -------------------------------------------------------------------------- */ @@ -204,7 +334,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 +345,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 +361,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 +384,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 +433,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 +454,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 +464,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 +474,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 +487,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 +494,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 +634,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 +708,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 +737,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 +754,19 @@ 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); + 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); 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 +775,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].bat.dev) + power_supply_unregister(&sbs->battery[id].bat); if (sbs->battery[id].proc_entry) { acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry), acpi_battery_dir); @@ -654,6 +795,12 @@ static int acpi_charger_add(struct acpi_sbs *sbs) &acpi_ac_state_fops, NULL, sbs); if (result) goto end; + 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); 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 +810,8 @@ static int acpi_charger_add(struct acpi_sbs *sbs) static void acpi_charger_remove(struct acpi_sbs *sbs) { - + if (sbs->charger.dev) + power_supply_unregister(&sbs->charger); if (sbs->charger_entry) acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir); } @@ -677,9 +825,12 @@ void acpi_sbs_callback(void *context) u8 saved_battery_state; acpi_ac_get_present(sbs); if (sbs->charger_present != saved_charger_state) { +#ifdef CONFIG_ACPI_PROC_EVENT acpi_bus_generate_proc_event4(ACPI_AC_CLASS, ACPI_AC_DIR_NAME, ACPI_SBS_NOTIFY_STATUS, sbs->charger_present); +#endif + kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE); } if (sbs->manager_present) { for (id = 0; id < MAX_SBS_BAT; ++id) { @@ -690,10 +841,13 @@ void acpi_sbs_callback(void *context) acpi_battery_read(bat); if (saved_battery_state == bat->present) continue; +#ifdef CONFIG_ACPI_PROC_EVENT acpi_bus_generate_proc_event4(ACPI_BATTERY_CLASS, bat->name, ACPI_SBS_NOTIFY_STATUS, bat->present); +#endif + kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE); } } } @@ -782,45 +936,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; } -- cgit v1.1 From 66e4b72bfa7347fd1017b9b82dce77a410f2e4a1 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Wed, 26 Sep 2007 19:43:54 +0400 Subject: ACPI: SBS: Add ACPI_PROCFS around procfs handling code. Make procfs support optional under ACPI_PROCFS Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/sbs.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers/acpi/sbs.c') diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index c4f9641..aae65e8 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -29,9 +29,11 @@ #include #include +#ifdef CONFIG_ACPI_PROCFS #include #include #include +#endif #include #include @@ -86,7 +88,9 @@ MODULE_DEVICE_TABLE(acpi, sbs_device_ids); struct acpi_battery { struct power_supply bat; 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]; @@ -118,7 +122,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; @@ -380,6 +386,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, @@ -416,6 +424,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; @@ -432,6 +442,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, @@ -705,6 +716,8 @@ static struct file_operations acpi_ac_state_fops = { .owner = THIS_MODULE, }; +#endif + /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ @@ -750,10 +763,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 battery->bat.name = battery->name; battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; if (!acpi_battery_mode(battery)) { @@ -777,10 +792,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); +#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) @@ -790,11 +807,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 sbs->charger.name = "sbs-charger"; sbs->charger.type = POWER_SUPPLY_TYPE_MAINS; sbs->charger.properties = sbs_ac_props; @@ -812,8 +831,10 @@ static void acpi_charger_remove(struct acpi_sbs *sbs) { if (sbs->charger.dev) power_supply_unregister(&sbs->charger); +#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) @@ -916,6 +937,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; @@ -924,6 +946,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) @@ -953,6 +976,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; @@ -961,6 +985,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(); -- cgit v1.1 From 8bd955320661cfd03ab8d5574d96aa684acd38f6 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Wed, 26 Sep 2007 19:44:00 +0400 Subject: ACPI: SBS: Add sysfs alarm Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/sbs.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'drivers/acpi/sbs.c') diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index aae65e8..90fd09c 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -386,8 +386,6 @@ 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,8 +422,6 @@ 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; @@ -438,6 +434,36 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs) return result; } +static ssize_t acpi_battery_alarm_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); + acpi_battery_get_alarm(battery); + return sprintf(buf, "%d\n", battery->alarm_capacity * + acpi_battery_scale(battery) * 1000); +} + +static ssize_t acpi_battery_alarm_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long x; + struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); + if (sscanf(buf, "%ld\n", &x) == 1) + battery->alarm_capacity = x / + (1000 * acpi_battery_scale(battery)); + if (battery->present) + acpi_battery_set_alarm(battery); + return count; +} + +static struct device_attribute alarm_attr = { + .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE}, + .show = acpi_battery_alarm_show, + .store = acpi_battery_alarm_store, +}; + /* -------------------------------------------------------------------------- FS Interface (/proc/acpi) -------------------------------------------------------------------------- */ @@ -782,6 +808,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) } battery->bat.get_property = acpi_sbs_battery_get_property; result = power_supply_register(&sbs->device->dev, &battery->bat); + device_create_file(battery->bat.dev, &alarm_attr); 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"); @@ -791,6 +818,7 @@ 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].bat.dev) + device_remove_file(sbs->battery[id].bat.dev, &alarm_attr); power_supply_unregister(&sbs->battery[id].bat); #ifdef CONFIG_ACPI_PROCFS if (sbs->battery[id].proc_entry) { -- cgit v1.1