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
d95a1b48
Commit
d95a1b48
authored
Aug 03, 2005
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge master.kernel.org:/pub/scm/linux/kernel/git/lenb/to-linus
parents
194d0710
8066eff0
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
634 additions
and
309 deletions
+634
-309
drivers/acpi/Kconfig
drivers/acpi/Kconfig
+3
-2
drivers/acpi/button.c
drivers/acpi/button.c
+205
-1
drivers/acpi/ec.c
drivers/acpi/ec.c
+19
-5
drivers/acpi/hotkey.c
drivers/acpi/hotkey.c
+393
-297
drivers/acpi/pci_link.c
drivers/acpi/pci_link.c
+11
-0
drivers/acpi/processor_idle.c
drivers/acpi/processor_idle.c
+3
-4
No files found.
drivers/acpi/Kconfig
View file @
d95a1b48
...
...
@@ -133,9 +133,10 @@ config ACPI_HOTKEY
depends on ACPI_INTERPRETER
depends on EXPERIMENTAL
depends on !IA64_SGI_SN
default
m
default
n
help
ACPI generic hotkey
Experimental consolidated hotkey driver.
If you are unsure, say N.
config ACPI_FAN
tristate "Fan"
...
...
drivers/acpi/button.c
View file @
d95a1b48
...
...
@@ -26,6 +26,9 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
...
...
@@ -33,6 +36,9 @@
#define ACPI_BUTTON_COMPONENT 0x00080000
#define ACPI_BUTTON_DRIVER_NAME "ACPI Button Driver"
#define ACPI_BUTTON_CLASS "button"
#define ACPI_BUTTON_FILE_INFO "info"
#define ACPI_BUTTON_FILE_STATE "state"
#define ACPI_BUTTON_TYPE_UNKNOWN 0x00
#define ACPI_BUTTON_NOTIFY_STATUS 0x80
#define ACPI_BUTTON_SUBCLASS_POWER "power"
...
...
@@ -64,6 +70,8 @@ MODULE_LICENSE("GPL");
static
int
acpi_button_add
(
struct
acpi_device
*
device
);
static
int
acpi_button_remove
(
struct
acpi_device
*
device
,
int
type
);
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
);
static
struct
acpi_driver
acpi_button_driver
=
{
.
name
=
ACPI_BUTTON_DRIVER_NAME
,
...
...
@@ -82,6 +90,179 @@ struct acpi_button {
unsigned
long
pushed
;
};
static
struct
file_operations
acpi_button_info_fops
=
{
.
open
=
acpi_button_info_open_fs
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
};
static
struct
file_operations
acpi_button_state_fops
=
{
.
open
=
acpi_button_state_open_fs
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
};
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
static
struct
proc_dir_entry
*
acpi_button_dir
;
static
int
acpi_button_info_seq_show
(
struct
seq_file
*
seq
,
void
*
offset
)
{
struct
acpi_button
*
button
=
(
struct
acpi_button
*
)
seq
->
private
;
ACPI_FUNCTION_TRACE
(
"acpi_button_info_seq_show"
);
if
(
!
button
||
!
button
->
device
)
return_VALUE
(
0
);
seq_printf
(
seq
,
"type: %s
\n
"
,
acpi_device_name
(
button
->
device
));
return_VALUE
(
0
);
}
static
int
acpi_button_info_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
acpi_button_info_seq_show
,
PDE
(
inode
)
->
data
);
}
static
int
acpi_button_state_seq_show
(
struct
seq_file
*
seq
,
void
*
offset
)
{
struct
acpi_button
*
button
=
(
struct
acpi_button
*
)
seq
->
private
;
acpi_status
status
;
unsigned
long
state
;
ACPI_FUNCTION_TRACE
(
"acpi_button_state_seq_show"
);
if
(
!
button
||
!
button
->
device
)
return_VALUE
(
0
);
status
=
acpi_evaluate_integer
(
button
->
handle
,
"_LID"
,
NULL
,
&
state
);
if
(
ACPI_FAILURE
(
status
))
{
seq_printf
(
seq
,
"state: unsupported
\n
"
);
}
else
{
seq_printf
(
seq
,
"state: %s
\n
"
,
(
state
?
"open"
:
"closed"
));
}
return_VALUE
(
0
);
}
static
int
acpi_button_state_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
acpi_button_state_seq_show
,
PDE
(
inode
)
->
data
);
}
static
struct
proc_dir_entry
*
acpi_power_dir
;
static
struct
proc_dir_entry
*
acpi_sleep_dir
;
static
struct
proc_dir_entry
*
acpi_lid_dir
;
static
int
acpi_button_add_fs
(
struct
acpi_device
*
device
)
{
struct
proc_dir_entry
*
entry
=
NULL
;
struct
acpi_button
*
button
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_button_add_fs"
);
if
(
!
device
||
!
acpi_driver_data
(
device
))
return_VALUE
(
-
EINVAL
);
button
=
acpi_driver_data
(
device
);
switch
(
button
->
type
)
{
case
ACPI_BUTTON_TYPE_POWER
:
case
ACPI_BUTTON_TYPE_POWERF
:
if
(
!
acpi_power_dir
)
acpi_power_dir
=
proc_mkdir
(
ACPI_BUTTON_SUBCLASS_POWER
,
acpi_button_dir
);
entry
=
acpi_power_dir
;
break
;
case
ACPI_BUTTON_TYPE_SLEEP
:
case
ACPI_BUTTON_TYPE_SLEEPF
:
if
(
!
acpi_sleep_dir
)
acpi_sleep_dir
=
proc_mkdir
(
ACPI_BUTTON_SUBCLASS_SLEEP
,
acpi_button_dir
);
entry
=
acpi_sleep_dir
;
break
;
case
ACPI_BUTTON_TYPE_LID
:
if
(
!
acpi_lid_dir
)
acpi_lid_dir
=
proc_mkdir
(
ACPI_BUTTON_SUBCLASS_LID
,
acpi_button_dir
);
entry
=
acpi_lid_dir
;
break
;
}
if
(
!
entry
)
return_VALUE
(
-
ENODEV
);
entry
->
owner
=
THIS_MODULE
;
acpi_device_dir
(
device
)
=
proc_mkdir
(
acpi_device_bid
(
device
),
entry
);
if
(
!
acpi_device_dir
(
device
))
return_VALUE
(
-
ENODEV
);
acpi_device_dir
(
device
)
->
owner
=
THIS_MODULE
;
/* 'info' [R] */
entry
=
create_proc_entry
(
ACPI_BUTTON_FILE_INFO
,
S_IRUGO
,
acpi_device_dir
(
device
));
if
(
!
entry
)
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Unable to create '%s' fs entry
\n
"
,
ACPI_BUTTON_FILE_INFO
));
else
{
entry
->
proc_fops
=
&
acpi_button_info_fops
;
entry
->
data
=
acpi_driver_data
(
device
);
entry
->
owner
=
THIS_MODULE
;
}
/* show lid state [R] */
if
(
button
->
type
==
ACPI_BUTTON_TYPE_LID
)
{
entry
=
create_proc_entry
(
ACPI_BUTTON_FILE_STATE
,
S_IRUGO
,
acpi_device_dir
(
device
));
if
(
!
entry
)
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Unable to create '%s' fs entry
\n
"
,
ACPI_BUTTON_FILE_INFO
));
else
{
entry
->
proc_fops
=
&
acpi_button_state_fops
;
entry
->
data
=
acpi_driver_data
(
device
);
entry
->
owner
=
THIS_MODULE
;
}
}
return_VALUE
(
0
);
}
static
int
acpi_button_remove_fs
(
struct
acpi_device
*
device
)
{
struct
acpi_button
*
button
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_button_remove_fs"
);
button
=
acpi_driver_data
(
device
);
if
(
acpi_device_dir
(
device
))
{
if
(
button
->
type
==
ACPI_BUTTON_TYPE_LID
)
remove_proc_entry
(
ACPI_BUTTON_FILE_STATE
,
acpi_device_dir
(
device
));
remove_proc_entry
(
ACPI_BUTTON_FILE_INFO
,
acpi_device_dir
(
device
));
remove_proc_entry
(
acpi_device_bid
(
device
),
acpi_device_dir
(
device
)
->
parent
);
acpi_device_dir
(
device
)
=
NULL
;
}
return_VALUE
(
0
);
}
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
...
...
@@ -121,7 +302,8 @@ acpi_button_notify_fixed (
ACPI_FUNCTION_TRACE
(
"acpi_button_notify_fixed"
);
BUG_ON
(
!
button
);
if
(
!
button
)
return_ACPI_STATUS
(
AE_BAD_PARAMETER
);
acpi_button_notify
(
button
->
handle
,
ACPI_BUTTON_NOTIFY_STATUS
,
button
);
...
...
@@ -197,6 +379,10 @@ acpi_button_add (
goto
end
;
}
result
=
acpi_button_add_fs
(
device
);
if
(
result
)
goto
end
;
switch
(
button
->
type
)
{
case
ACPI_BUTTON_TYPE_POWERF
:
status
=
acpi_install_fixed_event_handler
(
...
...
@@ -240,6 +426,7 @@ acpi_button_add (
end:
if
(
result
)
{
acpi_button_remove_fs
(
device
);
kfree
(
button
);
}
...
...
@@ -280,6 +467,8 @@ acpi_button_remove (struct acpi_device *device, int type)
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Error removing notify handler
\n
"
));
acpi_button_remove_fs
(
device
);
kfree
(
button
);
return_VALUE
(
0
);
...
...
@@ -293,14 +482,20 @@ acpi_button_init (void)
ACPI_FUNCTION_TRACE
(
"acpi_button_init"
);
acpi_button_dir
=
proc_mkdir
(
ACPI_BUTTON_CLASS
,
acpi_root_dir
);
if
(
!
acpi_button_dir
)
return_VALUE
(
-
ENODEV
);
acpi_button_dir
->
owner
=
THIS_MODULE
;
result
=
acpi_bus_register_driver
(
&
acpi_button_driver
);
if
(
result
<
0
)
{
remove_proc_entry
(
ACPI_BUTTON_CLASS
,
acpi_root_dir
);
return_VALUE
(
-
ENODEV
);
}
return_VALUE
(
0
);
}
static
void
__exit
acpi_button_exit
(
void
)
{
...
...
@@ -308,8 +503,17 @@ acpi_button_exit (void)
acpi_bus_unregister_driver
(
&
acpi_button_driver
);
if
(
acpi_power_dir
)
remove_proc_entry
(
ACPI_BUTTON_SUBCLASS_POWER
,
acpi_button_dir
);
if
(
acpi_sleep_dir
)
remove_proc_entry
(
ACPI_BUTTON_SUBCLASS_SLEEP
,
acpi_button_dir
);
if
(
acpi_lid_dir
)
remove_proc_entry
(
ACPI_BUTTON_SUBCLASS_LID
,
acpi_button_dir
);
remove_proc_entry
(
ACPI_BUTTON_CLASS
,
acpi_root_dir
);
return_VOID
;
}
module_init
(
acpi_button_init
);
module_exit
(
acpi_button_exit
);
drivers/acpi/ec.c
View file @
d95a1b48
...
...
@@ -76,13 +76,14 @@ static int acpi_ec_remove (struct acpi_device *device, int type);
static
int
acpi_ec_start
(
struct
acpi_device
*
device
);
static
int
acpi_ec_stop
(
struct
acpi_device
*
device
,
int
type
);
static
int
acpi_ec_burst_add
(
struct
acpi_device
*
device
);
static
int
acpi_ec_polling_add
(
struct
acpi_device
*
device
);
static
struct
acpi_driver
acpi_ec_driver
=
{
.
name
=
ACPI_EC_DRIVER_NAME
,
.
class
=
ACPI_EC_CLASS
,
.
ids
=
ACPI_EC_HID
,
.
ops
=
{
.
add
=
acpi_ec_
burst
_add
,
.
add
=
acpi_ec_
polling
_add
,
.
remove
=
acpi_ec_remove
,
.
start
=
acpi_ec_start
,
.
stop
=
acpi_ec_stop
,
...
...
@@ -164,7 +165,7 @@ static union acpi_ec *ec_ecdt;
/* External interfaces use first EC only, so remember */
static
struct
acpi_device
*
first_ec
;
static
int
acpi_ec_polling_mode
;
static
int
acpi_ec_polling_mode
=
EC_POLLING
;
/* --------------------------------------------------------------------------
Transaction Management
...
...
@@ -1710,11 +1711,24 @@ static int __init acpi_fake_ecdt_setup(char *str)
acpi_fake_ecdt_enabled
=
1
;
return
0
;
}
__setup
(
"acpi_fake_ecdt"
,
acpi_fake_ecdt_setup
);
static
int
__init
acpi_ec_set_polling_mode
(
char
*
str
)
{
acpi_ec_polling_mode
=
EC_POLLING
;
acpi_ec_driver
.
ops
.
add
=
acpi_ec_polling_add
;
int
burst
;
if
(
!
get_option
(
&
str
,
&
burst
))
return
0
;
if
(
burst
)
{
acpi_ec_polling_mode
=
EC_BURST
;
acpi_ec_driver
.
ops
.
add
=
acpi_ec_burst_add
;
}
else
{
acpi_ec_polling_mode
=
EC_POLLING
;
acpi_ec_driver
.
ops
.
add
=
acpi_ec_polling_add
;
}
printk
(
KERN_INFO
PREFIX
"EC %s mode.
\n
"
,
burst
?
"burst"
:
"polling"
);
return
0
;
}
__setup
(
"ec_
polling
"
,
acpi_ec_set_polling_mode
);
__setup
(
"ec_
burst=
"
,
acpi_ec_set_polling_mode
);
drivers/acpi/hotkey.c
View file @
d95a1b48
/*
* hotkey.c - ACPI Hotkey Driver ($Revision:$)
/*
* hotkey.c - ACPI Hotkey Driver ($Revision:
0.2
$)
*
* Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
*
...
...
@@ -51,17 +51,18 @@
#define ACPI_HOTKEY_POLLING 0x2
#define ACPI_UNDEFINED_EVENT 0xf
#define MAX_CONFIG_RECORD_LEN 80
#define MAX_NAME_PATH_LEN 80
#define MAX_CALL_PARM 80
#define RESULT_STR_LEN 80
#define
IS_EVENT(e) 0xff
/* ((e) & 0x40000000) */
#define
IS_POLL(e) 0xff
/* (~((e) & 0x40000000)) */
#define
ACTION_METHOD 0
#define
POLL_METHOD 1
#define IS_EVENT(e) ((e) <= 10000 && (e) >0)
#define IS_POLL(e) ((e) > 10000)
#define IS_OTHERS(e) ((e)<=0 || (e)>=20000)
#define _COMPONENT ACPI_HOTKEY_COMPONENT
ACPI_MODULE_NAME
(
"acpi_hotkey"
)
MODULE_AUTHOR
(
"luming.yu@intel.com"
);
MODULE_AUTHOR
(
"luming.yu@intel.com"
);
MODULE_DESCRIPTION
(
ACPI_HOTK_NAME
);
MODULE_LICENSE
(
"GPL"
);
...
...
@@ -114,7 +115,7 @@ struct acpi_event_hotkey {
char
*
action_method
;
/* action method */
};
/*
/*
* There are two ways to poll status
* 1. directy call read_xxx method, without any arguments passed in
* 2. call write_xxx method, with arguments passed in, you need
...
...
@@ -131,7 +132,7 @@ struct acpi_polling_hotkey {
char
*
poll_method
;
/* poll method */
acpi_handle
action_handle
;
/* acpi handle attached action method */
char
*
action_method
;
/* action method */
void
*
poll_result
;
/* polling_result */
union
acpi_object
*
poll_result
;
/* polling_result */
struct
proc_dir_entry
*
proc
;
};
...
...
@@ -162,20 +163,25 @@ static struct acpi_driver hotkey_driver = {
},
};
static
void
free_hotkey_device
(
union
acpi_hotkey
*
key
);
static
void
free_hotkey_buffer
(
union
acpi_hotkey
*
key
);
static
void
free_poll_hotkey_buffer
(
union
acpi_hotkey
*
key
);
static
int
hotkey_open_config
(
struct
inode
*
inode
,
struct
file
*
file
);
static
int
hotkey_poll_open_config
(
struct
inode
*
inode
,
struct
file
*
file
);
static
ssize_t
hotkey_write_config
(
struct
file
*
file
,
const
char
__user
*
buffer
,
size_t
count
,
loff_t
*
data
);
static
ssize_t
hotkey_write_poll_config
(
struct
file
*
file
,
const
char
__user
*
buffer
,
size_t
count
,
loff_t
*
data
);
static
int
hotkey_info_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
);
static
int
hotkey_action_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
);
static
ssize_t
hotkey_execute_aml_method
(
struct
file
*
file
,
const
char
__user
*
buffer
,
size_t
count
,
loff_t
*
data
);
static
int
hotkey_config_seq_show
(
struct
seq_file
*
seq
,
void
*
offset
);
static
int
hotkey_poll_config_seq_show
(
struct
seq_file
*
seq
,
void
*
offset
);
static
int
hotkey_polling_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
);
static
union
acpi_hotkey
*
get_hotkey_by_event
(
struct
acpi_hotkey_list
*
hotkey_list
,
int
event
);
/* event based config */
static
struct
file_operations
hotkey_config_fops
=
{
...
...
@@ -188,9 +194,9 @@ static struct file_operations hotkey_config_fops = {
/* polling based config */
static
struct
file_operations
hotkey_poll_config_fops
=
{
.
open
=
hotkey_open_config
,
.
open
=
hotkey_
poll_
open_config
,
.
read
=
seq_read
,
.
write
=
hotkey_write_
poll_
config
,
.
write
=
hotkey_write_config
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
};
...
...
@@ -227,7 +233,7 @@ static int hotkey_info_seq_show(struct seq_file *seq, void *offset)
{
ACPI_FUNCTION_TRACE
(
"hotkey_info_seq_show"
);
seq_printf
(
seq
,
"Hotkey generic driver ver: %s"
,
HOTKEY_ACPI_VERSION
);
seq_printf
(
seq
,
"Hotkey generic driver ver: %s
\n
"
,
HOTKEY_ACPI_VERSION
);
return_VALUE
(
0
);
}
...
...
@@ -239,27 +245,35 @@ static int hotkey_info_open_fs(struct inode *inode, struct file *file)
static
char
*
format_result
(
union
acpi_object
*
object
)
{
char
*
buf
=
(
char
*
)
kmalloc
(
sizeof
(
union
acpi_object
),
GFP_KERNEL
);
memset
(
buf
,
0
,
sizeof
(
union
acpi_object
));
char
*
buf
=
NULL
;
buf
=
(
char
*
)
kmalloc
(
RESULT_STR_LEN
,
GFP_KERNEL
);
if
(
buf
)
memset
(
buf
,
0
,
RESULT_STR_LEN
);
else
goto
do_fail
;
/* Now, just support integer type */
if
(
object
->
type
==
ACPI_TYPE_INTEGER
)
sprintf
(
buf
,
"%d"
,
(
u32
)
object
->
integer
.
value
);
return
buf
;
sprintf
(
buf
,
"%d
\n
"
,
(
u32
)
object
->
integer
.
value
);
do_fail:
return
(
buf
)
;
}
static
int
hotkey_polling_seq_show
(
struct
seq_file
*
seq
,
void
*
offset
)
{
struct
acpi_polling_hotkey
*
poll_hotkey
=
(
struct
acpi_polling_hotkey
*
)
seq
->
private
;
char
*
buf
;
ACPI_FUNCTION_TRACE
(
"hotkey_polling_seq_show"
);
if
(
poll_hotkey
->
poll_result
)
seq_printf
(
seq
,
"%s"
,
format_result
(
poll_hotkey
->
poll_result
));
if
(
poll_hotkey
->
poll_result
){
buf
=
format_result
(
poll_hotkey
->
poll_result
);
if
(
buf
)
seq_printf
(
seq
,
"%s"
,
buf
);
kfree
(
buf
);
}
return_VALUE
(
0
);
}
...
...
@@ -276,19 +290,19 @@ static int hotkey_action_open_fs(struct inode *inode, struct file *file)
/* Mapping external hotkey number to standardized hotkey event num */
static
int
hotkey_get_internal_event
(
int
event
,
struct
acpi_hotkey_list
*
list
)
{
struct
list_head
*
entries
,
*
next
;
int
val
=
0
;
struct
list_head
*
entries
;
int
val
=
-
1
;
ACPI_FUNCTION_TRACE
(
"hotkey_get_internal_event"
);
list_for_each
_safe
(
entries
,
next
,
list
->
entries
)
{
list_for_each
(
entries
,
list
->
entries
)
{
union
acpi_hotkey
*
key
=
container_of
(
entries
,
union
acpi_hotkey
,
entries
);
if
(
key
->
link
.
hotkey_type
==
ACPI_HOTKEY_EVENT
&&
key
->
event_hotkey
.
external_hotkey_num
==
event
)
&&
key
->
event_hotkey
.
external_hotkey_num
==
event
)
{
val
=
key
->
link
.
hotkey_standard_num
;
else
val
=
-
1
;
break
;
}
}
return_VALUE
(
val
);
...
...
@@ -306,7 +320,7 @@ acpi_hotkey_notify_handler(acpi_handle handle, u32 event, void *data)
return_VOID
;
internal_event
=
hotkey_get_internal_event
(
event
,
&
global_hotkey_list
);
acpi_bus_generate_event
(
device
,
event
,
0
);
acpi_bus_generate_event
(
device
,
internal_
event
,
0
);
return_VOID
;
}
...
...
@@ -329,13 +343,17 @@ static int auto_hotkey_remove(struct acpi_device *device, int type)
static
int
create_polling_proc
(
union
acpi_hotkey
*
device
)
{
struct
proc_dir_entry
*
proc
;
char
proc_name
[
80
];
mode_t
mode
;
ACPI_FUNCTION_TRACE
(
"create_polling_proc"
);
mode
=
S_IFREG
|
S_IRUGO
|
S_IWUGO
;
proc
=
create_proc_entry
(
device
->
poll_hotkey
.
action_method
,
mode
,
hotkey_proc_dir
);
sprintf
(
proc_name
,
"%d"
,
device
->
link
.
hotkey_standard_num
);
/*
strcat(proc_name, device->poll_hotkey.poll_method);
*/
proc
=
create_proc_entry
(
proc_name
,
mode
,
hotkey_proc_dir
);
if
(
!
proc
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
...
...
@@ -353,23 +371,6 @@ static int create_polling_proc(union acpi_hotkey *device)
return_VALUE
(
0
);
}
static
int
is_valid_acpi_path
(
const
char
*
pathname
)
{
acpi_handle
handle
;
acpi_status
status
;
ACPI_FUNCTION_TRACE
(
"is_valid_acpi_path"
);
status
=
acpi_get_handle
(
NULL
,
(
char
*
)
pathname
,
&
handle
);
return_VALUE
(
!
ACPI_FAILURE
(
status
));
}
static
int
is_valid_hotkey
(
union
acpi_hotkey
*
device
)
{
ACPI_FUNCTION_TRACE
(
"is_valid_hotkey"
);
/* Implement valid check */
return_VALUE
(
1
);
}
static
int
hotkey_add
(
union
acpi_hotkey
*
device
)
{
int
status
=
0
;
...
...
@@ -378,15 +379,11 @@ static int hotkey_add(union acpi_hotkey *device)
ACPI_FUNCTION_TRACE
(
"hotkey_add"
);
if
(
device
->
link
.
hotkey_type
==
ACPI_HOTKEY_EVENT
)
{
status
=
acpi_bus_get_device
(
device
->
event_hotkey
.
bus_handle
,
&
dev
);
if
(
status
)
return_VALUE
(
status
);
acpi_bus_get_device
(
device
->
event_hotkey
.
bus_handle
,
&
dev
);
status
=
acpi_install_notify_handler
(
dev
->
handle
,
ACPI_
SYSTEM
_NOTIFY
,
ACPI_
DEVICE
_NOTIFY
,
acpi_hotkey_notify_handler
,
dev
ice
);
dev
);
}
else
/* Add polling hotkey */
create_polling_proc
(
device
);
...
...
@@ -409,84 +406,143 @@ static int hotkey_remove(union acpi_hotkey *device)
if
(
key
->
link
.
hotkey_standard_num
==
device
->
link
.
hotkey_standard_num
)
{
list_del
(
&
key
->
link
.
entries
);
remove_proc_entry
(
key
->
poll_hotkey
.
action_method
,
hotkey_proc_dir
);
free_hotkey_device
(
key
);
global_hotkey_list
.
count
--
;
break
;
}
}
kfree
(
device
);
return_VALUE
(
0
);
}
static
void
hotkey_update
(
union
acpi_hotkey
*
key
)
static
int
hotkey_update
(
union
acpi_hotkey
*
key
)
{
struct
list_head
*
entries
,
*
next
;
struct
list_head
*
entries
;
ACPI_FUNCTION_TRACE
(
"hotkey_update"
);
list_for_each
_safe
(
entries
,
next
,
global_hotkey_list
.
entries
)
{
union
acpi_hotkey
*
key
=
list_for_each
(
entries
,
global_hotkey_list
.
entries
)
{
union
acpi_hotkey
*
tmp
=
container_of
(
entries
,
union
acpi_hotkey
,
entries
);
if
(
key
->
link
.
hotkey_standard_num
==
if
(
tmp
->
link
.
hotkey_standard_num
==
key
->
link
.
hotkey_standard_num
)
{
key
->
event_hotkey
.
bus_handle
=
key
->
event_hotkey
.
bus_handle
;
key
->
event_hotkey
.
external_hotkey_num
=
key
->
event_hotkey
.
external_hotkey_num
;
key
->
event_hotkey
.
action_handle
=
key
->
event_hotkey
.
action_handle
;
key
->
event_hotkey
.
action_method
=
key
->
event_hotkey
.
action_method
;
if
(
key
->
link
.
hotkey_type
==
ACPI_HOTKEY_EVENT
)
{
free_hotkey_buffer
(
tmp
);
tmp
->
event_hotkey
.
bus_handle
=
key
->
event_hotkey
.
bus_handle
;
tmp
->
event_hotkey
.
external_hotkey_num
=
key
->
event_hotkey
.
external_hotkey_num
;
tmp
->
event_hotkey
.
action_handle
=
key
->
event_hotkey
.
action_handle
;
tmp
->
event_hotkey
.
action_method
=
key
->
event_hotkey
.
action_method
;
kfree
(
key
);
}
else
{
/*
char proc_name[80];
sprintf(proc_name, "%d", tmp->link.hotkey_standard_num);
strcat(proc_name, tmp->poll_hotkey.poll_method);
remove_proc_entry(proc_name,hotkey_proc_dir);
*/
free_poll_hotkey_buffer
(
tmp
);
tmp
->
poll_hotkey
.
poll_handle
=
key
->
poll_hotkey
.
poll_handle
;
tmp
->
poll_hotkey
.
poll_method
=
key
->
poll_hotkey
.
poll_method
;
tmp
->
poll_hotkey
.
action_handle
=
key
->
poll_hotkey
.
action_handle
;
tmp
->
poll_hotkey
.
action_method
=
key
->
poll_hotkey
.
action_method
;
tmp
->
poll_hotkey
.
poll_result
=
key
->
poll_hotkey
.
poll_result
;
/*
create_polling_proc(tmp);
*/
kfree
(
key
);
}
return_VALUE
(
0
);
break
;
}
}
return_V
OID
;
return_V
ALUE
(
-
ENODEV
)
;
}
static
void
free_hotkey_device
(
union
acpi_hotkey
*
key
)
{
struct
acpi_device
*
dev
;
int
status
;
ACPI_FUNCTION_TRACE
(
"free_hotkey_device"
);
if
(
key
->
link
.
hotkey_type
==
ACPI_HOTKEY_EVENT
)
{
status
=
acpi_bus_get_device
(
key
->
event_hotkey
.
bus_handle
,
&
dev
);
acpi_bus_get_device
(
key
->
event_hotkey
.
bus_handle
,
&
dev
);
if
(
dev
->
handle
)
acpi_remove_notify_handler
(
dev
->
handle
,
ACPI_
SYSTEM
_NOTIFY
,
ACPI_
DEVICE
_NOTIFY
,
acpi_hotkey_notify_handler
);
}
else
remove_proc_entry
(
key
->
poll_hotkey
.
action_method
,
hotkey_proc_dir
);
free_hotkey_buffer
(
key
);
}
else
{
char
proc_name
[
80
];
sprintf
(
proc_name
,
"%d"
,
key
->
link
.
hotkey_standard_num
);
/*
strcat(proc_name, key->poll_hotkey.poll_method);
*/
remove_proc_entry
(
proc_name
,
hotkey_proc_dir
);
free_poll_hotkey_buffer
(
key
);
}
kfree
(
key
);
return_VOID
;
}
static
void
free_hotkey_buffer
(
union
acpi_hotkey
*
key
)
{
kfree
(
key
->
event_hotkey
.
action_method
);
}
static
void
free_poll_hotkey_buffer
(
union
acpi_hotkey
*
key
)
{
kfree
(
key
->
poll_hotkey
.
action_method
);
kfree
(
key
->
poll_hotkey
.
poll_method
);
kfree
(
key
->
poll_hotkey
.
poll_result
);
}
static
int
init_hotkey_device
(
union
acpi_hotkey
*
key
,
char
*
bus_str
,
char
*
action_str
,
char
*
method
,
int
std_num
,
int
external_num
)
{
acpi_handle
tmp_handle
;
acpi_status
status
=
AE_OK
;
ACPI_FUNCTION_TRACE
(
"init_hotkey_device"
);
if
(
std_num
<
0
||
IS_POLL
(
std_num
)
||
!
key
)
goto
do_fail
;
if
(
!
bus_str
||
!
action_str
||
!
method
)
goto
do_fail
;
key
->
link
.
hotkey_type
=
ACPI_HOTKEY_EVENT
;
key
->
link
.
hotkey_standard_num
=
std_num
;
key
->
event_hotkey
.
flag
=
0
;
if
(
is_valid_acpi_path
(
bus_str
))
acpi_get_handle
((
acpi_handle
)
0
,
bus_str
,
&
(
key
->
event_hotkey
.
bus_handle
));
else
return_VALUE
(
-
ENODEV
);
key
->
event_hotkey
.
external_hotkey_num
=
external_num
;
if
(
is_valid_acpi_path
(
action_str
))
acpi_get_handle
((
acpi_handle
)
0
,
action_str
,
&
(
key
->
event_hotkey
.
action_handle
));
key
->
event_hotkey
.
action_method
=
kmalloc
(
sizeof
(
method
),
GFP_KERNEL
);
strcpy
(
key
->
event_hotkey
.
action_method
,
method
);
key
->
event_hotkey
.
action_method
=
method
;
return_VALUE
(
!
is_valid_hotkey
(
key
));
status
=
acpi_get_handle
(
NULL
,
bus_str
,
&
(
key
->
event_hotkey
.
bus_handle
));
if
(
ACPI_FAILURE
(
status
))
goto
do_fail
;
key
->
event_hotkey
.
external_hotkey_num
=
external_num
;
status
=
acpi_get_handle
(
NULL
,
action_str
,
&
(
key
->
event_hotkey
.
action_handle
));
if
(
ACPI_FAILURE
(
status
))
goto
do_fail
;
status
=
acpi_get_handle
(
key
->
event_hotkey
.
action_handle
,
method
,
&
tmp_handle
);
if
(
ACPI_FAILURE
(
status
))
goto
do_fail
;
return_VALUE
(
AE_OK
);
do_fail:
return_VALUE
(
-
ENODEV
);
}
static
int
...
...
@@ -495,34 +551,46 @@ init_poll_hotkey_device(union acpi_hotkey *key,
char
*
poll_method
,
char
*
action_str
,
char
*
action_method
,
int
std_num
)
{
acpi_status
status
=
AE_OK
;
acpi_handle
tmp_handle
;
ACPI_FUNCTION_TRACE
(
"init_poll_hotkey_device"
);
if
(
std_num
<
0
||
IS_EVENT
(
std_num
)
||
!
key
)
goto
do_fail
;
if
(
!
poll_str
||
!
poll_method
||
!
action_str
||
!
action_method
)
goto
do_fail
;
key
->
link
.
hotkey_type
=
ACPI_HOTKEY_POLLING
;
key
->
link
.
hotkey_standard_num
=
std_num
;
key
->
poll_hotkey
.
flag
=
0
;
if
(
is_valid_acpi_path
(
poll_str
))
acpi_get_handle
((
acpi_handle
)
0
,
poll_str
,
&
(
key
->
poll_hotkey
.
poll_handle
));
else
return_VALUE
(
-
ENODEV
);
key
->
poll_hotkey
.
poll_method
=
poll_method
;
if
(
is_valid_acpi_path
(
action_str
))
acpi_get_handle
((
acpi_handle
)
0
,
action_str
,
&
(
key
->
poll_hotkey
.
action_handle
));
key
->
poll_hotkey
.
action_method
=
kmalloc
(
sizeof
(
action_method
),
GFP_KERNEL
);
strcpy
(
key
->
poll_hotkey
.
action_method
,
action_method
);
key
->
poll_hotkey
.
action_method
=
action_method
;
status
=
acpi_get_handle
(
NULL
,
poll_str
,
&
(
key
->
poll_hotkey
.
poll_handle
));
if
(
ACPI_FAILURE
(
status
))
goto
do_fail
;
status
=
acpi_get_handle
(
key
->
poll_hotkey
.
poll_handle
,
poll_method
,
&
tmp_handle
);
if
(
ACPI_FAILURE
(
status
))
goto
do_fail
;
status
=
acpi_get_handle
(
NULL
,
action_str
,
&
(
key
->
poll_hotkey
.
action_handle
));
if
(
ACPI_FAILURE
(
status
))
goto
do_fail
;
status
=
acpi_get_handle
(
key
->
poll_hotkey
.
action_handle
,
action_method
,
&
tmp_handle
);
if
(
ACPI_FAILURE
(
status
))
goto
do_fail
;
key
->
poll_hotkey
.
poll_result
=
(
union
acpi_object
*
)
kmalloc
(
sizeof
(
union
acpi_object
),
GFP_KERNEL
);
return_VALUE
(
is_valid_hotkey
(
key
));
if
(
!
key
->
poll_hotkey
.
poll_result
)
goto
do_fail
;
return_VALUE
(
AE_OK
);
do_fail:
return_VALUE
(
-
ENODEV
);
}
static
int
check_hotkey_valid
(
union
acpi_hotkey
*
key
,
struct
acpi_hotkey_list
*
list
)
{
ACPI_FUNCTION_TRACE
(
"check_hotkey_valid"
);
return_VALUE
(
0
);
}
static
int
hotkey_open_config
(
struct
inode
*
inode
,
struct
file
*
file
)
{
...
...
@@ -531,10 +599,17 @@ static int hotkey_open_config(struct inode *inode, struct file *file)
(
file
,
hotkey_config_seq_show
,
PDE
(
inode
)
->
data
));
}
static
int
hotkey_poll_open_config
(
struct
inode
*
inode
,
struct
file
*
file
)
{
ACPI_FUNCTION_TRACE
(
"hotkey_poll_open_config"
);
return_VALUE
(
single_open
(
file
,
hotkey_poll_config_seq_show
,
PDE
(
inode
)
->
data
));
}
static
int
hotkey_config_seq_show
(
struct
seq_file
*
seq
,
void
*
offset
)
{
struct
acpi_hotkey_list
*
hotkey_list
=
&
global_hotkey_list
;
struct
list_head
*
entries
,
*
next
;
struct
list_head
*
entries
;
char
bus_name
[
ACPI_PATHNAME_MAX
]
=
{
0
};
char
action_name
[
ACPI_PATHNAME_MAX
]
=
{
0
};
struct
acpi_buffer
bus
=
{
ACPI_PATHNAME_MAX
,
bus_name
};
...
...
@@ -542,10 +617,7 @@ static int hotkey_config_seq_show(struct seq_file *seq, void *offset)
ACPI_FUNCTION_TRACE
((
"hotkey_config_seq_show"
));
if
(
!
hotkey_list
)
goto
end
;
list_for_each_safe
(
entries
,
next
,
hotkey_list
->
entries
)
{
list_for_each
(
entries
,
hotkey_list
->
entries
)
{
union
acpi_hotkey
*
key
=
container_of
(
entries
,
union
acpi_hotkey
,
entries
);
if
(
key
->
link
.
hotkey_type
==
ACPI_HOTKEY_EVENT
)
{
...
...
@@ -553,18 +625,37 @@ static int hotkey_config_seq_show(struct seq_file *seq, void *offset)
ACPI_NAME_TYPE_MAX
,
&
bus
);
acpi_get_name
(
key
->
event_hotkey
.
action_handle
,
ACPI_NAME_TYPE_MAX
,
&
act
);
seq_printf
(
seq
,
"%s:%s:%s:%d:%d"
,
bus_name
,
seq_printf
(
seq
,
"%s:%s:%s:%d:%d
\n
"
,
bus_name
,
action_name
,
key
->
event_hotkey
.
action_method
,
key
->
link
.
hotkey_standard_num
,
key
->
event_hotkey
.
external_hotkey_num
);
}
/* ACPI_HOTKEY_POLLING */
else
{
}
}
seq_puts
(
seq
,
"
\n
"
);
return_VALUE
(
0
);
}
static
int
hotkey_poll_config_seq_show
(
struct
seq_file
*
seq
,
void
*
offset
)
{
struct
acpi_hotkey_list
*
hotkey_list
=
&
global_hotkey_list
;
struct
list_head
*
entries
;
char
bus_name
[
ACPI_PATHNAME_MAX
]
=
{
0
};
char
action_name
[
ACPI_PATHNAME_MAX
]
=
{
0
};
struct
acpi_buffer
bus
=
{
ACPI_PATHNAME_MAX
,
bus_name
};
struct
acpi_buffer
act
=
{
ACPI_PATHNAME_MAX
,
action_name
};
ACPI_FUNCTION_TRACE
((
"hotkey_config_seq_show"
));
list_for_each
(
entries
,
hotkey_list
->
entries
)
{
union
acpi_hotkey
*
key
=
container_of
(
entries
,
union
acpi_hotkey
,
entries
);
if
(
key
->
link
.
hotkey_type
==
ACPI_HOTKEY_POLLING
)
{
acpi_get_name
(
key
->
poll_hotkey
.
poll_handle
,
ACPI_NAME_TYPE_MAX
,
&
bus
);
acpi_get_name
(
key
->
poll_hotkey
.
action_handle
,
ACPI_NAME_TYPE_MAX
,
&
act
);
seq_printf
(
seq
,
"%s:%s:%s:%s:%d"
,
bus_name
,
seq_printf
(
seq
,
"%s:%s:%s:%s:%d
\n
"
,
bus_name
,
key
->
poll_hotkey
.
poll_method
,
action_name
,
key
->
poll_hotkey
.
action_method
,
...
...
@@ -572,49 +663,83 @@ static int hotkey_config_seq_show(struct seq_file *seq, void *offset)
}
}
seq_puts
(
seq
,
"
\n
"
);
end:
return_VALUE
(
0
);
}
static
int
get_parms
(
char
*
config_record
,
int
*
cmd
,
char
*
bus_handle
,
char
*
bus_method
,
char
*
action_handle
,
char
*
method
,
int
*
internal_event_num
,
int
*
external_event_num
)
char
*
*
bus_handle
,
char
*
*
bus_method
,
char
*
*
action_handle
,
char
*
*
method
,
int
*
internal_event_num
,
int
*
external_event_num
)
{
char
*
tmp
,
*
tmp1
;
char
*
tmp
,
*
tmp1
,
count
;
ACPI_FUNCTION_TRACE
((
"get_parms"
));
sscanf
(
config_record
,
"%d"
,
cmd
);
if
(
*
cmd
==
1
){
if
(
sscanf
(
config_record
,
"%d:%d"
,
cmd
,
internal_event_num
)
!=
2
)
goto
do_fail
;
else
return
(
6
);
}
tmp
=
strchr
(
config_record
,
':'
);
if
(
!
tmp
)
goto
do_fail
;
tmp
++
;
tmp1
=
strchr
(
tmp
,
':'
);
strncpy
(
bus_handle
,
tmp
,
tmp1
-
tmp
);
bus_handle
[
tmp1
-
tmp
]
=
0
;
if
(
!
tmp1
)
goto
do_fail
;
count
=
tmp1
-
tmp
;
*
bus_handle
=
(
char
*
)
kmalloc
(
count
+
1
,
GFP_KERNEL
);
if
(
!*
bus_handle
)
goto
do_fail
;
strncpy
(
*
bus_handle
,
tmp
,
count
);
*
(
*
bus_handle
+
count
)
=
0
;
tmp
=
tmp1
;
tmp
++
;
tmp1
=
strchr
(
tmp
,
':'
);
strncpy
(
bus_method
,
tmp
,
tmp1
-
tmp
);
bus_method
[
tmp1
-
tmp
]
=
0
;
if
(
!
tmp1
)
goto
do_fail
;
count
=
tmp1
-
tmp
;
*
bus_method
=
(
char
*
)
kmalloc
(
count
+
1
,
GFP_KERNEL
);
if
(
!*
bus_method
)
goto
do_fail
;
strncpy
(
*
bus_method
,
tmp
,
count
);
*
(
*
bus_method
+
count
)
=
0
;
tmp
=
tmp1
;
tmp
++
;
tmp1
=
strchr
(
tmp
,
':'
);
strncpy
(
action_handle
,
tmp
,
tmp1
-
tmp
);
action_handle
[
tmp1
-
tmp
]
=
0
;
if
(
!
tmp1
)
goto
do_fail
;
count
=
tmp1
-
tmp
;
*
action_handle
=
(
char
*
)
kmalloc
(
count
+
1
,
GFP_KERNEL
);
strncpy
(
*
action_handle
,
tmp
,
count
);
*
(
*
action_handle
+
count
)
=
0
;
tmp
=
tmp1
;
tmp
++
;
tmp1
=
strchr
(
tmp
,
':'
);
strncpy
(
method
,
tmp
,
tmp1
-
tmp
);
method
[
tmp1
-
tmp
]
=
0
;
if
(
!
tmp1
)
goto
do_fail
;
count
=
tmp1
-
tmp
;
*
method
=
(
char
*
)
kmalloc
(
count
+
1
,
GFP_KERNEL
);
if
(
!*
method
)
goto
do_fail
;
strncpy
(
*
method
,
tmp
,
count
);
*
(
*
method
+
count
)
=
0
;
if
(
sscanf
(
tmp1
+
1
,
"%d:%d"
,
internal_event_num
,
external_event_num
)
<=
0
)
goto
do_fail
;
sscanf
(
tmp1
+
1
,
"%d:%d"
,
internal_event_num
,
external_event_num
);
return_VALUE
(
6
);
do_fail:
return_VALUE
(
-
1
);
}
/* count is length for one input record */
...
...
@@ -622,135 +747,117 @@ static ssize_t hotkey_write_config(struct file *file,
const
char
__user
*
buffer
,
size_t
count
,
loff_t
*
data
)
{
struct
acpi_hotkey_list
*
hotkey_list
=
&
global_hotkey_list
;
char
config_record
[
MAX_CONFIG_RECORD_LEN
];
char
bus_handle
[
MAX_NAME_PATH_LEN
];
char
bus_method
[
MAX_NAME_PATH_LEN
];
char
action_handle
[
MAX_NAME_PATH_LEN
];
char
method
[
20
];
char
*
config_record
=
NULL
;
char
*
bus_handle
=
NULL
;
char
*
bus_method
=
NULL
;
char
*
action_handle
=
NULL
;
char
*
method
=
NULL
;
int
cmd
,
internal_event_num
,
external_event_num
;
int
ret
=
0
;
union
acpi_hotkey
*
key
=
NULL
;
ACPI_FUNCTION_TRACE
((
"hotkey_write_config"
));
if
(
!
hotkey_list
||
count
>
MAX_CONFIG_RECORD_LEN
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid arguments
\n
"
));
return_VALUE
(
-
EINVAL
);
}
config_record
=
(
char
*
)
kmalloc
(
count
+
1
,
GFP_KERNEL
);
if
(
!
config_record
)
return_VALUE
(
-
ENOMEM
);
if
(
copy_from_user
(
config_record
,
buffer
,
count
))
{
kfree
(
config_record
);
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid data
\n
"
));
return_VALUE
(
-
EINVAL
);
}
config_record
[
count
]
=
'\0'
;
config_record
[
count
]
=
0
;
ret
=
get_parms
(
config_record
,
&
cmd
,
bus_handle
,
bus_method
,
action_handle
,
method
,
&
internal_event_num
,
&
external_event_num
);
&
bus_handle
,
&
bus_method
,
&
action_handle
,
&
method
,
&
internal_event_num
,
&
external_event_num
);
kfree
(
config_record
);
if
(
IS_OTHERS
(
internal_event_num
))
goto
do_fail
;
if
(
ret
!=
6
)
{
do_fail:
kfree
(
bus_handle
);
kfree
(
bus_method
);
kfree
(
action_handle
);
kfree
(
method
);
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid data format ret=%d
\n
"
,
ret
));
return_VALUE
(
-
EINVAL
);
}
key
=
kmalloc
(
sizeof
(
union
acpi_hotkey
),
GFP_KERNEL
);
ret
=
init_hotkey_device
(
key
,
bus_handle
,
action_handle
,
method
,
if
(
!
key
)
goto
do_fail
;
memset
(
key
,
0
,
sizeof
(
union
acpi_hotkey
));
if
(
cmd
==
1
)
{
union
acpi_hotkey
*
tmp
=
NULL
;
tmp
=
get_hotkey_by_event
(
&
global_hotkey_list
,
internal_event_num
);
if
(
!
tmp
)
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid key"
));
else
memcpy
(
key
,
tmp
,
sizeof
(
union
acpi_hotkey
));
goto
cont_cmd
;
}
if
(
IS_EVENT
(
internal_event_num
))
{
kfree
(
bus_method
);
ret
=
init_hotkey_device
(
key
,
bus_handle
,
action_handle
,
method
,
internal_event_num
,
external_event_num
);
if
(
ret
||
check_hotkey_valid
(
key
,
hotkey_list
))
{
}
else
ret
=
init_poll_hotkey_device
(
key
,
bus_handle
,
bus_method
,
action_handle
,
method
,
internal_event_num
);
if
(
ret
)
{
kfree
(
bus_handle
);
kfree
(
action_handle
);
if
(
IS_EVENT
(
internal_event_num
))
free_hotkey_buffer
(
key
);
else
free_poll_hotkey_buffer
(
key
);
kfree
(
key
);
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid hotkey
\n
"
));
return_VALUE
(
-
EINVAL
);
}
switch
(
cmd
)
{
case
0
:
hotkey_add
(
key
);
break
;
case
1
:
hotkey_remove
(
key
);
free_hotkey_device
(
key
);
break
;
case
2
:
hotkey_update
(
key
);
break
;
default:
break
;
}
return_VALUE
(
count
);
}
/* count is length for one input record */
static
ssize_t
hotkey_write_poll_config
(
struct
file
*
file
,
const
char
__user
*
buffer
,
size_t
count
,
loff_t
*
data
)
{
struct
seq_file
*
m
=
(
struct
seq_file
*
)
file
->
private_data
;
struct
acpi_hotkey_list
*
hotkey_list
=
(
struct
acpi_hotkey_list
*
)
m
->
private
;
char
config_record
[
MAX_CONFIG_RECORD_LEN
];
char
polling_handle
[
MAX_NAME_PATH_LEN
];
char
action_handle
[
MAX_NAME_PATH_LEN
];
char
poll_method
[
20
],
action_method
[
20
];
int
ret
,
internal_event_num
,
cmd
,
external_event_num
;
union
acpi_hotkey
*
key
=
NULL
;
ACPI_FUNCTION_TRACE
(
"hotkey_write_poll_config"
);
if
(
!
hotkey_list
||
count
>
MAX_CONFIG_RECORD_LEN
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid arguments
\n
"
));
return_VALUE
(
-
EINVAL
);
}
if
(
copy_from_user
(
config_record
,
buffer
,
count
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid data
\n
"
));
return_VALUE
(
-
EINVAL
);
}
config_record
[
count
]
=
'\0'
;
ret
=
get_parms
(
config_record
,
&
cmd
,
polling_handle
,
poll_method
,
action_handle
,
action_method
,
&
internal_event_num
,
&
external_event_num
);
if
(
ret
!=
6
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid data format
\n
"
));
return_VALUE
(
-
EINVAL
);
}
cont_cmd:
kfree
(
bus_handle
);
kfree
(
action_handle
);
key
=
kmalloc
(
sizeof
(
union
acpi_hotkey
),
GFP_KERNEL
);
ret
=
init_poll_hotkey_device
(
key
,
polling_handle
,
poll_method
,
action_handle
,
action_method
,
internal_event_num
);
if
(
ret
||
check_hotkey_valid
(
key
,
hotkey_list
))
{
kfree
(
key
);
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid hotkey
\n
"
));
return_VALUE
(
-
EINVAL
);
}
switch
(
cmd
)
{
case
0
:
hotkey_add
(
key
);
if
(
get_hotkey_by_event
(
&
global_hotkey_list
,
key
->
link
.
hotkey_standard_num
))
goto
fail_out
;
else
hotkey_add
(
key
);
break
;
case
1
:
hotkey_remove
(
key
);
break
;
case
2
:
hotkey_update
(
key
);
if
(
hotkey_update
(
key
))
goto
fail_out
;
break
;
default:
goto
fail_out
;
break
;
}
return_VALUE
(
count
);
fail_out:
if
(
IS_EVENT
(
internal_event_num
))
free_hotkey_buffer
(
key
);
else
free_poll_hotkey_buffer
(
key
);
kfree
(
key
);
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"invalid key
\n
"
));
return_VALUE
(
-
EINVAL
);
}
/*
/*
* This function evaluates an ACPI method, given an int as parameter, the
* method is searched within the scope of the handle, can be NULL. The output
* of the method is written is output, which can also be NULL
...
...
@@ -775,7 +882,7 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val,
return_VALUE
(
status
==
AE_OK
);
}
static
int
read_acpi_int
(
acpi_handle
handle
,
const
char
*
method
,
in
t
*
val
)
static
int
read_acpi_int
(
acpi_handle
handle
,
const
char
*
method
,
union
acpi_objec
t
*
val
)
{
struct
acpi_buffer
output
;
union
acpi_object
out_obj
;
...
...
@@ -786,62 +893,32 @@ static int read_acpi_int(acpi_handle handle, const char *method, int *val)
output
.
pointer
=
&
out_obj
;
status
=
acpi_evaluate_object
(
handle
,
(
char
*
)
method
,
NULL
,
&
output
);
*
val
=
out_obj
.
integer
.
value
;
if
(
val
){
val
->
integer
.
value
=
out_obj
.
integer
.
value
;
val
->
type
=
out_obj
.
type
;
}
else
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"null val pointer"
));
return_VALUE
((
status
==
AE_OK
)
&&
(
out_obj
.
type
==
ACPI_TYPE_INTEGER
));
}
static
acpi_handle
get_handle_from_hotkeylist
(
struct
acpi_hotkey_list
*
hotkey_list
,
int
event_num
)
static
union
acpi_hotkey
*
get_hotkey_by_event
(
struct
acpi_hotkey_list
*
hotkey_list
,
int
event
)
{
struct
list_head
*
entries
,
*
next
;
list_for_each_safe
(
entries
,
next
,
hotkey_list
->
entries
)
{
union
acpi_hotkey
*
key
=
container_of
(
entries
,
union
acpi_hotkey
,
entries
);
if
(
key
->
link
.
hotkey_type
==
ACPI_HOTKEY_EVENT
&&
key
->
link
.
hotkey_standard_num
==
event_num
)
{
return
(
key
->
event_hotkey
.
action_handle
);
}
}
return
(
NULL
);
}
static
char
*
get_method_from_hotkeylist
(
struct
acpi_hotkey_list
*
hotkey_list
,
int
event_num
)
{
struct
list_head
*
entries
,
*
next
;
list_for_each_safe
(
entries
,
next
,
hotkey_list
->
entries
)
{
union
acpi_hotkey
*
key
=
container_of
(
entries
,
union
acpi_hotkey
,
entries
);
if
(
key
->
link
.
hotkey_type
==
ACPI_HOTKEY_EVENT
&&
key
->
link
.
hotkey_standard_num
==
event_num
)
return
(
key
->
event_hotkey
.
action_method
);
}
return
(
NULL
);
}
static
struct
acpi_polling_hotkey
*
get_hotkey_by_event
(
struct
acpi_hotkey_list
*
hotkey_list
,
int
event
)
{
struct
list_head
*
entries
,
*
next
;
struct
list_head
*
entries
;
list_for_each
_safe
(
entries
,
next
,
hotkey_list
->
entries
)
{
list_for_each
(
entries
,
hotkey_list
->
entries
)
{
union
acpi_hotkey
*
key
=
container_of
(
entries
,
union
acpi_hotkey
,
entries
);
if
(
key
->
link
.
hotkey_type
==
ACPI_HOTKEY_POLLING
&&
key
->
link
.
hotkey_standard_num
==
event
)
{
return
(
&
key
->
poll_hotkey
);
if
(
key
->
link
.
hotkey_standard_num
==
event
)
{
return
(
key
);
}
}
return
(
NULL
);
return
(
NULL
);
}
/*
/*
* user call AML method interface:
* Call convention:
* echo "event_num: arg type : value"
...
...
@@ -854,48 +931,56 @@ static ssize_t hotkey_execute_aml_method(struct file *file,
size_t
count
,
loff_t
*
data
)
{
struct
acpi_hotkey_list
*
hotkey_list
=
&
global_hotkey_list
;
char
arg
[
MAX_CALL_PARM
];
int
event
,
type
,
value
;
char
*
method
;
acpi_handle
handle
;
char
*
arg
;
int
event
,
method_type
,
type
,
value
;
union
acpi_hotkey
*
key
;
ACPI_FUNCTION_TRACE
(
"hotkey_execte_aml_method"
);
if
(
!
hotkey_list
||
count
>
MAX_CALL_PARM
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid argument 1"
));
return_VALUE
(
-
E
INVAL
);
}
arg
=
(
char
*
)
kmalloc
(
count
+
1
,
GFP_KERNEL
);
if
(
!
arg
)
return_VALUE
(
-
E
NOMEM
);
arg
[
count
]
=
0
;
if
(
copy_from_user
(
arg
,
buffer
,
count
))
{
kfree
(
arg
);
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid argument 2"
));
return_VALUE
(
-
EINVAL
);
}
arg
[
count
]
=
'\0'
;
if
(
sscanf
(
arg
,
"%d:%d:%d"
,
&
event
,
&
type
,
&
value
)
!=
3
)
{
if
(
sscanf
(
arg
,
"%d:%d:%d:%d"
,
&
event
,
&
method_type
,
&
type
,
&
value
)
!=
4
)
{
kfree
(
arg
);
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid argument 3"
));
return_VALUE
(
-
EINVAL
);
}
kfree
(
arg
);
if
(
type
==
ACPI_TYPE_INTEGER
)
{
handle
=
get_handle_from_hotkeylist
(
hotkey_list
,
event
);
method
=
(
char
*
)
get_method_from_hotkeylist
(
hotkey_list
,
event
);
key
=
get_hotkey_by_event
(
hotkey_list
,
event
);
if
(
!
key
)
goto
do_fail
;
if
(
IS_EVENT
(
event
))
write_acpi_int
(
handle
,
method
,
value
,
NULL
);
write_acpi_int
(
key
->
event_hotkey
.
action_handle
,
key
->
event_hotkey
.
action_method
,
value
,
NULL
);
else
if
(
IS_POLL
(
event
))
{
struct
acpi_polling_hotkey
*
key
;
key
=
(
struct
acpi_polling_hotkey
*
)
get_hotkey_by_event
(
hotkey_list
,
event
);
read_acpi_int
(
handle
,
method
,
key
->
poll_result
);
if
(
method_type
==
POLL_METHOD
)
read_acpi_int
(
key
->
poll_hotkey
.
poll_handle
,
key
->
poll_hotkey
.
poll_method
,
key
->
poll_hotkey
.
poll_result
);
else
if
(
method_type
==
ACTION_METHOD
)
write_acpi_int
(
key
->
poll_hotkey
.
action_handle
,
key
->
poll_hotkey
.
action_method
,
value
,
NULL
);
else
goto
do_fail
;
}
}
else
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Not supported"
));
return_VALUE
(
-
EINVAL
);
}
return_VALUE
(
count
);
do_fail:
return_VALUE
(
-
EINVAL
);
}
static
int
__init
hotkey_init
(
void
)
...
...
@@ -928,7 +1013,7 @@ static int __init hotkey_init(void)
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Hotkey: Unable to create %s entry
\n
"
,
HOTKEY_EV_CONFIG
));
return
(
-
ENODEV
)
;
goto
do_fail1
;
}
else
{
hotkey_config
->
proc_fops
=
&
hotkey_config_fops
;
hotkey_config
->
data
=
&
global_hotkey_list
;
...
...
@@ -943,7 +1028,8 @@ static int __init hotkey_init(void)
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Hotkey: Unable to create %s entry
\n
"
,
HOTKEY_EV_CONFIG
));
return
(
-
ENODEV
);
goto
do_fail2
;
}
else
{
hotkey_poll_config
->
proc_fops
=
&
hotkey_poll_config_fops
;
hotkey_poll_config
->
data
=
&
global_hotkey_list
;
...
...
@@ -957,7 +1043,7 @@ static int __init hotkey_init(void)
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Hotkey: Unable to create %s entry
\n
"
,
HOTKEY_ACTION
));
return
(
-
ENODEV
)
;
goto
do_fail3
;
}
else
{
hotkey_action
->
proc_fops
=
&
hotkey_action_fops
;
hotkey_action
->
owner
=
THIS_MODULE
;
...
...
@@ -970,7 +1056,7 @@ static int __init hotkey_init(void)
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Hotkey: Unable to create %s entry
\n
"
,
HOTKEY_INFO
));
return
(
-
ENODEV
)
;
goto
do_fail4
;
}
else
{
hotkey_info
->
proc_fops
=
&
hotkey_info_fops
;
hotkey_info
->
owner
=
THIS_MODULE
;
...
...
@@ -979,23 +1065,33 @@ static int __init hotkey_init(void)
}
result
=
acpi_bus_register_driver
(
&
hotkey_driver
);
if
(
result
<
0
)
{
remove_proc_entry
(
HOTKEY_PROC
,
acpi_root_dir
);
return
(
-
ENODEV
);
}
if
(
result
<
0
)
goto
do_fail5
;
global_hotkey_list
.
count
=
0
;
global_hotkey_list
.
entries
=
&
hotkey_entries
;
INIT_LIST_HEAD
(
&
hotkey_entries
);
return
(
0
);
do_fail5:
remove_proc_entry
(
HOTKEY_INFO
,
hotkey_proc_dir
);
do_fail4:
remove_proc_entry
(
HOTKEY_ACTION
,
hotkey_proc_dir
);
do_fail3:
remove_proc_entry
(
HOTKEY_PL_CONFIG
,
hotkey_proc_dir
);
do_fail2:
remove_proc_entry
(
HOTKEY_EV_CONFIG
,
hotkey_proc_dir
);
do_fail1:
remove_proc_entry
(
HOTKEY_PROC
,
acpi_root_dir
);
return
(
-
ENODEV
);
}
static
void
__exit
hotkey_exit
(
void
)
{
struct
list_head
*
entries
,
*
next
;
ACPI_FUNCTION_TRACE
(
"hotkey_
remove
"
);
ACPI_FUNCTION_TRACE
(
"hotkey_
exit
"
);
list_for_each_safe
(
entries
,
next
,
global_hotkey_list
.
entries
)
{
union
acpi_hotkey
*
key
=
...
...
drivers/acpi/pci_link.c
View file @
d95a1b48
...
...
@@ -692,7 +692,18 @@ acpi_pci_link_free_irq(acpi_handle handle)
return_VALUE
(
-
1
);
}
#ifdef FUTURE_USE
/*
* The Link reference count allows us to _DISable an unused link
* and suspend time, and set it again on resume.
* However, 2.6.12 still has irq_router.resume
* which blindly restores the link state.
* So we disable the reference count method
* to prevent duplicate acpi_pci_link_set()
* which would harm some systems
*/
link
->
refcnt
--
;
#endif
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Link %s is dereferenced
\n
"
,
acpi_device_bid
(
link
->
device
)));
...
...
drivers/acpi/processor_idle.c
View file @
d95a1b48
...
...
@@ -86,12 +86,11 @@ static int set_max_cstate(struct dmi_system_id *id)
if
(
max_cstate
>
ACPI_PROCESSOR_MAX_POWER
)
return
0
;
printk
(
KERN_NOTICE
PREFIX
"%s detected -
%s disabled
."
printk
(
KERN_NOTICE
PREFIX
"%s detected -
limiting to C%ld max_cstate
."
" Override with
\"
processor.max_cstate=%d
\"\n
"
,
id
->
ident
,
((
int
)
id
->
driver_data
==
1
)
?
"C2,C3"
:
"C3"
,
ACPI_PROCESSOR_MAX_POWER
+
1
);
(
long
)
id
->
driver_data
,
ACPI_PROCESSOR_MAX_POWER
+
1
);
max_cstate
=
(
int
)
id
->
driver_data
;
max_cstate
=
(
long
)
id
->
driver_data
;
return
0
;
}
...
...
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