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
d6ac1a79
Commit
d6ac1a79
authored
Jul 29, 2005
by
Len Brown
Browse files
Options
Browse Files
Download
Plain Diff
/home/lenb/src/to-linus branch 'acpi-2.6.12'
parents
577a4f81
87bec66b
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
980 additions
and
233 deletions
+980
-233
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+7
-0
arch/i386/pci/acpi.c
arch/i386/pci/acpi.c
+1
-0
arch/i386/pci/common.c
arch/i386/pci/common.c
+6
-0
arch/i386/pci/irq.c
arch/i386/pci/irq.c
+1
-0
arch/i386/pci/pci.h
arch/i386/pci/pci.h
+1
-0
drivers/acpi/ec.c
drivers/acpi/ec.c
+722
-171
drivers/acpi/pci_irq.c
drivers/acpi/pci_irq.c
+59
-26
drivers/acpi/pci_link.c
drivers/acpi/pci_link.c
+87
-16
drivers/acpi/processor_idle.c
drivers/acpi/processor_idle.c
+17
-14
drivers/net/sk98lin/skge.c
drivers/net/sk98lin/skge.c
+63
-0
drivers/pcmcia/yenta_socket.c
drivers/pcmcia/yenta_socket.c
+9
-0
include/acpi/acpi_drivers.h
include/acpi/acpi_drivers.h
+2
-1
include/linux/acpi.h
include/linux/acpi.h
+0
-4
sound/pci/intel8x0.c
sound/pci/intel8x0.c
+5
-1
No files found.
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
View file @
d6ac1a79
...
...
@@ -442,6 +442,13 @@ acpi_cpufreq_cpu_init (
(
u32
)
data
->
acpi_data
.
states
[
i
].
transition_latency
);
cpufreq_frequency_table_get_attr
(
data
->
freq_table
,
policy
->
cpu
);
/*
* the first call to ->target() should result in us actually
* writing something to the appropriate registers.
*/
data
->
resume
=
1
;
return
(
result
);
err_freqfree:
...
...
arch/i386/pci/acpi.c
View file @
d6ac1a79
...
...
@@ -30,6 +30,7 @@ static int __init pci_acpi_init(void)
acpi_irq_penalty_init
();
pcibios_scanned
++
;
pcibios_enable_irq
=
acpi_pci_irq_enable
;
pcibios_disable_irq
=
acpi_pci_irq_disable
;
if
(
pci_routeirq
)
{
/*
...
...
arch/i386/pci/common.c
View file @
d6ac1a79
...
...
@@ -254,3 +254,9 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
return
pcibios_enable_irq
(
dev
);
}
void
pcibios_disable_device
(
struct
pci_dev
*
dev
)
{
if
(
pcibios_disable_irq
)
pcibios_disable_irq
(
dev
);
}
arch/i386/pci/irq.c
View file @
d6ac1a79
...
...
@@ -56,6 +56,7 @@ struct irq_router_handler {
};
int
(
*
pcibios_enable_irq
)(
struct
pci_dev
*
dev
)
=
NULL
;
void
(
*
pcibios_disable_irq
)(
struct
pci_dev
*
dev
)
=
NULL
;
/*
* Check passed address for the PCI IRQ Routing Table signature
...
...
arch/i386/pci/pci.h
View file @
d6ac1a79
...
...
@@ -73,3 +73,4 @@ extern int pcibios_scanned;
extern
spinlock_t
pci_config_lock
;
extern
int
(
*
pcibios_enable_irq
)(
struct
pci_dev
*
dev
);
extern
void
(
*
pcibios_disable_irq
)(
struct
pci_dev
*
dev
);
drivers/acpi/ec.c
View file @
d6ac1a79
...
...
@@ -59,76 +59,185 @@ ACPI_MODULE_NAME ("acpi_ec")
#define ACPI_EC_DELAY 50
/* Wait 50ms max. during EC ops */
#define ACPI_EC_UDELAY_GLK 1000
/* Wait 1ms max. to get global lock */
#define ACPI_EC_UDELAY 100
/* Poll @ 100us increments */
#define ACPI_EC_UDELAY_COUNT 1000
/* Wait 10ms max. during EC ops */
#define ACPI_EC_COMMAND_READ 0x80
#define ACPI_EC_COMMAND_WRITE 0x81
#define ACPI_EC_BURST_ENABLE 0x82
#define ACPI_EC_BURST_DISABLE 0x83
#define ACPI_EC_COMMAND_QUERY 0x84
static
int
acpi_ec_add
(
struct
acpi_device
*
device
);
#define EC_POLLING 0xFF
#define EC_BURST 0x00
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
struct
acpi_driver
acpi_ec_driver
=
{
.
name
=
ACPI_EC_DRIVER_NAME
,
.
class
=
ACPI_EC_CLASS
,
.
ids
=
ACPI_EC_HID
,
.
ops
=
{
.
add
=
acpi_ec_add
,
.
add
=
acpi_ec_
burst_
add
,
.
remove
=
acpi_ec_remove
,
.
start
=
acpi_ec_start
,
.
stop
=
acpi_ec_stop
,
},
};
struct
acpi_ec
{
acpi_handle
handle
;
unsigned
long
uid
;
unsigned
long
gpe_bit
;
struct
acpi_generic_address
status_addr
;
struct
acpi_generic_address
command_addr
;
struct
acpi_generic_address
data_addr
;
unsigned
long
global_lock
;
unsigned
int
expect_event
;
atomic_t
leaving_burst
;
/* 0 : No, 1 : Yes, 2: abort*/
atomic_t
pending_gpe
;
struct
semaphore
sem
;
wait_queue_head_t
wait
;
union
acpi_ec
{
struct
{
u32
mode
;
acpi_handle
handle
;
unsigned
long
uid
;
unsigned
long
gpe_bit
;
struct
acpi_generic_address
status_addr
;
struct
acpi_generic_address
command_addr
;
struct
acpi_generic_address
data_addr
;
unsigned
long
global_lock
;
}
common
;
struct
{
u32
mode
;
acpi_handle
handle
;
unsigned
long
uid
;
unsigned
long
gpe_bit
;
struct
acpi_generic_address
status_addr
;
struct
acpi_generic_address
command_addr
;
struct
acpi_generic_address
data_addr
;
unsigned
long
global_lock
;
unsigned
int
expect_event
;
atomic_t
leaving_burst
;
/* 0 : No, 1 : Yes, 2: abort*/
atomic_t
pending_gpe
;
struct
semaphore
sem
;
wait_queue_head_t
wait
;
}
burst
;
struct
{
u32
mode
;
acpi_handle
handle
;
unsigned
long
uid
;
unsigned
long
gpe_bit
;
struct
acpi_generic_address
status_addr
;
struct
acpi_generic_address
command_addr
;
struct
acpi_generic_address
data_addr
;
unsigned
long
global_lock
;
spinlock_t
lock
;
}
polling
;
};
static
int
acpi_ec_polling_wait
(
union
acpi_ec
*
ec
,
u8
event
);
static
int
acpi_ec_burst_wait
(
union
acpi_ec
*
ec
,
unsigned
int
event
);
static
int
acpi_ec_polling_read
(
union
acpi_ec
*
ec
,
u8
address
,
u32
*
data
);
static
int
acpi_ec_burst_read
(
union
acpi_ec
*
ec
,
u8
address
,
u32
*
data
);
static
int
acpi_ec_polling_write
(
union
acpi_ec
*
ec
,
u8
address
,
u8
data
);
static
int
acpi_ec_burst_write
(
union
acpi_ec
*
ec
,
u8
address
,
u8
data
);
static
int
acpi_ec_polling_query
(
union
acpi_ec
*
ec
,
u32
*
data
);
static
int
acpi_ec_burst_query
(
union
acpi_ec
*
ec
,
u32
*
data
);
static
void
acpi_ec_gpe_polling_query
(
void
*
ec_cxt
);
static
void
acpi_ec_gpe_burst_query
(
void
*
ec_cxt
);
static
u32
acpi_ec_gpe_polling_handler
(
void
*
data
);
static
u32
acpi_ec_gpe_burst_handler
(
void
*
data
);
static
acpi_status
__init
acpi_fake_ecdt_polling_callback
(
acpi_handle
handle
,
u32
Level
,
void
*
context
,
void
**
retval
);
static
acpi_status
__init
acpi_fake_ecdt_burst_callback
(
acpi_handle
handle
,
u32
Level
,
void
*
context
,
void
**
retval
);
static
int
__init
acpi_ec_polling_get_real_ecdt
(
void
);
static
int
__init
acpi_ec_burst_get_real_ecdt
(
void
);
/* If we find an EC via the ECDT, we need to keep a ptr to its context */
static
struct
acpi_ec
*
ec_ecdt
;
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
;
/* --------------------------------------------------------------------------
Transaction Management
-------------------------------------------------------------------------- */
static
inline
u32
acpi_ec_read_status
(
struct
acpi_ec
*
ec
)
static
inline
u32
acpi_ec_read_status
(
union
acpi_ec
*
ec
)
{
u32
status
=
0
;
acpi_hw_low_level_read
(
8
,
&
status
,
&
ec
->
status_addr
);
acpi_hw_low_level_read
(
8
,
&
status
,
&
ec
->
common
.
status_addr
);
return
status
;
}
static
int
acpi_ec_wait
(
struct
acpi_ec
*
ec
,
unsigned
int
event
)
static
int
acpi_ec_wait
(
union
acpi_ec
*
ec
,
u8
event
)
{
if
(
acpi_ec_polling_mode
)
return
acpi_ec_polling_wait
(
ec
,
event
);
else
return
acpi_ec_burst_wait
(
ec
,
event
);
}
static
int
acpi_ec_polling_wait
(
union
acpi_ec
*
ec
,
u8
event
)
{
u32
acpi_ec_status
=
0
;
u32
i
=
ACPI_EC_UDELAY_COUNT
;
if
(
!
ec
)
return
-
EINVAL
;
/* Poll the EC status register waiting for the event to occur. */
switch
(
event
)
{
case
ACPI_EC_EVENT_OBF
:
do
{
acpi_hw_low_level_read
(
8
,
&
acpi_ec_status
,
&
ec
->
common
.
status_addr
);
if
(
acpi_ec_status
&
ACPI_EC_FLAG_OBF
)
return
0
;
udelay
(
ACPI_EC_UDELAY
);
}
while
(
--
i
>
0
);
break
;
case
ACPI_EC_EVENT_IBE
:
do
{
acpi_hw_low_level_read
(
8
,
&
acpi_ec_status
,
&
ec
->
common
.
status_addr
);
if
(
!
(
acpi_ec_status
&
ACPI_EC_FLAG_IBF
))
return
0
;
udelay
(
ACPI_EC_UDELAY
);
}
while
(
--
i
>
0
);
break
;
default:
return
-
EINVAL
;
}
return
-
ETIME
;
}
static
int
acpi_ec_burst_wait
(
union
acpi_ec
*
ec
,
unsigned
int
event
)
{
int
result
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_ec_wait"
);
ec
->
expect_event
=
event
;
ec
->
burst
.
expect_event
=
event
;
smp_mb
();
result
=
wait_event_interruptible_timeout
(
ec
->
wait
,
!
ec
->
expect_event
,
result
=
wait_event_interruptible_timeout
(
ec
->
burst
.
wait
,
!
ec
->
burst
.
expect_event
,
msecs_to_jiffies
(
ACPI_EC_DELAY
));
ec
->
expect_event
=
0
;
ec
->
burst
.
expect_event
=
0
;
smp_mb
();
if
(
result
<
0
){
...
...
@@ -160,7 +269,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, unsigned int event)
static
int
acpi_ec_enter_burst_mode
(
struct
acpi_ec
*
ec
)
union
acpi_ec
*
ec
)
{
u32
tmp
=
0
;
int
status
=
0
;
...
...
@@ -170,43 +279,43 @@ acpi_ec_enter_burst_mode (
status
=
acpi_ec_read_status
(
ec
);
if
(
status
!=
-
EINVAL
&&
!
(
status
&
ACPI_EC_FLAG_BURST
)){
acpi_hw_low_level_write
(
8
,
ACPI_EC_BURST_ENABLE
,
&
ec
->
command_addr
);
acpi_hw_low_level_write
(
8
,
ACPI_EC_BURST_ENABLE
,
&
ec
->
comm
on
.
comm
and_addr
);
status
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_OBF
);
if
(
status
){
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
return_VALUE
(
-
EINVAL
);
}
acpi_hw_low_level_read
(
8
,
&
tmp
,
&
ec
->
data_addr
);
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_hw_low_level_read
(
8
,
&
tmp
,
&
ec
->
common
.
data_addr
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
if
(
tmp
!=
0x90
)
{
/* Burst ACK byte*/
return_VALUE
(
-
EINVAL
);
}
}
atomic_set
(
&
ec
->
leaving_burst
,
0
);
atomic_set
(
&
ec
->
burst
.
leaving_burst
,
0
);
return_VALUE
(
0
);
}
static
int
acpi_ec_leave_burst_mode
(
struct
acpi_ec
*
ec
)
union
acpi_ec
*
ec
)
{
int
status
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_ec_leave_burst_mode"
);
atomic_set
(
&
ec
->
leaving_burst
,
1
);
atomic_set
(
&
ec
->
burst
.
leaving_burst
,
1
);
status
=
acpi_ec_read_status
(
ec
);
if
(
status
!=
-
EINVAL
&&
(
status
&
ACPI_EC_FLAG_BURST
)){
acpi_hw_low_level_write
(
8
,
ACPI_EC_BURST_DISABLE
,
&
ec
->
command_addr
);
acpi_hw_low_level_write
(
8
,
ACPI_EC_BURST_DISABLE
,
&
ec
->
comm
on
.
comm
and_addr
);
status
=
acpi_ec_wait
(
ec
,
ACPI_EC_FLAG_IBF
);
if
(
status
){
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"------->wait fail
\n
"
));
return_VALUE
(
-
EINVAL
);
}
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
status
=
acpi_ec_read_status
(
ec
);
}
...
...
@@ -215,7 +324,131 @@ acpi_ec_leave_burst_mode (
static
int
acpi_ec_read
(
struct
acpi_ec
*
ec
,
union
acpi_ec
*
ec
,
u8
address
,
u32
*
data
)
{
if
(
acpi_ec_polling_mode
)
return
acpi_ec_polling_read
(
ec
,
address
,
data
);
else
return
acpi_ec_burst_read
(
ec
,
address
,
data
);
}
static
int
acpi_ec_write
(
union
acpi_ec
*
ec
,
u8
address
,
u8
data
)
{
if
(
acpi_ec_polling_mode
)
return
acpi_ec_polling_write
(
ec
,
address
,
data
);
else
return
acpi_ec_burst_write
(
ec
,
address
,
data
);
}
static
int
acpi_ec_polling_read
(
union
acpi_ec
*
ec
,
u8
address
,
u32
*
data
)
{
acpi_status
status
=
AE_OK
;
int
result
=
0
;
unsigned
long
flags
=
0
;
u32
glk
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_ec_read"
);
if
(
!
ec
||
!
data
)
return_VALUE
(
-
EINVAL
);
*
data
=
0
;
if
(
ec
->
common
.
global_lock
)
{
status
=
acpi_acquire_global_lock
(
ACPI_EC_UDELAY_GLK
,
&
glk
);
if
(
ACPI_FAILURE
(
status
))
return_VALUE
(
-
ENODEV
);
}
spin_lock_irqsave
(
&
ec
->
polling
.
lock
,
flags
);
acpi_hw_low_level_write
(
8
,
ACPI_EC_COMMAND_READ
,
&
ec
->
common
.
command_addr
);
result
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_IBE
);
if
(
result
)
goto
end
;
acpi_hw_low_level_write
(
8
,
address
,
&
ec
->
common
.
data_addr
);
result
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_OBF
);
if
(
result
)
goto
end
;
acpi_hw_low_level_read
(
8
,
data
,
&
ec
->
common
.
data_addr
);
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Read [%02x] from address [%02x]
\n
"
,
*
data
,
address
));
end:
spin_unlock_irqrestore
(
&
ec
->
polling
.
lock
,
flags
);
if
(
ec
->
common
.
global_lock
)
acpi_release_global_lock
(
glk
);
return_VALUE
(
result
);
}
static
int
acpi_ec_polling_write
(
union
acpi_ec
*
ec
,
u8
address
,
u8
data
)
{
int
result
=
0
;
acpi_status
status
=
AE_OK
;
unsigned
long
flags
=
0
;
u32
glk
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_ec_write"
);
if
(
!
ec
)
return_VALUE
(
-
EINVAL
);
if
(
ec
->
common
.
global_lock
)
{
status
=
acpi_acquire_global_lock
(
ACPI_EC_UDELAY_GLK
,
&
glk
);
if
(
ACPI_FAILURE
(
status
))
return_VALUE
(
-
ENODEV
);
}
spin_lock_irqsave
(
&
ec
->
polling
.
lock
,
flags
);
acpi_hw_low_level_write
(
8
,
ACPI_EC_COMMAND_WRITE
,
&
ec
->
common
.
command_addr
);
result
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_IBE
);
if
(
result
)
goto
end
;
acpi_hw_low_level_write
(
8
,
address
,
&
ec
->
common
.
data_addr
);
result
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_IBE
);
if
(
result
)
goto
end
;
acpi_hw_low_level_write
(
8
,
data
,
&
ec
->
common
.
data_addr
);
result
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_IBE
);
if
(
result
)
goto
end
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Wrote [%02x] to address [%02x]
\n
"
,
data
,
address
));
end:
spin_unlock_irqrestore
(
&
ec
->
polling
.
lock
,
flags
);
if
(
ec
->
common
.
global_lock
)
acpi_release_global_lock
(
glk
);
return_VALUE
(
result
);
}
static
int
acpi_ec_burst_read
(
union
acpi_ec
*
ec
,
u8
address
,
u32
*
data
)
{
...
...
@@ -230,51 +463,51 @@ acpi_ec_read (
retry:
*
data
=
0
;
if
(
ec
->
global_lock
)
{
if
(
ec
->
common
.
global_lock
)
{
status
=
acpi_acquire_global_lock
(
ACPI_EC_UDELAY_GLK
,
&
glk
);
if
(
ACPI_FAILURE
(
status
))
return_VALUE
(
-
ENODEV
);
}
WARN_ON
(
in_interrupt
());
down
(
&
ec
->
sem
);
down
(
&
ec
->
burst
.
sem
);
if
(
acpi_ec_enter_burst_mode
(
ec
))
goto
end
;
acpi_hw_low_level_write
(
8
,
ACPI_EC_COMMAND_READ
,
&
ec
->
command_addr
);
acpi_hw_low_level_write
(
8
,
ACPI_EC_COMMAND_READ
,
&
ec
->
comm
on
.
comm
and_addr
);
status
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_IBE
);
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
if
(
status
)
{
goto
end
;
}
acpi_hw_low_level_write
(
8
,
address
,
&
ec
->
data_addr
);
acpi_hw_low_level_write
(
8
,
address
,
&
ec
->
common
.
data_addr
);
status
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_OBF
);
if
(
status
){
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
goto
end
;
}
acpi_hw_low_level_read
(
8
,
data
,
&
ec
->
data_addr
);
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_hw_low_level_read
(
8
,
data
,
&
ec
->
common
.
data_addr
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Read [%02x] from address [%02x]
\n
"
,
*
data
,
address
));
end:
acpi_ec_leave_burst_mode
(
ec
);
up
(
&
ec
->
sem
);
up
(
&
ec
->
burst
.
sem
);
if
(
ec
->
global_lock
)
if
(
ec
->
common
.
global_lock
)
acpi_release_global_lock
(
glk
);
if
(
atomic_read
(
&
ec
->
leaving_burst
)
==
2
){
if
(
atomic_read
(
&
ec
->
burst
.
leaving_burst
)
==
2
){
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"aborted, retry ...
\n
"
));
while
(
atomic_read
(
&
ec
->
pending_gpe
)){
while
(
atomic_read
(
&
ec
->
burst
.
pending_gpe
)){
msleep
(
1
);
}
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
goto
retry
;
}
...
...
@@ -283,8 +516,8 @@ end:
static
int
acpi_ec_write
(
struct
acpi_ec
*
ec
,
acpi_ec_
burst_
write
(
union
acpi_ec
*
ec
,
u8
address
,
u8
data
)
{
...
...
@@ -297,14 +530,14 @@ acpi_ec_write (
if
(
!
ec
)
return_VALUE
(
-
EINVAL
);
retry:
if
(
ec
->
global_lock
)
{
if
(
ec
->
common
.
global_lock
)
{
status
=
acpi_acquire_global_lock
(
ACPI_EC_UDELAY_GLK
,
&
glk
);
if
(
ACPI_FAILURE
(
status
))
return_VALUE
(
-
ENODEV
);
}
WARN_ON
(
in_interrupt
());
down
(
&
ec
->
sem
);
down
(
&
ec
->
burst
.
sem
);
if
(
acpi_ec_enter_burst_mode
(
ec
))
goto
end
;
...
...
@@ -312,33 +545,33 @@ retry:
status
=
acpi_ec_read_status
(
ec
);
if
(
status
!=
-
EINVAL
&&
!
(
status
&
ACPI_EC_FLAG_BURST
)){
acpi_hw_low_level_write
(
8
,
ACPI_EC_BURST_ENABLE
,
&
ec
->
command_addr
);
acpi_hw_low_level_write
(
8
,
ACPI_EC_BURST_ENABLE
,
&
ec
->
comm
on
.
comm
and_addr
);
status
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_OBF
);
if
(
status
)
goto
end
;
acpi_hw_low_level_read
(
8
,
&
tmp
,
&
ec
->
data_addr
);
acpi_hw_low_level_read
(
8
,
&
tmp
,
&
ec
->
common
.
data_addr
);
if
(
tmp
!=
0x90
)
/* Burst ACK byte*/
goto
end
;
}
/*Now we are in burst mode*/
acpi_hw_low_level_write
(
8
,
ACPI_EC_COMMAND_WRITE
,
&
ec
->
command_addr
);
acpi_hw_low_level_write
(
8
,
ACPI_EC_COMMAND_WRITE
,
&
ec
->
comm
on
.
comm
and_addr
);
status
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_IBE
);
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
if
(
status
){
goto
end
;
}
acpi_hw_low_level_write
(
8
,
address
,
&
ec
->
data_addr
);
acpi_hw_low_level_write
(
8
,
address
,
&
ec
->
common
.
data_addr
);
status
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_IBE
);
if
(
status
){
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
goto
end
;
}
acpi_hw_low_level_write
(
8
,
data
,
&
ec
->
data_addr
);
acpi_hw_low_level_write
(
8
,
data
,
&
ec
->
common
.
data_addr
);
status
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_IBE
);
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
if
(
status
)
goto
end
;
...
...
@@ -347,17 +580,17 @@ retry:
end:
acpi_ec_leave_burst_mode
(
ec
);
up
(
&
ec
->
sem
);
up
(
&
ec
->
burst
.
sem
);
if
(
ec
->
global_lock
)
if
(
ec
->
common
.
global_lock
)
acpi_release_global_lock
(
glk
);
if
(
atomic_read
(
&
ec
->
leaving_burst
)
==
2
){
if
(
atomic_read
(
&
ec
->
burst
.
leaving_burst
)
==
2
){
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"aborted, retry ...
\n
"
));
while
(
atomic_read
(
&
ec
->
pending_gpe
)){
while
(
atomic_read
(
&
ec
->
burst
.
pending_gpe
)){
msleep
(
1
);
}
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
goto
retry
;
}
...
...
@@ -370,7 +603,7 @@ end:
int
ec_read
(
u8
addr
,
u8
*
val
)
{
struct
acpi_ec
*
ec
;
union
acpi_ec
*
ec
;
int
err
;
u32
temp_data
;
...
...
@@ -393,7 +626,7 @@ EXPORT_SYMBOL(ec_read);
int
ec_write
(
u8
addr
,
u8
val
)
{
struct
acpi_ec
*
ec
;
union
acpi_ec
*
ec
;
int
err
;
if
(
!
first_ec
)
...
...
@@ -407,10 +640,66 @@ ec_write(u8 addr, u8 val)
}
EXPORT_SYMBOL
(
ec_write
);
static
int
acpi_ec_query
(
struct
acpi_ec
*
ec
,
union
acpi_ec
*
ec
,
u32
*
data
)
{
if
(
acpi_ec_polling_mode
)
return
acpi_ec_polling_query
(
ec
,
data
);
else
return
acpi_ec_burst_query
(
ec
,
data
);
}
static
int
acpi_ec_polling_query
(
union
acpi_ec
*
ec
,
u32
*
data
)
{
int
result
=
0
;
acpi_status
status
=
AE_OK
;
unsigned
long
flags
=
0
;
u32
glk
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_ec_query"
);
if
(
!
ec
||
!
data
)
return_VALUE
(
-
EINVAL
);
*
data
=
0
;
if
(
ec
->
common
.
global_lock
)
{
status
=
acpi_acquire_global_lock
(
ACPI_EC_UDELAY_GLK
,
&
glk
);
if
(
ACPI_FAILURE
(
status
))
return_VALUE
(
-
ENODEV
);
}
/*
* Query the EC to find out which _Qxx method we need to evaluate.
* Note that successful completion of the query causes the ACPI_EC_SCI
* bit to be cleared (and thus clearing the interrupt source).
*/
spin_lock_irqsave
(
&
ec
->
polling
.
lock
,
flags
);
acpi_hw_low_level_write
(
8
,
ACPI_EC_COMMAND_QUERY
,
&
ec
->
common
.
command_addr
);
result
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_OBF
);
if
(
result
)
goto
end
;
acpi_hw_low_level_read
(
8
,
data
,
&
ec
->
common
.
data_addr
);
if
(
!*
data
)
result
=
-
ENODATA
;
end:
spin_unlock_irqrestore
(
&
ec
->
polling
.
lock
,
flags
);
if
(
ec
->
common
.
global_lock
)
acpi_release_global_lock
(
glk
);
return_VALUE
(
result
);
}
static
int
acpi_ec_burst_query
(
union
acpi_ec
*
ec
,
u32
*
data
)
{
int
status
=
0
;
...
...
@@ -422,13 +711,13 @@ acpi_ec_query (
return_VALUE
(
-
EINVAL
);
*
data
=
0
;
if
(
ec
->
global_lock
)
{
if
(
ec
->
common
.
global_lock
)
{
status
=
acpi_acquire_global_lock
(
ACPI_EC_UDELAY_GLK
,
&
glk
);
if
(
ACPI_FAILURE
(
status
))
return_VALUE
(
-
ENODEV
);
}
down
(
&
ec
->
sem
);
down
(
&
ec
->
burst
.
sem
);
if
(
acpi_ec_enter_burst_mode
(
ec
))
goto
end
;
/*
...
...
@@ -436,28 +725,28 @@ acpi_ec_query (
* Note that successful completion of the query causes the ACPI_EC_SCI
* bit to be cleared (and thus clearing the interrupt source).
*/
acpi_hw_low_level_write
(
8
,
ACPI_EC_COMMAND_QUERY
,
&
ec
->
command_addr
);
acpi_hw_low_level_write
(
8
,
ACPI_EC_COMMAND_QUERY
,
&
ec
->
comm
on
.
comm
and_addr
);
status
=
acpi_ec_wait
(
ec
,
ACPI_EC_EVENT_OBF
);
if
(
status
){
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
goto
end
;
}
acpi_hw_low_level_read
(
8
,
data
,
&
ec
->
data_addr
);
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_hw_low_level_read
(
8
,
data
,
&
ec
->
common
.
data_addr
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
if
(
!*
data
)
status
=
-
ENODATA
;
end:
acpi_ec_leave_burst_mode
(
ec
);
up
(
&
ec
->
sem
);
up
(
&
ec
->
burst
.
sem
);
if
(
ec
->
global_lock
)
if
(
ec
->
common
.
global_lock
)
acpi_release_global_lock
(
glk
);
if
(
atomic_read
(
&
ec
->
leaving_burst
)
==
2
){
if
(
atomic_read
(
&
ec
->
burst
.
leaving_burst
)
==
2
){
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"aborted, retry ...
\n
"
));
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
status
=
-
ENODATA
;
}
return_VALUE
(
status
);
...
...
@@ -468,7 +757,7 @@ end:
Event Management
-------------------------------------------------------------------------- */
struct
acpi_ec_query_data
{
union
acpi_ec_query_data
{
acpi_handle
handle
;
u8
data
;
};
...
...
@@ -477,7 +766,59 @@ static void
acpi_ec_gpe_query
(
void
*
ec_cxt
)
{
struct
acpi_ec
*
ec
=
(
struct
acpi_ec
*
)
ec_cxt
;
if
(
acpi_ec_polling_mode
)
acpi_ec_gpe_polling_query
(
ec_cxt
);
else
acpi_ec_gpe_burst_query
(
ec_cxt
);
}
static
void
acpi_ec_gpe_polling_query
(
void
*
ec_cxt
)
{
union
acpi_ec
*
ec
=
(
union
acpi_ec
*
)
ec_cxt
;
u32
value
=
0
;
unsigned
long
flags
=
0
;
static
char
object_name
[
5
]
=
{
'_'
,
'Q'
,
'0'
,
'0'
,
'\0'
};
const
char
hex
[]
=
{
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
};
ACPI_FUNCTION_TRACE
(
"acpi_ec_gpe_query"
);
if
(
!
ec_cxt
)
goto
end
;
spin_lock_irqsave
(
&
ec
->
polling
.
lock
,
flags
);
acpi_hw_low_level_read
(
8
,
&
value
,
&
ec
->
common
.
command_addr
);
spin_unlock_irqrestore
(
&
ec
->
polling
.
lock
,
flags
);
/* TBD: Implement asynch events!
* NOTE: All we care about are EC-SCI's. Other EC events are
* handled via polling (yuck!). This is because some systems
* treat EC-SCIs as level (versus EDGE!) triggered, preventing
* a purely interrupt-driven approach (grumble, grumble).
*/
if
(
!
(
value
&
ACPI_EC_FLAG_SCI
))
goto
end
;
if
(
acpi_ec_query
(
ec
,
&
value
))
goto
end
;
object_name
[
2
]
=
hex
[((
value
>>
4
)
&
0x0F
)];
object_name
[
3
]
=
hex
[(
value
&
0x0F
)];
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Evaluating %s
\n
"
,
object_name
));
acpi_evaluate_object
(
ec
->
common
.
handle
,
object_name
,
NULL
,
NULL
);
end:
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
}
static
void
acpi_ec_gpe_burst_query
(
void
*
ec_cxt
)
{
union
acpi_ec
*
ec
=
(
union
acpi_ec
*
)
ec_cxt
;
u32
value
;
int
result
=
-
ENODATA
;
static
char
object_name
[
5
]
=
{
'_'
,
'Q'
,
'0'
,
'0'
,
'\0'
};
...
...
@@ -497,58 +838,87 @@ acpi_ec_gpe_query (
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Evaluating %s
\n
"
,
object_name
));
acpi_evaluate_object
(
ec
->
handle
,
object_name
,
NULL
,
NULL
);
acpi_evaluate_object
(
ec
->
common
.
handle
,
object_name
,
NULL
,
NULL
);
end:
atomic_dec
(
&
ec
->
pending_gpe
);
atomic_dec
(
&
ec
->
burst
.
pending_gpe
);
return
;
}
static
u32
acpi_ec_gpe_handler
(
void
*
data
)
{
if
(
acpi_ec_polling_mode
)
return
acpi_ec_gpe_polling_handler
(
data
);
else
return
acpi_ec_gpe_burst_handler
(
data
);
}
static
u32
acpi_ec_gpe_polling_handler
(
void
*
data
)
{
acpi_status
status
=
AE_OK
;
union
acpi_ec
*
ec
=
(
union
acpi_ec
*
)
data
;
if
(
!
ec
)
return
ACPI_INTERRUPT_NOT_HANDLED
;
acpi_disable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_ISR
);
status
=
acpi_os_queue_for_execution
(
OSD_PRIORITY_GPE
,
acpi_ec_gpe_query
,
ec
);
if
(
status
==
AE_OK
)
return
ACPI_INTERRUPT_HANDLED
;
else
return
ACPI_INTERRUPT_NOT_HANDLED
;
}
static
u32
acpi_ec_gpe_burst_handler
(
void
*
data
)
{
acpi_status
status
=
AE_OK
;
u32
value
;
struct
acpi_ec
*
ec
=
(
struct
acpi_ec
*
)
data
;
union
acpi_ec
*
ec
=
(
union
acpi_ec
*
)
data
;
if
(
!
ec
)
return
ACPI_INTERRUPT_NOT_HANDLED
;
acpi_disable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_ISR
);
acpi_disable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_ISR
);
value
=
acpi_ec_read_status
(
ec
);
if
((
value
&
ACPI_EC_FLAG_IBF
)
&&
!
(
value
&
ACPI_EC_FLAG_BURST
)
&&
(
atomic_read
(
&
ec
->
leaving_burst
)
==
0
))
{
(
atomic_read
(
&
ec
->
burst
.
leaving_burst
)
==
0
))
{
/*
* the embedded controller disables
* burst mode for any reason other
* than the burst disable command
* to process critical event.
*/
atomic_set
(
&
ec
->
leaving_burst
,
2
);
/* block current pending transaction
atomic_set
(
&
ec
->
burst
.
leaving_burst
,
2
);
/* block current pending transaction
and retry */
wake_up
(
&
ec
->
wait
);
wake_up
(
&
ec
->
burst
.
wait
);
}
else
{
if
((
ec
->
expect_event
==
ACPI_EC_EVENT_OBF
&&
if
((
ec
->
burst
.
expect_event
==
ACPI_EC_EVENT_OBF
&&
(
value
&
ACPI_EC_FLAG_OBF
))
||
(
ec
->
expect_event
==
ACPI_EC_EVENT_IBE
&&
(
ec
->
burst
.
expect_event
==
ACPI_EC_EVENT_IBE
&&
!
(
value
&
ACPI_EC_FLAG_IBF
)))
{
ec
->
expect_event
=
0
;
wake_up
(
&
ec
->
wait
);
ec
->
burst
.
expect_event
=
0
;
wake_up
(
&
ec
->
burst
.
wait
);
return
ACPI_INTERRUPT_HANDLED
;
}
}
if
(
value
&
ACPI_EC_FLAG_SCI
){
atomic_add
(
1
,
&
ec
->
pending_gpe
)
;
atomic_add
(
1
,
&
ec
->
burst
.
pending_gpe
)
;
status
=
acpi_os_queue_for_execution
(
OSD_PRIORITY_GPE
,
acpi_ec_gpe_query
,
ec
);
return
status
==
AE_OK
?
ACPI_INTERRUPT_HANDLED
:
ACPI_INTERRUPT_NOT_HANDLED
;
}
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_ISR
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_ISR
);
return
status
==
AE_OK
?
ACPI_INTERRUPT_HANDLED
:
ACPI_INTERRUPT_NOT_HANDLED
;
}
...
...
@@ -585,7 +955,7 @@ acpi_ec_space_handler (
void
*
region_context
)
{
int
result
=
0
;
struct
acpi_ec
*
ec
=
NULL
;
union
acpi_ec
*
ec
=
NULL
;
u64
temp
=
*
value
;
acpi_integer
f_v
=
0
;
int
i
=
0
;
...
...
@@ -600,7 +970,7 @@ acpi_ec_space_handler (
return_VALUE
(
AE_BAD_PARAMETER
);
}
ec
=
(
struct
acpi_ec
*
)
handler_context
;
ec
=
(
union
acpi_ec
*
)
handler_context
;
next_byte:
switch
(
function
)
{
...
...
@@ -661,7 +1031,7 @@ static struct proc_dir_entry *acpi_ec_dir;
static
int
acpi_ec_read_info
(
struct
seq_file
*
seq
,
void
*
offset
)
{
struct
acpi_ec
*
ec
=
(
struct
acpi_ec
*
)
seq
->
private
;
union
acpi_ec
*
ec
=
(
union
acpi_ec
*
)
seq
->
private
;
ACPI_FUNCTION_TRACE
(
"acpi_ec_read_info"
);
...
...
@@ -669,12 +1039,12 @@ acpi_ec_read_info (struct seq_file *seq, void *offset)
goto
end
;
seq_printf
(
seq
,
"gpe bit: 0x%02x
\n
"
,
(
u32
)
ec
->
gpe_bit
);
(
u32
)
ec
->
common
.
gpe_bit
);
seq_printf
(
seq
,
"ports: 0x%02x, 0x%02x
\n
"
,
(
u32
)
ec
->
status_addr
.
address
,
(
u32
)
ec
->
data_addr
.
address
);
(
u32
)
ec
->
common
.
status_addr
.
address
,
(
u32
)
ec
->
common
.
data_addr
.
address
);
seq_printf
(
seq
,
"use global lock: %s
\n
"
,
ec
->
global_lock
?
"yes"
:
"no"
);
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
ec
->
common
.
global_lock
?
"yes"
:
"no"
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
end:
return_VALUE
(
0
);
...
...
@@ -697,7 +1067,7 @@ static int
acpi_ec_add_fs
(
struct
acpi_device
*
device
)
{
struct
proc_dir_entry
*
entry
;
struct
proc_dir_entry
*
entry
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_ec_add_fs"
);
...
...
@@ -744,13 +1114,82 @@ acpi_ec_remove_fs (
Driver Interface
-------------------------------------------------------------------------- */
static
int
acpi_ec_add
(
acpi_ec_
polling_
add
(
struct
acpi_device
*
device
)
{
int
result
;
acpi_status
status
;
struct
acpi_ec
*
ec
;
int
result
=
0
;
acpi_status
status
=
AE_OK
;
union
acpi_ec
*
ec
=
NULL
;
unsigned
long
uid
;
ACPI_FUNCTION_TRACE
(
"acpi_ec_add"
);
if
(
!
device
)
return_VALUE
(
-
EINVAL
);
ec
=
kmalloc
(
sizeof
(
union
acpi_ec
),
GFP_KERNEL
);
if
(
!
ec
)
return_VALUE
(
-
ENOMEM
);
memset
(
ec
,
0
,
sizeof
(
union
acpi_ec
));
ec
->
common
.
handle
=
device
->
handle
;
ec
->
common
.
uid
=
-
1
;
spin_lock_init
(
&
ec
->
polling
.
lock
);
strcpy
(
acpi_device_name
(
device
),
ACPI_EC_DEVICE_NAME
);
strcpy
(
acpi_device_class
(
device
),
ACPI_EC_CLASS
);
acpi_driver_data
(
device
)
=
ec
;
/* Use the global lock for all EC transactions? */
acpi_evaluate_integer
(
ec
->
common
.
handle
,
"_GLK"
,
NULL
,
&
ec
->
common
.
global_lock
);
/* If our UID matches the UID for the ECDT-enumerated EC,
we now have the *real* EC info, so kill the makeshift one.*/
acpi_evaluate_integer
(
ec
->
common
.
handle
,
"_UID"
,
NULL
,
&
uid
);
if
(
ec_ecdt
&&
ec_ecdt
->
common
.
uid
==
uid
)
{
acpi_remove_address_space_handler
(
ACPI_ROOT_OBJECT
,
ACPI_ADR_SPACE_EC
,
&
acpi_ec_space_handler
);
acpi_remove_gpe_handler
(
NULL
,
ec_ecdt
->
common
.
gpe_bit
,
&
acpi_ec_gpe_handler
);
kfree
(
ec_ecdt
);
}
/* Get GPE bit assignment (EC events). */
/* TODO: Add support for _GPE returning a package */
status
=
acpi_evaluate_integer
(
ec
->
common
.
handle
,
"_GPE"
,
NULL
,
&
ec
->
common
.
gpe_bit
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Error obtaining GPE bit assignment
\n
"
));
result
=
-
ENODEV
;
goto
end
;
}
result
=
acpi_ec_add_fs
(
device
);
if
(
result
)
goto
end
;
printk
(
KERN_INFO
PREFIX
"%s [%s] (gpe %d)
\n
"
,
acpi_device_name
(
device
),
acpi_device_bid
(
device
),
(
u32
)
ec
->
common
.
gpe_bit
);
if
(
!
first_ec
)
first_ec
=
device
;
end:
if
(
result
)
kfree
(
ec
);
return_VALUE
(
result
);
}
static
int
acpi_ec_burst_add
(
struct
acpi_device
*
device
)
{
int
result
=
0
;
acpi_status
status
=
AE_OK
;
union
acpi_ec
*
ec
=
NULL
;
unsigned
long
uid
;
ACPI_FUNCTION_TRACE
(
"acpi_ec_add"
);
...
...
@@ -758,39 +1197,39 @@ acpi_ec_add (
if
(
!
device
)
return_VALUE
(
-
EINVAL
);
ec
=
kmalloc
(
sizeof
(
struct
acpi_ec
),
GFP_KERNEL
);
ec
=
kmalloc
(
sizeof
(
union
acpi_ec
),
GFP_KERNEL
);
if
(
!
ec
)
return_VALUE
(
-
ENOMEM
);
memset
(
ec
,
0
,
sizeof
(
struct
acpi_ec
));
ec
->
handle
=
device
->
handle
;
ec
->
uid
=
-
1
;
atomic_set
(
&
ec
->
pending_gpe
,
0
);
atomic_set
(
&
ec
->
leaving_burst
,
1
);
init_MUTEX
(
&
ec
->
sem
);
init_waitqueue_head
(
&
ec
->
wait
);
memset
(
ec
,
0
,
sizeof
(
union
acpi_ec
));
ec
->
common
.
handle
=
device
->
handle
;
ec
->
common
.
uid
=
-
1
;
atomic_set
(
&
ec
->
burst
.
pending_gpe
,
0
);
atomic_set
(
&
ec
->
burst
.
leaving_burst
,
1
);
init_MUTEX
(
&
ec
->
burst
.
sem
);
init_waitqueue_head
(
&
ec
->
burst
.
wait
);
strcpy
(
acpi_device_name
(
device
),
ACPI_EC_DEVICE_NAME
);
strcpy
(
acpi_device_class
(
device
),
ACPI_EC_CLASS
);
acpi_driver_data
(
device
)
=
ec
;
/* Use the global lock for all EC transactions? */
acpi_evaluate_integer
(
ec
->
handle
,
"_GLK"
,
NULL
,
&
ec
->
global_lock
);
acpi_evaluate_integer
(
ec
->
common
.
handle
,
"_GLK"
,
NULL
,
&
ec
->
common
.
global_lock
);
/* If our UID matches the UID for the ECDT-enumerated EC,
we now have the *real* EC info, so kill the makeshift one.*/
acpi_evaluate_integer
(
ec
->
handle
,
"_UID"
,
NULL
,
&
uid
);
if
(
ec_ecdt
&&
ec_ecdt
->
uid
==
uid
)
{
acpi_evaluate_integer
(
ec
->
common
.
handle
,
"_UID"
,
NULL
,
&
uid
);
if
(
ec_ecdt
&&
ec_ecdt
->
common
.
uid
==
uid
)
{
acpi_remove_address_space_handler
(
ACPI_ROOT_OBJECT
,
ACPI_ADR_SPACE_EC
,
&
acpi_ec_space_handler
);
acpi_remove_gpe_handler
(
NULL
,
ec_ecdt
->
gpe_bit
,
&
acpi_ec_gpe_handler
);
acpi_remove_gpe_handler
(
NULL
,
ec_ecdt
->
common
.
gpe_bit
,
&
acpi_ec_gpe_handler
);
kfree
(
ec_ecdt
);
}
/* Get GPE bit assignment (EC events). */
/* TODO: Add support for _GPE returning a package */
status
=
acpi_evaluate_integer
(
ec
->
handle
,
"_GPE"
,
NULL
,
&
ec
->
gpe_bit
);
status
=
acpi_evaluate_integer
(
ec
->
common
.
handle
,
"_GPE"
,
NULL
,
&
ec
->
common
.
gpe_bit
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Error obtaining GPE bit assignment
\n
"
));
...
...
@@ -804,7 +1243,7 @@ acpi_ec_add (
printk
(
KERN_INFO
PREFIX
"%s [%s] (gpe %d)
\n
"
,
acpi_device_name
(
device
),
acpi_device_bid
(
device
),
(
u32
)
ec
->
gpe_bit
);
(
u32
)
ec
->
common
.
gpe_bit
);
if
(
!
first_ec
)
first_ec
=
device
;
...
...
@@ -822,7 +1261,7 @@ acpi_ec_remove (
struct
acpi_device
*
device
,
int
type
)
{
struct
acpi_ec
*
ec
;
union
acpi_ec
*
ec
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_ec_remove"
);
...
...
@@ -844,7 +1283,7 @@ acpi_ec_io_ports (
struct
acpi_resource
*
resource
,
void
*
context
)
{
struct
acpi_ec
*
ec
=
(
struct
acpi_ec
*
)
context
;
union
acpi_ec
*
ec
=
(
union
acpi_ec
*
)
context
;
struct
acpi_generic_address
*
addr
;
if
(
resource
->
id
!=
ACPI_RSTYPE_IO
)
{
...
...
@@ -856,10 +1295,10 @@ acpi_ec_io_ports (
* the second address region returned is the status/command
* port.
*/
if
(
ec
->
data_addr
.
register_bit_width
==
0
)
{
addr
=
&
ec
->
data_addr
;
}
else
if
(
ec
->
command_addr
.
register_bit_width
==
0
)
{
addr
=
&
ec
->
command_addr
;
if
(
ec
->
common
.
data_addr
.
register_bit_width
==
0
)
{
addr
=
&
ec
->
common
.
data_addr
;
}
else
if
(
ec
->
comm
on
.
comm
and_addr
.
register_bit_width
==
0
)
{
addr
=
&
ec
->
comm
on
.
comm
and_addr
;
}
else
{
return
AE_CTRL_TERMINATE
;
}
...
...
@@ -877,8 +1316,8 @@ static int
acpi_ec_start
(
struct
acpi_device
*
device
)
{
acpi_status
status
;
struct
acpi_ec
*
ec
;
acpi_status
status
=
AE_OK
;
union
acpi_ec
*
ec
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_ec_start"
);
...
...
@@ -893,35 +1332,36 @@ acpi_ec_start (
/*
* Get I/O port addresses. Convert to GAS format.
*/
status
=
acpi_walk_resources
(
ec
->
handle
,
METHOD_NAME__CRS
,
status
=
acpi_walk_resources
(
ec
->
common
.
handle
,
METHOD_NAME__CRS
,
acpi_ec_io_ports
,
ec
);
if
(
ACPI_FAILURE
(
status
)
||
ec
->
command_addr
.
register_bit_width
==
0
)
{
if
(
ACPI_FAILURE
(
status
)
||
ec
->
comm
on
.
comm
and_addr
.
register_bit_width
==
0
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Error getting I/O port addresses"
));
return_VALUE
(
-
ENODEV
);
}
ec
->
status_addr
=
ec
->
command_addr
;
ec
->
common
.
status_addr
=
ec
->
common
.
command_addr
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"gpe=0x%02x, ports=0x%2x,0x%2x
\n
"
,
(
u32
)
ec
->
gpe_bit
,
(
u32
)
ec
->
command_addr
.
address
,
(
u32
)
ec
->
data_addr
.
address
));
(
u32
)
ec
->
common
.
gpe_bit
,
(
u32
)
ec
->
common
.
command_addr
.
address
,
(
u32
)
ec
->
common
.
data_addr
.
address
));
/*
* Install GPE handler
*/
status
=
acpi_install_gpe_handler
(
NULL
,
ec
->
gpe_bit
,
status
=
acpi_install_gpe_handler
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_GPE_EDGE_TRIGGERED
,
&
acpi_ec_gpe_handler
,
ec
);
if
(
ACPI_FAILURE
(
status
))
{
return_VALUE
(
-
ENODEV
);
}
acpi_set_gpe_type
(
NULL
,
ec
->
gpe_bit
,
ACPI_GPE_TYPE_RUNTIME
);
acpi_enable_gpe
(
NULL
,
ec
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_set_gpe_type
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_GPE_TYPE_RUNTIME
);
acpi_enable_gpe
(
NULL
,
ec
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
status
=
acpi_install_address_space_handler
(
ec
->
handle
,
status
=
acpi_install_address_space_handler
(
ec
->
common
.
handle
,
ACPI_ADR_SPACE_EC
,
&
acpi_ec_space_handler
,
&
acpi_ec_space_setup
,
ec
);
if
(
ACPI_FAILURE
(
status
))
{
acpi_remove_gpe_handler
(
NULL
,
ec
->
gpe_bit
,
&
acpi_ec_gpe_handler
);
acpi_remove_gpe_handler
(
NULL
,
ec
->
common
.
gpe_bit
,
&
acpi_ec_gpe_handler
);
return_VALUE
(
-
ENODEV
);
}
...
...
@@ -934,8 +1374,8 @@ acpi_ec_stop (
struct
acpi_device
*
device
,
int
type
)
{
acpi_status
status
;
struct
acpi_ec
*
ec
;
acpi_status
status
=
AE_OK
;
union
acpi_ec
*
ec
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_ec_stop"
);
...
...
@@ -944,12 +1384,12 @@ acpi_ec_stop (
ec
=
acpi_driver_data
(
device
);
status
=
acpi_remove_address_space_handler
(
ec
->
handle
,
status
=
acpi_remove_address_space_handler
(
ec
->
common
.
handle
,
ACPI_ADR_SPACE_EC
,
&
acpi_ec_space_handler
);
if
(
ACPI_FAILURE
(
status
))
return_VALUE
(
-
ENODEV
);
status
=
acpi_remove_gpe_handler
(
NULL
,
ec
->
gpe_bit
,
&
acpi_ec_gpe_handler
);
status
=
acpi_remove_gpe_handler
(
NULL
,
ec
->
common
.
gpe_bit
,
&
acpi_ec_gpe_handler
);
if
(
ACPI_FAILURE
(
status
))
return_VALUE
(
-
ENODEV
);
...
...
@@ -963,26 +1403,76 @@ acpi_fake_ecdt_callback (
void
*
context
,
void
**
retval
)
{
if
(
acpi_ec_polling_mode
)
return
acpi_fake_ecdt_polling_callback
(
handle
,
Level
,
context
,
retval
);
else
return
acpi_fake_ecdt_burst_callback
(
handle
,
Level
,
context
,
retval
);
}
static
acpi_status
__init
acpi_fake_ecdt_polling_callback
(
acpi_handle
handle
,
u32
Level
,
void
*
context
,
void
**
retval
)
{
acpi_status
status
;
status
=
acpi_walk_resources
(
handle
,
METHOD_NAME__CRS
,
acpi_ec_io_ports
,
ec_ecdt
);
if
(
ACPI_FAILURE
(
status
))
return
status
;
ec_ecdt
->
common
.
status_addr
=
ec_ecdt
->
common
.
command_addr
;
ec_ecdt
->
common
.
uid
=
-
1
;
acpi_evaluate_integer
(
handle
,
"_UID"
,
NULL
,
&
ec_ecdt
->
common
.
uid
);
status
=
acpi_evaluate_integer
(
handle
,
"_GPE"
,
NULL
,
&
ec_ecdt
->
common
.
gpe_bit
);
if
(
ACPI_FAILURE
(
status
))
return
status
;
spin_lock_init
(
&
ec_ecdt
->
polling
.
lock
);
ec_ecdt
->
common
.
global_lock
=
TRUE
;
ec_ecdt
->
common
.
handle
=
handle
;
printk
(
KERN_INFO
PREFIX
"GPE=0x%02x, ports=0x%2x, 0x%2x
\n
"
,
(
u32
)
ec_ecdt
->
common
.
gpe_bit
,
(
u32
)
ec_ecdt
->
common
.
command_addr
.
address
,
(
u32
)
ec_ecdt
->
common
.
data_addr
.
address
);
return
AE_CTRL_TERMINATE
;
}
static
acpi_status
__init
acpi_fake_ecdt_burst_callback
(
acpi_handle
handle
,
u32
Level
,
void
*
context
,
void
**
retval
)
{
acpi_status
status
;
init_MUTEX
(
&
ec_ecdt
->
burst
.
sem
);
init_waitqueue_head
(
&
ec_ecdt
->
burst
.
wait
);
status
=
acpi_walk_resources
(
handle
,
METHOD_NAME__CRS
,
acpi_ec_io_ports
,
ec_ecdt
);
if
(
ACPI_FAILURE
(
status
))
return
status
;
ec_ecdt
->
status_addr
=
ec_ecdt
->
command_addr
;
ec_ecdt
->
common
.
status_addr
=
ec_ecdt
->
common
.
command_addr
;
ec_ecdt
->
uid
=
-
1
;
acpi_evaluate_integer
(
handle
,
"_UID"
,
NULL
,
&
ec_ecdt
->
uid
);
ec_ecdt
->
common
.
uid
=
-
1
;
acpi_evaluate_integer
(
handle
,
"_UID"
,
NULL
,
&
ec_ecdt
->
common
.
uid
);
status
=
acpi_evaluate_integer
(
handle
,
"_GPE"
,
NULL
,
&
ec_ecdt
->
gpe_bit
);
status
=
acpi_evaluate_integer
(
handle
,
"_GPE"
,
NULL
,
&
ec_ecdt
->
common
.
gpe_bit
);
if
(
ACPI_FAILURE
(
status
))
return
status
;
ec_ecdt
->
global_lock
=
TRUE
;
ec_ecdt
->
handle
=
handle
;
ec_ecdt
->
common
.
global_lock
=
TRUE
;
ec_ecdt
->
common
.
handle
=
handle
;
printk
(
KERN_INFO
PREFIX
"GPE=0x%02x, ports=0x%2x, 0x%2x
\n
"
,
(
u32
)
ec_ecdt
->
gpe_bit
,
(
u32
)
ec_ecdt
->
command_addr
.
address
,
(
u32
)
ec_ecdt
->
data_addr
.
address
);
(
u32
)
ec_ecdt
->
common
.
gpe_bit
,
(
u32
)
ec_ecdt
->
common
.
command_addr
.
address
,
(
u32
)
ec_ecdt
->
common
.
data_addr
.
address
);
return
AE_CTRL_TERMINATE
;
}
...
...
@@ -1005,12 +1495,12 @@ acpi_ec_fake_ecdt(void)
printk
(
KERN_INFO
PREFIX
"Try to make an fake ECDT
\n
"
);
ec_ecdt
=
kmalloc
(
sizeof
(
struct
acpi_ec
),
GFP_KERNEL
);
ec_ecdt
=
kmalloc
(
sizeof
(
union
acpi_ec
),
GFP_KERNEL
);
if
(
!
ec_ecdt
)
{
ret
=
-
ENOMEM
;
goto
error
;
}
memset
(
ec_ecdt
,
0
,
sizeof
(
struct
acpi_ec
));
memset
(
ec_ecdt
,
0
,
sizeof
(
union
acpi_ec
));
status
=
acpi_get_devices
(
ACPI_EC_HID
,
acpi_fake_ecdt_callback
,
...
...
@@ -1030,6 +1520,60 @@ error:
static
int
__init
acpi_ec_get_real_ecdt
(
void
)
{
if
(
acpi_ec_polling_mode
)
return
acpi_ec_polling_get_real_ecdt
();
else
return
acpi_ec_burst_get_real_ecdt
();
}
static
int
__init
acpi_ec_polling_get_real_ecdt
(
void
)
{
acpi_status
status
;
struct
acpi_table_ecdt
*
ecdt_ptr
;
status
=
acpi_get_firmware_table
(
"ECDT"
,
1
,
ACPI_LOGICAL_ADDRESSING
,
(
struct
acpi_table_header
**
)
&
ecdt_ptr
);
if
(
ACPI_FAILURE
(
status
))
return
-
ENODEV
;
printk
(
KERN_INFO
PREFIX
"Found ECDT
\n
"
);
/*
* Generate a temporary ec context to use until the namespace is scanned
*/
ec_ecdt
=
kmalloc
(
sizeof
(
union
acpi_ec
),
GFP_KERNEL
);
if
(
!
ec_ecdt
)
return
-
ENOMEM
;
memset
(
ec_ecdt
,
0
,
sizeof
(
union
acpi_ec
));
ec_ecdt
->
common
.
command_addr
=
ecdt_ptr
->
ec_control
;
ec_ecdt
->
common
.
status_addr
=
ecdt_ptr
->
ec_control
;
ec_ecdt
->
common
.
data_addr
=
ecdt_ptr
->
ec_data
;
ec_ecdt
->
common
.
gpe_bit
=
ecdt_ptr
->
gpe_bit
;
spin_lock_init
(
&
ec_ecdt
->
polling
.
lock
);
/* use the GL just to be safe */
ec_ecdt
->
common
.
global_lock
=
TRUE
;
ec_ecdt
->
common
.
uid
=
ecdt_ptr
->
uid
;
status
=
acpi_get_handle
(
NULL
,
ecdt_ptr
->
ec_id
,
&
ec_ecdt
->
common
.
handle
);
if
(
ACPI_FAILURE
(
status
))
{
goto
error
;
}
return
0
;
error:
printk
(
KERN_ERR
PREFIX
"Could not use ECDT
\n
"
);
kfree
(
ec_ecdt
);
ec_ecdt
=
NULL
;
return
-
ENODEV
;
}
static
int
__init
acpi_ec_burst_get_real_ecdt
(
void
)
{
acpi_status
status
;
struct
acpi_table_ecdt
*
ecdt_ptr
;
...
...
@@ -1044,22 +1588,22 @@ acpi_ec_get_real_ecdt(void)
/*
* Generate a temporary ec context to use until the namespace is scanned
*/
ec_ecdt
=
kmalloc
(
sizeof
(
struct
acpi_ec
),
GFP_KERNEL
);
ec_ecdt
=
kmalloc
(
sizeof
(
union
acpi_ec
),
GFP_KERNEL
);
if
(
!
ec_ecdt
)
return
-
ENOMEM
;
memset
(
ec_ecdt
,
0
,
sizeof
(
struct
acpi_ec
));
init_MUTEX
(
&
ec_ecdt
->
sem
);
init_waitqueue_head
(
&
ec_ecdt
->
wait
);
ec_ecdt
->
command_addr
=
ecdt_ptr
->
ec_control
;
ec_ecdt
->
status_addr
=
ecdt_ptr
->
ec_control
;
ec_ecdt
->
data_addr
=
ecdt_ptr
->
ec_data
;
ec_ecdt
->
gpe_bit
=
ecdt_ptr
->
gpe_bit
;
memset
(
ec_ecdt
,
0
,
sizeof
(
union
acpi_ec
));
init_MUTEX
(
&
ec_ecdt
->
burst
.
sem
);
init_waitqueue_head
(
&
ec_ecdt
->
burst
.
wait
);
ec_ecdt
->
comm
on
.
comm
and_addr
=
ecdt_ptr
->
ec_control
;
ec_ecdt
->
common
.
status_addr
=
ecdt_ptr
->
ec_control
;
ec_ecdt
->
common
.
data_addr
=
ecdt_ptr
->
ec_data
;
ec_ecdt
->
common
.
gpe_bit
=
ecdt_ptr
->
gpe_bit
;
/* use the GL just to be safe */
ec_ecdt
->
global_lock
=
TRUE
;
ec_ecdt
->
uid
=
ecdt_ptr
->
uid
;
ec_ecdt
->
common
.
global_lock
=
TRUE
;
ec_ecdt
->
common
.
uid
=
ecdt_ptr
->
uid
;
status
=
acpi_get_handle
(
NULL
,
ecdt_ptr
->
ec_id
,
&
ec_ecdt
->
handle
);
status
=
acpi_get_handle
(
NULL
,
ecdt_ptr
->
ec_id
,
&
ec_ecdt
->
common
.
handle
);
if
(
ACPI_FAILURE
(
status
))
{
goto
error
;
}
...
...
@@ -1092,20 +1636,20 @@ acpi_ec_ecdt_probe (void)
/*
* Install GPE handler
*/
status
=
acpi_install_gpe_handler
(
NULL
,
ec_ecdt
->
gpe_bit
,
status
=
acpi_install_gpe_handler
(
NULL
,
ec_ecdt
->
common
.
gpe_bit
,
ACPI_GPE_EDGE_TRIGGERED
,
&
acpi_ec_gpe_handler
,
ec_ecdt
);
if
(
ACPI_FAILURE
(
status
))
{
goto
error
;
}
acpi_set_gpe_type
(
NULL
,
ec_ecdt
->
gpe_bit
,
ACPI_GPE_TYPE_RUNTIME
);
acpi_enable_gpe
(
NULL
,
ec_ecdt
->
gpe_bit
,
ACPI_NOT_ISR
);
acpi_set_gpe_type
(
NULL
,
ec_ecdt
->
common
.
gpe_bit
,
ACPI_GPE_TYPE_RUNTIME
);
acpi_enable_gpe
(
NULL
,
ec_ecdt
->
common
.
gpe_bit
,
ACPI_NOT_ISR
);
status
=
acpi_install_address_space_handler
(
ACPI_ROOT_OBJECT
,
ACPI_ADR_SPACE_EC
,
&
acpi_ec_space_handler
,
&
acpi_ec_space_setup
,
ec_ecdt
);
if
(
ACPI_FAILURE
(
status
))
{
acpi_remove_gpe_handler
(
NULL
,
ec_ecdt
->
gpe_bit
,
acpi_remove_gpe_handler
(
NULL
,
ec_ecdt
->
common
.
gpe_bit
,
&
acpi_ec_gpe_handler
);
goto
error
;
}
...
...
@@ -1123,7 +1667,7 @@ error:
static
int
__init
acpi_ec_init
(
void
)
{
int
result
;
int
result
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_ec_init"
);
...
...
@@ -1167,3 +1711,10 @@ static int __init acpi_fake_ecdt_setup(char *str)
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
;
return
0
;
}
__setup
(
"ec_polling"
,
acpi_ec_set_polling_mode
);
drivers/acpi/pci_irq.c
View file @
d6ac1a79
...
...
@@ -269,7 +269,51 @@ acpi_pci_irq_del_prt (int segment, int bus)
/* --------------------------------------------------------------------------
PCI Interrupt Routing Support
-------------------------------------------------------------------------- */
typedef
int
(
*
irq_lookup_func
)(
struct
acpi_prt_entry
*
,
int
*
,
int
*
,
char
**
);
static
int
acpi_pci_allocate_irq
(
struct
acpi_prt_entry
*
entry
,
int
*
edge_level
,
int
*
active_high_low
,
char
**
link
)
{
int
irq
;
ACPI_FUNCTION_TRACE
(
"acpi_pci_allocate_irq"
);
if
(
entry
->
link
.
handle
)
{
irq
=
acpi_pci_link_allocate_irq
(
entry
->
link
.
handle
,
entry
->
link
.
index
,
edge_level
,
active_high_low
,
link
);
if
(
irq
<
0
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_WARN
,
"Invalid IRQ link routing entry
\n
"
));
return_VALUE
(
-
1
);
}
}
else
{
irq
=
entry
->
link
.
index
;
*
edge_level
=
ACPI_LEVEL_SENSITIVE
;
*
active_high_low
=
ACPI_ACTIVE_LOW
;
}
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Found IRQ %d
\n
"
,
irq
));
return_VALUE
(
irq
);
}
static
int
acpi_pci_free_irq
(
struct
acpi_prt_entry
*
entry
,
int
*
edge_level
,
int
*
active_high_low
,
char
**
link
)
{
int
irq
;
ACPI_FUNCTION_TRACE
(
"acpi_pci_free_irq"
);
if
(
entry
->
link
.
handle
)
{
irq
=
acpi_pci_link_free_irq
(
entry
->
link
.
handle
);
}
else
{
irq
=
entry
->
link
.
index
;
}
return_VALUE
(
irq
);
}
/*
* acpi_pci_irq_lookup
* success: return IRQ >= 0
...
...
@@ -282,12 +326,13 @@ acpi_pci_irq_lookup (
int
pin
,
int
*
edge_level
,
int
*
active_high_low
,
char
**
link
)
char
**
link
,
irq_lookup_func
func
)
{
struct
acpi_prt_entry
*
entry
=
NULL
;
int
segment
=
pci_domain_nr
(
bus
);
int
bus_nr
=
bus
->
number
;
int
irq
;
int
ret
;
ACPI_FUNCTION_TRACE
(
"acpi_pci_irq_lookup"
);
...
...
@@ -301,22 +346,8 @@ acpi_pci_irq_lookup (
return_VALUE
(
-
1
);
}
if
(
entry
->
link
.
handle
)
{
irq
=
acpi_pci_link_get_irq
(
entry
->
link
.
handle
,
entry
->
link
.
index
,
edge_level
,
active_high_low
,
link
);
if
(
irq
<
0
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_WARN
,
"Invalid IRQ link routing entry
\n
"
));
return_VALUE
(
-
1
);
}
}
else
{
irq
=
entry
->
link
.
index
;
*
edge_level
=
ACPI_LEVEL_SENSITIVE
;
*
active_high_low
=
ACPI_ACTIVE_LOW
;
}
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Found IRQ %d
\n
"
,
irq
));
return_VALUE
(
irq
);
ret
=
func
(
entry
,
edge_level
,
active_high_low
,
link
);
return_VALUE
(
ret
);
}
/*
...
...
@@ -330,7 +361,8 @@ acpi_pci_irq_derive (
int
pin
,
int
*
edge_level
,
int
*
active_high_low
,
char
**
link
)
char
**
link
,
irq_lookup_func
func
)
{
struct
pci_dev
*
bridge
=
dev
;
int
irq
=
-
1
;
...
...
@@ -363,7 +395,7 @@ acpi_pci_irq_derive (
}
irq
=
acpi_pci_irq_lookup
(
bridge
->
bus
,
PCI_SLOT
(
bridge
->
devfn
),
pin
,
edge_level
,
active_high_low
,
link
);
pin
,
edge_level
,
active_high_low
,
link
,
func
);
}
if
(
irq
<
0
)
{
...
...
@@ -415,7 +447,7 @@ acpi_pci_irq_enable (
* values override any BIOS-assigned IRQs set during boot.
*/
irq
=
acpi_pci_irq_lookup
(
dev
->
bus
,
PCI_SLOT
(
dev
->
devfn
),
pin
,
&
edge_level
,
&
active_high_low
,
&
link
);
&
edge_level
,
&
active_high_low
,
&
link
,
acpi_pci_allocate_irq
);
/*
* If no PRT entry was found, we'll try to derive an IRQ from the
...
...
@@ -423,7 +455,7 @@ acpi_pci_irq_enable (
*/
if
(
irq
<
0
)
irq
=
acpi_pci_irq_derive
(
dev
,
pin
,
&
edge_level
,
&
active_high_low
,
&
link
);
&
active_high_low
,
&
link
,
acpi_pci_allocate_irq
);
/*
* No IRQ known to the ACPI subsystem - maybe the BIOS /
...
...
@@ -462,7 +494,9 @@ acpi_pci_irq_enable (
EXPORT_SYMBOL
(
acpi_pci_irq_enable
);
#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
/* FIXME: implement x86/x86_64 version */
void
__attribute__
((
weak
))
acpi_unregister_gsi
(
u32
i
)
{}
void
acpi_pci_irq_disable
(
struct
pci_dev
*
dev
)
...
...
@@ -489,14 +523,14 @@ acpi_pci_irq_disable (
* First we check the PCI IRQ routing table (PRT) for an IRQ.
*/
gsi
=
acpi_pci_irq_lookup
(
dev
->
bus
,
PCI_SLOT
(
dev
->
devfn
),
pin
,
&
edge_level
,
&
active_high_low
,
NULL
);
&
edge_level
,
&
active_high_low
,
NULL
,
acpi_pci_free_irq
);
/*
* If no PRT entry was found, we'll try to derive an IRQ from the
* device's parent bridge.
*/
if
(
gsi
<
0
)
gsi
=
acpi_pci_irq_derive
(
dev
,
pin
,
&
edge_level
,
&
active_high_low
,
NULL
);
&
edge_level
,
&
active_high_low
,
NULL
,
acpi_pci_free_irq
);
if
(
gsi
<
0
)
return_VOID
;
...
...
@@ -512,4 +546,3 @@ acpi_pci_irq_disable (
return_VOID
;
}
#endif
/* CONFIG_ACPI_DEALLOCATE_IRQ */
drivers/acpi/pci_link.c
View file @
d6ac1a79
...
...
@@ -68,6 +68,10 @@ static struct acpi_driver acpi_pci_link_driver = {
},
};
/*
* If a link is initialized, we never change its active and initialized
* later even the link is disable. Instead, we just repick the active irq
*/
struct
acpi_pci_link_irq
{
u8
active
;
/* Current IRQ */
u8
edge_level
;
/* All IRQs */
...
...
@@ -76,8 +80,7 @@ struct acpi_pci_link_irq {
u8
possible_count
;
u8
possible
[
ACPI_PCI_LINK_MAX_POSSIBLE
];
u8
initialized
:
1
;
u8
suspend_resume
:
1
;
u8
reserved
:
6
;
u8
reserved
:
7
;
};
struct
acpi_pci_link
{
...
...
@@ -85,12 +88,14 @@ struct acpi_pci_link {
struct
acpi_device
*
device
;
acpi_handle
handle
;
struct
acpi_pci_link_irq
irq
;
int
refcnt
;
};
static
struct
{
int
count
;
struct
list_head
entries
;
}
acpi_link
;
DECLARE_MUTEX
(
acpi_link_lock
);
/* --------------------------------------------------------------------------
...
...
@@ -532,12 +537,12 @@ static int acpi_pci_link_allocate(
ACPI_FUNCTION_TRACE
(
"acpi_pci_link_allocate"
);
if
(
link
->
irq
.
suspend_resume
)
{
acpi_pci_link_set
(
link
,
link
->
irq
.
active
);
link
->
irq
.
suspend_resume
=
0
;
}
if
(
link
->
irq
.
initialized
)
if
(
link
->
irq
.
initialized
)
{
if
(
link
->
refcnt
==
0
)
/* This means the link is disabled but initialized */
acpi_pci_link_set
(
link
,
link
->
irq
.
active
);
return_VALUE
(
0
);
}
/*
* search for active IRQ in list of possible IRQs.
...
...
@@ -596,13 +601,13 @@ static int acpi_pci_link_allocate(
}
/*
* acpi_pci_link_
get
_irq
* acpi_pci_link_
allocate
_irq
* success: return IRQ >= 0
* failure: return -1
*/
int
acpi_pci_link_
get
_irq
(
acpi_pci_link_
allocate
_irq
(
acpi_handle
handle
,
int
index
,
int
*
edge_level
,
...
...
@@ -613,7 +618,7 @@ acpi_pci_link_get_irq (
struct
acpi_device
*
device
=
NULL
;
struct
acpi_pci_link
*
link
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_pci_link_
get
_irq"
);
ACPI_FUNCTION_TRACE
(
"acpi_pci_link_
allocate
_irq"
);
result
=
acpi_bus_get_device
(
handle
,
&
device
);
if
(
result
)
{
...
...
@@ -633,21 +638,70 @@ acpi_pci_link_get_irq (
return_VALUE
(
-
1
);
}
if
(
acpi_pci_link_allocate
(
link
))
down
(
&
acpi_link_lock
);
if
(
acpi_pci_link_allocate
(
link
))
{
up
(
&
acpi_link_lock
);
return_VALUE
(
-
1
);
}
if
(
!
link
->
irq
.
active
)
{
up
(
&
acpi_link_lock
);
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Link active IRQ is 0!
\n
"
));
return_VALUE
(
-
1
);
}
link
->
refcnt
++
;
up
(
&
acpi_link_lock
);
if
(
edge_level
)
*
edge_level
=
link
->
irq
.
edge_level
;
if
(
active_high_low
)
*
active_high_low
=
link
->
irq
.
active_high_low
;
if
(
name
)
*
name
=
acpi_device_bid
(
link
->
device
);
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Link %s is referenced
\n
"
,
acpi_device_bid
(
link
->
device
)));
return_VALUE
(
link
->
irq
.
active
);
}
/*
* We don't change link's irq information here. After it is reenabled, we
* continue use the info
*/
int
acpi_pci_link_free_irq
(
acpi_handle
handle
)
{
struct
acpi_device
*
device
=
NULL
;
struct
acpi_pci_link
*
link
=
NULL
;
acpi_status
result
;
ACPI_FUNCTION_TRACE
(
"acpi_pci_link_free_irq"
);
result
=
acpi_bus_get_device
(
handle
,
&
device
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid link device
\n
"
));
return_VALUE
(
-
1
);
}
link
=
(
struct
acpi_pci_link
*
)
acpi_driver_data
(
device
);
if
(
!
link
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid link context
\n
"
));
return_VALUE
(
-
1
);
}
down
(
&
acpi_link_lock
);
if
(
!
link
->
irq
.
initialized
)
{
up
(
&
acpi_link_lock
);
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Link isn't initialized
\n
"
));
return_VALUE
(
-
1
);
}
link
->
refcnt
--
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Link %s is dereferenced
\n
"
,
acpi_device_bid
(
link
->
device
)));
if
(
link
->
refcnt
==
0
)
{
acpi_ut_evaluate_object
(
link
->
handle
,
"_DIS"
,
0
,
NULL
);
}
up
(
&
acpi_link_lock
);
return_VALUE
(
link
->
irq
.
active
);
}
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
...
...
@@ -677,6 +731,7 @@ acpi_pci_link_add (
strcpy
(
acpi_device_class
(
device
),
ACPI_PCI_LINK_CLASS
);
acpi_driver_data
(
device
)
=
link
;
down
(
&
acpi_link_lock
);
result
=
acpi_pci_link_get_possible
(
link
);
if
(
result
)
goto
end
;
...
...
@@ -712,6 +767,7 @@ acpi_pci_link_add (
end:
/* disable all links -- to be activated on use */
acpi_ut_evaluate_object
(
link
->
handle
,
"_DIS"
,
0
,
NULL
);
up
(
&
acpi_link_lock
);
if
(
result
)
kfree
(
link
);
...
...
@@ -726,19 +782,32 @@ irqrouter_suspend(
{
struct
list_head
*
node
=
NULL
;
struct
acpi_pci_link
*
link
=
NULL
;
int
ret
=
0
;
ACPI_FUNCTION_TRACE
(
"irqrouter_suspend"
);
list_for_each
(
node
,
&
acpi_link
.
entries
)
{
link
=
list_entry
(
node
,
struct
acpi_pci_link
,
node
);
if
(
!
link
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid link context
\n
"
));
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid link context
\n
"
));
continue
;
}
if
(
link
->
irq
.
active
&&
link
->
irq
.
initialized
)
link
->
irq
.
suspend_resume
=
1
;
if
(
link
->
irq
.
initialized
&&
link
->
refcnt
!=
0
/* We ignore legacy IDE device irq */
&&
link
->
irq
.
active
!=
14
&&
link
->
irq
.
active
!=
15
)
{
printk
(
KERN_WARNING
PREFIX
"%d drivers with interrupt %d neglected to call"
" pci_disable_device at .suspend
\n
"
,
link
->
refcnt
,
link
->
irq
.
active
);
printk
(
KERN_WARNING
PREFIX
"Fix the driver, or rmmod before suspend
\n
"
);
link
->
refcnt
=
0
;
ret
=
-
EINVAL
;
}
}
return_VALUE
(
0
);
return_VALUE
(
ret
);
}
...
...
@@ -756,8 +825,9 @@ acpi_pci_link_remove (
link
=
(
struct
acpi_pci_link
*
)
acpi_driver_data
(
device
);
/* TBD: Acquire/release lock */
down
(
&
acpi_link_lock
);
list_del
(
&
link
->
node
);
up
(
&
acpi_link_lock
);
kfree
(
link
);
...
...
@@ -849,6 +919,7 @@ int __init acpi_irq_balance_set(char *str)
__setup
(
"acpi_irq_balance"
,
acpi_irq_balance_set
);
/* FIXME: we will remove this interface after all drivers call pci_disable_device */
static
struct
sysdev_class
irqrouter_sysdev_class
=
{
set_kset_name
(
"irqrouter"
),
.
suspend
=
irqrouter_suspend
,
...
...
drivers/acpi/processor_idle.c
View file @
d6ac1a79
...
...
@@ -81,30 +81,33 @@ module_param(bm_history, uint, 0644);
*
* To skip this limit, boot/load with a large max_cstate limit.
*/
static
int
no_c2c3
(
struct
dmi_system_id
*
id
)
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 -
C2,C3
disabled."
printk
(
KERN_NOTICE
PREFIX
"%s detected -
%s
disabled."
" Override with
\"
processor.max_cstate=%d
\"\n
"
,
id
->
ident
,
((
int
)
id
->
driver_data
==
1
)
?
"C2,C3"
:
"C3"
,
ACPI_PROCESSOR_MAX_POWER
+
1
);
max_cstate
=
1
;
max_cstate
=
(
int
)
id
->
driver_data
;
return
0
;
}
static
struct
dmi_system_id
__initdata
processor_power_dmi_table
[]
=
{
{
no_c2c3
,
"IBM ThinkPad R40e"
,
{
{
set_max_cstate
,
"IBM ThinkPad R40e"
,
{
DMI_MATCH
(
DMI_BIOS_VENDOR
,
"IBM"
),
DMI_MATCH
(
DMI_BIOS_VERSION
,
"1SET60WW"
)
}},
{
no_c2c3
,
"Medion 41700"
,
{
DMI_MATCH
(
DMI_BIOS_VERSION
,
"1SET60WW"
)
},
(
void
*
)
1
},
{
set_max_cstate
,
"Medion 41700"
,
{
DMI_MATCH
(
DMI_BIOS_VENDOR
,
"Phoenix Technologies LTD"
),
DMI_MATCH
(
DMI_BIOS_VERSION
,
"R01-A1J"
)
},
(
void
*
)
1
},
{
set_max_cstate
,
"Clevo 5600D"
,
{
DMI_MATCH
(
DMI_BIOS_VENDOR
,
"Phoenix Technologies LTD"
),
DMI_MATCH
(
DMI_BIOS_VERSION
,
"R01-A1J"
)
}},
DMI_MATCH
(
DMI_BIOS_VERSION
,
"SHE845M0.86C.0013.D.0302131307"
)
},
(
void
*
)
2
},
{},
};
...
...
@@ -549,7 +552,8 @@ static int acpi_processor_get_power_info_default_c1 (struct acpi_processor *pr)
ACPI_FUNCTION_TRACE
(
"acpi_processor_get_power_info_default_c1"
);
for
(
i
=
0
;
i
<
ACPI_PROCESSOR_MAX_POWER
;
i
++
)
memset
(
pr
->
power
.
states
,
0
,
sizeof
(
struct
acpi_processor_cx
));
memset
(
&
(
pr
->
power
.
states
[
i
]),
0
,
sizeof
(
struct
acpi_processor_cx
));
/* if info is obtained from pblk/fadt, type equals state */
pr
->
power
.
states
[
ACPI_STATE_C1
].
type
=
ACPI_STATE_C1
;
...
...
@@ -580,7 +584,8 @@ static int acpi_processor_get_power_info_cst (struct acpi_processor *pr)
pr
->
power
.
count
=
0
;
for
(
i
=
0
;
i
<
ACPI_PROCESSOR_MAX_POWER
;
i
++
)
memset
(
pr
->
power
.
states
,
0
,
sizeof
(
struct
acpi_processor_cx
));
memset
(
&
(
pr
->
power
.
states
[
i
]),
0
,
sizeof
(
struct
acpi_processor_cx
));
status
=
acpi_evaluate_object
(
pr
->
handle
,
"_CST"
,
NULL
,
&
buffer
);
if
(
ACPI_FAILURE
(
status
))
{
...
...
@@ -763,7 +768,6 @@ static void acpi_processor_power_verify_c3(
}
if
(
pr
->
flags
.
bm_check
)
{
printk
(
"Disabling BM access before entering C3
\n
"
);
/* bus mastering control is necessary */
if
(
!
pr
->
flags
.
bm_control
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
...
...
@@ -771,7 +775,6 @@ static void acpi_processor_power_verify_c3(
return_VOID
;
}
}
else
{
printk
(
"Invalidating cache before entering C3
\n
"
);
/*
* WBINVD should be set in fadt, for C3 state to be
* supported on when bm_check is not required.
...
...
@@ -842,7 +845,7 @@ static int acpi_processor_get_power_info (
result
=
acpi_processor_get_power_info_cst
(
pr
);
if
((
result
)
||
(
acpi_processor_power_verify
(
pr
)
<
2
))
{
result
=
acpi_processor_get_power_info_fadt
(
pr
);
if
(
result
)
if
(
(
result
)
||
(
acpi_processor_power_verify
(
pr
)
<
2
)
)
result
=
acpi_processor_get_power_info_default_c1
(
pr
);
}
...
...
drivers/net/sk98lin/skge.c
View file @
d6ac1a79
...
...
@@ -5133,6 +5133,67 @@ static void __devexit skge_remove_one(struct pci_dev *pdev)
kfree
(
pAC
);
}
#ifdef CONFIG_PM
static
int
skge_suspend
(
struct
pci_dev
*
pdev
,
pm_message_t
state
)
{
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
DEV_NET
*
pNet
=
netdev_priv
(
dev
);
SK_AC
*
pAC
=
pNet
->
pAC
;
struct
net_device
*
otherdev
=
pAC
->
dev
[
1
];
if
(
pNet
->
Up
)
{
pAC
->
WasIfUp
[
0
]
=
SK_TRUE
;
DoPrintInterfaceChange
=
SK_FALSE
;
SkDrvDeInitAdapter
(
pAC
,
0
);
/* performs SkGeClose */
}
if
(
otherdev
!=
dev
)
{
pNet
=
netdev_priv
(
otherdev
);
if
(
pNet
->
Up
)
{
pAC
->
WasIfUp
[
1
]
=
SK_TRUE
;
DoPrintInterfaceChange
=
SK_FALSE
;
SkDrvDeInitAdapter
(
pAC
,
1
);
/* performs SkGeClose */
}
}
pci_save_state
(
pdev
);
pci_enable_wake
(
pdev
,
pci_choose_state
(
pdev
,
state
),
0
);
if
(
pAC
->
AllocFlag
&
SK_ALLOC_IRQ
)
{
free_irq
(
dev
->
irq
,
dev
);
}
pci_disable_device
(
pdev
);
pci_set_power_state
(
pdev
,
pci_choose_state
(
pdev
,
state
));
return
0
;
}
static
int
skge_resume
(
struct
pci_dev
*
pdev
)
{
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
DEV_NET
*
pNet
=
netdev_priv
(
dev
);
SK_AC
*
pAC
=
pNet
->
pAC
;
pci_set_power_state
(
pdev
,
PCI_D0
);
pci_restore_state
(
pdev
);
pci_enable_device
(
pdev
);
pci_set_master
(
pdev
);
if
(
pAC
->
GIni
.
GIMacsFound
==
2
)
request_irq
(
dev
->
irq
,
SkGeIsr
,
SA_SHIRQ
,
pAC
->
Name
,
dev
);
else
request_irq
(
dev
->
irq
,
SkGeIsrOnePort
,
SA_SHIRQ
,
pAC
->
Name
,
dev
);
if
(
pAC
->
WasIfUp
[
0
]
==
SK_TRUE
)
{
DoPrintInterfaceChange
=
SK_FALSE
;
SkDrvInitAdapter
(
pAC
,
0
);
/* first device */
}
if
(
pAC
->
dev
[
1
]
!=
dev
&&
pAC
->
WasIfUp
[
1
]
==
SK_TRUE
)
{
DoPrintInterfaceChange
=
SK_FALSE
;
SkDrvInitAdapter
(
pAC
,
1
);
/* first device */
}
return
0
;
}
#endif
static
struct
pci_device_id
skge_pci_tbl
[]
=
{
{
PCI_VENDOR_ID_3COM
,
0x1700
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_3COM
,
0x80eb
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
...
...
@@ -5158,6 +5219,8 @@ static struct pci_driver skge_driver = {
.
id_table
=
skge_pci_tbl
,
.
probe
=
skge_probe_one
,
.
remove
=
__devexit_p
(
skge_remove_one
),
.
suspend
=
skge_suspend
,
.
resume
=
skge_resume
,
};
static
int
__init
skge_init
(
void
)
...
...
drivers/pcmcia/yenta_socket.c
View file @
d6ac1a79
...
...
@@ -1107,6 +1107,8 @@ static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state)
pci_read_config_dword
(
dev
,
17
*
4
,
&
socket
->
saved_state
[
1
]);
pci_disable_device
(
dev
);
free_irq
(
dev
->
irq
,
socket
);
/*
* Some laptops (IBM T22) do not like us putting the Cardbus
* bridge into D3. At a guess, some other laptop will
...
...
@@ -1132,6 +1134,13 @@ static int yenta_dev_resume (struct pci_dev *dev)
pci_enable_device
(
dev
);
pci_set_master
(
dev
);
if
(
socket
->
cb_irq
)
if
(
request_irq
(
socket
->
cb_irq
,
yenta_interrupt
,
SA_SHIRQ
,
"yenta"
,
socket
))
{
printk
(
KERN_WARNING
"Yenta: request_irq() failed on resume!
\n
"
);
socket
->
cb_irq
=
0
;
}
if
(
socket
->
type
&&
socket
->
type
->
restore_state
)
socket
->
type
->
restore_state
(
socket
);
}
...
...
include/acpi/acpi_drivers.h
View file @
d6ac1a79
...
...
@@ -56,8 +56,9 @@
/* ACPI PCI Interrupt Link (pci_link.c) */
int
acpi_irq_penalty_init
(
void
);
int
acpi_pci_link_
get
_irq
(
acpi_handle
handle
,
int
index
,
int
*
edge_level
,
int
acpi_pci_link_
allocate
_irq
(
acpi_handle
handle
,
int
index
,
int
*
edge_level
,
int
*
active_high_low
,
char
**
name
);
int
acpi_pci_link_free_irq
(
acpi_handle
handle
);
/* ACPI PCI Interrupt Routing (pci_irq.c) */
...
...
include/linux/acpi.h
View file @
d6ac1a79
...
...
@@ -453,9 +453,7 @@ int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
* If this matches the last registration, any IRQ resources for gsi
* are freed.
*/
#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
void
acpi_unregister_gsi
(
u32
gsi
);
#endif
#ifdef CONFIG_ACPI_PCI
...
...
@@ -480,9 +478,7 @@ struct pci_dev;
int
acpi_pci_irq_enable
(
struct
pci_dev
*
dev
);
void
acpi_penalize_isa_irq
(
int
irq
,
int
active
);
#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
void
acpi_pci_irq_disable
(
struct
pci_dev
*
dev
);
#endif
struct
acpi_pci_driver
{
struct
acpi_pci_driver
*
next
;
...
...
sound/pci/intel8x0.c
View file @
d6ac1a79
...
...
@@ -2373,6 +2373,8 @@ static int intel8x0_suspend(snd_card_t *card, pm_message_t state)
for
(
i
=
0
;
i
<
3
;
i
++
)
if
(
chip
->
ac97
[
i
])
snd_ac97_suspend
(
chip
->
ac97
[
i
]);
if
(
chip
->
irq
>=
0
)
free_irq
(
chip
->
irq
,
(
void
*
)
chip
);
pci_disable_device
(
chip
->
pci
);
return
0
;
}
...
...
@@ -2384,7 +2386,9 @@ static int intel8x0_resume(snd_card_t *card)
pci_enable_device
(
chip
->
pci
);
pci_set_master
(
chip
->
pci
);
snd_intel8x0_chip_init
(
chip
,
0
);
request_irq
(
chip
->
irq
,
snd_intel8x0_interrupt
,
SA_INTERRUPT
|
SA_SHIRQ
,
card
->
shortname
,
(
void
*
)
chip
);
synchronize_irq
(
chip
->
irq
);
snd_intel8x0_chip_init
(
chip
,
1
);
/* refill nocache */
if
(
chip
->
fix_nocache
)
...
...
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