Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci-2.6.23
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci-2.6.23
Commits
8269cc4e
Commit
8269cc4e
authored
Jul 22, 2007
by
Len Brown
Browse files
Options
Browse Files
Download
Plain Diff
Pull battery into release branch
parents
939ab201
78490d82
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
438 additions
and
235 deletions
+438
-235
drivers/acpi/battery.c
drivers/acpi/battery.c
+438
-235
No files found.
drivers/acpi/battery.c
View file @
8269cc4e
...
...
@@ -43,21 +43,30 @@
#define ACPI_BATTERY_CLASS "battery"
#define ACPI_BATTERY_HID "PNP0C0A"
#define ACPI_BATTERY_DEVICE_NAME "Battery"
#define ACPI_BATTERY_FILE_INFO "info"
#define ACPI_BATTERY_FILE_STATUS "state"
#define ACPI_BATTERY_FILE_ALARM "alarm"
#define ACPI_BATTERY_NOTIFY_STATUS 0x80
#define ACPI_BATTERY_NOTIFY_INFO 0x81
#define ACPI_BATTERY_UNITS_WATTS "mW"
#define ACPI_BATTERY_UNITS_AMPS "mA"
#define _COMPONENT ACPI_BATTERY_COMPONENT
#define ACPI_BATTERY_UPDATE_TIME 0
#define ACPI_BATTERY_NONE_UPDATE 0
#define ACPI_BATTERY_EASY_UPDATE 1
#define ACPI_BATTERY_INIT_UPDATE 2
ACPI_MODULE_NAME
(
"battery"
);
MODULE_AUTHOR
(
"Paul Diefenbaugh"
);
MODULE_DESCRIPTION
(
"ACPI Battery Driver"
);
MODULE_LICENSE
(
"GPL"
);
static
unsigned
int
update_time
=
ACPI_BATTERY_UPDATE_TIME
;
/* 0 - every time, > 0 - by update_time */
module_param
(
update_time
,
uint
,
0644
);
extern
struct
proc_dir_entry
*
acpi_lock_battery_dir
(
void
);
extern
void
*
acpi_unlock_battery_dir
(
struct
proc_dir_entry
*
acpi_battery_dir
);
...
...
@@ -76,7 +85,7 @@ static struct acpi_driver acpi_battery_driver = {
},
};
struct
acpi_battery_stat
us
{
struct
acpi_battery_stat
e
{
acpi_integer
state
;
acpi_integer
present_rate
;
acpi_integer
remaining_capacity
;
...
...
@@ -99,33 +108,111 @@ struct acpi_battery_info {
acpi_string
oem_info
;
};
struct
acpi_battery_flags
{
u8
present
:
1
;
/* Bay occupied? */
u8
power_unit
:
1
;
/* 0=watts, 1=apms */
u8
alarm
:
1
;
/* _BTP present? */
u8
reserved
:
5
;
enum
acpi_battery_files
{
ACPI_BATTERY_INFO
=
0
,
ACPI_BATTERY_STATE
,
ACPI_BATTERY_ALARM
,
ACPI_BATTERY_NUMFILES
,
};
struct
acpi_battery_trips
{
unsigned
long
warning
;
unsigned
long
low
;
struct
acpi_battery_flags
{
u8
battery_present_prev
;
u8
alarm_present
;
u8
init_update
;
u8
update
[
ACPI_BATTERY_NUMFILES
];
u8
power_unit
;
};
struct
acpi_battery
{
struct
acpi_device
*
device
;
struct
mutex
mutex
;
struct
acpi_device
*
device
;
struct
acpi_battery_flags
flags
;
struct
acpi_battery_trips
trips
;
struct
acpi_buffer
bif_data
;
struct
acpi_buffer
bst_data
;
unsigned
long
alarm
;
struct
acpi_battery_info
*
info
;
unsigned
long
update_time
[
ACPI_BATTERY_NUMFILES
]
;
};
inline
int
acpi_battery_present
(
struct
acpi_battery
*
battery
)
{
return
battery
->
device
->
status
.
battery_present
;
}
inline
char
*
acpi_battery_power_units
(
struct
acpi_battery
*
battery
)
{
if
(
battery
->
flags
.
power_unit
)
return
ACPI_BATTERY_UNITS_AMPS
;
else
return
ACPI_BATTERY_UNITS_WATTS
;
}
inline
acpi_handle
acpi_battery_handle
(
struct
acpi_battery
*
battery
)
{
return
battery
->
device
->
handle
;
}
/* --------------------------------------------------------------------------
Battery Management
-------------------------------------------------------------------------- */
static
int
acpi_battery_get_info
(
struct
acpi_battery
*
battery
,
struct
acpi_battery_info
**
bif
)
static
void
acpi_battery_check_result
(
struct
acpi_battery
*
battery
,
int
result
)
{
if
(
!
battery
)
return
;
if
(
result
)
{
battery
->
flags
.
init_update
=
1
;
}
}
static
int
acpi_battery_extract_package
(
struct
acpi_battery
*
battery
,
union
acpi_object
*
package
,
struct
acpi_buffer
*
format
,
struct
acpi_buffer
*
data
,
char
*
package_name
)
{
acpi_status
status
=
AE_OK
;
struct
acpi_buffer
data_null
=
{
0
,
NULL
};
status
=
acpi_extract_package
(
package
,
format
,
&
data_null
);
if
(
status
!=
AE_BUFFER_OVERFLOW
)
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"Extracting size %s"
,
package_name
));
return
-
ENODEV
;
}
if
(
data_null
.
length
!=
data
->
length
)
{
kfree
(
data
->
pointer
);
data
->
pointer
=
kzalloc
(
data_null
.
length
,
GFP_KERNEL
);
if
(
!
data
->
pointer
)
{
ACPI_EXCEPTION
((
AE_INFO
,
AE_NO_MEMORY
,
"kzalloc()"
));
return
-
ENOMEM
;
}
data
->
length
=
data_null
.
length
;
}
status
=
acpi_extract_package
(
package
,
format
,
data
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"Extracting %s"
,
package_name
));
return
-
ENODEV
;
}
return
0
;
}
static
int
acpi_battery_get_status
(
struct
acpi_battery
*
battery
)
{
int
result
=
0
;
result
=
acpi_bus_get_status
(
battery
->
device
);
if
(
result
)
{
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"Evaluating _STA"
));
return
-
ENODEV
;
}
return
result
;
}
static
int
acpi_battery_get_info
(
struct
acpi_battery
*
battery
)
{
int
result
=
0
;
acpi_status
status
=
0
;
...
...
@@ -133,16 +220,20 @@ acpi_battery_get_info(struct acpi_battery *battery,
struct
acpi_buffer
format
=
{
sizeof
(
ACPI_BATTERY_FORMAT_BIF
),
ACPI_BATTERY_FORMAT_BIF
};
struct
acpi_buffer
data
=
{
0
,
NULL
};
union
acpi_object
*
package
=
NULL
;
struct
acpi_buffer
*
data
=
NULL
;
struct
acpi_battery_info
*
bif
=
NULL
;
battery
->
update_time
[
ACPI_BATTERY_INFO
]
=
get_seconds
();
if
(
!
battery
||
!
bif
)
return
-
EINVAL
;
if
(
!
acpi_battery_present
(
battery
)
)
return
0
;
/* Evalute _BIF */
/* Evalu
a
te _BIF */
status
=
acpi_evaluate_object
(
battery
->
device
->
handle
,
"_BIF"
,
NULL
,
&
buffer
);
status
=
acpi_evaluate_object
(
acpi_battery_handle
(
battery
),
"_BIF"
,
NULL
,
&
buffer
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"Evaluating _BIF"
));
return
-
ENODEV
;
...
...
@@ -150,41 +241,29 @@ acpi_battery_get_info(struct acpi_battery *battery,
package
=
buffer
.
pointer
;
/* Extract Package Data */
status
=
acpi_extract_package
(
package
,
&
format
,
&
data
);
if
(
status
!=
AE_BUFFER_OVERFLOW
)
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"Extracting _BIF"
));
result
=
-
ENODEV
;
goto
end
;
}
data
=
&
battery
->
bif_data
;
data
.
pointer
=
kzalloc
(
data
.
length
,
GFP_KERNEL
);
if
(
!
data
.
pointer
)
{
result
=
-
ENOMEM
;
goto
end
;
}
/* Extract Package Data */
status
=
acpi_extract_package
(
package
,
&
format
,
&
data
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"Extracting _BIF"
));
kfree
(
data
.
pointer
);
result
=
-
ENODEV
;
result
=
acpi_battery_extract_package
(
battery
,
package
,
&
format
,
data
,
"_BIF"
);
if
(
result
)
goto
end
;
}
end:
kfree
(
buffer
.
pointer
);
if
(
!
result
)
(
*
bif
)
=
data
.
pointer
;
if
(
!
result
)
{
bif
=
data
->
pointer
;
battery
->
flags
.
power_unit
=
bif
->
power_unit
;
}
return
result
;
}
static
int
acpi_battery_get_status
(
struct
acpi_battery
*
battery
,
struct
acpi_battery_status
**
bst
)
static
int
acpi_battery_get_state
(
struct
acpi_battery
*
battery
)
{
int
result
=
0
;
acpi_status
status
=
0
;
...
...
@@ -192,16 +271,19 @@ acpi_battery_get_status(struct acpi_battery *battery,
struct
acpi_buffer
format
=
{
sizeof
(
ACPI_BATTERY_FORMAT_BST
),
ACPI_BATTERY_FORMAT_BST
};
struct
acpi_buffer
data
=
{
0
,
NULL
};
union
acpi_object
*
package
=
NULL
;
struct
acpi_buffer
*
data
=
NULL
;
battery
->
update_time
[
ACPI_BATTERY_STATE
]
=
get_seconds
();
if
(
!
battery
||
!
bst
)
return
-
EINVAL
;
if
(
!
acpi_battery_present
(
battery
)
)
return
0
;
/* Evalute _BST */
/* Evalu
a
te _BST */
status
=
acpi_evaluate_object
(
battery
->
device
->
handle
,
"_BST"
,
NULL
,
&
buffer
);
status
=
acpi_evaluate_object
(
acpi_battery_handle
(
battery
),
"_BST"
,
NULL
,
&
buffer
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"Evaluating _BST"
));
return
-
ENODEV
;
...
...
@@ -209,55 +291,49 @@ acpi_battery_get_status(struct acpi_battery *battery,
package
=
buffer
.
pointer
;
/* Extract Package Data */
status
=
acpi_extract_package
(
package
,
&
format
,
&
data
);
if
(
status
!=
AE_BUFFER_OVERFLOW
)
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"Extracting _BST"
));
result
=
-
ENODEV
;
goto
end
;
}
data
=
&
battery
->
bst_data
;
data
.
pointer
=
kzalloc
(
data
.
length
,
GFP_KERNEL
);
if
(
!
data
.
pointer
)
{
result
=
-
ENOMEM
;
goto
end
;
}
/* Extract Package Data */
status
=
acpi_extract_package
(
package
,
&
format
,
&
data
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"Extracting _BST"
));
kfree
(
data
.
pointer
);
result
=
-
ENODEV
;
result
=
acpi_battery_extract_package
(
battery
,
package
,
&
format
,
data
,
"_BST"
);
if
(
result
)
goto
end
;
}
end:
kfree
(
buffer
.
pointer
);
if
(
!
result
)
(
*
bst
)
=
data
.
pointer
;
return
result
;
}
static
int
acpi_battery_set_alarm
(
struct
acpi_battery
*
battery
,
unsigned
long
alarm
)
static
int
acpi_battery_get_alarm
(
struct
acpi_battery
*
battery
)
{
battery
->
update_time
[
ACPI_BATTERY_ALARM
]
=
get_seconds
();
return
0
;
}
static
int
acpi_battery_set_alarm
(
struct
acpi_battery
*
battery
,
unsigned
long
alarm
)
{
acpi_status
status
=
0
;
union
acpi_object
arg0
=
{
ACPI_TYPE_INTEGER
};
struct
acpi_object_list
arg_list
=
{
1
,
&
arg0
};
battery
->
update_time
[
ACPI_BATTERY_ALARM
]
=
get_seconds
();
if
(
!
battery
)
return
-
E
INVAL
;
if
(
!
acpi_battery_present
(
battery
)
)
return
-
E
NODEV
;
if
(
!
battery
->
flags
.
alarm
)
if
(
!
battery
->
flags
.
alarm
_present
)
return
-
ENODEV
;
arg0
.
integer
.
value
=
alarm
;
status
=
acpi_evaluate_object
(
battery
->
device
->
handle
,
"_BTP"
,
&
arg_list
,
NULL
);
status
=
acpi_evaluate_object
(
acpi_battery_handle
(
battery
),
"_BTP"
,
&
arg_list
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
return
-
ENODEV
;
...
...
@@ -268,65 +344,114 @@ acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm)
return
0
;
}
static
int
acpi_battery_
check
(
struct
acpi_battery
*
battery
)
static
int
acpi_battery_
init_alarm
(
struct
acpi_battery
*
battery
)
{
int
result
=
0
;
acpi_status
status
=
AE_OK
;
acpi_handle
handle
=
NULL
;
struct
acpi_
device
*
device
=
NULL
;
struct
acpi_battery_info
*
bif
=
NULL
;
struct
acpi_
battery_info
*
bif
=
battery
->
bif_data
.
pointer
;
unsigned
long
alarm
=
battery
->
alarm
;
/* See if alarms are supported, and if so, set default */
if
(
!
battery
)
return
-
EINVAL
;
device
=
battery
->
device
;
status
=
acpi_get_handle
(
acpi_battery_handle
(
battery
),
"_BTP"
,
&
handle
);
if
(
ACPI_SUCCESS
(
status
))
{
battery
->
flags
.
alarm_present
=
1
;
if
(
!
alarm
&&
bif
)
{
alarm
=
bif
->
design_capacity_warning
;
}
result
=
acpi_battery_set_alarm
(
battery
,
alarm
);
if
(
result
)
goto
end
;
}
else
{
battery
->
flags
.
alarm_present
=
0
;
}
result
=
acpi_bus_get_status
(
device
);
if
(
result
)
return
result
;
end:
/* Insertion? */
return
result
;
}
if
(
!
battery
->
flags
.
present
&&
device
->
status
.
battery_present
)
{
static
int
acpi_battery_init_update
(
struct
acpi_battery
*
battery
)
{
int
result
=
0
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Battery inserted
\n
"
));
result
=
acpi_battery_get_status
(
battery
);
if
(
result
)
return
result
;
/* Evalute _BIF to get certain static information */
battery
->
flags
.
battery_present_prev
=
acpi_battery_present
(
battery
);
result
=
acpi_battery_get_info
(
battery
,
&
bif
);
if
(
acpi_battery_present
(
battery
))
{
result
=
acpi_battery_get_info
(
battery
);
if
(
result
)
return
result
;
result
=
acpi_battery_get_state
(
battery
);
if
(
result
)
return
result
;
battery
->
flags
.
power_unit
=
bif
->
power_unit
;
battery
->
trips
.
warning
=
bif
->
design_capacity_warning
;
battery
->
trips
.
low
=
bif
->
design_capacity_low
;
kfree
(
bif
);
acpi_battery_init_alarm
(
battery
);
}
return
result
;
}
/* See if alarms are supported, and if so, set default */
static
int
acpi_battery_update
(
struct
acpi_battery
*
battery
,
int
update
,
int
*
update_result_ptr
)
{
int
result
=
0
;
int
update_result
=
ACPI_BATTERY_NONE_UPDATE
;
if
(
!
acpi_battery_present
(
battery
))
{
update
=
1
;
}
status
=
acpi_get_handle
(
battery
->
device
->
handle
,
"_BTP"
,
&
handle
);
if
(
ACPI_SUCCESS
(
status
))
{
battery
->
flags
.
alarm
=
1
;
acpi_battery_set_alarm
(
battery
,
battery
->
trips
.
warning
);
if
(
battery
->
flags
.
init_update
)
{
result
=
acpi_battery_init_update
(
battery
);
if
(
result
)
goto
end
;
update_result
=
ACPI_BATTERY_INIT_UPDATE
;
}
else
if
(
update
)
{
result
=
acpi_battery_get_status
(
battery
);
if
(
result
)
goto
end
;
if
((
!
battery
->
flags
.
battery_present_prev
&
acpi_battery_present
(
battery
))
||
(
battery
->
flags
.
battery_present_prev
&
!
acpi_battery_present
(
battery
)))
{
result
=
acpi_battery_init_update
(
battery
);
if
(
result
)
goto
end
;
update_result
=
ACPI_BATTERY_INIT_UPDATE
;
}
else
{
update_result
=
ACPI_BATTERY_EASY_UPDATE
;
}
}
/* Removal? */
end:
else
if
(
battery
->
flags
.
present
&&
!
device
->
status
.
battery_present
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Battery removed
\n
"
));
}
battery
->
flags
.
init_update
=
(
result
!=
0
);
battery
->
flags
.
present
=
device
->
status
.
battery_presen
t
;
*
update_result_ptr
=
update_resul
t
;
return
result
;
}
static
void
acpi_battery_
check_present
(
struct
acpi_battery
*
battery
)
static
void
acpi_battery_
notify_update
(
struct
acpi_battery
*
battery
)
{
if
(
!
battery
->
flags
.
present
)
{
acpi_battery_check
(
battery
);
acpi_battery_get_status
(
battery
);
if
(
battery
->
flags
.
init_update
)
{
return
;
}
if
((
!
battery
->
flags
.
battery_present_prev
&
acpi_battery_present
(
battery
))
||
(
battery
->
flags
.
battery_present_prev
&
!
acpi_battery_present
(
battery
)))
{
battery
->
flags
.
init_update
=
1
;
}
else
{
battery
->
flags
.
update
[
ACPI_BATTERY_INFO
]
=
1
;
battery
->
flags
.
update
[
ACPI_BATTERY_STATE
]
=
1
;
battery
->
flags
.
update
[
ACPI_BATTERY_ALARM
]
=
1
;
}
}
...
...
@@ -335,37 +460,33 @@ static void acpi_battery_check_present(struct acpi_battery *battery)
-------------------------------------------------------------------------- */
static
struct
proc_dir_entry
*
acpi_battery_dir
;
static
int
acpi_battery_read_info
(
struct
seq_file
*
seq
,
void
*
offset
)
static
int
acpi_battery_print_info
(
struct
seq_file
*
seq
,
int
result
)
{
int
result
=
0
;
struct
acpi_battery
*
battery
=
seq
->
private
;
struct
acpi_battery_info
*
bif
=
NULL
;
char
*
units
=
"?"
;
if
(
!
battery
)
if
(
result
)
goto
end
;
acpi_battery_check_present
(
battery
);
if
(
battery
->
flags
.
present
)
if
(
acpi_battery_present
(
battery
))
seq_printf
(
seq
,
"present: yes
\n
"
);
else
{
seq_printf
(
seq
,
"present: no
\n
"
);
goto
end
;
}
/* Battery Info (_BIF) */
result
=
acpi_battery_get_info
(
battery
,
&
bif
);
if
(
result
||
!
bif
)
{
seq_printf
(
seq
,
"ERROR: Unable to read battery information
\n
"
);
bif
=
battery
->
bif_data
.
pointer
;
if
(
!
bif
)
{
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"BIF buffer is NULL"
));
result
=
-
ENODEV
;
goto
end
;
}
units
=
bif
->
power_unit
?
ACPI_BATTERY_UNITS_AMPS
:
ACPI_BATTERY_UNITS_WATTS
;
/* Battery Units */
units
=
acpi_battery_power_units
(
battery
)
;
if
(
bif
->
design_capacity
==
ACPI_BATTERY_VALUE_UNKNOWN
)
seq_printf
(
seq
,
"design capacity: unknown
\n
"
);
...
...
@@ -396,7 +517,6 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
else
seq_printf
(
seq
,
"design voltage: %d mV
\n
"
,
(
u32
)
bif
->
design_voltage
);
seq_printf
(
seq
,
"design capacity warning: %d %sh
\n
"
,
(
u32
)
bif
->
design_capacity_warning
,
units
);
seq_printf
(
seq
,
"design capacity low: %d %sh
\n
"
,
...
...
@@ -411,50 +531,40 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
seq_printf
(
seq
,
"OEM info: %s
\n
"
,
bif
->
oem_info
);
end:
kfree
(
bif
);
return
0
;
}
if
(
result
)
seq_printf
(
seq
,
"ERROR: Unable to read battery info
\n
"
);
static
int
acpi_battery_info_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
acpi_battery_read_info
,
PDE
(
inode
)
->
data
);
return
result
;
}
static
int
acpi_battery_
read_state
(
struct
seq_file
*
seq
,
void
*
offse
t
)
static
int
acpi_battery_
print_state
(
struct
seq_file
*
seq
,
int
resul
t
)
{
int
result
=
0
;
struct
acpi_battery
*
battery
=
seq
->
private
;
struct
acpi_battery_stat
us
*
bst
=
NULL
;
struct
acpi_battery_stat
e
*
bst
=
NULL
;
char
*
units
=
"?"
;
if
(
!
battery
)
if
(
result
)
goto
end
;
acpi_battery_check_present
(
battery
);
if
(
battery
->
flags
.
present
)
if
(
acpi_battery_present
(
battery
))
seq_printf
(
seq
,
"present: yes
\n
"
);
else
{
seq_printf
(
seq
,
"present: no
\n
"
);
goto
end
;
}
/* Battery Units */
units
=
battery
->
flags
.
power_unit
?
ACPI_BATTERY_UNITS_AMPS
:
ACPI_BATTERY_UNITS_WATTS
;
/* Battery Status (_BST) */
result
=
acpi_battery_get_status
(
battery
,
&
bst
);
if
(
result
||
!
bst
)
{
seq_printf
(
seq
,
"ERROR: Unable to read battery status
\n
"
);
bst
=
battery
->
bst_data
.
pointer
;
if
(
!
bst
)
{
ACPI_EXCEPTION
((
AE_INFO
,
AE_ERROR
,
"BST buffer is NULL"
));
result
=
-
ENODEV
;
goto
end
;
}
/* Battery Units */
units
=
acpi_battery_power_units
(
battery
);
if
(
!
(
bst
->
state
&
0x04
))
seq_printf
(
seq
,
"capacity state: ok
\n
"
);
else
...
...
@@ -490,48 +600,43 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
(
u32
)
bst
->
present_voltage
);
end:
kfree
(
bst
);
return
0
;
}
if
(
result
)
{
seq_printf
(
seq
,
"ERROR: Unable to read battery state
\n
"
);
}
static
int
acpi_battery_state_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
acpi_battery_read_state
,
PDE
(
inode
)
->
data
);
return
result
;
}
static
int
acpi_battery_
read_alarm
(
struct
seq_file
*
seq
,
void
*
offse
t
)
static
int
acpi_battery_
print_alarm
(
struct
seq_file
*
seq
,
int
resul
t
)
{
struct
acpi_battery
*
battery
=
seq
->
private
;
char
*
units
=
"?"
;
if
(
!
battery
)
if
(
result
)
goto
end
;
acpi_battery_check_present
(
battery
);
if
(
!
battery
->
flags
.
present
)
{
if
(
!
acpi_battery_present
(
battery
))
{
seq_printf
(
seq
,
"present: no
\n
"
);
goto
end
;
}
/* Battery Units */
units
=
battery
->
flags
.
power_unit
?
ACPI_BATTERY_UNITS_AMPS
:
ACPI_BATTERY_UNITS_WATTS
;
/* Battery Alarm */
units
=
acpi_battery_power_units
(
battery
);
seq_printf
(
seq
,
"alarm: "
);
if
(
!
battery
->
alarm
)
seq_printf
(
seq
,
"unsupported
\n
"
);
else
seq_printf
(
seq
,
"%
d %sh
\n
"
,
(
u32
)
battery
->
alarm
,
units
);
seq_printf
(
seq
,
"%
lu %sh
\n
"
,
battery
->
alarm
,
units
);
end:
return
0
;
if
(
result
)
seq_printf
(
seq
,
"ERROR: Unable to read battery alarm
\n
"
);
return
result
;
}
static
ssize_t
...
...
@@ -543,27 +648,113 @@ acpi_battery_write_alarm(struct file *file,
char
alarm_string
[
12
]
=
{
'\0'
};
struct
seq_file
*
m
=
file
->
private_data
;
struct
acpi_battery
*
battery
=
m
->
private
;
int
update_result
=
ACPI_BATTERY_NONE_UPDATE
;
if
(
!
battery
||
(
count
>
sizeof
(
alarm_string
)
-
1
))
return
-
EINVAL
;
acpi_battery_check_present
(
battery
);
mutex_lock
(
&
battery
->
mutex
);
if
(
!
battery
->
flags
.
present
)
return
-
ENODEV
;
result
=
acpi_battery_update
(
battery
,
1
,
&
update_result
);
if
(
result
)
{
result
=
-
ENODEV
;
goto
end
;
}
if
(
!
acpi_battery_present
(
battery
))
{
result
=
-
ENODEV
;
goto
end
;
}
if
(
copy_from_user
(
alarm_string
,
buffer
,
count
))
return
-
EFAULT
;
if
(
copy_from_user
(
alarm_string
,
buffer
,
count
))
{
result
=
-
EFAULT
;
goto
end
;
}
alarm_string
[
count
]
=
'\0'
;
result
=
acpi_battery_set_alarm
(
battery
,
simple_strtoul
(
alarm_string
,
NULL
,
0
));
if
(
result
)
return
result
;
goto
end
;
end:
return
count
;
acpi_battery_check_result
(
battery
,
result
);
if
(
!
result
)
result
=
count
;
mutex_unlock
(
&
battery
->
mutex
);
return
result
;
}
typedef
int
(
*
print_func
)(
struct
seq_file
*
seq
,
int
result
);
typedef
int
(
*
get_func
)(
struct
acpi_battery
*
battery
);
static
struct
acpi_read_mux
{
print_func
print
;
get_func
get
;
}
acpi_read_funcs
[
ACPI_BATTERY_NUMFILES
]
=
{
{.
get
=
acpi_battery_get_info
,
.
print
=
acpi_battery_print_info
},
{.
get
=
acpi_battery_get_state
,
.
print
=
acpi_battery_print_state
},
{.
get
=
acpi_battery_get_alarm
,
.
print
=
acpi_battery_print_alarm
},
};
static
int
acpi_battery_read
(
int
fid
,
struct
seq_file
*
seq
)
{
struct
acpi_battery
*
battery
=
seq
->
private
;
int
result
=
0
;
int
update_result
=
ACPI_BATTERY_NONE_UPDATE
;
int
update
=
0
;
mutex_lock
(
&
battery
->
mutex
);
update
=
(
get_seconds
()
-
battery
->
update_time
[
fid
]
>=
update_time
);
update
=
(
update
|
battery
->
flags
.
update
[
fid
]);
result
=
acpi_battery_update
(
battery
,
update
,
&
update_result
);
if
(
result
)
goto
end
;
if
(
update_result
==
ACPI_BATTERY_EASY_UPDATE
)
{
result
=
acpi_read_funcs
[
fid
].
get
(
battery
);
if
(
result
)
goto
end
;
}
end:
result
=
acpi_read_funcs
[
fid
].
print
(
seq
,
result
);
acpi_battery_check_result
(
battery
,
result
);
battery
->
flags
.
update
[
fid
]
=
result
;
mutex_unlock
(
&
battery
->
mutex
);
return
result
;
}
static
int
acpi_battery_read_info
(
struct
seq_file
*
seq
,
void
*
offset
)
{
return
acpi_battery_read
(
ACPI_BATTERY_INFO
,
seq
);
}
static
int
acpi_battery_read_state
(
struct
seq_file
*
seq
,
void
*
offset
)
{
return
acpi_battery_read
(
ACPI_BATTERY_STATE
,
seq
);
}
static
int
acpi_battery_read_alarm
(
struct
seq_file
*
seq
,
void
*
offset
)
{
return
acpi_battery_read
(
ACPI_BATTERY_ALARM
,
seq
);
}
static
int
acpi_battery_info_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
acpi_battery_read_info
,
PDE
(
inode
)
->
data
);
}
static
int
acpi_battery_state_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
acpi_battery_read_state
,
PDE
(
inode
)
->
data
);
}
static
int
acpi_battery_alarm_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
)
...
...
@@ -571,35 +762,51 @@ static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
return
single_open
(
file
,
acpi_battery_read_alarm
,
PDE
(
inode
)
->
data
);
}
static
const
struct
file_operations
acpi_battery_info_ops
=
{
static
struct
battery_file
{
struct
file_operations
ops
;
mode_t
mode
;
char
*
name
;
}
acpi_battery_file
[]
=
{
{
.
name
=
"info"
,
.
mode
=
S_IRUGO
,
.
ops
=
{
.
open
=
acpi_battery_info_open_fs
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
.
owner
=
THIS_MODULE
,
};
static
const
struct
file_operations
acpi_battery_state_ops
=
{
},
},
{
.
name
=
"state"
,
.
mode
=
S_IRUGO
,
.
ops
=
{
.
open
=
acpi_battery_state_open_fs
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
.
owner
=
THIS_MODULE
,
};
static
const
struct
file_operations
acpi_battery_alarm_ops
=
{
},
},
{
.
name
=
"alarm"
,
.
mode
=
S_IFREG
|
S_IRUGO
|
S_IWUSR
,
.
ops
=
{
.
open
=
acpi_battery_alarm_open_fs
,
.
read
=
seq_read
,
.
write
=
acpi_battery_write_alarm
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
.
owner
=
THIS_MODULE
,
},
},
};
static
int
acpi_battery_add_fs
(
struct
acpi_device
*
device
)
{
struct
proc_dir_entry
*
entry
=
NULL
;
int
i
;
if
(
!
acpi_device_dir
(
device
))
{
acpi_device_dir
(
device
)
=
proc_mkdir
(
acpi_device_bid
(
device
),
...
...
@@ -609,38 +816,16 @@ static int acpi_battery_add_fs(struct acpi_device *device)
acpi_device_dir
(
device
)
->
owner
=
THIS_MODULE
;
}
/* 'info' [R] */
entry
=
create_proc_entry
(
ACPI_BATTERY_FILE_INFO
,
S_IRUGO
,
acpi_device_dir
(
device
));
if
(
!
entry
)
return
-
ENODEV
;
else
{
entry
->
proc_fops
=
&
acpi_battery_info_ops
;
entry
->
data
=
acpi_driver_data
(
device
);
entry
->
owner
=
THIS_MODULE
;
}
/* 'status' [R] */
entry
=
create_proc_entry
(
ACPI_BATTERY_FILE_STATUS
,
S_IRUGO
,
acpi_device_dir
(
device
));
if
(
!
entry
)
return
-
ENODEV
;
else
{
entry
->
proc_fops
=
&
acpi_battery_state_ops
;
entry
->
data
=
acpi_driver_data
(
device
);
entry
->
owner
=
THIS_MODULE
;
}
/* 'alarm' [R/W] */
entry
=
create_proc_entry
(
ACPI_BATTERY_FILE_ALARM
,
S_IFREG
|
S_IRUGO
|
S_IWUSR
,
acpi_device_dir
(
device
));
if
(
!
entry
)
return
-
ENODEV
;
else
{
entry
->
proc_fops
=
&
acpi_battery_alarm_ops
;
entry
->
data
=
acpi_driver_data
(
device
);
entry
->
owner
=
THIS_MODULE
;
for
(
i
=
0
;
i
<
ACPI_BATTERY_NUMFILES
;
++
i
)
{
entry
=
create_proc_entry
(
acpi_battery_file
[
i
].
name
,
acpi_battery_file
[
i
].
mode
,
acpi_device_dir
(
device
));
if
(
!
entry
)
return
-
ENODEV
;
else
{
entry
->
proc_fops
=
&
acpi_battery_file
[
i
].
ops
;
entry
->
data
=
acpi_driver_data
(
device
);
entry
->
owner
=
THIS_MODULE
;
}
}
return
0
;
...
...
@@ -648,15 +833,12 @@ static int acpi_battery_add_fs(struct acpi_device *device)
static
int
acpi_battery_remove_fs
(
struct
acpi_device
*
device
)
{
int
i
;
if
(
acpi_device_dir
(
device
))
{
remove_proc_entry
(
ACPI_BATTERY_FILE_ALARM
,
for
(
i
=
0
;
i
<
ACPI_BATTERY_NUMFILES
;
++
i
)
{
remove_proc_entry
(
acpi_battery_file
[
i
].
name
,
acpi_device_dir
(
device
));
remove_proc_entry
(
ACPI_BATTERY_FILE_STATUS
,
acpi_device_dir
(
device
));
remove_proc_entry
(
ACPI_BATTERY_FILE_INFO
,
acpi_device_dir
(
device
));
}
remove_proc_entry
(
acpi_device_bid
(
device
),
acpi_battery_dir
);
acpi_device_dir
(
device
)
=
NULL
;
}
...
...
@@ -673,7 +855,6 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
struct
acpi_battery
*
battery
=
data
;
struct
acpi_device
*
device
=
NULL
;
if
(
!
battery
)
return
;
...
...
@@ -684,8 +865,10 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
case
ACPI_BATTERY_NOTIFY_INFO
:
case
ACPI_NOTIFY_BUS_CHECK
:
case
ACPI_NOTIFY_DEVICE_CHECK
:
acpi_battery_check
(
battery
);
acpi_bus_generate_event
(
device
,
event
,
battery
->
flags
.
present
);
device
=
battery
->
device
;
acpi_battery_notify_update
(
battery
);
acpi_bus_generate_event
(
device
,
event
,
acpi_battery_present
(
battery
));
break
;
default:
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
...
...
@@ -702,7 +885,6 @@ static int acpi_battery_add(struct acpi_device *device)
acpi_status
status
=
0
;
struct
acpi_battery
*
battery
=
NULL
;
if
(
!
device
)
return
-
EINVAL
;
...
...
@@ -710,15 +892,21 @@ static int acpi_battery_add(struct acpi_device *device)
if
(
!
battery
)
return
-
ENOMEM
;
mutex_init
(
&
battery
->
mutex
);
mutex_lock
(
&
battery
->
mutex
);
battery
->
device
=
device
;
strcpy
(
acpi_device_name
(
device
),
ACPI_BATTERY_DEVICE_NAME
);
strcpy
(
acpi_device_class
(
device
),
ACPI_BATTERY_CLASS
);
acpi_driver_data
(
device
)
=
battery
;
result
=
acpi_battery_
check
(
battery
);
result
=
acpi_battery_
get_status
(
battery
);
if
(
result
)
goto
end
;
battery
->
flags
.
init_update
=
1
;
result
=
acpi_battery_add_fs
(
device
);
if
(
result
)
goto
end
;
...
...
@@ -727,6 +915,7 @@ static int acpi_battery_add(struct acpi_device *device)
ACPI_ALL_NOTIFY
,
acpi_battery_notify
,
battery
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"Installing notify handler"
));
result
=
-
ENODEV
;
goto
end
;
}
...
...
@@ -736,11 +925,14 @@ static int acpi_battery_add(struct acpi_device *device)
device
->
status
.
battery_present
?
"present"
:
"absent"
);
end:
if
(
result
)
{
acpi_battery_remove_fs
(
device
);
kfree
(
battery
);
}
mutex_unlock
(
&
battery
->
mutex
);
return
result
;
}
...
...
@@ -749,18 +941,27 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
acpi_status
status
=
0
;
struct
acpi_battery
*
battery
=
NULL
;
if
(
!
device
||
!
acpi_driver_data
(
device
))
return
-
EINVAL
;
battery
=
acpi_driver_data
(
device
);
mutex_lock
(
&
battery
->
mutex
);
status
=
acpi_remove_notify_handler
(
device
->
handle
,
ACPI_ALL_NOTIFY
,
acpi_battery_notify
);
acpi_battery_remove_fs
(
device
);
kfree
(
battery
->
bif_data
.
pointer
);
kfree
(
battery
->
bst_data
.
pointer
);
mutex_unlock
(
&
battery
->
mutex
);
mutex_destroy
(
&
battery
->
mutex
);
kfree
(
battery
);
return
0
;
...
...
@@ -775,7 +976,10 @@ static int acpi_battery_resume(struct acpi_device *device)
return
-
EINVAL
;
battery
=
device
->
driver_data
;
return
acpi_battery_check
(
battery
);
battery
->
flags
.
init_update
=
1
;
return
0
;
}
static
int
__init
acpi_battery_init
(
void
)
...
...
@@ -800,7 +1004,6 @@ static int __init acpi_battery_init(void)
static
void
__exit
acpi_battery_exit
(
void
)
{
acpi_bus_unregister_driver
(
&
acpi_battery_driver
);
acpi_unlock_battery_dir
(
acpi_battery_dir
);
...
...
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