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
2e856220
Commit
2e856220
authored
Jul 22, 2007
by
Len Brown
Browse files
Options
Browse Files
Download
Plain Diff
Pull ec into release branch
parents
b43035a5
837012ed
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
149 additions
and
104 deletions
+149
-104
MAINTAINERS
MAINTAINERS
+3
-3
drivers/acpi/ec.c
drivers/acpi/ec.c
+146
-101
No files found.
MAINTAINERS
View file @
2e856220
...
...
@@ -225,15 +225,15 @@ T: git kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
S: Supported
ACPI BATTERY DRIVERS
P:
Vladimir P. Lebedev
M:
vladimir.p.lebedev@intel.com
P:
Alexey Starikovskiy
M:
astarikovskiy@suse.de
L: linux-acpi@vger.kernel.org
W: http://acpi.sourceforge.net/
S: Supported
ACPI EC DRIVER
P: Alexey Starikovskiy
M: a
lexey.y.starikovskiy@linux.intel.com
M: a
starikovskiy@suse.de
L: linux-acpi@vger.kernel.org
W: http://acpi.sourceforge.net/
S: Supported
...
...
drivers/acpi/ec.c
View file @
2e856220
...
...
@@ -34,25 +34,26 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <asm/io.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <acpi/actypes.h>
#define _COMPONENT ACPI_EC_COMPONENT
ACPI_MODULE_NAME
(
"ec"
);
#define ACPI_EC_COMPONENT 0x00100000
#define ACPI_EC_CLASS "embedded_controller"
#define ACPI_EC_HID "PNP0C09"
#define ACPI_EC_DEVICE_NAME "Embedded Controller"
#define ACPI_EC_FILE_INFO "info"
#undef PREFIX
#define PREFIX "ACPI: EC: "
/* EC status register */
#define ACPI_EC_FLAG_OBF 0x01
/* Output buffer full */
#define ACPI_EC_FLAG_IBF 0x02
/* Input buffer full */
#define ACPI_EC_FLAG_BURST 0x10
/* burst mode */
#define ACPI_EC_FLAG_SCI 0x20
/* EC-SCI occurred */
/* EC commands */
enum
ec_command
{
ACPI_EC_COMMAND_READ
=
0x80
,
...
...
@@ -61,6 +62,7 @@ enum ec_command {
ACPI_EC_BURST_DISABLE
=
0x83
,
ACPI_EC_COMMAND_QUERY
=
0x84
,
};
/* EC events */
enum
ec_event
{
ACPI_EC_EVENT_OBF_1
=
1
,
/* Output buffer full */
...
...
@@ -94,6 +96,16 @@ static struct acpi_driver acpi_ec_driver = {
/* If we find an EC via the ECDT, we need to keep a ptr to its context */
/* External interfaces use first EC only, so remember */
typedef
int
(
*
acpi_ec_query_func
)
(
void
*
data
);
struct
acpi_ec_query_handler
{
struct
list_head
node
;
acpi_ec_query_func
func
;
acpi_handle
handle
;
void
*
data
;
u8
query_bit
;
};
static
struct
acpi_ec
{
acpi_handle
handle
;
unsigned
long
gpe
;
...
...
@@ -104,6 +116,7 @@ static struct acpi_ec {
atomic_t
query_pending
;
atomic_t
event_count
;
wait_queue_head_t
wait
;
struct
list_head
list
;
}
*
boot_ec
,
*
first_ec
;
/* --------------------------------------------------------------------------
...
...
@@ -245,7 +258,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
status
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_IBF_0
,
0
,
0
);
if
(
status
)
{
printk
(
KERN_
DEBUG
PREFIX
printk
(
KERN_
ERR
PREFIX
"input buffer is not empty, aborting transaction
\n
"
);
goto
end
;
}
...
...
@@ -394,21 +407,67 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
/* --------------------------------------------------------------------------
Event Management
-------------------------------------------------------------------------- */
int
acpi_ec_add_query_handler
(
struct
acpi_ec
*
ec
,
u8
query_bit
,
acpi_handle
handle
,
acpi_ec_query_func
func
,
void
*
data
)
{
struct
acpi_ec_query_handler
*
handler
=
kzalloc
(
sizeof
(
struct
acpi_ec_query_handler
),
GFP_KERNEL
);
if
(
!
handler
)
return
-
ENOMEM
;
handler
->
query_bit
=
query_bit
;
handler
->
handle
=
handle
;
handler
->
func
=
func
;
handler
->
data
=
data
;
mutex_lock
(
&
ec
->
lock
);
list_add_tail
(
&
handler
->
node
,
&
ec
->
list
);
mutex_unlock
(
&
ec
->
lock
);
return
0
;
}
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
;
mutex_lock
(
&
ec
->
lock
);
list_for_each_entry
(
handler
,
&
ec
->
list
,
node
)
{
if
(
query_bit
==
handler
->
query_bit
)
{
list_del
(
&
handler
->
node
);
kfree
(
handler
);
break
;
}
}
mutex_unlock
(
&
ec
->
lock
);
}
EXPORT_SYMBOL_GPL
(
acpi_ec_remove_query_handler
);
static
void
acpi_ec_gpe_query
(
void
*
ec_cxt
)
{
struct
acpi_ec
*
ec
=
ec_cxt
;
u8
value
=
0
;
char
object_name
[
8
]
;
struct
acpi_ec_query_handler
*
handler
,
copy
;
if
(
!
ec
||
acpi_ec_query
(
ec
,
&
value
))
return
;
snprintf
(
object_name
,
8
,
"_Q%2.2X"
,
value
);
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Evaluating %s"
,
object_name
));
acpi_evaluate_object
(
ec
->
handle
,
object_name
,
NULL
,
NULL
);
mutex_lock
(
&
ec
->
lock
);
list_for_each_entry
(
handler
,
&
ec
->
list
,
node
)
{
if
(
value
==
handler
->
query_bit
)
{
/* have custom handler for this bit */
memcpy
(
&
copy
,
handler
,
sizeof
(
copy
));
mutex_unlock
(
&
ec
->
lock
);
if
(
copy
.
func
)
{
copy
.
func
(
copy
.
data
);
}
else
if
(
copy
.
handle
)
{
acpi_evaluate_object
(
copy
.
handle
,
NULL
,
NULL
,
NULL
);
}
return
;
}
}
mutex_unlock
(
&
ec
->
lock
);
printk
(
KERN_ERR
PREFIX
"Handler for query 0x%x is not found!
\n
"
,
value
);
}
static
u32
acpi_ec_gpe_handler
(
void
*
data
)
...
...
@@ -427,8 +486,7 @@ static u32 acpi_ec_gpe_handler(void *data)
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
);
acpi_os_execute
(
OSL_EC_BURST_HANDLER
,
acpi_ec_gpe_query
,
ec
);
}
return
status
==
AE_OK
?
...
...
@@ -454,57 +512,35 @@ acpi_ec_space_setup(acpi_handle region_handle,
}
static
acpi_status
acpi_ec_space_handler
(
u32
function
,
acpi_physical_address
address
,
u32
bit_width
,
acpi_integer
*
value
,
acpi_ec_space_handler
(
u32
function
,
acpi_physical_address
address
,
u32
bits
,
acpi_integer
*
value
,
void
*
handler_context
,
void
*
region_context
)
{
int
result
=
0
;
struct
acpi_ec
*
ec
=
handler_context
;
u64
temp
=
*
value
;
acpi_integer
f_v
=
0
;
int
i
=
0
;
int
result
=
0
,
i
=
0
;
u8
temp
=
0
;
if
((
address
>
0xFF
)
||
!
value
||
!
handler_context
)
return
AE_BAD_PARAMETER
;
if
(
bit_width
!=
8
&&
acpi_strict
)
{
if
(
function
!=
ACPI_READ
&&
function
!=
ACPI_WRITE
)
return
AE_BAD_PARAMETER
;
}
next_byte:
switch
(
function
)
{
case
ACPI_READ
:
temp
=
0
;
result
=
acpi_ec_read
(
ec
,
(
u8
)
address
,
(
u8
*
)
&
temp
);
break
;
case
ACPI_WRITE
:
result
=
acpi_ec_write
(
ec
,
(
u8
)
address
,
(
u8
)
temp
);
break
;
default:
result
=
-
EINVAL
;
goto
out
;
break
;
}
bit_width
-=
8
;
if
(
bit_width
)
{
if
(
function
==
ACPI_READ
)
f_v
|=
temp
<<
8
*
i
;
if
(
function
==
ACPI_WRITE
)
temp
>>=
8
;
i
++
;
address
++
;
goto
next_byte
;
}
if
(
bits
!=
8
&&
acpi_strict
)
return
AE_BAD_PARAMETER
;
if
(
function
==
ACPI_READ
)
{
f_v
|=
temp
<<
8
*
i
;
*
value
=
f_v
;
while
(
bits
-
i
>
0
)
{
if
(
function
==
ACPI_READ
)
{
result
=
acpi_ec_read
(
ec
,
address
,
&
temp
);
(
*
value
)
|=
((
acpi_integer
)
temp
)
<<
i
;
}
else
{
temp
=
0xff
&
((
*
value
)
>>
i
);
result
=
acpi_ec_write
(
ec
,
address
,
temp
);
}
i
+=
8
;
++
address
;
}
out:
switch
(
result
)
{
case
-
EINVAL
:
return
AE_BAD_PARAMETER
;
...
...
@@ -597,9 +633,6 @@ static int acpi_ec_remove_fs(struct acpi_device *device)
static
acpi_status
ec_parse_io_ports
(
struct
acpi_resource
*
resource
,
void
*
context
);
static
acpi_status
ec_parse_device
(
acpi_handle
handle
,
u32
Level
,
void
*
context
,
void
**
retval
);
static
struct
acpi_ec
*
make_acpi_ec
(
void
)
{
struct
acpi_ec
*
ec
=
kzalloc
(
sizeof
(
struct
acpi_ec
),
GFP_KERNEL
);
...
...
@@ -610,13 +643,52 @@ static struct acpi_ec *make_acpi_ec(void)
atomic_set
(
&
ec
->
event_count
,
1
);
mutex_init
(
&
ec
->
lock
);
init_waitqueue_head
(
&
ec
->
wait
);
INIT_LIST_HEAD
(
&
ec
->
list
);
return
ec
;
}
static
acpi_status
acpi_ec_register_query_methods
(
acpi_handle
handle
,
u32
level
,
void
*
context
,
void
**
return_value
)
{
struct
acpi_namespace_node
*
node
=
handle
;
struct
acpi_ec
*
ec
=
context
;
int
value
=
0
;
if
(
sscanf
(
node
->
name
.
ascii
,
"_Q%x"
,
&
value
)
==
1
)
{
acpi_ec_add_query_handler
(
ec
,
value
,
handle
,
NULL
,
NULL
);
}
return
AE_OK
;
}
static
int
ec_parse_device
(
struct
acpi_ec
*
ec
,
acpi_handle
handle
)
{
if
(
ACPI_FAILURE
(
acpi_walk_resources
(
handle
,
METHOD_NAME__CRS
,
ec_parse_io_ports
,
ec
)))
return
-
EINVAL
;
/* Get GPE bit assignment (EC events). */
/* TODO: Add support for _GPE returning a package */
if
(
ACPI_FAILURE
(
acpi_evaluate_integer
(
handle
,
"_GPE"
,
NULL
,
&
ec
->
gpe
)))
return
-
EINVAL
;
/* Use the global lock for all EC transactions? */
acpi_evaluate_integer
(
handle
,
"_GLK"
,
NULL
,
&
ec
->
global_lock
);
/* Find and register all query methods */
acpi_walk_namespace
(
ACPI_TYPE_METHOD
,
handle
,
1
,
acpi_ec_register_query_methods
,
ec
,
NULL
);
ec
->
handle
=
handle
;
printk
(
KERN_INFO
PREFIX
"GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx"
,
ec
->
gpe
,
ec
->
command_addr
,
ec
->
data_addr
);
return
0
;
}
static
int
acpi_ec_add
(
struct
acpi_device
*
device
)
{
acpi_status
status
=
AE_OK
;
struct
acpi_ec
*
ec
=
NULL
;
if
(
!
device
)
...
...
@@ -629,8 +701,7 @@ static int acpi_ec_add(struct acpi_device *device)
if
(
!
ec
)
return
-
ENOMEM
;
status
=
ec_parse_device
(
device
->
handle
,
0
,
ec
,
NULL
);
if
(
status
!=
AE_CTRL_TERMINATE
)
{
if
(
ec_parse_device
(
ec
,
device
->
handle
))
{
kfree
(
ec
);
return
-
EINVAL
;
}
...
...
@@ -641,6 +712,8 @@ static int acpi_ec_add(struct acpi_device *device)
/* We might have incorrect info for GL at boot time */
mutex_lock
(
&
boot_ec
->
lock
);
boot_ec
->
global_lock
=
ec
->
global_lock
;
/* Copy handlers from new ec into boot ec */
list_splice
(
&
ec
->
list
,
&
boot_ec
->
list
);
mutex_unlock
(
&
boot_ec
->
lock
);
kfree
(
ec
);
ec
=
boot_ec
;
...
...
@@ -651,22 +724,24 @@ static int acpi_ec_add(struct acpi_device *device)
acpi_driver_data
(
device
)
=
ec
;
acpi_ec_add_fs
(
device
);
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"%s [%s] (gpe %d) interrupt mode."
,
acpi_device_name
(
device
),
acpi_device_bid
(
device
),
(
u32
)
ec
->
gpe
));
return
0
;
}
static
int
acpi_ec_remove
(
struct
acpi_device
*
device
,
int
type
)
{
struct
acpi_ec
*
ec
;
struct
acpi_ec_query_handler
*
handler
;
if
(
!
device
)
return
-
EINVAL
;
ec
=
acpi_driver_data
(
device
);
mutex_lock
(
&
ec
->
lock
);
list_for_each_entry
(
handler
,
&
ec
->
list
,
node
)
{
list_del
(
&
handler
->
node
);
kfree
(
handler
);
}
mutex_unlock
(
&
ec
->
lock
);
acpi_ec_remove_fs
(
device
);
acpi_driver_data
(
device
)
=
NULL
;
if
(
ec
==
first_ec
)
...
...
@@ -722,15 +797,13 @@ static int ec_install_handlers(struct acpi_ec *ec)
return
-
ENODEV
;
}
/* EC is fully operational, allow queries */
atomic_set
(
&
ec
->
query_pending
,
0
);
return
0
;
}
static
int
acpi_ec_start
(
struct
acpi_device
*
device
)
{
struct
acpi_ec
*
ec
;
int
ret
=
0
;
if
(
!
device
)
return
-
EINVAL
;
...
...
@@ -740,14 +813,14 @@ static int acpi_ec_start(struct acpi_device *device)
if
(
!
ec
)
return
-
EINVAL
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"gpe=0x%02lx, ports=0x%2lx,0x%2lx"
,
ec
->
gpe
,
ec
->
command_addr
,
ec
->
data_addr
));
/* Boot EC is already working */
if
(
ec
==
boot_ec
)
return
0
;
if
(
ec
!=
boot_ec
)
ret
=
ec_install_handlers
(
ec
);
/* EC is fully operational, allow queries */
atomic_set
(
&
ec
->
query_pending
,
0
);
return
ec_install_handlers
(
ec
)
;
return
ret
;
}
static
int
acpi_ec_stop
(
struct
acpi_device
*
device
,
int
type
)
...
...
@@ -779,34 +852,6 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
return
0
;
}
static
acpi_status
ec_parse_device
(
acpi_handle
handle
,
u32
Level
,
void
*
context
,
void
**
retval
)
{
acpi_status
status
;
struct
acpi_ec
*
ec
=
context
;
status
=
acpi_walk_resources
(
handle
,
METHOD_NAME__CRS
,
ec_parse_io_ports
,
ec
);
if
(
ACPI_FAILURE
(
status
))
return
status
;
/* Get GPE bit assignment (EC events). */
/* TODO: Add support for _GPE returning a package */
status
=
acpi_evaluate_integer
(
handle
,
"_GPE"
,
NULL
,
&
ec
->
gpe
);
if
(
ACPI_FAILURE
(
status
))
return
status
;
/* Use the global lock for all EC transactions? */
acpi_evaluate_integer
(
handle
,
"_GLK"
,
NULL
,
&
ec
->
global_lock
);
ec
->
handle
=
handle
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"GPE=0x%02lx, ports=0x%2lx, 0x%2lx"
,
ec
->
gpe
,
ec
->
command_addr
,
ec
->
data_addr
));
return
AE_CTRL_TERMINATE
;
}
int
__init
acpi_ec_ecdt_probe
(
void
)
{
int
ret
;
...
...
@@ -825,7 +870,7 @@ int __init acpi_ec_ecdt_probe(void)
if
(
ACPI_FAILURE
(
status
))
goto
error
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Found ECDT"
)
);
printk
(
KERN_INFO
PREFIX
"EC description table is found, configuring boot EC
\n
"
);
boot_ec
->
command_addr
=
ecdt_ptr
->
control
.
address
;
boot_ec
->
data_addr
=
ecdt_ptr
->
data
.
address
;
...
...
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