Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
12a5a712
Commit
12a5a712
authored
Apr 28, 2007
by
Len Brown
Browse files
Options
Browse Files
Download
Plain Diff
Pull sbs into release branch
parents
14d21785
439a8888
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
682 additions
and
1040 deletions
+682
-1040
drivers/acpi/Kconfig
drivers/acpi/Kconfig
+1
-2
drivers/acpi/Makefile
drivers/acpi/Makefile
+1
-1
drivers/acpi/i2c_ec.c
drivers/acpi/i2c_ec.c
+0
-403
drivers/acpi/i2c_ec.h
drivers/acpi/i2c_ec.h
+0
-23
drivers/acpi/sbs.c
drivers/acpi/sbs.c
+680
-611
No files found.
drivers/acpi/Kconfig
View file @
12a5a712
...
...
@@ -351,11 +351,10 @@ config ACPI_HOTPLUG_MEMORY
config ACPI_SBS
tristate "Smart Battery System (EXPERIMENTAL)"
depends on X86
&& I2C
depends on X86
depends on EXPERIMENTAL
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.
...
...
drivers/acpi/Makefile
View file @
12a5a712
...
...
@@ -59,4 +59,4 @@ obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o
obj-$(CONFIG_ACPI_TOSHIBA)
+=
toshiba_acpi.o
obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)
+=
acpi_memhotplug.o
obj-y
+=
cm_sbs.o
obj-$(CONFIG_ACPI_SBS)
+=
i2c_ec.o
sbs.o
obj-$(CONFIG_ACPI_SBS)
+=
sbs.o
drivers/acpi/i2c_ec.c
deleted
100644 → 0
View file @
14d21785
/*
* SMBus driver for ACPI Embedded Controller ($Revision: 1.3 $)
*
* Copyright (c) 2002, 2005 Ducrot Bruno
* Copyright (c) 2005 Rich Townsend (tiny hacks & tweaks)
*
* 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 version 2.
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/acpi.h>
#include <linux/delay.h>
#include "i2c_ec.h"
#define xudelay(t) udelay(t)
#define xmsleep(t) msleep(t)
#define ACPI_EC_HC_COMPONENT 0x00080000
#define ACPI_EC_HC_CLASS "ec_hc_smbus"
#define ACPI_EC_HC_HID "ACPI0001"
#define ACPI_EC_HC_DEVICE_NAME "EC HC smbus"
#define _COMPONENT ACPI_EC_HC_COMPONENT
ACPI_MODULE_NAME
(
"i2c_ec"
);
static
int
acpi_ec_hc_add
(
struct
acpi_device
*
device
);
static
int
acpi_ec_hc_remove
(
struct
acpi_device
*
device
,
int
type
);
static
struct
acpi_driver
acpi_ec_hc_driver
=
{
.
name
=
"i2c_ec"
,
.
class
=
ACPI_EC_HC_CLASS
,
.
ids
=
ACPI_EC_HC_HID
,
.
ops
=
{
.
add
=
acpi_ec_hc_add
,
.
remove
=
acpi_ec_hc_remove
,
},
};
/* Various bit mask for EC_SC (R) */
#define OBF 0x01
#define IBF 0x02
#define CMD 0x08
#define BURST 0x10
#define SCI_EVT 0x20
#define SMI_EVT 0x40
/* Commands for EC_SC (W) */
#define RD_EC 0x80
#define WR_EC 0x81
#define BE_EC 0x82
#define BD_EC 0x83
#define QR_EC 0x84
/*
* ACPI 2.0 chapter 13 SMBus 2.0 EC register model
*/
#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_ALRM_A 0x25
/* alarm address */
#define ACPI_EC_SMB_ALRM_D 0x26
/* 2 bytes alarm data */
#define ACPI_EC_SMB_STS_DONE 0x80
#define ACPI_EC_SMB_STS_ALRM 0x40
#define ACPI_EC_SMB_STS_RES 0x20
#define ACPI_EC_SMB_STS_STATUS 0x1f
#define ACPI_EC_SMB_STATUS_OK 0x00
#define ACPI_EC_SMB_STATUS_FAIL 0x07
#define ACPI_EC_SMB_STATUS_DNAK 0x10
#define ACPI_EC_SMB_STATUS_DERR 0x11
#define ACPI_EC_SMB_STATUS_CMD_DENY 0x12
#define ACPI_EC_SMB_STATUS_UNKNOWN 0x13
#define ACPI_EC_SMB_STATUS_ACC_DENY 0x17
#define ACPI_EC_SMB_STATUS_TIMEOUT 0x18
#define ACPI_EC_SMB_STATUS_NOTSUP 0x19
#define ACPI_EC_SMB_STATUS_BUSY 0x1A
#define ACPI_EC_SMB_STATUS_PEC 0x1F
#define ACPI_EC_SMB_PRTCL_WRITE 0x00
#define ACPI_EC_SMB_PRTCL_READ 0x01
#define ACPI_EC_SMB_PRTCL_QUICK 0x02
#define ACPI_EC_SMB_PRTCL_BYTE 0x04
#define ACPI_EC_SMB_PRTCL_BYTE_DATA 0x06
#define ACPI_EC_SMB_PRTCL_WORD_DATA 0x08
#define ACPI_EC_SMB_PRTCL_BLOCK_DATA 0x0a
#define ACPI_EC_SMB_PRTCL_PROC_CALL 0x0c
#define ACPI_EC_SMB_PRTCL_BLOCK_PROC_CALL 0x0d
#define ACPI_EC_SMB_PRTCL_I2C_BLOCK_DATA 0x4a
#define ACPI_EC_SMB_PRTCL_PEC 0x80
/* Length of pre/post transaction sleep (msec) */
#define ACPI_EC_SMB_TRANSACTION_SLEEP 1
#define ACPI_EC_SMB_ACCESS_SLEEP1 1
#define ACPI_EC_SMB_ACCESS_SLEEP2 10
static
int
acpi_ec_smb_read
(
struct
acpi_ec_smbus
*
smbus
,
u8
address
,
u8
*
data
)
{
u8
val
;
int
err
;
err
=
ec_read
(
smbus
->
base
+
address
,
&
val
);
if
(
!
err
)
{
*
data
=
val
;
}
xmsleep
(
ACPI_EC_SMB_TRANSACTION_SLEEP
);
return
(
err
);
}
static
int
acpi_ec_smb_write
(
struct
acpi_ec_smbus
*
smbus
,
u8
address
,
u8
data
)
{
int
err
;
err
=
ec_write
(
smbus
->
base
+
address
,
data
);
return
(
err
);
}
static
int
acpi_ec_smb_access
(
struct
i2c_adapter
*
adap
,
u16
addr
,
unsigned
short
flags
,
char
read_write
,
u8
command
,
int
size
,
union
i2c_smbus_data
*
data
)
{
struct
acpi_ec_smbus
*
smbus
=
adap
->
algo_data
;
unsigned
char
protocol
,
len
=
0
,
pec
,
temp
[
2
]
=
{
0
,
0
};
int
i
;
if
(
read_write
==
I2C_SMBUS_READ
)
{
protocol
=
ACPI_EC_SMB_PRTCL_READ
;
}
else
{
protocol
=
ACPI_EC_SMB_PRTCL_WRITE
;
}
pec
=
(
flags
&
I2C_CLIENT_PEC
)
?
ACPI_EC_SMB_PRTCL_PEC
:
0
;
switch
(
size
)
{
case
I2C_SMBUS_QUICK
:
protocol
|=
ACPI_EC_SMB_PRTCL_QUICK
;
read_write
=
I2C_SMBUS_WRITE
;
break
;
case
I2C_SMBUS_BYTE
:
if
(
read_write
==
I2C_SMBUS_WRITE
)
{
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_DATA
,
data
->
byte
);
}
protocol
|=
ACPI_EC_SMB_PRTCL_BYTE
;
break
;
case
I2C_SMBUS_BYTE_DATA
:
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_CMD
,
command
);
if
(
read_write
==
I2C_SMBUS_WRITE
)
{
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_DATA
,
data
->
byte
);
}
protocol
|=
ACPI_EC_SMB_PRTCL_BYTE_DATA
;
break
;
case
I2C_SMBUS_WORD_DATA
:
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_CMD
,
command
);
if
(
read_write
==
I2C_SMBUS_WRITE
)
{
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_DATA
,
data
->
word
);
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_DATA
+
1
,
data
->
word
>>
8
);
}
protocol
|=
ACPI_EC_SMB_PRTCL_WORD_DATA
|
pec
;
break
;
case
I2C_SMBUS_BLOCK_DATA
:
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_CMD
,
command
);
if
(
read_write
==
I2C_SMBUS_WRITE
)
{
len
=
min_t
(
u8
,
data
->
block
[
0
],
32
);
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_BCNT
,
len
);
for
(
i
=
0
;
i
<
len
;
i
++
)
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_DATA
+
i
,
data
->
block
[
i
+
1
]);
}
protocol
|=
ACPI_EC_SMB_PRTCL_BLOCK_DATA
|
pec
;
break
;
case
I2C_SMBUS_I2C_BLOCK_DATA
:
len
=
min_t
(
u8
,
data
->
block
[
0
],
32
);
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_CMD
,
command
);
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_BCNT
,
len
);
if
(
read_write
==
I2C_SMBUS_WRITE
)
{
for
(
i
=
0
;
i
<
len
;
i
++
)
{
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_DATA
+
i
,
data
->
block
[
i
+
1
]);
}
}
protocol
|=
ACPI_EC_SMB_PRTCL_I2C_BLOCK_DATA
;
break
;
case
I2C_SMBUS_PROC_CALL
:
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_CMD
,
command
);
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_DATA
,
data
->
word
);
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_DATA
+
1
,
data
->
word
>>
8
);
protocol
=
ACPI_EC_SMB_PRTCL_PROC_CALL
|
pec
;
read_write
=
I2C_SMBUS_READ
;
break
;
case
I2C_SMBUS_BLOCK_PROC_CALL
:
protocol
|=
pec
;
len
=
min_t
(
u8
,
data
->
block
[
0
],
31
);
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_CMD
,
command
);
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_BCNT
,
len
);
for
(
i
=
0
;
i
<
len
;
i
++
)
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_DATA
+
i
,
data
->
block
[
i
+
1
]);
protocol
=
ACPI_EC_SMB_PRTCL_BLOCK_PROC_CALL
|
pec
;
read_write
=
I2C_SMBUS_READ
;
break
;
default:
ACPI_DEBUG_PRINT
((
ACPI_DB_WARN
,
"EC SMBus adapter: "
"Unsupported transaction %d
\n
"
,
size
));
return
(
-
1
);
}
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_ADDR
,
addr
<<
1
);
acpi_ec_smb_write
(
smbus
,
ACPI_EC_SMB_PRTCL
,
protocol
);
acpi_ec_smb_read
(
smbus
,
ACPI_EC_SMB_STS
,
temp
+
0
);
if
(
~
temp
[
0
]
&
ACPI_EC_SMB_STS_DONE
)
{
xudelay
(
500
);
acpi_ec_smb_read
(
smbus
,
ACPI_EC_SMB_STS
,
temp
+
0
);
}
if
(
~
temp
[
0
]
&
ACPI_EC_SMB_STS_DONE
)
{
xmsleep
(
ACPI_EC_SMB_ACCESS_SLEEP2
);
acpi_ec_smb_read
(
smbus
,
ACPI_EC_SMB_STS
,
temp
+
0
);
}
if
((
~
temp
[
0
]
&
ACPI_EC_SMB_STS_DONE
)
||
(
temp
[
0
]
&
ACPI_EC_SMB_STS_STATUS
))
{
return
(
-
1
);
}
if
(
read_write
==
I2C_SMBUS_WRITE
)
{
return
(
0
);
}
switch
(
size
)
{
case
I2C_SMBUS_BYTE
:
case
I2C_SMBUS_BYTE_DATA
:
acpi_ec_smb_read
(
smbus
,
ACPI_EC_SMB_DATA
,
&
data
->
byte
);
break
;
case
I2C_SMBUS_WORD_DATA
:
case
I2C_SMBUS_PROC_CALL
:
acpi_ec_smb_read
(
smbus
,
ACPI_EC_SMB_DATA
,
temp
+
0
);
acpi_ec_smb_read
(
smbus
,
ACPI_EC_SMB_DATA
+
1
,
temp
+
1
);
data
->
word
=
(
temp
[
1
]
<<
8
)
|
temp
[
0
];
break
;
case
I2C_SMBUS_BLOCK_DATA
:
case
I2C_SMBUS_BLOCK_PROC_CALL
:
len
=
0
;
acpi_ec_smb_read
(
smbus
,
ACPI_EC_SMB_BCNT
,
&
len
);
len
=
min_t
(
u8
,
len
,
32
);
case
I2C_SMBUS_I2C_BLOCK_DATA
:
for
(
i
=
0
;
i
<
len
;
i
++
)
acpi_ec_smb_read
(
smbus
,
ACPI_EC_SMB_DATA
+
i
,
data
->
block
+
i
+
1
);
data
->
block
[
0
]
=
len
;
break
;
}
return
(
0
);
}
static
u32
acpi_ec_smb_func
(
struct
i2c_adapter
*
adapter
)
{
return
(
I2C_FUNC_SMBUS_QUICK
|
I2C_FUNC_SMBUS_BYTE
|
I2C_FUNC_SMBUS_BYTE_DATA
|
I2C_FUNC_SMBUS_WORD_DATA
|
I2C_FUNC_SMBUS_BLOCK_DATA
|
I2C_FUNC_SMBUS_PROC_CALL
|
I2C_FUNC_SMBUS_BLOCK_PROC_CALL
|
I2C_FUNC_SMBUS_I2C_BLOCK
|
I2C_FUNC_SMBUS_HWPEC_CALC
);
}
static
const
struct
i2c_algorithm
acpi_ec_smbus_algorithm
=
{
.
smbus_xfer
=
acpi_ec_smb_access
,
.
functionality
=
acpi_ec_smb_func
,
};
static
int
acpi_ec_hc_add
(
struct
acpi_device
*
device
)
{
int
status
;
unsigned
long
val
;
struct
acpi_ec_hc
*
ec_hc
;
struct
acpi_ec_smbus
*
smbus
;
if
(
!
device
)
{
return
-
EINVAL
;
}
ec_hc
=
kzalloc
(
sizeof
(
struct
acpi_ec_hc
),
GFP_KERNEL
);
if
(
!
ec_hc
)
{
return
-
ENOMEM
;
}
smbus
=
kzalloc
(
sizeof
(
struct
acpi_ec_smbus
),
GFP_KERNEL
);
if
(
!
smbus
)
{
kfree
(
ec_hc
);
return
-
ENOMEM
;
}
ec_hc
->
handle
=
device
->
handle
;
strcpy
(
acpi_device_name
(
device
),
ACPI_EC_HC_DEVICE_NAME
);
strcpy
(
acpi_device_class
(
device
),
ACPI_EC_HC_CLASS
);
acpi_driver_data
(
device
)
=
ec_hc
;
status
=
acpi_evaluate_integer
(
ec_hc
->
handle
,
"_EC"
,
NULL
,
&
val
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_WARN
,
"Error obtaining _EC
\n
"
));
kfree
(
ec_hc
);
kfree
(
smbus
);
return
-
EIO
;
}
smbus
->
ec
=
acpi_driver_data
(
device
->
parent
);
smbus
->
base
=
(
val
&
0xff00ull
)
>>
8
;
smbus
->
alert
=
val
&
0xffull
;
smbus
->
adapter
.
owner
=
THIS_MODULE
;
smbus
->
adapter
.
algo
=
&
acpi_ec_smbus_algorithm
;
smbus
->
adapter
.
algo_data
=
smbus
;
smbus
->
adapter
.
dev
.
parent
=
&
device
->
dev
;
if
(
i2c_add_adapter
(
&
smbus
->
adapter
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_WARN
,
"EC SMBus adapter: Failed to register adapter
\n
"
));
kfree
(
smbus
);
kfree
(
ec_hc
);
return
-
EIO
;
}
ec_hc
->
smbus
=
smbus
;
printk
(
KERN_INFO
PREFIX
"%s [%s]
\n
"
,
acpi_device_name
(
device
),
acpi_device_bid
(
device
));
return
AE_OK
;
}
static
int
acpi_ec_hc_remove
(
struct
acpi_device
*
device
,
int
type
)
{
struct
acpi_ec_hc
*
ec_hc
;
if
(
!
device
)
{
return
-
EINVAL
;
}
ec_hc
=
acpi_driver_data
(
device
);
i2c_del_adapter
(
&
ec_hc
->
smbus
->
adapter
);
kfree
(
ec_hc
->
smbus
);
kfree
(
ec_hc
);
return
AE_OK
;
}
static
int
__init
acpi_ec_hc_init
(
void
)
{
int
result
;
result
=
acpi_bus_register_driver
(
&
acpi_ec_hc_driver
);
if
(
result
<
0
)
{
return
-
ENODEV
;
}
return
0
;
}
static
void
__exit
acpi_ec_hc_exit
(
void
)
{
acpi_bus_unregister_driver
(
&
acpi_ec_hc_driver
);
}
struct
acpi_ec_hc
*
acpi_get_ec_hc
(
struct
acpi_device
*
device
)
{
return
acpi_driver_data
(
device
->
parent
);
}
EXPORT_SYMBOL
(
acpi_get_ec_hc
);
module_init
(
acpi_ec_hc_init
);
module_exit
(
acpi_ec_hc_exit
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Ducrot Bruno"
);
MODULE_DESCRIPTION
(
"ACPI EC SMBus driver"
);
drivers/acpi/i2c_ec.h
deleted
100644 → 0
View file @
14d21785
/*
* SMBus driver for ACPI Embedded Controller ($Revision: 1.2 $)
*
* Copyright (c) 2002, 2005 Ducrot Bruno
*
* 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 version 2.
*/
struct
acpi_ec_smbus
{
struct
i2c_adapter
adapter
;
union
acpi_ec
*
ec
;
int
base
;
int
alert
;
};
struct
acpi_ec_hc
{
acpi_handle
handle
;
struct
acpi_ec_smbus
*
smbus
;
};
struct
acpi_ec_hc
*
acpi_get_ec_hc
(
struct
acpi_device
*
device
);
drivers/acpi/sbs.c
View file @
12a5a712
...
...
@@ -30,30 +30,10 @@
#include <linux/seq_file.h>
#include <asm/uaccess.h>
#include <linux/acpi.h>
#include <linux/i2c.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/delay.h>
#include "i2c_ec.h"
#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
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 ACPI_SBS_COMPONENT 0x00080000
#define ACPI_SBS_CLASS "sbs"
#define ACPI_AC_CLASS "ac_adapter"
...
...
@@ -74,39 +54,75 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
#define _COMPONENT ACPI_SBS_COMPONENT
#define MAX_SBS_BAT 4
#define MAX_SMBUS_ERR 1
ACPI_MODULE_NAME
(
"sbs"
);
MODULE_AUTHOR
(
"Rich Townsend"
);
MODULE_DESCRIPTION
(
"Smart Battery System ACPI interface driver"
);
MODULE_LICENSE
(
"GPL"
);
static
struct
semaphore
sbs_sem
;
#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 UPDATE_MODE QUEUE_UPDATE_MODE
/* REQUEST_UPDATE_MODE QUEUE_UPDATE_MODE */
#define UPDATE_INFO_MODE 0
#define UPDATE_TIME 60
#define UPDATE_TIME2 0
#define ACPI_EC_SMB_STS_DONE 0x80
#define ACPI_EC_SMB_STS_STATUS 0x1f
static
int
capacity_mode
=
CAPACITY_UNIT
;
static
int
update_mode
=
UPDATE_MODE
;
static
int
update_info_mode
=
UPDATE_INFO_MODE
;
static
int
update_time
=
UPDATE_TIME
;
static
int
update_time2
=
UPDATE_TIME2
;
#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
module_param
(
capacity_mode
,
int
,
0
);
module_param
(
update_mode
,
int
,
0
);
module_param
(
update_info_mode
,
int
,
0
);
module_param
(
update_time
,
int
,
0
);
module_param
(
update_time2
,
int
,
0
);
#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
#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
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 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 */
static
unsigned
int
update_time
=
120
;
static
unsigned
int
capacity_mode
=
CAPACITY_UNIT
;
module_param
(
update_time
,
uint
,
0644
);
module_param
(
capacity_mode
,
uint
,
0444
);
static
int
acpi_sbs_add
(
struct
acpi_device
*
device
);
static
int
acpi_sbs_remove
(
struct
acpi_device
*
device
,
int
type
);
static
void
acpi_battery_smbus_err_handler
(
struct
acpi_ec_smbus
*
smbus
);
static
void
acpi_sbs_update_queue
(
void
*
data
);
static
int
acpi_sbs_resume
(
struct
acpi_device
*
device
);
static
struct
acpi_driver
acpi_sbs_driver
=
{
.
name
=
"sbs"
,
...
...
@@ -115,9 +131,14 @@ static struct acpi_driver acpi_sbs_driver = {
.
ops
=
{
.
add
=
acpi_sbs_add
,
.
remove
=
acpi_sbs_remove
,
.
resume
=
acpi_sbs_resume
,
},
};
struct
acpi_ac
{
int
ac_present
;
};
struct
acpi_battery_info
{
int
capacity_mode
;
s16
full_charge_capacity
;
...
...
@@ -126,18 +147,16 @@ struct acpi_battery_info {
int
vscale
;
int
ipscale
;
s16
serial_number
;
char
manufacturer_name
[
I2C_SMBU
S_BLOCK_MAX
+
3
];
char
device_name
[
I2C_SMBU
S_BLOCK_MAX
+
3
];
char
device_chemistry
[
I2C_SMBU
S_BLOCK_MAX
+
3
];
char
manufacturer_name
[
ACPI_SB
S_BLOCK_MAX
+
3
];
char
device_name
[
ACPI_SB
S_BLOCK_MAX
+
3
];
char
device_chemistry
[
ACPI_SB
S_BLOCK_MAX
+
3
];
};
struct
acpi_battery_state
{
s16
voltage
;
s16
amperage
;
s16
remaining_capacity
;
s16
average_time_to_empty
;
s16
average_time_to_full
;
s16
battery_status
;
s16
battery_state
;
};
struct
acpi_battery_alarm
{
...
...
@@ -146,9 +165,9 @@ struct acpi_battery_alarm {
struct
acpi_battery
{
int
alive
;
int
battery_present
;
int
id
;
int
init_state
;
int
battery_present
;
struct
acpi_sbs
*
sbs
;
struct
acpi_battery_info
info
;
struct
acpi_battery_state
state
;
...
...
@@ -158,186 +177,251 @@ struct acpi_battery {
struct
acpi_sbs
{
acpi_handle
handle
;
int
base
;
struct
acpi_device
*
device
;
struct
acpi_ec_smbus
*
smbus
;
struct
mutex
mutex
;
int
sbsm_present
;
int
sbsm_batteries_supported
;
int
ac_present
;
struct
proc_dir_entry
*
ac_entry
;
struct
acpi_ac
ac
;
struct
acpi_battery
battery
[
MAX_SBS_BAT
];
int
update_info_mode
;
int
zombie
;
int
update_time
;
int
update_time2
;
struct
timer_list
update_timer
;
int
run_cnt
;
int
update_proc_flg
;
};
static
void
acpi_update_delay
(
struct
acpi_sbs
*
sbs
);
static
int
acpi_sbs_update_run
(
struct
acpi_sbs
*
sbs
,
int
data_type
);
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
void
acpi_battery_smbus_err_handler
(
struct
acpi_ec_smbus
*
smbus
)
static
int
acpi_ec_sbs_read
(
struct
acpi_sbs
*
sbs
,
u8
address
,
u8
*
data
)
{
union
i2c_smbus_data
data
;
int
result
=
0
;
char
*
err_str
;
int
err_number
;
u8
val
;
int
err
;
data
.
word
=
0
;
err
=
ec_read
(
sbs
->
base
+
address
,
&
val
);
if
(
!
err
)
{
*
data
=
val
;
}
xmsleep
(
ACPI_EC_SMB_TRANSACTION_SLEEP
);
return
(
err
);
}
result
=
smbus
->
adapter
.
algo
->
smbus_xfer
(
&
smbus
->
adapter
,
ACPI_SB_SMBUS_ADDR
,
0
,
I2C_SMBUS_READ
,
0x16
,
I2C_SMBUS_BLOCK_DATA
,
&
data
);
static
int
acpi_ec_sbs_write
(
struct
acpi_sbs
*
sbs
,
u8
address
,
u8
data
)
{
int
err
;
err_number
=
(
data
.
word
&
0x000f
);
err
=
ec_write
(
sbs
->
base
+
address
,
data
);
return
(
err
);
}
switch
(
data
.
word
&
0x000f
)
{
case
0x0000
:
err_str
=
"unexpected bus error"
;
break
;
case
0x0001
:
err_str
=
"busy"
;
break
;
case
0x0002
:
err_str
=
"reserved command"
;
break
;
case
0x0003
:
err_str
=
"unsupported command"
;
break
;
case
0x0004
:
err_str
=
"access denied"
;
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
0x0005
:
err_str
=
"overflow/underflow"
;
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
;
case
0x0006
:
err_str
=
"bad size"
;
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
0x0007
:
err_str
=
"unknown error"
;
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:
err_str
=
"unrecognized error"
;
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"unsupported transaction %d"
,
size
));
return
(
-
1
);
}
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"%s: ret %i, err %i
\n
"
,
err_str
,
result
,
err_number
)
);
return
(
0
);
}
static
int
acpi_sbs_smbus_read_word
(
struct
acpi_ec_smbus
*
smbus
,
int
addr
,
int
func
,
u16
*
word
,
void
(
*
err_handler
)
(
struct
acpi_ec_smbus
*
smbus
))
acpi_sbs_read_word
(
struct
acpi_sbs
*
sbs
,
int
addr
,
int
func
,
u16
*
word
)
{
union
i2c_smbus
_data
data
;
union
sbs_rw
_data
data
;
int
result
=
0
;
int
i
;
if
(
err_handler
==
NULL
)
{
err_handler
=
acpi_battery_smbus_err_handler
;
}
for
(
i
=
0
;
i
<
MAX_SMBUS_ERR
;
i
++
)
{
result
=
smbus
->
adapter
.
algo
->
smbus_xfer
(
&
smbus
->
adapter
,
addr
,
0
,
I2C_SMBUS_READ
,
func
,
I2C_SMBUS_WORD_DATA
,
&
data
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"try %i: smbus->adapter.algo->smbus_xfer() failed
\n
"
,
i
));
if
(
err_handler
)
{
err_handler
(
smbus
);
}
}
else
{
*
word
=
data
.
word
;
break
;
}
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_smbus_read_str
(
struct
acpi_ec_smbus
*
smbus
,
int
addr
,
int
func
,
char
*
str
,
void
(
*
err_handler
)
(
struct
acpi_ec_smbus
*
smbus
))
acpi_sbs_read_str
(
struct
acpi_sbs
*
sbs
,
int
addr
,
int
func
,
char
*
str
)
{
union
i2c_smbus
_data
data
;
union
sbs_rw
_data
data
;
int
result
=
0
;
int
i
;
if
(
err_handler
==
NULL
)
{
err_handler
=
acpi_battery_smbus_err_handler
;
}
for
(
i
=
0
;
i
<
MAX_SMBUS_ERR
;
i
++
)
{
result
=
smbus
->
adapter
.
algo
->
smbus_xfer
(
&
smbus
->
adapter
,
addr
,
0
,
I2C_SMBUS_READ
,
func
,
I2C_SMBUS_BLOCK_DATA
,
&
data
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"try %i: smbus->adapter.algo->smbus_xfer() failed
\n
"
,
i
));
if
(
err_handler
)
{
err_handler
(
smbus
);
}
}
else
{
strncpy
(
str
,
(
const
char
*
)
data
.
block
+
1
,
data
.
block
[
0
]);
str
[
data
.
block
[
0
]]
=
0
;
break
;
}
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_smbus_write_word
(
struct
acpi_ec_smbus
*
smbus
,
int
addr
,
int
func
,
int
word
,
void
(
*
err_handler
)
(
struct
acpi_ec_smbus
*
smbus
))
acpi_sbs_write_word
(
struct
acpi_sbs
*
sbs
,
int
addr
,
int
func
,
int
word
)
{
union
i2c_smbus
_data
data
;
union
sbs_rw
_data
data
;
int
result
=
0
;
int
i
;
if
(
err_handler
==
NULL
)
{
err_handler
=
acpi_battery_smbus_err_handler
;
}
data
.
word
=
word
;
for
(
i
=
0
;
i
<
MAX_SMBUS_ERR
;
i
++
)
{
result
=
smbus
->
adapter
.
algo
->
smbus_xfer
(
&
smbus
->
adapter
,
addr
,
0
,
I2C_SMBUS_WRITE
,
func
,
I2C_SMBUS_WORD_DATA
,
&
data
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"try %i: smbus->adapter.algo"
"->smbus_xfer() failed
\n
"
,
i
));
if
(
err_handler
)
{
err_handler
(
smbus
);
}
}
else
{
break
;
}
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
);
}
static
int
sbs_mutex_lock
(
struct
acpi_sbs
*
sbs
)
{
if
(
sbs_zombie
(
sbs
))
{
return
-
ENODEV
;
}
mutex_lock
(
&
sbs
->
mutex
);
return
0
;
}
static
void
sbs_mutex_unlock
(
struct
acpi_sbs
*
sbs
)
{
mutex_unlock
(
&
sbs
->
mutex
);
}
/* --------------------------------------------------------------------------
Smart Battery System Management
-------------------------------------------------------------------------- */
/* Smart Battery */
static
int
acpi_check_update_proc
(
struct
acpi_sbs
*
sbs
)
{
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
;
}
static
int
acpi_sbs_generate_event
(
struct
acpi_device
*
device
,
int
event
,
int
state
,
char
*
bid
,
char
*
class
)
...
...
@@ -366,12 +450,11 @@ static int acpi_battery_get_present(struct acpi_battery *battery)
int
result
=
0
;
int
is_present
=
0
;
result
=
acpi_sbs_smbus_read_word
(
battery
->
sbs
->
smbus
,
ACPI_SBSM_SMBUS_ADDR
,
0x01
,
&
state
,
NULL
);
result
=
acpi_sbs_read_word
(
battery
->
sbs
,
ACPI_SBSM_SMBUS_ADDR
,
0x01
,
&
state
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbu
s_read_word() failed"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sb
s_read_word() failed"
));
}
if
(
!
result
)
{
is_present
=
(
state
&
0x000f
)
&
(
1
<<
battery
->
id
);
...
...
@@ -381,45 +464,33 @@ static int acpi_battery_get_present(struct acpi_battery *battery)
return
result
;
}
static
int
acpi_battery_is_present
(
struct
acpi_battery
*
battery
)
{
return
(
battery
->
battery_present
);
}
static
int
acpi_ac_is_present
(
struct
acpi_sbs
*
sbs
)
{
return
(
sbs
->
ac_present
);
}
static
int
acpi_battery_select
(
struct
acpi_battery
*
battery
)
{
struct
acpi_
ec_smbus
*
smbus
=
battery
->
sbs
->
smbu
s
;
struct
acpi_
sbs
*
sbs
=
battery
->
sb
s
;
int
result
=
0
;
s16
state
;
int
foo
;
if
(
battery
->
sbs
->
sbsm_present
)
{
if
(
sbs
->
sbsm_present
)
{
/* Take special care not to knobble other nibbles of
* state (aka selector_state), since
* it causes charging to halt on SBSELs */
result
=
acpi_sbs_smbus_read_word
(
smbus
,
ACPI_SBSM_SMBUS_ADDR
,
0x01
,
&
state
,
NULL
);
acpi_sbs_read_word
(
sbs
,
ACPI_SBSM_SMBUS_ADDR
,
0x01
,
&
state
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_word() failed
"
));
goto
end
;
}
foo
=
(
state
&
0x0fff
)
|
(
1
<<
(
battery
->
id
+
12
));
result
=
acpi_sbs_smbus_write_word
(
smbus
,
ACPI_SBSM_SMBUS_ADDR
,
0x01
,
foo
,
NULL
);
acpi_sbs_write_word
(
sbs
,
ACPI_SBSM_SMBUS_ADDR
,
0x01
,
foo
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_write_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_write_word() failed
"
));
goto
end
;
}
}
...
...
@@ -430,15 +501,14 @@ static int acpi_battery_select(struct acpi_battery *battery)
static
int
acpi_sbsm_get_info
(
struct
acpi_sbs
*
sbs
)
{
struct
acpi_ec_smbus
*
smbus
=
sbs
->
smbus
;
int
result
=
0
;
s16
battery_system_info
;
result
=
acpi_sbs_
smbus_read_word
(
smbu
s
,
ACPI_SBSM_SMBUS_ADDR
,
0x04
,
&
battery_system_info
,
NULL
);
result
=
acpi_sbs_
read_word
(
sb
s
,
ACPI_SBSM_SMBUS_ADDR
,
0x04
,
&
battery_system_info
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_word() failed
"
));
goto
end
;
}
...
...
@@ -451,53 +521,50 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
static
int
acpi_battery_get_info
(
struct
acpi_battery
*
battery
)
{
struct
acpi_
ec_smbus
*
smbus
=
battery
->
sbs
->
smbu
s
;
struct
acpi_
sbs
*
sbs
=
battery
->
sb
s
;
int
result
=
0
;
s16
battery_mode
;
s16
specification_info
;
result
=
acpi_sbs_smbus_read_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x03
,
&
battery_mode
,
&
acpi_battery_smbus_err_handler
);
result
=
acpi_sbs_read_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x03
,
&
battery_mode
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_word() failed
"
));
goto
end
;
}
battery
->
info
.
capacity_mode
=
(
battery_mode
&
0x8000
)
>>
15
;
result
=
acpi_sbs_smbus_read_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x10
,
&
battery
->
info
.
full_charge_capacity
,
&
acpi_battery_smbus_err_handler
);
result
=
acpi_sbs_read_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x10
,
&
battery
->
info
.
full_charge_capacity
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_word() failed
"
));
goto
end
;
}
result
=
acpi_sbs_smbus_read_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x18
,
&
battery
->
info
.
design_capacity
,
&
acpi_battery_smbus_err_handler
);
result
=
acpi_sbs_read_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x18
,
&
battery
->
info
.
design_capacity
);
if
(
result
)
{
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"acpi_sbs_read_word() failed"
));
goto
end
;
}
result
=
acpi_sbs_smbus_read_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x19
,
&
battery
->
info
.
design_voltage
,
&
acpi_battery_smbus_err_handler
);
result
=
acpi_sbs_read_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x19
,
&
battery
->
info
.
design_voltage
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_word() failed
"
));
goto
end
;
}
result
=
acpi_sbs_smbus_read_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x1a
,
&
specification_info
,
&
acpi_battery_smbus_err_handler
);
result
=
acpi_sbs_read_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x1a
,
&
specification_info
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_word() failed
"
));
goto
end
;
}
...
...
@@ -529,37 +596,35 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
battery
->
info
.
ipscale
=
1
;
}
result
=
acpi_sbs_smbus_read_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x1c
,
&
battery
->
info
.
serial_number
,
&
acpi_battery_smbus_err_handler
);
result
=
acpi_sbs_read_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x1c
,
&
battery
->
info
.
serial_number
);
if
(
result
)
{
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"acpi_sbs_read_word() failed"
));
goto
end
;
}
result
=
acpi_sbs_smbus_read_str
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x20
,
battery
->
info
.
manufacturer_name
,
&
acpi_battery_smbus_err_handler
);
result
=
acpi_sbs_read_str
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x20
,
battery
->
info
.
manufacturer_name
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_str() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_str() failed
"
));
goto
end
;
}
result
=
acpi_sbs_smbus_read_str
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x21
,
battery
->
info
.
device_name
,
&
acpi_battery_smbus_err_handler
);
result
=
acpi_sbs_read_str
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x21
,
battery
->
info
.
device_name
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_str() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_str() failed
"
));
goto
end
;
}
result
=
acpi_sbs_smbus_read_str
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x22
,
battery
->
info
.
device_chemistry
,
&
acpi_battery_smbus_err_handler
);
result
=
acpi_sbs_read_str
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x22
,
battery
->
info
.
device_chemistry
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_str() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_str() failed
"
));
goto
end
;
}
...
...
@@ -567,103 +632,60 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
return
result
;
}
static
void
acpi_update_delay
(
struct
acpi_sbs
*
sbs
)
{
if
(
sbs
->
zombie
)
{
return
;
}
if
(
sbs
->
update_time2
>
0
)
{
msleep
(
sbs
->
update_time2
*
1000
);
}
}
static
int
acpi_battery_get_state
(
struct
acpi_battery
*
battery
)
{
struct
acpi_
ec_smbus
*
smbus
=
battery
->
sbs
->
smbu
s
;
struct
acpi_
sbs
*
sbs
=
battery
->
sb
s
;
int
result
=
0
;
acpi_update_delay
(
battery
->
sbs
);
result
=
acpi_sbs_smbus_read_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x09
,
&
battery
->
state
.
voltage
,
&
acpi_battery_smbus_err_handler
);
result
=
acpi_sbs_read_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x09
,
&
battery
->
state
.
voltage
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_word() failed
"
));
goto
end
;
}
acpi_update_delay
(
battery
->
sbs
);
result
=
acpi_sbs_smbus_read_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x0a
,
&
battery
->
state
.
amperage
,
&
acpi_battery_smbus_err_handler
);
result
=
acpi_sbs_read_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x0a
,
&
battery
->
state
.
amperage
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_word() failed
"
));
goto
end
;
}
acpi_update_delay
(
battery
->
sbs
);
result
=
acpi_sbs_smbus_read_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x0f
,
&
battery
->
state
.
remaining_capacity
,
&
acpi_battery_smbus_err_handler
);
result
=
acpi_sbs_read_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x0f
,
&
battery
->
state
.
remaining_capacity
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_word() failed
"
));
goto
end
;
}
acpi_update_delay
(
battery
->
sbs
);
result
=
acpi_sbs_smbus_read_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x12
,
&
battery
->
state
.
average_time_to_empty
,
&
acpi_battery_smbus_err_handler
);
result
=
acpi_sbs_read_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x16
,
&
battery
->
state
.
battery_state
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_word() failed
"
));
goto
end
;
}
acpi_update_delay
(
battery
->
sbs
);
result
=
acpi_sbs_smbus_read_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x13
,
&
battery
->
state
.
average_time_to_full
,
&
acpi_battery_smbus_err_handler
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
goto
end
;
}
acpi_update_delay
(
battery
->
sbs
);
result
=
acpi_sbs_smbus_read_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x16
,
&
battery
->
state
.
battery_status
,
&
acpi_battery_smbus_err_handler
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
goto
end
;
}
acpi_update_delay
(
battery
->
sbs
);
end:
return
result
;
}
static
int
acpi_battery_get_alarm
(
struct
acpi_battery
*
battery
)
{
struct
acpi_
ec_smbus
*
smbus
=
battery
->
sbs
->
smbu
s
;
struct
acpi_
sbs
*
sbs
=
battery
->
sb
s
;
int
result
=
0
;
result
=
acpi_sbs_smbus_read_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x01
,
&
battery
->
alarm
.
remaining_capacity
,
&
acpi_battery_smbus_err_handler
);
result
=
acpi_sbs_read_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x01
,
&
battery
->
alarm
.
remaining_capacity
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_word() failed
"
));
goto
end
;
}
acpi_update_delay
(
battery
->
sbs
);
end:
return
result
;
...
...
@@ -672,15 +694,15 @@ 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_
ec_smbus
*
smbus
=
battery
->
sbs
->
smbu
s
;
struct
acpi_
sbs
*
sbs
=
battery
->
sb
s
;
int
result
=
0
;
s16
battery_mode
;
int
foo
;
result
=
acpi_battery_select
(
battery
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_battery_select() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_battery_select() failed
"
));
goto
end
;
}
...
...
@@ -688,33 +710,29 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
if
(
alarm
>
0
)
{
result
=
acpi_sbs_smbus_read_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x03
,
&
battery_mode
,
&
acpi_battery_smbus_err_handler
);
acpi_sbs_read_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x03
,
&
battery_mode
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_word() failed
"
));
goto
end
;
}
result
=
acpi_sbs_smbus_write_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x01
,
battery_mode
&
0xbfff
,
&
acpi_battery_smbus_err_handler
);
acpi_sbs_write_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x01
,
battery_mode
&
0xbfff
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_write_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_write_word() failed
"
));
goto
end
;
}
}
foo
=
alarm
/
(
battery
->
info
.
capacity_mode
?
10
:
1
);
result
=
acpi_sbs_smbus_write_word
(
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x01
,
foo
,
&
acpi_battery_smbus_err_handler
);
result
=
acpi_sbs_write_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x01
,
foo
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_write_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_write_word() failed
"
));
goto
end
;
}
...
...
@@ -725,6 +743,7 @@ 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
;
...
...
@@ -732,12 +751,11 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
goto
end
;
}
result
=
acpi_sbs_smbus_read_word
(
battery
->
sbs
->
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x03
,
&
battery_mode
,
NULL
);
result
=
acpi_sbs_read_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x03
,
&
battery_mode
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_word() failed
"
));
goto
end
;
}
...
...
@@ -746,21 +764,19 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
}
else
{
battery_mode
|=
0x8000
;
}
result
=
acpi_sbs_smbus_write_word
(
battery
->
sbs
->
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x03
,
battery_mode
,
NULL
);
result
=
acpi_sbs_write_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x03
,
battery_mode
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_write_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_write_word() failed
"
));
goto
end
;
}
result
=
acpi_sbs_smbus_read_word
(
battery
->
sbs
->
smbus
,
ACPI_SB_SMBUS_ADDR
,
0x03
,
&
battery_mode
,
NULL
);
result
=
acpi_sbs_read_word
(
sbs
,
ACPI_SB_SMBUS_ADDR
,
0x03
,
&
battery_mode
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_word() failed
"
));
goto
end
;
}
...
...
@@ -774,36 +790,36 @@ static int acpi_battery_init(struct acpi_battery *battery)
result
=
acpi_battery_select
(
battery
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_battery_init() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_battery_select() failed
"
));
goto
end
;
}
result
=
acpi_battery_set_mode
(
battery
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_battery_set_mode() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_battery_set_mode() failed
"
));
goto
end
;
}
result
=
acpi_battery_get_info
(
battery
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_battery_get_info() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_battery_get_info() failed
"
));
goto
end
;
}
result
=
acpi_battery_get_state
(
battery
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_battery_get_state() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_battery_get_state() failed
"
));
goto
end
;
}
result
=
acpi_battery_get_alarm
(
battery
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_battery_get_alarm() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_battery_get_alarm() failed
"
));
goto
end
;
}
...
...
@@ -813,20 +829,19 @@ static int acpi_battery_init(struct acpi_battery *battery)
static
int
acpi_ac_get_present
(
struct
acpi_sbs
*
sbs
)
{
struct
acpi_ec_smbus
*
smbus
=
sbs
->
smbus
;
int
result
=
0
;
s16
charger_status
;
result
=
acpi_sbs_
smbus_read_word
(
smbu
s
,
ACPI_SBC_SMBUS_ADDR
,
0x13
,
&
charger_status
,
NULL
);
result
=
acpi_sbs_
read_word
(
sb
s
,
ACPI_SBC_SMBUS_ADDR
,
0x13
,
&
charger_status
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_smbus_read_word() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_read_word() failed
"
));
goto
end
;
}
sbs
->
ac_present
=
(
charger_status
&
0x8000
)
>>
15
;
sbs
->
ac
.
ac
_present
=
(
charger_status
&
0x8000
)
>>
15
;
end:
...
...
@@ -852,8 +867,8 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
if
(
!*
dir
)
{
*
dir
=
proc_mkdir
(
dir_name
,
parent_dir
);
if
(
!*
dir
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"proc_mkdir() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"proc_mkdir() failed
"
));
return
-
ENODEV
;
}
(
*
dir
)
->
owner
=
THIS_MODULE
;
...
...
@@ -863,8 +878,8 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
if
(
info_fops
)
{
entry
=
create_proc_entry
(
ACPI_SBS_FILE_INFO
,
S_IRUGO
,
*
dir
);
if
(
!
entry
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"create_proc_entry() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"create_proc_entry() failed
"
));
}
else
{
entry
->
proc_fops
=
info_fops
;
entry
->
data
=
data
;
...
...
@@ -876,8 +891,8 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
if
(
state_fops
)
{
entry
=
create_proc_entry
(
ACPI_SBS_FILE_STATE
,
S_IRUGO
,
*
dir
);
if
(
!
entry
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"create_proc_entry() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"create_proc_entry() failed
"
));
}
else
{
entry
->
proc_fops
=
state_fops
;
entry
->
data
=
data
;
...
...
@@ -889,8 +904,8 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
if
(
alarm_fops
)
{
entry
=
create_proc_entry
(
ACPI_SBS_FILE_ALARM
,
S_IRUGO
,
*
dir
);
if
(
!
entry
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"create_proc_entry() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"create_proc_entry() failed
"
));
}
else
{
entry
->
proc_fops
=
alarm_fops
;
entry
->
data
=
data
;
...
...
@@ -923,24 +938,27 @@ static struct proc_dir_entry *acpi_battery_dir = NULL;
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
(
battery
->
sbs
->
zombie
)
{
if
(
sbs_mutex_lock
(
sbs
)
)
{
return
-
ENODEV
;
}
down
(
&
sbs_sem
);
result
=
acpi_check_update_proc
(
sbs
);
if
(
result
)
goto
end
;
if
(
update_
mode
==
REQUEST_UPDATE_MODE
)
{
result
=
acpi_sbs_update_run
(
battery
->
sbs
,
DATA_TYPE_INFO
);
if
(
update_
time
==
0
)
{
result
=
acpi_sbs_update_run
(
sbs
,
battery
->
id
,
DATA_TYPE_INFO
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_update_run() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_update_run() failed
"
));
}
}
if
(
acpi_battery_is_present
(
battery
)
)
{
if
(
battery
->
battery_present
)
{
seq_printf
(
seq
,
"present: yes
\n
"
);
}
else
{
seq_printf
(
seq
,
"present: no
\n
"
);
...
...
@@ -952,13 +970,13 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
}
else
{
cscale
=
battery
->
info
.
ipscale
;
}
seq_printf
(
seq
,
"design capacity: %i%s"
,
seq_printf
(
seq
,
"design capacity: %i%s
\n
"
,
battery
->
info
.
design_capacity
*
cscale
,
battery
->
info
.
capacity_mode
?
"0 mWh
\n
"
:
" mAh
\n
"
);
battery
->
info
.
capacity_mode
?
"0 mWh
"
:
" mAh
"
);
seq_printf
(
seq
,
"last full capacity: %i%s"
,
seq_printf
(
seq
,
"last full capacity: %i%s
\n
"
,
battery
->
info
.
full_charge_capacity
*
cscale
,
battery
->
info
.
capacity_mode
?
"0 mWh
\n
"
:
" mAh
\n
"
);
battery
->
info
.
capacity_mode
?
"0 mWh
"
:
" mAh
"
);
seq_printf
(
seq
,
"battery technology: rechargeable
\n
"
);
...
...
@@ -984,7 +1002,7 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
end:
up
(
&
sbs_sem
);
sbs_mutex_unlock
(
sbs
);
return
result
;
}
...
...
@@ -996,26 +1014,29 @@ static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
static
int
acpi_battery_read_state
(
struct
seq_file
*
seq
,
void
*
offset
)
{
struct
acpi_battery
*
battery
=
(
struct
acpi_battery
*
)
seq
->
private
;
struct
acpi_battery
*
battery
=
seq
->
private
;
struct
acpi_sbs
*
sbs
=
battery
->
sbs
;
int
result
=
0
;
int
cscale
;
int
foo
;
if
(
battery
->
sbs
->
zombie
)
{
if
(
sbs_mutex_lock
(
sbs
)
)
{
return
-
ENODEV
;
}
down
(
&
sbs_sem
);
result
=
acpi_check_update_proc
(
sbs
);
if
(
result
)
goto
end
;
if
(
update_
mode
==
REQUEST_UPDATE_MODE
)
{
result
=
acpi_sbs_update_run
(
battery
->
sbs
,
DATA_TYPE_STATE
);
if
(
update_
time
==
0
)
{
result
=
acpi_sbs_update_run
(
sbs
,
battery
->
id
,
DATA_TYPE_STATE
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_update_run() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_update_run() failed
"
));
}
}
if
(
acpi_battery_is_present
(
battery
)
)
{
if
(
battery
->
battery_present
)
{
seq_printf
(
seq
,
"present: yes
\n
"
);
}
else
{
seq_printf
(
seq
,
"present: no
\n
"
);
...
...
@@ -1028,7 +1049,7 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
cscale
=
battery
->
info
.
ipscale
;
}
if
(
battery
->
state
.
battery_stat
us
&
0x0010
)
{
if
(
battery
->
state
.
battery_stat
e
&
0x0010
)
{
seq_printf
(
seq
,
"capacity state: critical
\n
"
);
}
else
{
seq_printf
(
seq
,
"capacity state: ok
\n
"
);
...
...
@@ -1052,16 +1073,16 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
battery
->
info
.
capacity_mode
?
"mW"
:
"mA"
);
}
seq_printf
(
seq
,
"remaining capacity: %i%s"
,
seq_printf
(
seq
,
"remaining capacity: %i%s
\n
"
,
battery
->
state
.
remaining_capacity
*
cscale
,
battery
->
info
.
capacity_mode
?
"0 mWh
\n
"
:
" mAh
\n
"
);
battery
->
info
.
capacity_mode
?
"0 mWh
"
:
" mAh
"
);
seq_printf
(
seq
,
"present voltage: %i mV
\n
"
,
battery
->
state
.
voltage
*
battery
->
info
.
vscale
);
end:
up
(
&
sbs_sem
);
sbs_mutex_unlock
(
sbs
);
return
result
;
}
...
...
@@ -1074,24 +1095,27 @@ static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
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
(
battery
->
sbs
->
zombie
)
{
if
(
sbs_mutex_lock
(
sbs
)
)
{
return
-
ENODEV
;
}
down
(
&
sbs_sem
);
result
=
acpi_check_update_proc
(
sbs
);
if
(
result
)
goto
end
;
if
(
update_
mode
==
REQUEST_UPDATE_MODE
)
{
result
=
acpi_sbs_update_run
(
battery
->
sbs
,
DATA_TYPE_ALARM
);
if
(
update_
time
==
0
)
{
result
=
acpi_sbs_update_run
(
sbs
,
battery
->
id
,
DATA_TYPE_ALARM
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_update_run() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_update_run() failed
"
));
}
}
if
(
!
acpi_battery_is_present
(
battery
)
)
{
if
(
!
battery
->
battery_present
)
{
seq_printf
(
seq
,
"present: no
\n
"
);
goto
end
;
}
...
...
@@ -1104,16 +1128,16 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
seq_printf
(
seq
,
"alarm: "
);
if
(
battery
->
alarm
.
remaining_capacity
)
{
seq_printf
(
seq
,
"%i%s"
,
seq_printf
(
seq
,
"%i%s
\n
"
,
battery
->
alarm
.
remaining_capacity
*
cscale
,
battery
->
info
.
capacity_mode
?
"0 mWh
\n
"
:
" mAh
\n
"
);
battery
->
info
.
capacity_mode
?
"0 mWh
"
:
" mAh
"
);
}
else
{
seq_printf
(
seq
,
"disabled
\n
"
);
}
end:
up
(
&
sbs_sem
);
sbs_mutex_unlock
(
sbs
);
return
result
;
}
...
...
@@ -1124,16 +1148,19 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
{
struct
seq_file
*
seq
=
file
->
private_data
;
struct
acpi_battery
*
battery
=
seq
->
private
;
struct
acpi_sbs
*
sbs
=
battery
->
sbs
;
char
alarm_string
[
12
]
=
{
'\0'
};
int
result
,
old_alarm
,
new_alarm
;
if
(
battery
->
sbs
->
zombie
)
{
if
(
sbs_mutex_lock
(
sbs
)
)
{
return
-
ENODEV
;
}
down
(
&
sbs_sem
);
result
=
acpi_check_update_proc
(
sbs
);
if
(
result
)
goto
end
;
if
(
!
acpi_battery_is_present
(
battery
)
)
{
if
(
!
battery
->
battery_present
)
{
result
=
-
ENODEV
;
goto
end
;
}
...
...
@@ -1155,21 +1182,21 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
result
=
acpi_battery_set_alarm
(
battery
,
new_alarm
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_battery_set_alarm() failed
\n
"
));
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_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_battery_get_alarm() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_battery_get_alarm() failed
"
));
acpi_battery_set_alarm
(
battery
,
old_alarm
);
goto
end
;
}
end:
up
(
&
sbs_sem
);
sbs_mutex_unlock
(
sbs
);
if
(
result
)
{
return
result
;
...
...
@@ -1217,24 +1244,22 @@ static int acpi_ac_read_state(struct seq_file *seq, void *offset)
struct
acpi_sbs
*
sbs
=
seq
->
private
;
int
result
;
if
(
sbs
->
zombie
)
{
if
(
sbs
_mutex_lock
(
sbs
)
)
{
return
-
ENODEV
;
}
down
(
&
sbs_sem
);
if
(
update_mode
==
REQUEST_UPDATE_MODE
)
{
result
=
acpi_sbs_update_run
(
sbs
,
DATA_TYPE_AC_STATE
);
if
(
update_time
==
0
)
{
result
=
acpi_sbs_update_run
(
sbs
,
-
1
,
DATA_TYPE_AC_STATE
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_update_run() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_update_run() failed
"
));
}
}
seq_printf
(
seq
,
"state: %s
\n
"
,
sbs
->
ac_present
?
"on-line"
:
"off-line"
);
sbs
->
ac
.
ac
_present
?
"on-line"
:
"off-line"
);
up
(
&
sbs_sem
);
sbs_mutex_unlock
(
sbs
);
return
0
;
}
...
...
@@ -1275,25 +1300,25 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
result
=
acpi_battery_select
(
battery
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_battery_select() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_battery_select() failed
"
));
goto
end
;
}
result
=
acpi_battery_get_present
(
battery
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_battery_get_present() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_battery_get_present() failed
"
));
goto
end
;
}
is_present
=
acpi_battery_is_present
(
battery
)
;
is_present
=
battery
->
battery_present
;
if
(
is_present
)
{
result
=
acpi_battery_init
(
battery
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_battery_init() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_battery_init() failed
"
));
goto
end
;
}
battery
->
init_state
=
1
;
...
...
@@ -1308,12 +1333,16 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
&
acpi_battery_state_fops
,
&
acpi_battery_alarm_fops
,
battery
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_generic_add_fs() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_generic_add_fs() failed
"
));
goto
end
;
}
battery
->
alive
=
1
;
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"
);
end:
return
result
;
}
...
...
@@ -1333,8 +1362,8 @@ static int acpi_ac_add(struct acpi_sbs *sbs)
result
=
acpi_ac_get_present
(
sbs
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_ac_get_present() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_ac_get_present() failed
"
));
goto
end
;
}
...
...
@@ -1343,11 +1372,15 @@ static int acpi_ac_add(struct acpi_sbs *sbs)
ACPI_AC_DIR_NAME
,
NULL
,
&
acpi_ac_state_fops
,
NULL
,
sbs
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_generic_add_fs() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_generic_add_fs() failed
"
));
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
->
ac
.
ac_present
?
"on-line"
:
"off-line"
);
end:
return
result
;
...
...
@@ -1361,45 +1394,85 @@ static void acpi_ac_remove(struct acpi_sbs *sbs)
}
}
static
void
acpi_sbs_update_
queu
e_run
(
unsigned
long
data
)
static
void
acpi_sbs_update_
tim
e_run
(
unsigned
long
data
)
{
acpi_os_execute
(
OSL_GPE_HANDLER
,
acpi_sbs_update_
queu
e
,
(
void
*
)
data
);
acpi_os_execute
(
OSL_GPE_HANDLER
,
acpi_sbs_update_
tim
e
,
(
void
*
)
data
);
}
static
int
acpi_sbs_update_run
(
struct
acpi_sbs
*
sbs
,
int
data_type
)
static
int
acpi_sbs_update_run
(
struct
acpi_sbs
*
sbs
,
int
id
,
int
data_type
)
{
struct
acpi_battery
*
battery
;
int
result
=
0
;
int
old_ac_present
;
int
old_battery_present
;
int
new_ac_present
;
int
new_battery_present
;
int
id
;
int
result
=
0
,
cnt
;
int
old_ac_present
=
-
1
;
int
old_battery_present
=
-
1
;
int
new_ac_present
=
-
1
;
int
new_battery_present
=
-
1
;
int
id
_min
=
0
,
id_max
=
MAX_SBS_BAT
-
1
;
char
dir_name
[
32
];
int
do_battery_init
,
do_ac_init
;
s16
old_remaining_capacity
;
int
do_battery_init
=
0
,
do_ac_init
=
0
;
int
old_remaining_capacity
=
0
;
int
update_ac
=
1
,
update_battery
=
1
;
int
up_tm
=
update_time
;
if
(
sbs
->
zombie
)
{
if
(
sbs
_zombie
(
sbs
)
)
{
goto
end
;
}
old_ac_present
=
acpi_ac_is_present
(
sbs
);
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_ac
&&
!
update_battery
)
{
goto
end
;
}
old_ac_present
=
sbs
->
ac
.
ac_present
;
result
=
acpi_ac_get_present
(
sbs
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_ac_get_present() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_ac_get_present() failed
"
));
}
new_ac_present
=
acpi_ac_is_present
(
sbs
)
;
new_ac_present
=
sbs
->
ac
.
ac_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
(
data_type
==
DATA_TYPE_AC_STATE
)
{
if
(
do_ac_init
)
{
result
=
acpi_sbs_generate_event
(
sbs
->
device
,
ACPI_SBS_AC_NOTIFY_STATUS
,
new_ac_present
,
ACPI_AC_DIR_NAME
,
ACPI_AC_CLASS
);
if
(
result
)
{
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"acpi_sbs_generate_event() failed"
));
}
}
if
(
data_type
==
DATA_TYPE_COMMON
)
{
if
(
!
do_ac_init
&&
!
update_battery
)
{
goto
end
;
}
}
if
(
data_type
==
DATA_TYPE_AC_STATE
&&
!
do_ac_init
)
{
goto
end
;
}
for
(
id
=
0
;
id
<
MAX_SBS_BAT
;
id
++
)
{
for
(
id
=
id_min
;
id
<=
id_max
;
id
++
)
{
battery
=
&
sbs
->
battery
[
id
];
if
(
battery
->
alive
==
0
)
{
continue
;
...
...
@@ -1407,94 +1480,92 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
old_remaining_capacity
=
battery
->
state
.
remaining_capacity
;
old_battery_present
=
acpi_battery_is_present
(
battery
)
;
old_battery_present
=
battery
->
battery_present
;
result
=
acpi_battery_select
(
battery
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_battery_select() failed
\n
"
));
}
if
(
sbs
->
zombie
)
{
goto
end
;
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"acpi_battery_select() failed"
));
}
result
=
acpi_battery_get_present
(
battery
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_battery_get_present() failed
\n
"
));
}
if
(
sbs
->
zombie
)
{
goto
end
;
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"acpi_battery_get_present() failed"
));
}
new_battery_present
=
acpi_battery_is_present
(
battery
)
;
new_battery_present
=
battery
->
battery_present
;
do_battery_init
=
((
old_battery_present
!=
new_battery_present
)
&&
new_battery_present
);
if
(
sbs
->
zombie
)
{
if
(
!
new_battery_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
(
do_ac_init
||
do_battery_init
||
update_info_mode
||
sbs
->
update_info_mode
)
{
if
(
sbs
->
update_info_mode
)
{
sbs
->
update_info_mode
=
0
;
}
else
{
sbs
->
update_info_mode
=
1
;
}
result
=
acpi_battery_init
(
battery
);
if
((
data_type
==
DATA_TYPE_COMMON
||
data_type
==
DATA_TYPE_INFO
)
&&
new_battery_present
)
{
result
=
acpi_battery_get_info
(
battery
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_battery_init() "
"failed
\n
"
));
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"acpi_battery_get_info() failed"
));
}
}
if
(
data_type
==
DATA_TYPE_INFO
)
{
continue
;
}
if
(
sbs
->
zombie
)
{
if
(
sbs_zombie
(
sbs
))
{
goto
end
;
}
if
(
new_battery_present
)
{
result
=
acpi_battery_get_alarm
(
battery
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_battery_get_alarm() "
"failed
\n
"
));
}
if
(
data_type
==
DATA_TYPE_ALARM
)
{
continue
;
}
if
((
data_type
==
DATA_TYPE_COMMON
||
data_type
==
DATA_TYPE_STATE
)
&&
new_battery_present
)
{
result
=
acpi_battery_get_state
(
battery
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_battery_get_state() "
"failed
\n
"
));
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"acpi_battery_get_state() failed"
));
}
}
if
(
sbs
->
zombie
)
{
goto
e
nd
;
if
(
data_type
==
DATA_TYPE_STATE
)
{
goto
e
vent
;
}
if
(
data_type
!=
DATA_TYPE_COMMON
)
{
continue
;
if
(
sbs_zombie
(
sbs
)
)
{
goto
end
;
}
if
(
old_battery_present
!=
new_battery_present
)
{
sprintf
(
dir_name
,
ACPI_BATTERY_DIR_NAME
,
id
);
result
=
acpi_sbs_generate_event
(
sbs
->
device
,
ACPI_SBS_BATTERY_NOTIFY_STATUS
,
new_battery_present
,
dir_name
,
ACPI_BATTERY_CLASS
);
if
((
data_type
==
DATA_TYPE_COMMON
||
data_type
==
DATA_TYPE_ALARM
)
&&
new_battery_present
)
{
result
=
acpi_battery_get_alarm
(
battery
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_generate_event
() "
"failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_battery_get_alarm
() "
"failed
"
));
}
}
if
(
old_remaining_capacity
!=
battery
->
state
.
remaining_capacity
)
{
if
(
data_type
==
DATA_TYPE_ALARM
)
{
continue
;
}
if
(
sbs_zombie
(
sbs
))
{
goto
end
;
}
event:
if
(
old_battery_present
!=
new_battery_present
||
do_ac_init
||
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
,
...
...
@@ -1502,138 +1573,120 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
dir_name
,
ACPI_BATTERY_CLASS
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_sbs_generate_event() failed
\n
"
));
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"acpi_sbs_generate_event() "
"failed"
));
}
}
}
if
(
sbs
->
zombie
)
{
goto
end
;
}
if
(
data_type
!=
DATA_TYPE_COMMON
)
{
goto
end
;
}
if
(
old_ac_present
!=
new_ac_present
)
{
result
=
acpi_sbs_generate_event
(
sbs
->
device
,
ACPI_SBS_AC_NOTIFY_STATUS
,
new_ac_present
,
ACPI_AC_DIR_NAME
,
ACPI_AC_CLASS
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_sbs_generate_event() failed
\n
"
));
}
}
end:
return
result
;
}
static
void
acpi_sbs_update_
queu
e
(
void
*
data
)
static
void
acpi_sbs_update_
tim
e
(
void
*
data
)
{
struct
acpi_sbs
*
sbs
=
data
;
unsigned
long
delay
=
-
1
;
int
result
;
unsigned
int
up_tm
=
update_time
;
if
(
sbs
->
zombie
)
{
goto
end
;
}
if
(
sbs_mutex_lock
(
sbs
))
return
;
result
=
acpi_sbs_update_run
(
sbs
,
DATA_TYPE_COMMON
);
result
=
acpi_sbs_update_run
(
sbs
,
-
1
,
DATA_TYPE_COMMON
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_update_run() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_update_run() failed
"
));
}
if
(
sbs
->
zombie
)
{
if
(
sbs
_zombie
(
sbs
)
)
{
goto
end
;
}
if
(
update_mode
==
REQUEST_UPDATE_MODE
)
{
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
);
}
}
delay
=
jiffies
+
HZ
*
update_time
;
sbs
->
update_timer
.
data
=
(
unsigned
long
)
data
;
sbs
->
update_timer
.
function
=
acpi_sbs_update_queue_run
;
sbs
->
update_timer
.
expires
=
delay
;
add_timer
(
&
sbs
->
update_timer
);
end:
;
sbs_mutex_unlock
(
sbs
);
}
static
int
acpi_sbs_add
(
struct
acpi_device
*
device
)
{
struct
acpi_sbs
*
sbs
=
NULL
;
struct
acpi_ec_hc
*
ec_hc
=
NULL
;
int
result
,
remove_result
=
0
;
int
result
=
0
,
remove_result
=
0
;
unsigned
long
sbs_obj
;
int
id
,
cnt
;
int
id
;
acpi_status
status
=
AE_OK
;
unsigned
long
val
;
status
=
acpi_evaluate_integer
(
device
->
parent
->
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
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"kmalloc() failed
\n
"
));
return
-
ENOMEM
;
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"kzalloc() failed"
));
result
=
-
ENOMEM
;
goto
end
;
}
cnt
=
0
;
while
(
cnt
<
10
)
{
cnt
++
;
ec_hc
=
acpi_get_ec_hc
(
device
);
if
(
ec_hc
)
{
break
;
}
msleep
(
1000
);
}
mutex_init
(
&
sbs
->
mutex
);
if
(
!
ec_hc
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_get_ec_hc() failed: "
"NO driver found for EC HC SMBus
\n
"
));
result
=
-
ENODEV
;
goto
end
;
}
sbs_mutex_lock
(
sbs
);
sbs
->
base
=
(
val
&
0xff00ull
)
>>
8
;
sbs
->
device
=
device
;
sbs
->
smbus
=
ec_hc
->
smbus
;
strcpy
(
acpi_device_name
(
device
),
ACPI_SBS_DEVICE_NAME
);
strcpy
(
acpi_device_class
(
device
),
ACPI_SBS_CLASS
);
acpi_driver_data
(
device
)
=
sbs
;
sbs
->
update_time
=
0
;
sbs
->
update_time2
=
0
;
result
=
acpi_ac_add
(
sbs
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_ac_add() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"acpi_ac_add() failed
"
));
goto
end
;
}
result
=
acpi_evaluate_integer
(
device
->
handle
,
"_SBS"
,
NULL
,
&
sbs_obj
);
if
(
ACPI_FAILURE
(
result
)
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_evaluate_integer() failed
\n
"
));
status
=
acpi_evaluate_integer
(
device
->
handle
,
"_SBS"
,
NULL
,
&
sbs_obj
);
if
(
status
)
{
ACPI_
EXCEPTION
((
AE_INFO
,
status
,
"acpi_evaluate_integer() failed
"
));
result
=
-
EIO
;
goto
end
;
}
if
(
sbs_obj
>
0
)
{
result
=
acpi_sbsm_get_info
(
sbs
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbsm_get_info() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbsm_get_info() failed
"
));
goto
end
;
}
sbs
->
sbsm_present
=
1
;
}
if
(
sbs
->
sbsm_present
==
0
)
{
result
=
acpi_battery_add
(
sbs
,
0
);
if
(
result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_battery_add() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_battery_add() failed
"
));
goto
end
;
}
}
else
{
...
...
@@ -1641,9 +1694,8 @@ static int acpi_sbs_add(struct acpi_device *device)
if
((
sbs
->
sbsm_batteries_supported
&
(
1
<<
id
)))
{
result
=
acpi_battery_add
(
sbs
,
id
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_battery_add() "
"failed
\n
"
));
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"acpi_battery_add() failed"
));
goto
end
;
}
}
...
...
@@ -1653,33 +1705,26 @@ static int acpi_sbs_add(struct acpi_device *device)
sbs
->
handle
=
device
->
handle
;
init_timer
(
&
sbs
->
update_timer
);
if
(
update_mode
==
QUEUE_UPDATE_MODE
)
{
status
=
acpi_os_execute
(
OSL_GPE_HANDLER
,
acpi_sbs_update_queue
,
sbs
);
if
(
status
!=
AE_OK
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_os_execute() failed
\n
"
));
}
}
sbs
->
update_time
=
update_time
;
sbs
->
update_time2
=
update_time2
;
printk
(
KERN_INFO
PREFIX
"%s [%s]
\n
"
,
acpi_device_name
(
device
),
acpi_device_bid
(
device
));
result
=
acpi_check_update_proc
(
sbs
);
if
(
result
)
goto
end
;
end:
sbs_mutex_unlock
(
sbs
);
if
(
result
)
{
remove_result
=
acpi_sbs_remove
(
device
,
0
);
if
(
remove_result
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_sbs_remove() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_sbs_remove() failed
"
));
}
}
return
result
;
}
int
acpi_sbs_remove
(
struct
acpi_device
*
device
,
int
type
)
static
int
acpi_sbs_remove
(
struct
acpi_device
*
device
,
int
type
)
{
struct
acpi_sbs
*
sbs
;
int
id
;
...
...
@@ -1688,15 +1733,14 @@ int acpi_sbs_remove(struct acpi_device *device, int type)
return
-
EINVAL
;
}
sbs
=
(
struct
acpi_sbs
*
)
acpi_driver_data
(
device
);
sbs
=
acpi_driver_data
(
device
);
if
(
!
sbs
)
{
return
-
EINVAL
;
}
sbs_mutex_lock
(
sbs
);
sbs
->
zombie
=
1
;
sbs
->
update_time
=
0
;
sbs
->
update_time2
=
0
;
del_timer_sync
(
&
sbs
->
update_timer
);
acpi_os_wait_events_complete
(
NULL
);
del_timer_sync
(
&
sbs
->
update_timer
);
...
...
@@ -1707,11 +1751,41 @@ int acpi_sbs_remove(struct acpi_device *device, int type)
acpi_ac_remove
(
sbs
);
sbs_mutex_unlock
(
sbs
);
mutex_destroy
(
&
sbs
->
mutex
);
kfree
(
sbs
);
return
0
;
}
static
void
acpi_sbs_rmdirs
(
void
)
{
if
(
acpi_ac_dir
)
{
acpi_unlock_ac_dir
(
acpi_ac_dir
);
acpi_ac_dir
=
NULL
;
}
if
(
acpi_battery_dir
)
{
acpi_unlock_battery_dir
(
acpi_battery_dir
);
acpi_battery_dir
=
NULL
;
}
}
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
;
return
0
;
}
static
int
__init
acpi_sbs_init
(
void
)
{
int
result
=
0
;
...
...
@@ -1719,35 +1793,34 @@ static int __init acpi_sbs_init(void)
if
(
acpi_disabled
)
return
-
ENODEV
;
init_MUTEX
(
&
sbs_sem
);
if
(
capacity_mode
!=
DEF_CAPACITY_UNIT
&&
capacity_mode
!=
MAH_CAPACITY_UNIT
&&
capacity_mode
!=
MWH_CAPACITY_UNIT
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_sbs_init: "
"invalid capacity_mode = %d
\n
"
,
capacity_mode
));
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"invalid capacity_mode = %d"
,
capacity_mode
));
return
-
EINVAL
;
}
acpi_ac_dir
=
acpi_lock_ac_dir
();
if
(
!
acpi_ac_dir
)
{
ACPI_
DEBUG_PRINT
((
ACPI_DB
_ERROR
,
"acpi_lock_ac_dir() failed
\n
"
));
ACPI_
EXCEPTION
((
AE_INFO
,
AE
_ERROR
,
"acpi_lock_ac_dir() failed
"
));
return
-
ENODEV
;
}
acpi_battery_dir
=
acpi_lock_battery_dir
();
if
(
!
acpi_battery_dir
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_lock_battery_dir() failed
\n
"
));
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_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"acpi_bus_register_driver() failed
\n
"
));
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"acpi_bus_register_driver() failed"
));
acpi_sbs_rmdirs
();
return
-
ENODEV
;
}
...
...
@@ -1756,13 +1829,9 @@ static int __init acpi_sbs_init(void)
static
void
__exit
acpi_sbs_exit
(
void
)
{
acpi_bus_unregister_driver
(
&
acpi_sbs_driver
);
acpi_unlock_ac_dir
(
acpi_ac_dir
);
acpi_ac_dir
=
NULL
;
acpi_unlock_battery_dir
(
acpi_battery_dir
);
acpi_battery_dir
=
NULL
;
acpi_sbs_rmdirs
();
return
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment