Skip to content

Commit

Permalink
ACPI: add support for Smart Battery
Browse files Browse the repository at this point in the history
Most batteries today are ACPI "Control Method" batteries,
but some models ship with the older "Smart Battery"
that requires this code.

Rich Townsend and Bruno Ducrot were the original authors.
Vladimir Lebedev updated to run on latest kernel.

http://bugzilla.kernel.org/show_bug.cgi?id=3734

Signed-off-by: Len Brown <len.brown@intel.com>
  • Loading branch information
Rich Townsend authored and Len Brown committed Jul 1, 2006
1 parent 37672d4 commit 3f86b83
Show file tree
Hide file tree
Showing 8 changed files with 2,434 additions and 11 deletions.
12 changes: 12 additions & 0 deletions drivers/acpi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,18 @@ config ACPI_HOTPLUG_MEMORY
If one selects "m," this driver can be loaded using the following
command:
$>modprobe acpi_memhotplug

config ACPI_SBS
tristate "Smart Battery System (EXPERIMENTAL)"
depends on X86 && I2C
depends on EXPERIMENTAL
default y
help
This driver adds support for the Smart Battery System.
Depends on I2C (Device Drivers ---> I2C support)
A "Smart Battery" is quite old and quite rare compared
to today's ACPI "Control Method" battery.

endif # ACPI

endmenu
2 changes: 2 additions & 0 deletions drivers/acpi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,5 @@ obj-$(CONFIG_ACPI_IBM) += ibm_acpi.o
obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
obj-y += scan.o motherboard.o
obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
obj-y += cm_sbs.o
obj-$(CONFIG_ACPI_SBS) += i2c_ec.o sbs.o
12 changes: 7 additions & 5 deletions drivers/acpi/ac.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ ACPI_MODULE_NAME("acpi_ac")
MODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME);
MODULE_LICENSE("GPL");

extern struct proc_dir_entry *acpi_lock_ac_dir(void);
extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);

static int acpi_ac_add(struct acpi_device *device);
static int acpi_ac_remove(struct acpi_device *device, int type);
static int acpi_ac_open_fs(struct inode *inode, struct file *file);
Expand Down Expand Up @@ -278,17 +281,16 @@ static int acpi_ac_remove(struct acpi_device *device, int type)

static int __init acpi_ac_init(void)
{
int result = 0;
int result;


acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir);
acpi_ac_dir = acpi_lock_ac_dir();
if (!acpi_ac_dir)
return -ENODEV;
acpi_ac_dir->owner = THIS_MODULE;

result = acpi_bus_register_driver(&acpi_ac_driver);
if (result < 0) {
remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir);
acpi_unlock_ac_dir(acpi_ac_dir);
return -ENODEV;
}

Expand All @@ -300,7 +302,7 @@ static void __exit acpi_ac_exit(void)

acpi_bus_unregister_driver(&acpi_ac_driver);

remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir);
acpi_unlock_ac_dir(acpi_ac_dir);

return;
}
Expand Down
13 changes: 7 additions & 6 deletions drivers/acpi/battery.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ ACPI_MODULE_NAME("acpi_battery")
MODULE_DESCRIPTION(ACPI_BATTERY_DRIVER_NAME);
MODULE_LICENSE("GPL");

extern struct proc_dir_entry *acpi_lock_battery_dir(void);
extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);

static int acpi_battery_add(struct acpi_device *device);
static int acpi_battery_remove(struct acpi_device *device, int type);

Expand Down Expand Up @@ -750,17 +753,15 @@ static int acpi_battery_remove(struct acpi_device *device, int type)

static int __init acpi_battery_init(void)
{
int result = 0;

int result;

acpi_battery_dir = proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir);
acpi_battery_dir = acpi_lock_battery_dir();
if (!acpi_battery_dir)
return -ENODEV;
acpi_battery_dir->owner = THIS_MODULE;

result = acpi_bus_register_driver(&acpi_battery_driver);
if (result < 0) {
remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir);
acpi_unlock_battery_dir(acpi_battery_dir);
return -ENODEV;
}

Expand All @@ -772,7 +773,7 @@ static void __exit acpi_battery_exit(void)

acpi_bus_unregister_driver(&acpi_battery_driver);

remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir);
acpi_unlock_battery_dir(acpi_battery_dir);

return;
}
Expand Down
135 changes: 135 additions & 0 deletions drivers/acpi/cm_sbs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acmacros.h>
#include <acpi/actypes.h>
#include <acpi/acutils.h>

ACPI_MODULE_NAME("cm_sbs")
#define ACPI_AC_CLASS "ac_adapter"
#define ACPI_BATTERY_CLASS "battery"
#define ACPI_SBS_COMPONENT 0x00080000
#define _COMPONENT ACPI_SBS_COMPONENT
static struct proc_dir_entry *acpi_ac_dir;
static struct proc_dir_entry *acpi_battery_dir;

static struct semaphore cm_sbs_sem;

static int lock_ac_dir_cnt = 0;
static int lock_battery_dir_cnt = 0;

struct proc_dir_entry *acpi_lock_ac_dir(void)
{
ACPI_FUNCTION_TRACE("acpi_lock_ac_dir");

down(&cm_sbs_sem);
if (!acpi_ac_dir) {
acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir);
}
if (acpi_ac_dir) {
lock_ac_dir_cnt++;
} else {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Cannot create %s\n", ACPI_AC_CLASS));
}
up(&cm_sbs_sem);
return (acpi_ac_dir);
}

EXPORT_SYMBOL(acpi_lock_ac_dir);

void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir_param)
{
ACPI_FUNCTION_TRACE("acpi_unlock_ac_dir");

down(&cm_sbs_sem);
if (acpi_ac_dir_param) {
lock_ac_dir_cnt--;
}
if (lock_ac_dir_cnt == 0 && acpi_ac_dir_param && acpi_ac_dir) {
remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir);
acpi_ac_dir = 0;
}
up(&cm_sbs_sem);
}

EXPORT_SYMBOL(acpi_unlock_ac_dir);

struct proc_dir_entry *acpi_lock_battery_dir(void)
{
ACPI_FUNCTION_TRACE("acpi_lock_battery_dir");

down(&cm_sbs_sem);
if (!acpi_battery_dir) {
acpi_battery_dir =
proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir);
}
if (acpi_battery_dir) {
lock_battery_dir_cnt++;
} else {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Cannot create %s\n", ACPI_BATTERY_CLASS));
}
up(&cm_sbs_sem);
return (acpi_battery_dir);
}

EXPORT_SYMBOL(acpi_lock_battery_dir);

void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param)
{
ACPI_FUNCTION_TRACE("acpi_unlock_battery_dir");

down(&cm_sbs_sem);
if (acpi_battery_dir_param) {
lock_battery_dir_cnt--;
}
if (lock_battery_dir_cnt == 0 && acpi_battery_dir_param
&& acpi_battery_dir) {
remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir);
acpi_battery_dir = 0;
}
up(&cm_sbs_sem);
}

EXPORT_SYMBOL(acpi_unlock_battery_dir);

static int __init acpi_cm_sbs_init(void)
{
ACPI_FUNCTION_TRACE("acpi_cm_sbs_init");

if (acpi_disabled)
return_VALUE(0);

init_MUTEX(&cm_sbs_sem);

return_VALUE(0);
}

subsys_initcall(acpi_cm_sbs_init);
Loading

0 comments on commit 3f86b83

Please sign in to comment.