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
Kirill Smelkov
linux
Commits
14f7d720
Commit
14f7d720
authored
Oct 29, 2007
by
Len Brown
Browse files
Options
Browse Files
Download
Plain Diff
Pull alexey-fixes into release branch
parents
6a22c57b
5527c8be
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
237 additions
and
274 deletions
+237
-274
Documentation/kernel-parameters.txt
Documentation/kernel-parameters.txt
+0
-5
drivers/acpi/Kconfig
drivers/acpi/Kconfig
+5
-3
drivers/acpi/battery.c
drivers/acpi/battery.c
+95
-69
drivers/acpi/bus.c
drivers/acpi/bus.c
+3
-5
drivers/acpi/button.c
drivers/acpi/button.c
+29
-8
drivers/acpi/ec.c
drivers/acpi/ec.c
+70
-76
drivers/acpi/fan.c
drivers/acpi/fan.c
+7
-65
drivers/acpi/power.c
drivers/acpi/power.c
+24
-39
drivers/acpi/sleep/main.c
drivers/acpi/sleep/main.c
+3
-2
include/acpi/acpi_bus.h
include/acpi/acpi_bus.h
+1
-2
No files found.
Documentation/kernel-parameters.txt
View file @
14f7d720
...
...
@@ -586,11 +586,6 @@ and is between 256 and 4096 characters. It is defined in the file
eata= [HW,SCSI]
ec_intr= [HW,ACPI] ACPI Embedded Controller interrupt mode
Format: <int>
0: polling mode
non-0: interrupt mode (default)
edd= [EDD]
Format: {"of[f]" | "sk[ipmbr]"}
See comment in arch/i386/boot/edd.S
...
...
drivers/acpi/Kconfig
View file @
14f7d720
...
...
@@ -88,7 +88,8 @@ config ACPI_PROC_EVENT
config ACPI_AC
tristate "AC Adapter"
depends on X86 && POWER_SUPPLY
depends on X86
select POWER_SUPPLY
default y
help
This driver adds support for the AC Adapter object, which indicates
...
...
@@ -97,7 +98,8 @@ config ACPI_AC
config ACPI_BATTERY
tristate "Battery"
depends on X86 && POWER_SUPPLY
depends on X86
select POWER_SUPPLY
default y
help
This driver adds support for battery information through
...
...
@@ -352,7 +354,7 @@ config ACPI_HOTPLUG_MEMORY
config ACPI_SBS
tristate "Smart Battery System"
depends on X86
depends on
POWER_SUPPLY
select
POWER_SUPPLY
help
This driver adds support for the Smart Battery System, another
type of access to battery information, found on some laptops.
...
...
drivers/acpi/battery.c
View file @
14f7d720
...
...
@@ -125,11 +125,15 @@ static int acpi_battery_technology(struct acpi_battery *battery)
return
POWER_SUPPLY_TECHNOLOGY_NiMH
;
if
(
!
strcasecmp
(
"LION"
,
battery
->
type
))
return
POWER_SUPPLY_TECHNOLOGY_LION
;
if
(
!
strcasecmp
(
"LI-ION"
,
battery
->
type
))
return
POWER_SUPPLY_TECHNOLOGY_LION
;
if
(
!
strcasecmp
(
"LiP"
,
battery
->
type
))
return
POWER_SUPPLY_TECHNOLOGY_LIPO
;
return
POWER_SUPPLY_TECHNOLOGY_UNKNOWN
;
}
static
int
acpi_battery_update
(
struct
acpi_battery
*
battery
);
static
int
acpi_battery_get_property
(
struct
power_supply
*
psy
,
enum
power_supply_property
psp
,
union
power_supply_propval
*
val
)
...
...
@@ -139,6 +143,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
if
((
!
acpi_battery_present
(
battery
))
&&
psp
!=
POWER_SUPPLY_PROP_PRESENT
)
return
-
ENODEV
;
acpi_battery_update
(
battery
);
switch
(
psp
)
{
case
POWER_SUPPLY_PROP_STATUS
:
if
(
battery
->
state
&
0x01
)
...
...
@@ -257,7 +262,7 @@ static int extract_package(struct acpi_battery *battery,
union
acpi_object
*
package
,
struct
acpi_offsets
*
offsets
,
int
num
)
{
int
i
,
*
x
;
int
i
;
union
acpi_object
*
element
;
if
(
package
->
type
!=
ACPI_TYPE_PACKAGE
)
return
-
EFAULT
;
...
...
@@ -266,16 +271,21 @@ static int extract_package(struct acpi_battery *battery,
return
-
EFAULT
;
element
=
&
package
->
package
.
elements
[
i
];
if
(
offsets
[
i
].
mode
)
{
if
(
element
->
type
!=
ACPI_TYPE_STRING
&&
element
->
type
!=
ACPI_TYPE_BUFFER
)
return
-
EFAULT
;
strncpy
((
u8
*
)
battery
+
offsets
[
i
].
offset
,
element
->
string
.
pointer
,
32
);
u8
*
ptr
=
(
u8
*
)
battery
+
offsets
[
i
].
offset
;
if
(
element
->
type
==
ACPI_TYPE_STRING
||
element
->
type
==
ACPI_TYPE_BUFFER
)
strncpy
(
ptr
,
element
->
string
.
pointer
,
32
);
else
if
(
element
->
type
==
ACPI_TYPE_INTEGER
)
{
strncpy
(
ptr
,
(
u8
*
)
&
element
->
integer
.
value
,
sizeof
(
acpi_integer
));
ptr
[
sizeof
(
acpi_integer
)]
=
0
;
}
else
return
-
EFAULT
;
}
else
{
if
(
element
->
type
!=
ACPI_TYPE_INTEGER
)
return
-
EFAULT
;
x
=
(
int
*
)((
u8
*
)
battery
+
offsets
[
i
].
offset
);
if
(
element
->
type
==
ACPI_TYPE_INTEGER
)
{
int
*
x
=
(
int
*
)((
u8
*
)
battery
+
offsets
[
i
].
offset
);
*
x
=
element
->
integer
.
value
;
}
else
return
-
EFAULT
;
}
}
return
0
;
...
...
@@ -385,16 +395,40 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
return
acpi_battery_set_alarm
(
battery
);
}
static
int
acpi_battery_update
(
struct
acpi_battery
*
battery
)
static
ssize_t
acpi_battery_alarm_show
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
int
saved_present
=
acpi_battery_present
(
battery
);
int
result
=
acpi_battery_get_status
(
battery
);
if
(
result
||
!
acpi_battery_present
(
battery
))
return
result
;
if
(
saved_present
!=
acpi_battery_present
(
battery
)
||
!
battery
->
update_time
)
{
struct
acpi_battery
*
battery
=
to_acpi_battery
(
dev_get_drvdata
(
dev
));
return
sprintf
(
buf
,
"%d
\n
"
,
battery
->
alarm
*
1000
);
}
static
ssize_t
acpi_battery_alarm_store
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
unsigned
long
x
;
struct
acpi_battery
*
battery
=
to_acpi_battery
(
dev_get_drvdata
(
dev
));
if
(
sscanf
(
buf
,
"%ld
\n
"
,
&
x
)
==
1
)
battery
->
alarm
=
x
/
1000
;
if
(
acpi_battery_present
(
battery
))
acpi_battery_set_alarm
(
battery
);
return
count
;
}
static
struct
device_attribute
alarm_attr
=
{
.
attr
=
{.
name
=
"alarm"
,
.
mode
=
0644
,
.
owner
=
THIS_MODULE
},
.
show
=
acpi_battery_alarm_show
,
.
store
=
acpi_battery_alarm_store
,
};
static
int
sysfs_add_battery
(
struct
acpi_battery
*
battery
)
{
int
result
;
battery
->
update_time
=
0
;
result
=
acpi_battery_get_info
(
battery
);
acpi_battery_init_alarm
(
battery
);
if
(
result
)
return
result
;
if
(
battery
->
power_unit
)
{
...
...
@@ -406,8 +440,36 @@ static int acpi_battery_update(struct acpi_battery *battery)
battery
->
bat
.
num_properties
=
ARRAY_SIZE
(
energy_battery_props
);
}
acpi_battery_init_alarm
(
battery
);
battery
->
bat
.
name
=
acpi_device_bid
(
battery
->
device
);
battery
->
bat
.
type
=
POWER_SUPPLY_TYPE_BATTERY
;
battery
->
bat
.
get_property
=
acpi_battery_get_property
;
result
=
power_supply_register
(
&
battery
->
device
->
dev
,
&
battery
->
bat
);
if
(
result
)
return
result
;
return
device_create_file
(
battery
->
bat
.
dev
,
&
alarm_attr
);
}
static
void
sysfs_remove_battery
(
struct
acpi_battery
*
battery
)
{
if
(
!
battery
->
bat
.
dev
)
return
;
device_remove_file
(
battery
->
bat
.
dev
,
&
alarm_attr
);
power_supply_unregister
(
&
battery
->
bat
);
}
static
int
acpi_battery_update
(
struct
acpi_battery
*
battery
)
{
int
result
=
acpi_battery_get_status
(
battery
);
if
(
result
)
return
result
;
if
(
!
acpi_battery_present
(
battery
))
{
sysfs_remove_battery
(
battery
);
return
0
;
}
if
(
!
battery
->
bat
.
dev
)
sysfs_add_battery
(
battery
);
return
acpi_battery_get_state
(
battery
);
}
...
...
@@ -554,10 +616,6 @@ static ssize_t acpi_battery_write_alarm(struct file *file,
if
(
!
battery
||
(
count
>
sizeof
(
alarm_string
)
-
1
))
return
-
EINVAL
;
if
(
result
)
{
result
=
-
ENODEV
;
goto
end
;
}
if
(
!
acpi_battery_present
(
battery
))
{
result
=
-
ENODEV
;
goto
end
;
...
...
@@ -688,33 +746,6 @@ static void acpi_battery_remove_fs(struct acpi_device *device)
#endif
static
ssize_t
acpi_battery_alarm_show
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
acpi_battery
*
battery
=
to_acpi_battery
(
dev_get_drvdata
(
dev
));
return
sprintf
(
buf
,
"%d
\n
"
,
battery
->
alarm
*
1000
);
}
static
ssize_t
acpi_battery_alarm_store
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
unsigned
long
x
;
struct
acpi_battery
*
battery
=
to_acpi_battery
(
dev_get_drvdata
(
dev
));
if
(
sscanf
(
buf
,
"%ld
\n
"
,
&
x
)
==
1
)
battery
->
alarm
=
x
/
1000
;
if
(
acpi_battery_present
(
battery
))
acpi_battery_set_alarm
(
battery
);
return
count
;
}
static
struct
device_attribute
alarm_attr
=
{
.
attr
=
{.
name
=
"alarm"
,
.
mode
=
0644
,
.
owner
=
THIS_MODULE
},
.
show
=
acpi_battery_alarm_show
,
.
store
=
acpi_battery_alarm_store
,
};
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
...
...
@@ -732,6 +763,8 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
acpi_bus_generate_netlink_event
(
device
->
pnp
.
device_class
,
device
->
dev
.
bus_id
,
event
,
acpi_battery_present
(
battery
));
/* acpi_batter_update could remove power_supply object */
if
(
battery
->
bat
.
dev
)
kobject_uevent
(
&
battery
->
bat
.
dev
->
kobj
,
KOBJ_CHANGE
);
}
...
...
@@ -756,11 +789,6 @@ static int acpi_battery_add(struct acpi_device *device)
if
(
result
)
goto
end
;
#endif
battery
->
bat
.
name
=
acpi_device_bid
(
device
);
battery
->
bat
.
type
=
POWER_SUPPLY_TYPE_BATTERY
;
battery
->
bat
.
get_property
=
acpi_battery_get_property
;
result
=
power_supply_register
(
&
battery
->
device
->
dev
,
&
battery
->
bat
);
result
=
device_create_file
(
battery
->
bat
.
dev
,
&
alarm_attr
);
status
=
acpi_install_notify_handler
(
device
->
handle
,
ACPI_ALL_NOTIFY
,
acpi_battery_notify
,
battery
);
...
...
@@ -796,10 +824,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
#ifdef CONFIG_ACPI_PROCFS
acpi_battery_remove_fs
(
device
);
#endif
if
(
battery
->
bat
.
dev
)
{
device_remove_file
(
battery
->
bat
.
dev
,
&
alarm_attr
);
power_supply_unregister
(
&
battery
->
bat
);
}
sysfs_remove_battery
(
battery
);
mutex_destroy
(
&
battery
->
lock
);
kfree
(
battery
);
return
0
;
...
...
@@ -813,6 +838,7 @@ static int acpi_battery_resume(struct acpi_device *device)
return
-
EINVAL
;
battery
=
acpi_driver_data
(
device
);
battery
->
update_time
=
0
;
acpi_battery_update
(
battery
);
return
0
;
}
...
...
drivers/acpi/bus.c
View file @
14f7d720
...
...
@@ -198,12 +198,10 @@ int acpi_bus_set_power(acpi_handle handle, int state)
return
-
ENODEV
;
}
/*
* Get device's current power state if it's unknown
* This means device power state isn't initialized or previous setting failed
* Get device's current power state
*/
if
((
device
->
power
.
state
==
ACPI_STATE_UNKNOWN
)
||
device
->
flags
.
force_power_state
)
acpi_bus_get_power
(
device
->
handle
,
&
device
->
power
.
state
);
if
(
(
state
==
device
->
power
.
state
)
&&
!
device
->
flags
.
force_power_
state
)
{
if
(
state
==
device
->
power
.
state
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Device is already at D%d
\n
"
,
state
));
return
0
;
...
...
drivers/acpi/button.c
View file @
14f7d720
...
...
@@ -78,6 +78,7 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids);
static
int
acpi_button_add
(
struct
acpi_device
*
device
);
static
int
acpi_button_remove
(
struct
acpi_device
*
device
,
int
type
);
static
int
acpi_button_resume
(
struct
acpi_device
*
device
);
static
int
acpi_button_info_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
);
static
int
acpi_button_state_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
);
...
...
@@ -87,6 +88,7 @@ static struct acpi_driver acpi_button_driver = {
.
ids
=
button_device_ids
,
.
ops
=
{
.
add
=
acpi_button_add
,
.
resume
=
acpi_button_resume
,
.
remove
=
acpi_button_remove
,
},
};
...
...
@@ -253,6 +255,19 @@ static int acpi_button_remove_fs(struct acpi_device *device)
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
static
int
acpi_lid_send_state
(
struct
acpi_button
*
button
)
{
unsigned
long
state
;
acpi_status
status
;
status
=
acpi_evaluate_integer
(
button
->
device
->
handle
,
"_LID"
,
NULL
,
&
state
);
if
(
ACPI_FAILURE
(
status
))
return
-
ENODEV
;
/* input layer checks if event is redundant */
input_report_switch
(
button
->
input
,
SW_LID
,
!
state
);
return
0
;
}
static
void
acpi_button_notify
(
acpi_handle
handle
,
u32
event
,
void
*
data
)
{
...
...
@@ -265,15 +280,8 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
switch
(
event
)
{
case
ACPI_BUTTON_NOTIFY_STATUS
:
input
=
button
->
input
;
if
(
button
->
type
==
ACPI_BUTTON_TYPE_LID
)
{
struct
acpi_handle
*
handle
=
button
->
device
->
handle
;
unsigned
long
state
;
if
(
!
ACPI_FAILURE
(
acpi_evaluate_integer
(
handle
,
"_LID"
,
NULL
,
&
state
)))
input_report_switch
(
input
,
SW_LID
,
!
state
);
acpi_lid_send_state
(
button
);
}
else
{
int
keycode
=
test_bit
(
KEY_SLEEP
,
input
->
keybit
)
?
KEY_SLEEP
:
KEY_POWER
;
...
...
@@ -336,6 +344,17 @@ static int acpi_button_install_notify_handlers(struct acpi_button *button)
return
ACPI_FAILURE
(
status
)
?
-
ENODEV
:
0
;
}
static
int
acpi_button_resume
(
struct
acpi_device
*
device
)
{
struct
acpi_button
*
button
;
if
(
!
device
)
return
-
EINVAL
;
button
=
acpi_driver_data
(
device
);
if
(
button
&&
button
->
type
==
ACPI_BUTTON_TYPE_LID
)
return
acpi_lid_send_state
(
button
);
return
0
;
}
static
void
acpi_button_remove_notify_handlers
(
struct
acpi_button
*
button
)
{
switch
(
button
->
type
)
{
...
...
@@ -453,6 +472,8 @@ static int acpi_button_add(struct acpi_device *device)
error
=
input_register_device
(
input
);
if
(
error
)
goto
err_remove_handlers
;
if
(
button
->
type
==
ACPI_BUTTON_TYPE_LID
)
acpi_lid_send_state
(
button
);
if
(
device
->
wakeup
.
flags
.
valid
)
{
/* Button's GPE is run-wake GPE */
...
...
drivers/acpi/ec.c
View file @
14f7d720
...
...
@@ -71,10 +71,12 @@ enum ec_event {
#define ACPI_EC_DELAY 500
/* Wait 500ms max. during EC ops */
#define ACPI_EC_UDELAY_GLK 1000
/* Wait 1ms max. to get global lock */
static
enum
ec_mode
{
EC_INTR
=
1
,
/* Output buffer full */
EC_POLL
,
/* Input buffer empty */
}
acpi_ec_mode
=
EC_INTR
;
enum
{
EC_FLAGS_WAIT_GPE
=
0
,
/* Don't check status until GPE arrives */
EC_FLAGS_QUERY_PENDING
,
/* Query is pending */
EC_FLAGS_GPE_MODE
,
/* Expect GPE to be sent for status change */
EC_FLAGS_ONLY_IBF_GPE
,
/* Expect GPE only for IBF = 0 event */
};
static
int
acpi_ec_remove
(
struct
acpi_device
*
device
,
int
type
);
static
int
acpi_ec_start
(
struct
acpi_device
*
device
);
...
...
@@ -116,9 +118,8 @@ static struct acpi_ec {
unsigned
long
command_addr
;
unsigned
long
data_addr
;
unsigned
long
global_lock
;
unsigned
long
flags
;
struct
mutex
lock
;
atomic_t
query_pending
;
atomic_t
event_count
;
wait_queue_head_t
wait
;
struct
list_head
list
;
u8
handlers_installed
;
...
...
@@ -148,45 +149,54 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
outb
(
data
,
ec
->
data_addr
);
}
static
inline
int
acpi_ec_check_status
(
struct
acpi_ec
*
ec
,
enum
ec_event
event
,
unsigned
old_count
)
static
inline
int
acpi_ec_check_status
(
struct
acpi_ec
*
ec
,
enum
ec_event
event
)
{
u8
status
=
acpi_ec_read_status
(
ec
);
if
(
old_count
==
atomic_read
(
&
ec
->
event_count
))
if
(
test_bit
(
EC_FLAGS_WAIT_GPE
,
&
ec
->
flags
))
return
0
;
if
(
event
==
ACPI_EC_EVENT_OBF_1
)
{
if
(
status
&
ACPI_EC_FLAG_OBF
)
if
(
acpi_ec_read_status
(
ec
)
&
ACPI_EC_FLAG_OBF
)
return
1
;
}
else
if
(
event
==
ACPI_EC_EVENT_IBF_0
)
{
if
(
!
(
status
&
ACPI_EC_FLAG_IBF
))
if
(
!
(
acpi_ec_read_status
(
ec
)
&
ACPI_EC_FLAG_IBF
))
return
1
;
}
return
0
;
}
static
int
acpi_ec_wait
(
struct
acpi_ec
*
ec
,
enum
ec_event
event
,
unsigned
count
,
int
force_poll
)
static
int
acpi_ec_wait
(
struct
acpi_ec
*
ec
,
enum
ec_event
event
,
int
force_poll
)
{
if
(
unlikely
(
force_poll
)
||
acpi_ec_mode
==
EC_POLL
)
{
unsigned
long
delay
=
jiffies
+
msecs_to_jiffies
(
ACPI_EC_DELAY
);
while
(
time_before
(
jiffies
,
delay
))
{
if
(
acpi_ec_check_status
(
ec
,
event
,
0
))
if
(
likely
(
test_bit
(
EC_FLAGS_GPE_MODE
,
&
ec
->
flags
))
&&
likely
(
!
force_poll
))
{
if
(
wait_event_timeout
(
ec
->
wait
,
acpi_ec_check_status
(
ec
,
event
),
msecs_to_jiffies
(
ACPI_EC_DELAY
)
))
return
0
;
}
clear_bit
(
EC_FLAGS_WAIT_GPE
,
&
ec
->
flags
);
if
(
acpi_ec_check_status
(
ec
,
event
))
{
if
(
event
==
ACPI_EC_EVENT_OBF_1
)
{
/* miss OBF = 1 GPE, don't expect it anymore */
printk
(
KERN_INFO
PREFIX
"missing OBF_1 confirmation,"
"switching to degraded mode.
\n
"
);
set_bit
(
EC_FLAGS_ONLY_IBF_GPE
,
&
ec
->
flags
);
}
else
{
if
(
wait_event_timeout
(
ec
->
wait
,
acpi_ec_check_status
(
ec
,
event
,
count
),
msecs_to_jiffies
(
ACPI_EC_DELAY
))
||
acpi_ec_check_status
(
ec
,
event
,
0
))
{
/* missing GPEs, switch back to poll mode */
printk
(
KERN_INFO
PREFIX
"missing IBF_1 confirmations,"
"switch off interrupt mode.
\n
"
);
clear_bit
(
EC_FLAGS_GPE_MODE
,
&
ec
->
flags
);
}
return
0
;
}
}
else
{
unsigned
long
delay
=
jiffies
+
msecs_to_jiffies
(
ACPI_EC_DELAY
);
clear_bit
(
EC_FLAGS_WAIT_GPE
,
&
ec
->
flags
);
while
(
time_before
(
jiffies
,
delay
))
{
if
(
acpi_ec_check_status
(
ec
,
event
))
return
0
;
}
}
printk
(
KERN_ERR
PREFIX
"acpi_ec_wait timeout,"
" status = %d, expect_event = %d
\n
"
,
acpi_ec_read_status
(
ec
),
event
);
}
}
return
-
ETIME
;
}
...
...
@@ -196,39 +206,42 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
int
force_poll
)
{
int
result
=
0
;
unsigned
count
=
atomic_read
(
&
ec
->
event_count
);
set_bit
(
EC_FLAGS_WAIT_GPE
,
&
ec
->
flags
);
acpi_ec_write_cmd
(
ec
,
command
);
for
(;
wdata_len
>
0
;
--
wdata_len
)
{
result
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_IBF_0
,
count
,
force_poll
);
result
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_IBF_0
,
force_poll
);
if
(
result
)
{
printk
(
KERN_ERR
PREFIX
"write_cmd timeout, command = %d
\n
"
,
command
);
goto
end
;
}
count
=
atomic_read
(
&
ec
->
event_count
);
set_bit
(
EC_FLAGS_WAIT_GPE
,
&
ec
->
flags
);
acpi_ec_write_data
(
ec
,
*
(
wdata
++
));
}
if
(
!
rdata_len
)
{
result
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_IBF_0
,
count
,
force_poll
);
result
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_IBF_0
,
force_poll
);
if
(
result
)
{
printk
(
KERN_ERR
PREFIX
"finish-write timeout, command = %d
\n
"
,
command
);
goto
end
;
}
}
else
if
(
command
==
ACPI_EC_COMMAND_QUERY
)
{
atomic_set
(
&
ec
->
query_pending
,
0
);
}
}
else
if
(
command
==
ACPI_EC_COMMAND_QUERY
)
clear_bit
(
EC_FLAGS_QUERY_PENDING
,
&
ec
->
flags
);
for
(;
rdata_len
>
0
;
--
rdata_len
)
{
result
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_OBF_1
,
count
,
force_poll
);
if
(
test_bit
(
EC_FLAGS_ONLY_IBF_GPE
,
&
ec
->
flags
))
force_poll
=
1
;
result
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_OBF_1
,
force_poll
);
if
(
result
)
{
printk
(
KERN_ERR
PREFIX
"read timeout, command = %d
\n
"
,
command
);
goto
end
;
}
count
=
atomic_read
(
&
ec
->
event_count
);
/* Don't expect GPE after last read */
if
(
rdata_len
>
1
)
set_bit
(
EC_FLAGS_WAIT_GPE
,
&
ec
->
flags
);
*
(
rdata
++
)
=
acpi_ec_read_data
(
ec
);
}
end:
...
...
@@ -258,10 +271,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
}
}
/* Make sure GPE is enabled before doing transaction */
acpi_enable_gpe
(
NULL
,
ec
->
gpe
,
ACPI_NOT_ISR
);
status
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_IBF_0
,
0
,
0
);
status
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_IBF_0
,
0
);
if
(
status
)
{
printk
(
KERN_ERR
PREFIX
"input buffer is not empty, aborting transaction
\n
"
);
...
...
@@ -435,9 +445,9 @@ EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);
void
acpi_ec_remove_query_handler
(
struct
acpi_ec
*
ec
,
u8
query_bit
)
{
struct
acpi_ec_query_handler
*
handler
;
struct
acpi_ec_query_handler
*
handler
,
*
tmp
;
mutex_lock
(
&
ec
->
lock
);
list_for_each_entry
(
handler
,
&
ec
->
list
,
node
)
{
list_for_each_entry
_safe
(
handler
,
tmp
,
&
ec
->
list
,
node
)
{
if
(
query_bit
==
handler
->
query_bit
)
{
list_del
(
&
handler
->
node
);
kfree
(
handler
);
...
...
@@ -476,23 +486,24 @@ static void acpi_ec_gpe_query(void *ec_cxt)
static
u32
acpi_ec_gpe_handler
(
void
*
data
)
{
acpi_status
status
=
AE_OK
;
u8
value
;
struct
acpi_ec
*
ec
=
data
;
atomic_inc
(
&
ec
->
event_count
);
if
(
acpi_ec_mode
==
EC_INTR
)
{
clear_bit
(
EC_FLAGS_WAIT_GPE
,
&
ec
->
flags
);
if
(
test_bit
(
EC_FLAGS_GPE_MODE
,
&
ec
->
flags
))
wake_up
(
&
ec
->
wait
);
}
value
=
acpi_ec_read_status
(
ec
);
if
((
value
&
ACPI_EC_FLAG_SCI
)
&&
!
atomic_read
(
&
ec
->
query_pending
))
{
atomic_set
(
&
ec
->
query_pending
,
1
);
status
=
acpi_os_execute
(
OSL_EC_BURST_HANDLER
,
acpi_ec_gpe_query
,
ec
);
if
(
acpi_ec_read_status
(
ec
)
&
ACPI_EC_FLAG_SCI
)
{
if
(
!
test_and_set_bit
(
EC_FLAGS_QUERY_PENDING
,
&
ec
->
flags
))
status
=
acpi_os_execute
(
OSL_EC_BURST_HANDLER
,
acpi_ec_gpe_query
,
ec
);
}
else
if
(
unlikely
(
!
test_bit
(
EC_FLAGS_GPE_MODE
,
&
ec
->
flags
)))
{
/* this is non-query, must be confirmation */
printk
(
KERN_INFO
PREFIX
"non-query interrupt received,"
" switching to interrupt mode
\n
"
);
set_bit
(
EC_FLAGS_GPE_MODE
,
&
ec
->
flags
);
}
return
status
==
AE_OK
?
return
ACPI_SUCCESS
(
status
)
?
ACPI_INTERRUPT_HANDLED
:
ACPI_INTERRUPT_NOT_HANDLED
;
}
...
...
@@ -641,13 +652,10 @@ static struct acpi_ec *make_acpi_ec(void)
struct
acpi_ec
*
ec
=
kzalloc
(
sizeof
(
struct
acpi_ec
),
GFP_KERNEL
);
if
(
!
ec
)
return
NULL
;
atomic_set
(
&
ec
->
query_pending
,
1
);
atomic_set
(
&
ec
->
event_count
,
1
);
ec
->
flags
=
1
<<
EC_FLAGS_QUERY_PENDING
;
mutex_init
(
&
ec
->
lock
);
init_waitqueue_head
(
&
ec
->
wait
);
INIT_LIST_HEAD
(
&
ec
->
list
);
return
ec
;
}
...
...
@@ -741,6 +749,8 @@ static int acpi_ec_add(struct acpi_device *device)
acpi_ec_add_fs
(
device
);
printk
(
KERN_INFO
PREFIX
"GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx
\n
"
,
ec
->
gpe
,
ec
->
command_addr
,
ec
->
data_addr
);
printk
(
KERN_INFO
PREFIX
"driver started in %s mode
\n
"
,
(
test_bit
(
EC_FLAGS_GPE_MODE
,
&
ec
->
flags
))
?
"interrupt"
:
"poll"
);
return
0
;
}
...
...
@@ -833,7 +843,7 @@ static int acpi_ec_start(struct acpi_device *device)
ret
=
ec_install_handlers
(
ec
);
/* EC is fully operational, allow queries */
atomic_set
(
&
ec
->
query_pending
,
0
);
clear_bit
(
EC_FLAGS_QUERY_PENDING
,
&
ec
->
flags
);
return
ret
;
}
...
...
@@ -925,19 +935,3 @@ static void __exit acpi_ec_exit(void)
return;
}
#endif /* 0 */
static
int
__init
acpi_ec_set_intr_mode
(
char
*
str
)
{
int
intr
;
if
(
!
get_option
(
&
str
,
&
intr
))
return
0
;
acpi_ec_mode
=
(
intr
)
?
EC_INTR
:
EC_POLL
;
printk
(
KERN_NOTICE
PREFIX
"%s mode.
\n
"
,
intr
?
"interrupt"
:
"polling"
);
return
1
;
}
__setup
(
"ec_intr="
,
acpi_ec_set_intr_mode
);
drivers/acpi/fan.c
View file @
14f7d720
...
...
@@ -47,8 +47,6 @@ MODULE_LICENSE("GPL");
static
int
acpi_fan_add
(
struct
acpi_device
*
device
);
static
int
acpi_fan_remove
(
struct
acpi_device
*
device
,
int
type
);
static
int
acpi_fan_suspend
(
struct
acpi_device
*
device
,
pm_message_t
state
);
static
int
acpi_fan_resume
(
struct
acpi_device
*
device
);
static
const
struct
acpi_device_id
fan_device_ids
[]
=
{
{
"PNP0C0B"
,
0
},
...
...
@@ -63,15 +61,9 @@ static struct acpi_driver acpi_fan_driver = {
.
ops
=
{
.
add
=
acpi_fan_add
,
.
remove
=
acpi_fan_remove
,
.
suspend
=
acpi_fan_suspend
,
.
resume
=
acpi_fan_resume
,
},
};
struct
acpi_fan
{
struct
acpi_device
*
device
;
};
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
...
...
@@ -80,12 +72,12 @@ static struct proc_dir_entry *acpi_fan_dir;
static
int
acpi_fan_read_state
(
struct
seq_file
*
seq
,
void
*
offset
)
{
struct
acpi_
fan
*
fan
=
seq
->
private
;
struct
acpi_
device
*
device
=
seq
->
private
;
int
state
=
0
;
if
(
fan
)
{
if
(
acpi_bus_get_power
(
fan
->
device
->
handle
,
&
state
))
if
(
device
)
{
if
(
acpi_bus_get_power
(
device
->
handle
,
&
state
))
seq_printf
(
seq
,
"status: ERROR
\n
"
);
else
seq_printf
(
seq
,
"status: %s
\n
"
,
...
...
@@ -105,11 +97,10 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
{
int
result
=
0
;
struct
seq_file
*
m
=
file
->
private_data
;
struct
acpi_
fan
*
fan
=
m
->
private
;
struct
acpi_
device
*
device
=
m
->
private
;
char
state_string
[
12
]
=
{
'\0'
};
if
(
!
fan
||
(
count
>
sizeof
(
state_string
)
-
1
))
if
(
count
>
sizeof
(
state_string
)
-
1
)
return
-
EINVAL
;
if
(
copy_from_user
(
state_string
,
buffer
,
count
))
...
...
@@ -117,7 +108,7 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
state_string
[
count
]
=
'\0'
;
result
=
acpi_bus_set_power
(
fan
->
device
->
handle
,
result
=
acpi_bus_set_power
(
device
->
handle
,
simple_strtoul
(
state_string
,
NULL
,
0
));
if
(
result
)
return
result
;
...
...
@@ -158,7 +149,7 @@ static int acpi_fan_add_fs(struct acpi_device *device)
return
-
ENODEV
;
else
{
entry
->
proc_fops
=
&
acpi_fan_state_ops
;
entry
->
data
=
acpi_driver_data
(
device
)
;
entry
->
data
=
device
;
entry
->
owner
=
THIS_MODULE
;
}
...
...
@@ -191,14 +182,8 @@ static int acpi_fan_add(struct acpi_device *device)
if
(
!
device
)
return
-
EINVAL
;
fan
=
kzalloc
(
sizeof
(
struct
acpi_fan
),
GFP_KERNEL
);
if
(
!
fan
)
return
-
ENOMEM
;
fan
->
device
=
device
;
strcpy
(
acpi_device_name
(
device
),
"Fan"
);
strcpy
(
acpi_device_class
(
device
),
ACPI_FAN_CLASS
);
acpi_driver_data
(
device
)
=
fan
;
result
=
acpi_bus_get_power
(
device
->
handle
,
&
state
);
if
(
result
)
{
...
...
@@ -206,10 +191,6 @@ static int acpi_fan_add(struct acpi_device *device)
goto
end
;
}
device
->
flags
.
force_power_state
=
1
;
acpi_bus_set_power
(
device
->
handle
,
state
);
device
->
flags
.
force_power_state
=
0
;
result
=
acpi_fan_add_fs
(
device
);
if
(
result
)
goto
end
;
...
...
@@ -227,53 +208,14 @@ static int acpi_fan_add(struct acpi_device *device)
static
int
acpi_fan_remove
(
struct
acpi_device
*
device
,
int
type
)
{
struct
acpi_fan
*
fan
=
NULL
;
if
(
!
device
||
!
acpi_driver_data
(
device
))
return
-
EINVAL
;
fan
=
acpi_driver_data
(
device
);
acpi_fan_remove_fs
(
device
);
kfree
(
fan
);
return
0
;
}
static
int
acpi_fan_suspend
(
struct
acpi_device
*
device
,
pm_message_t
state
)
{
if
(
!
device
)
return
-
EINVAL
;
acpi_bus_set_power
(
device
->
handle
,
ACPI_STATE_D0
);
return
AE_OK
;
}
static
int
acpi_fan_resume
(
struct
acpi_device
*
device
)
{
int
result
=
0
;
int
power_state
=
0
;
if
(
!
device
)
return
-
EINVAL
;
result
=
acpi_bus_get_power
(
device
->
handle
,
&
power_state
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Error reading fan power state
\n
"
));
return
result
;
}
device
->
flags
.
force_power_state
=
1
;
acpi_bus_set_power
(
device
->
handle
,
power_state
);
device
->
flags
.
force_power_state
=
0
;
return
result
;
}
static
int
__init
acpi_fan_init
(
void
)
{
int
result
=
0
;
...
...
drivers/acpi/power.c
View file @
14f7d720
...
...
@@ -86,7 +86,6 @@ struct acpi_power_resource {
acpi_bus_id
name
;
u32
system_level
;
u32
order
;
int
state
;
struct
mutex
resource_lock
;
struct
list_head
reference
;
};
...
...
@@ -128,33 +127,31 @@ acpi_power_get_context(acpi_handle handle,
return
0
;
}
static
int
acpi_power_get_state
(
struct
acpi_power_resource
*
resource
)
static
int
acpi_power_get_state
(
struct
acpi_power_resource
*
resource
,
int
*
state
)
{
acpi_status
status
=
AE_OK
;
unsigned
long
sta
=
0
;
if
(
!
resource
)
if
(
!
resource
||
!
state
)
return
-
EINVAL
;
status
=
acpi_evaluate_integer
(
resource
->
device
->
handle
,
"_STA"
,
NULL
,
&
sta
);
if
(
ACPI_FAILURE
(
status
))
return
-
ENODEV
;
if
(
sta
&
0x01
)
resource
->
state
=
ACPI_POWER_RESOURCE_STATE_ON
;
else
resource
->
state
=
ACPI_POWER_RESOURCE_STATE_OFF
;
*
state
=
(
sta
&
0x01
)
?
ACPI_POWER_RESOURCE_STATE_ON
:
ACPI_POWER_RESOURCE_STATE_OFF
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Resource [%s] is %s
\n
"
,
resource
->
name
,
resource
->
state
?
"on"
:
"off"
));
resource
->
name
,
state
?
"on"
:
"off"
));
return
0
;
}
static
int
acpi_power_get_list_state
(
struct
acpi_handle_list
*
list
,
int
*
state
)
{
int
result
=
0
;
int
result
=
0
,
state1
;
struct
acpi_power_resource
*
resource
=
NULL
;
u32
i
=
0
;
...
...
@@ -168,11 +165,11 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
result
=
acpi_power_get_context
(
list
->
handles
[
i
],
&
resource
);
if
(
result
)
return
result
;
result
=
acpi_power_get_state
(
resource
);
result
=
acpi_power_get_state
(
resource
,
&
state1
);
if
(
result
)
return
result
;
*
state
=
resource
->
state
;
*
state
=
state1
;
if
(
*
state
!=
ACPI_POWER_RESOURCE_STATE_ON
)
break
;
...
...
@@ -186,7 +183,7 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
static
int
acpi_power_on
(
acpi_handle
handle
,
struct
acpi_device
*
dev
)
{
int
result
=
0
;
int
result
=
0
,
state
;
int
found
=
0
;
acpi_status
status
=
AE_OK
;
struct
acpi_power_resource
*
resource
=
NULL
;
...
...
@@ -224,20 +221,14 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
}
mutex_unlock
(
&
resource
->
resource_lock
);
if
(
resource
->
state
==
ACPI_POWER_RESOURCE_STATE_ON
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Resource [%s] already on
\n
"
,
resource
->
name
));
return
0
;
}
status
=
acpi_evaluate_object
(
resource
->
device
->
handle
,
"_ON"
,
NULL
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
return
-
ENODEV
;
result
=
acpi_power_get_state
(
resource
);
result
=
acpi_power_get_state
(
resource
,
&
state
);
if
(
result
)
return
result
;
if
(
resource
->
state
!=
ACPI_POWER_RESOURCE_STATE_ON
)
if
(
state
!=
ACPI_POWER_RESOURCE_STATE_ON
)
return
-
ENOEXEC
;
/* Update the power resource's _device_ power state */
...
...
@@ -250,7 +241,7 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
static
int
acpi_power_off_device
(
acpi_handle
handle
,
struct
acpi_device
*
dev
)
{
int
result
=
0
;
int
result
=
0
,
state
;
acpi_status
status
=
AE_OK
;
struct
acpi_power_resource
*
resource
=
NULL
;
struct
list_head
*
node
,
*
next
;
...
...
@@ -281,20 +272,14 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
}
mutex_unlock
(
&
resource
->
resource_lock
);
if
(
resource
->
state
==
ACPI_POWER_RESOURCE_STATE_OFF
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Resource [%s] already off
\n
"
,
resource
->
name
));
return
0
;
}
status
=
acpi_evaluate_object
(
resource
->
device
->
handle
,
"_OFF"
,
NULL
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
return
-
ENODEV
;
result
=
acpi_power_get_state
(
resource
);
result
=
acpi_power_get_state
(
resource
,
&
state
);
if
(
result
)
return
result
;
if
(
resource
->
state
!=
ACPI_POWER_RESOURCE_STATE_OFF
)
if
(
state
!=
ACPI_POWER_RESOURCE_STATE_OFF
)
return
-
ENOEXEC
;
/* Update the power resource's _device_ power state */
...
...
@@ -494,7 +479,7 @@ static struct proc_dir_entry *acpi_power_dir;
static
int
acpi_power_seq_show
(
struct
seq_file
*
seq
,
void
*
offset
)
{
int
count
=
0
;
int
result
=
0
;
int
result
=
0
,
state
;
struct
acpi_power_resource
*
resource
=
NULL
;
struct
list_head
*
node
,
*
next
;
struct
acpi_power_reference
*
ref
;
...
...
@@ -505,12 +490,12 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset)
if
(
!
resource
)
goto
end
;
result
=
acpi_power_get_state
(
resource
);
result
=
acpi_power_get_state
(
resource
,
&
state
);
if
(
result
)
goto
end
;
seq_puts
(
seq
,
"state: "
);
switch
(
resource
->
state
)
{
switch
(
state
)
{
case
ACPI_POWER_RESOURCE_STATE_ON
:
seq_puts
(
seq
,
"on
\n
"
);
break
;
...
...
@@ -591,7 +576,7 @@ static int acpi_power_remove_fs(struct acpi_device *device)
static
int
acpi_power_add
(
struct
acpi_device
*
device
)
{
int
result
=
0
;
int
result
=
0
,
state
;
acpi_status
status
=
AE_OK
;
struct
acpi_power_resource
*
resource
=
NULL
;
union
acpi_object
acpi_object
;
...
...
@@ -622,11 +607,11 @@ static int acpi_power_add(struct acpi_device *device)
resource
->
system_level
=
acpi_object
.
power_resource
.
system_level
;
resource
->
order
=
acpi_object
.
power_resource
.
resource_order
;
result
=
acpi_power_get_state
(
resource
);
result
=
acpi_power_get_state
(
resource
,
&
state
);
if
(
result
)
goto
end
;
switch
(
resource
->
state
)
{
switch
(
state
)
{
case
ACPI_POWER_RESOURCE_STATE_ON
:
device
->
power
.
state
=
ACPI_STATE_D0
;
break
;
...
...
@@ -643,7 +628,7 @@ static int acpi_power_add(struct acpi_device *device)
goto
end
;
printk
(
KERN_INFO
PREFIX
"%s [%s] (%s)
\n
"
,
acpi_device_name
(
device
),
acpi_device_bid
(
device
),
resource
->
state
?
"on"
:
"off"
);
acpi_device_bid
(
device
),
state
?
"on"
:
"off"
);
end:
if
(
result
)
...
...
@@ -680,7 +665,7 @@ static int acpi_power_remove(struct acpi_device *device, int type)
static
int
acpi_power_resume
(
struct
acpi_device
*
device
)
{
int
result
=
0
;
int
result
=
0
,
state
;
struct
acpi_power_resource
*
resource
=
NULL
;
struct
acpi_power_reference
*
ref
;
...
...
@@ -689,12 +674,12 @@ static int acpi_power_resume(struct acpi_device *device)
resource
=
(
struct
acpi_power_resource
*
)
acpi_driver_data
(
device
);
result
=
acpi_power_get_state
(
resource
);
result
=
acpi_power_get_state
(
resource
,
&
state
);
if
(
result
)
return
result
;
mutex_lock
(
&
resource
->
resource_lock
);
if
(
(
resource
->
state
==
ACPI_POWER_RESOURCE_STATE_OFF
)
&&
if
(
state
==
ACPI_POWER_RESOURCE_STATE_OFF
&&
!
list_empty
(
&
resource
->
reference
))
{
ref
=
container_of
(
resource
->
reference
.
next
,
struct
acpi_power_reference
,
node
);
mutex_unlock
(
&
resource
->
resource_lock
);
...
...
drivers/acpi/sleep/main.c
View file @
14f7d720
...
...
@@ -167,8 +167,8 @@ static void acpi_pm_finish(void)
{
u32
acpi_state
=
acpi_target_sleep_state
;
acpi_leave_sleep_state
(
acpi_state
);
acpi_disable_wakeup_device
(
acpi_state
);
acpi_leave_sleep_state
(
acpi_state
);
/* reset firmware waking vector */
acpi_set_firmware_waking_vector
((
acpi_physical_address
)
0
);
...
...
@@ -272,8 +272,8 @@ static void acpi_hibernation_finish(void)
* enable it here.
*/
acpi_enable
();
acpi_leave_sleep_state
(
ACPI_STATE_S4
);
acpi_disable_wakeup_device
(
ACPI_STATE_S4
);
acpi_leave_sleep_state
(
ACPI_STATE_S4
);
/* reset firmware waking vector */
acpi_set_firmware_waking_vector
((
acpi_physical_address
)
0
);
...
...
@@ -410,6 +410,7 @@ static void acpi_power_off(void)
/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
printk
(
"%s called
\n
"
,
__FUNCTION__
);
local_irq_disable
();
acpi_enable_wakeup_device
(
ACPI_STATE_S5
);
acpi_enter_sleep_state
(
ACPI_STATE_S5
);
}
...
...
include/acpi/acpi_bus.h
View file @
14f7d720
...
...
@@ -168,8 +168,7 @@ struct acpi_device_flags {
u32
power_manageable
:
1
;
u32
performance_manageable
:
1
;
u32
wake_capable
:
1
;
/* Wakeup(_PRW) supported? */
u32
force_power_state
:
1
;
u32
reserved
:
19
;
u32
reserved
:
20
;
};
/* File System */
...
...
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