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
nexedi
linux
Commits
3a40a2c1
Commit
3a40a2c1
authored
Jun 16, 2004
by
Len Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.7
into intel.com:/home/lenb/bk/linux-acpi-test-2.6.7
parents
331cc23e
c76f4547
Changes
17
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
279 additions
and
422 deletions
+279
-422
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/acpi/boot.c
+29
-0
arch/i386/kernel/mpparse.c
arch/i386/kernel/mpparse.c
+36
-76
arch/i386/pci/acpi.c
arch/i386/pci/acpi.c
+23
-8
arch/ia64/kernel/acpi.c
arch/ia64/kernel/acpi.c
+8
-15
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/iosapic.c
+79
-128
arch/ia64/pci/pci.c
arch/ia64/pci/pci.c
+12
-4
arch/x86_64/kernel/mpparse.c
arch/x86_64/kernel/mpparse.c
+36
-73
drivers/acpi/pci_irq.c
drivers/acpi/pci_irq.c
+36
-83
drivers/acpi/pci_link.c
drivers/acpi/pci_link.c
+2
-2
drivers/acpi/tables.c
drivers/acpi/tables.c
+3
-3
drivers/serial/8250_acpi.c
drivers/serial/8250_acpi.c
+6
-16
drivers/serial/8250_hcdp.c
drivers/serial/8250_hcdp.c
+4
-8
include/acpi/acpi_drivers.h
include/acpi/acpi_drivers.h
+1
-1
include/asm-i386/mpspec.h
include/asm-i386/mpspec.h
+1
-1
include/asm-ia64/iosapic.h
include/asm-ia64/iosapic.h
+0
-1
include/asm-x86_64/mpspec.h
include/asm-x86_64/mpspec.h
+1
-1
include/linux/acpi.h
include/linux/acpi.h
+2
-2
No files found.
arch/i386/kernel/acpi/boot.c
View file @
3a40a2c1
...
...
@@ -437,6 +437,35 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
return
0
;
}
unsigned
int
acpi_register_gsi
(
u32
gsi
,
int
edge_level
,
int
active_high_low
)
{
unsigned
int
irq
;
#ifdef CONFIG_PCI
/*
* Make sure all (legacy) PCI IRQs are set as level-triggered.
*/
if
(
acpi_irq_model
==
ACPI_IRQ_MODEL_PIC
)
{
static
u16
irq_mask
;
extern
void
eisa_set_level_irq
(
unsigned
int
irq
);
if
((
gsi
<
16
)
&&
!
((
1
<<
gsi
)
&
irq_mask
))
{
Dprintk
(
KERN_DEBUG
PREFIX
"Setting GSI %u as level-triggered
\n
"
,
gsi
);
irq_mask
|=
(
1
<<
gsi
);
eisa_set_level_irq
(
gsi
);
}
}
#endif
#ifdef CONFIG_X86_IO_APIC
if
(
acpi_irq_model
==
ACPI_IRQ_MODEL_IOAPIC
)
{
mp_register_gsi
(
gsi
,
edge_level
,
active_high_low
);
}
#endif
acpi_gsi_to_irq
(
gsi
,
&
irq
);
return
irq
;
}
static
unsigned
long
__init
acpi_scan_rsdp
(
unsigned
long
start
,
...
...
arch/i386/kernel/mpparse.c
View file @
3a40a2c1
...
...
@@ -1025,53 +1025,26 @@ void __init mp_config_acpi_legacy_irqs (void)
}
}
extern
FADT_DESCRIPTOR
acpi_fadt
;
#ifdef CONFIG_ACPI_PCI
int
(
*
platform_rename_gsi
)(
int
ioapic
,
int
gsi
);
void
__init
mp_parse_prt
(
void
)
void
mp_register_gsi
(
u32
gsi
,
int
edge_level
,
int
active_high_low
)
{
struct
list_head
*
node
=
NULL
;
struct
acpi_prt_entry
*
entry
=
NULL
;
int
ioapic
=
-
1
;
int
ioapic_pin
=
0
;
int
gsi
=
0
;
int
idx
,
bit
=
0
;
int
edge_level
=
0
;
int
active_high_low
=
0
;
/*
* Parsing through the PCI Interrupt Routing Table (PRT) and program
* routing for all entries.
*/
list_for_each
(
node
,
&
acpi_prt
.
entries
)
{
entry
=
list_entry
(
node
,
struct
acpi_prt_entry
,
node
);
/* Need to get gsi for dynamic entry */
if
(
entry
->
link
.
handle
)
{
gsi
=
acpi_pci_link_get_irq
(
entry
->
link
.
handle
,
entry
->
link
.
index
,
&
edge_level
,
&
active_high_low
);
if
(
!
gsi
)
continue
;
}
else
{
/* Hardwired GSI. Assume PCI standard settings */
gsi
=
entry
->
link
.
index
;
edge_level
=
1
;
active_high_low
=
1
;
}
#ifdef CONFIG_ACPI_BUS
/* Don't set up the ACPI SCI because it's already set up */
if
(
acpi_fadt
.
sci_int
==
gsi
)
{
/* we still need to set entry's irq */
acpi_gsi_to_irq
(
gsi
,
&
entry
->
irq
);
continue
;
}
if
(
acpi_fadt
.
sci_int
==
gsi
)
return
;
#endif
ioapic
=
mp_find_ioapic
(
gsi
);
if
(
ioapic
<
0
)
continue
;
if
(
ioapic
<
0
)
{
printk
(
KERN_WARNING
"No IOAPIC for GSI %u
\n
"
,
gsi
);
return
;
}
ioapic_pin
=
gsi
-
mp_ioapic_routing
[
ioapic
].
gsi_base
;
if
(
platform_rename_gsi
)
...
...
@@ -1080,7 +1053,7 @@ void __init mp_parse_prt (void)
/*
* Avoid pin reprogramming. PRTs typically include entries
* with redundant pin->gsi mappings (but unique PCI devices);
* we only
only program the IOAPIC on the first.
* we
only program the IOAPIC on the first.
*/
bit
=
ioapic_pin
%
32
;
idx
=
(
ioapic_pin
<
32
)
?
0
:
(
ioapic_pin
/
32
);
...
...
@@ -1088,33 +1061,20 @@ void __init mp_parse_prt (void)
printk
(
KERN_ERR
"Invalid reference to IOAPIC pin "
"%d-%d
\n
"
,
mp_ioapic_routing
[
ioapic
].
apic_id
,
ioapic_pin
);
continue
;
return
;
}
if
((
1
<<
bit
)
&
mp_ioapic_routing
[
ioapic
].
pin_programmed
[
idx
])
{
Dprintk
(
KERN_DEBUG
"Pin %d-%d already programmed
\n
"
,
mp_ioapic_routing
[
ioapic
].
apic_id
,
ioapic_pin
);
acpi_gsi_to_irq
(
gsi
,
&
entry
->
irq
);
continue
;
return
;
}
mp_ioapic_routing
[
ioapic
].
pin_programmed
[
idx
]
|=
(
1
<<
bit
);
if
(
!
io_apic_set_pci_routing
(
ioapic
,
ioapic_pin
,
gsi
,
edge_level
,
active_high_low
))
{
acpi_gsi_to_irq
(
gsi
,
&
entry
->
irq
);
}
printk
(
KERN_DEBUG
"%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d %s %s
\n
"
,
entry
->
id
.
segment
,
entry
->
id
.
bus
,
entry
->
id
.
device
,
(
'A'
+
entry
->
pin
),
mp_ioapic_routing
[
ioapic
].
apic_id
,
ioapic_pin
,
entry
->
irq
,
edge_level
?
"level"
:
"edge"
,
active_high_low
?
"low"
:
"high"
);
}
print_IO_APIC
();
return
;
io_apic_set_pci_routing
(
ioapic
,
ioapic_pin
,
gsi
,
edge_level
==
ACPI_EDGE_SENSITIVE
?
0
:
1
,
active_high_low
==
ACPI_ACTIVE_HIGH
?
0
:
1
);
}
#endif
/*CONFIG_ACPI_PCI*/
#endif
/*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/
#endif
/*CONFIG_ACPI_BOOT*/
arch/i386/pci/acpi.c
View file @
3a40a2c1
#include <linux/pci.h>
#include <linux/acpi.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/hw_irq.h>
#include "pci.h"
struct
pci_bus
*
__devinit
pci_acpi_scan_root
(
struct
acpi_device
*
device
,
int
domain
,
int
busnum
)
...
...
@@ -15,18 +17,31 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
static
int
__init
pci_acpi_init
(
void
)
{
struct
pci_dev
*
dev
=
NULL
;
if
(
pcibios_scanned
)
return
0
;
if
(
!
acpi_noirq
)
{
if
(
!
acpi_pci_irq_init
())
{
if
(
acpi_noirq
)
return
0
;
printk
(
KERN_INFO
"PCI: Using ACPI for IRQ routing
\n
"
);
acpi_irq_penalty_init
();
pcibios_scanned
++
;
pcibios_enable_irq
=
acpi_pci_irq_enable
;
}
else
printk
(
KERN_WARNING
"PCI: Invalid ACPI-PCI IRQ routing table
\n
"
);
}
/*
* PCI IRQ routing is set up by pci_enable_device(), but we
* also do it here in case there are still broken drivers that
* don't use pci_enable_device().
*/
while
((
dev
=
pci_find_device
(
PCI_ANY_ID
,
PCI_ANY_ID
,
dev
))
!=
NULL
)
acpi_pci_irq_enable
(
dev
);
#ifdef CONFIG_X86_IO_APIC
if
(
acpi_ioapic
)
print_IO_APIC
();
#endif
return
0
;
}
...
...
arch/ia64/kernel/acpi.c
View file @
3a40a2c1
...
...
@@ -521,9 +521,14 @@ acpi_numa_arch_fixup (void)
#endif
/* CONFIG_ACPI_NUMA */
unsigned
int
acpi_register_gsi
(
u32
gsi
,
int
polarity
,
int
trigger
)
acpi_register_gsi
(
u32
gsi
,
int
edge_level
,
int
active_high_low
)
{
return
acpi_register_irq
(
gsi
,
polarity
,
trigger
);
if
(
has_8259
&&
gsi
<
16
)
return
isa_irq_to_vector
(
gsi
);
return
iosapic_register_intr
(
gsi
,
(
active_high_low
==
ACPI_ACTIVE_HIGH
)
?
IOSAPIC_POL_HIGH
:
IOSAPIC_POL_LOW
,
(
edge_level
==
ACPI_EDGE_SENSITIVE
)
?
IOSAPIC_EDGE
:
IOSAPIC_LEVEL
);
}
EXPORT_SYMBOL
(
acpi_register_gsi
);
...
...
@@ -548,7 +553,7 @@ acpi_parse_fadt (unsigned long phys_addr, unsigned long size)
if
(
fadt
->
iapc_boot_arch
&
BAF_LEGACY_DEVICES
)
acpi_legacy_devices
=
1
;
acpi_register_gsi
(
fadt
->
sci_int
,
ACPI_
ACTIVE_LOW
,
ACPI_LEVEL_SENSITIVE
);
acpi_register_gsi
(
fadt
->
sci_int
,
ACPI_
LEVEL_SENSITIVE
,
ACPI_ACTIVE_LOW
);
return
0
;
}
...
...
@@ -662,16 +667,4 @@ acpi_gsi_to_irq (u32 gsi, unsigned int *irq)
return
0
;
}
int
acpi_register_irq
(
u32
gsi
,
u32
polarity
,
u32
trigger
)
{
if
(
has_8259
&&
gsi
<
16
)
return
isa_irq_to_vector
(
gsi
);
return
iosapic_register_intr
(
gsi
,
(
polarity
==
ACPI_ACTIVE_HIGH
)
?
IOSAPIC_POL_HIGH
:
IOSAPIC_POL_LOW
,
(
trigger
==
ACPI_EDGE_SENSITIVE
)
?
IOSAPIC_EDGE
:
IOSAPIC_LEVEL
);
}
EXPORT_SYMBOL
(
acpi_register_irq
);
#endif
/* CONFIG_ACPI_BOOT */
arch/ia64/kernel/iosapic.c
View file @
3a40a2c1
...
...
@@ -483,7 +483,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
index
=
find_iosapic
(
gsi
);
if
(
index
<
0
)
{
printk
(
KERN_WARNING
"%s: No IOSAPIC for GSI
0x%x
\n
"
,
__FUNCTION__
,
gsi
);
printk
(
KERN_WARNING
"%s: No IOSAPIC for GSI
%u
\n
"
,
__FUNCTION__
,
gsi
);
return
;
}
...
...
@@ -512,6 +512,42 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
}
}
static
unsigned
int
get_target_cpu
(
void
)
{
#ifdef CONFIG_SMP
static
int
cpu
=
-
1
;
/*
* If the platform supports redirection via XTP, let it
* distribute interrupts.
*/
if
(
smp_int_redirect
&
SMP_IRQ_REDIRECTION
)
return
hard_smp_processor_id
();
/*
* Some interrupts (ACPI SCI, for instance) are registered
* before the BSP is marked as online.
*/
if
(
!
cpu_online
(
smp_processor_id
()))
return
hard_smp_processor_id
();
/*
* Otherwise, round-robin interrupt vectors across all the
* processors. (It'd be nice if we could be smarter in the
* case of NUMA.)
*/
do
{
if
(
++
cpu
>=
NR_CPUS
)
cpu
=
0
;
}
while
(
!
cpu_online
(
cpu
));
return
cpu_physical_id
(
cpu
);
#else
return
hard_smp_processor_id
();
#endif
}
/*
* ACPI can describe IOSAPIC interrupts via static tables and namespace
* methods. This provides an interface to register those interrupts and
...
...
@@ -522,21 +558,35 @@ iosapic_register_intr (unsigned int gsi,
unsigned
long
polarity
,
unsigned
long
trigger
)
{
int
vector
;
unsigned
int
dest
=
(
ia64_getreg
(
_IA64_REG_CR_LID
)
>>
16
)
&
0xffff
;
unsigned
int
dest
;
unsigned
long
flags
;
/*
* If this GSI has already been registered (i.e., it's a
* shared interrupt, or we lost a race to register it),
* don't touch the RTE.
*/
spin_lock_irqsave
(
&
iosapic_lock
,
flags
);
{
vector
=
gsi_to_vector
(
gsi
);
if
(
vector
<
0
)
vector
=
assign_irq_vector
(
AUTO_ASSIGN
);
if
(
vector
>
0
)
{
spin_unlock_irqrestore
(
&
iosapic_lock
,
flags
);
return
vector
;
}
vector
=
assign_irq_vector
(
AUTO_ASSIGN
);
dest
=
get_target_cpu
();
register_intr
(
gsi
,
vector
,
IOSAPIC_LOWEST_PRIORITY
,
polarity
,
trigger
);
}
spin_unlock_irqrestore
(
&
iosapic_lock
,
flags
);
printk
(
KERN_INFO
"GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d
\n
"
,
gsi
,
(
polarity
==
IOSAPIC_POL_HIGH
?
"high"
:
"low"
),
(
trigger
==
IOSAPIC_EDGE
?
"edge"
:
"level"
),
dest
,
vector
);
printk
(
KERN_INFO
"GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d
\n
"
,
gsi
,
(
trigger
==
IOSAPIC_EDGE
?
"edge"
:
"level"
),
(
polarity
==
IOSAPIC_POL_HIGH
?
"high"
:
"low"
),
cpu_logical_id
(
dest
),
dest
,
vector
);
/* program the IOSAPIC routing table */
set_rte
(
vector
,
dest
,
0
);
set_rte
(
vector
,
dest
,
1
);
return
vector
;
}
...
...
@@ -549,8 +599,9 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
int
iosapic_vector
,
u16
eid
,
u16
id
,
unsigned
long
polarity
,
unsigned
long
trigger
)
{
static
const
char
*
const
name
[]
=
{
"unknown"
,
"PMI"
,
"INIT"
,
"CPEI"
};
unsigned
char
delivery
;
int
vector
;
int
vector
,
mask
=
0
;
unsigned
int
dest
=
((
id
<<
8
)
|
eid
)
&
0xffff
;
switch
(
int_type
)
{
...
...
@@ -570,21 +621,22 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
case
ACPI_INTERRUPT_CPEI
:
vector
=
IA64_CPE_VECTOR
;
delivery
=
IOSAPIC_LOWEST_PRIORITY
;
mask
=
1
;
break
;
default:
printk
(
KERN_ERR
"iosapic_register_platform_irq(): invalid int type
\n
"
);
printk
(
KERN_ERR
"iosapic_register_platform_irq(): invalid int type
0x%x
\n
"
,
int_type
);
return
-
1
;
}
register_intr
(
gsi
,
vector
,
delivery
,
polarity
,
trigger
);
register_intr
(
gsi
,
vector
,
delivery
,
polarity
,
trigger
);
printk
(
KERN_INFO
"PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d
\n
"
,
int_type
,
gsi
,
(
polarity
==
IOSAPIC_POL_HIGH
?
"high"
:
"low"
),
(
trigger
==
IOSAPIC_EDGE
?
"edge"
:
"level"
),
dest
,
vector
);
printk
(
KERN_INFO
"PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d
\n
"
,
int_type
<
ARRAY_SIZE
(
name
)
?
name
[
int_type
]
:
"unknown"
,
int_type
,
gsi
,
(
trigger
==
IOSAPIC_EDGE
?
"edge"
:
"level"
),
(
polarity
==
IOSAPIC_POL_HIGH
?
"high"
:
"low"
),
cpu_logical_id
(
dest
),
dest
,
vector
);
/* program the IOSAPIC routing table */
set_rte
(
vector
,
dest
,
0
);
set_rte
(
vector
,
dest
,
mask
);
return
vector
;
}
...
...
@@ -599,18 +651,18 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
unsigned
long
trigger
)
{
int
vector
;
unsigned
int
dest
=
(
ia64_getreg
(
_IA64_REG_CR_LID
)
>>
16
)
&
0xffff
;
unsigned
int
dest
=
hard_smp_processor_id
()
;
vector
=
isa_irq_to_vector
(
isa_irq
);
register_intr
(
gsi
,
vector
,
IOSAPIC_LOWEST_PRIORITY
,
polarity
,
trigger
);
DBG
(
"ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU 0x%04x vector %d
\n
"
,
isa_irq
,
gsi
,
polarity
==
IOSAPIC_POL_HIGH
?
"high"
:
"low"
,
trigger
==
IOSAPIC_EDGE
?
"edge"
:
"level"
,
dest
,
vector
);
DBG
(
"ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d
\n
"
,
isa_irq
,
gsi
,
trigger
==
IOSAPIC_EDGE
?
"edge"
:
"level"
,
polarity
==
IOSAPIC_POL_HIGH
?
"high"
:
"low"
,
cpu_logical_id
(
dest
),
dest
,
vector
);
/* program the IOSAPIC routing table */
set_rte
(
vector
,
dest
,
0
);
set_rte
(
vector
,
dest
,
1
);
}
void
__init
...
...
@@ -665,104 +717,3 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
iosapic_override_isa_irq
(
isa_irq
,
isa_irq
,
IOSAPIC_POL_HIGH
,
IOSAPIC_EDGE
);
}
}
void
iosapic_enable_intr
(
unsigned
int
vector
)
{
unsigned
int
dest
;
irq_desc_t
*
desc
;
/*
* In the case of a shared interrupt, do not re-route the vector, and
* especially do not mask a running interrupt (startup will not get
* called for a shared interrupt).
*/
desc
=
irq_descp
(
vector
);
if
(
desc
->
action
)
return
;
#ifdef CONFIG_SMP
/*
* For platforms that do not support interrupt redirect via the XTP interface, we
* can round-robin the PCI device interrupts to the processors
*/
if
(
!
(
smp_int_redirect
&
SMP_IRQ_REDIRECTION
))
{
static
int
cpu_index
=
-
1
;
do
if
(
++
cpu_index
>=
NR_CPUS
)
cpu_index
=
0
;
while
(
!
cpu_online
(
cpu_index
));
dest
=
cpu_physical_id
(
cpu_index
)
&
0xffff
;
}
else
{
/*
* Direct the interrupt vector to the current cpu, platform redirection
* will distribute them.
*/
dest
=
(
ia64_getreg
(
_IA64_REG_CR_LID
)
>>
16
)
&
0xffff
;
}
#else
/* direct the interrupt vector to the running cpu id */
dest
=
(
ia64_getreg
(
_IA64_REG_CR_LID
)
>>
16
)
&
0xffff
;
#endif
set_rte
(
vector
,
dest
,
1
);
printk
(
KERN_INFO
"IOSAPIC: vector %d -> CPU 0x%04x, enabled
\n
"
,
vector
,
dest
);
}
#ifdef CONFIG_ACPI_PCI
void
__init
iosapic_parse_prt
(
void
)
{
struct
acpi_prt_entry
*
entry
;
struct
list_head
*
node
;
unsigned
int
gsi
;
int
vector
;
char
pci_id
[
16
];
struct
hw_interrupt_type
*
irq_type
=
&
irq_type_iosapic_level
;
irq_desc_t
*
idesc
;
list_for_each
(
node
,
&
acpi_prt
.
entries
)
{
entry
=
list_entry
(
node
,
struct
acpi_prt_entry
,
node
);
/* We're only interested in static (non-link) entries. */
if
(
entry
->
link
.
handle
)
continue
;
gsi
=
entry
->
link
.
index
;
vector
=
gsi_to_vector
(
gsi
);
if
(
vector
<
0
)
{
if
(
find_iosapic
(
gsi
)
<
0
)
continue
;
/* allocate a vector for this interrupt line */
if
(
pcat_compat
&&
(
gsi
<
16
))
vector
=
isa_irq_to_vector
(
gsi
);
else
/* new GSI; allocate a vector for it */
vector
=
assign_irq_vector
(
AUTO_ASSIGN
);
register_intr
(
gsi
,
vector
,
IOSAPIC_LOWEST_PRIORITY
,
IOSAPIC_POL_LOW
,
IOSAPIC_LEVEL
);
}
entry
->
irq
=
vector
;
snprintf
(
pci_id
,
sizeof
(
pci_id
),
"%02x:%02x:%02x[%c]"
,
entry
->
id
.
segment
,
entry
->
id
.
bus
,
entry
->
id
.
device
,
'A'
+
entry
->
pin
);
/*
* If vector was previously initialized to a different
* handler, re-initialize.
*/
idesc
=
irq_descp
(
vector
);
if
(
idesc
->
handler
!=
irq_type
)
register_intr
(
gsi
,
vector
,
IOSAPIC_LOWEST_PRIORITY
,
IOSAPIC_POL_LOW
,
IOSAPIC_LEVEL
);
}
}
#endif
/* CONFIG_ACPI */
arch/ia64/pci/pci.c
View file @
3a40a2c1
...
...
@@ -134,10 +134,18 @@ static struct pci_ops pci_root_ops = {
static
int
__init
pci_acpi_init
(
void
)
{
if
(
!
acpi_pci_irq_init
())
struct
pci_dev
*
dev
=
NULL
;
printk
(
KERN_INFO
"PCI: Using ACPI for IRQ routing
\n
"
);
else
printk
(
KERN_WARNING
"PCI: Invalid ACPI-PCI IRQ routing table
\n
"
);
/*
* PCI IRQ routing is set up by pci_enable_device(), but we
* also do it here in case there are still broken drivers that
* don't use pci_enable_device().
*/
while
((
dev
=
pci_find_device
(
PCI_ANY_ID
,
PCI_ANY_ID
,
dev
))
!=
NULL
)
acpi_pci_irq_enable
(
dev
);
return
0
;
}
...
...
arch/x86_64/kernel/mpparse.c
View file @
3a40a2c1
...
...
@@ -888,57 +888,33 @@ void __init mp_config_acpi_legacy_irqs (void)
return
;
}
extern
FADT_DESCRIPTOR
acpi_fadt
;
#ifdef CONFIG_ACPI_PCI
void
__init
mp_parse_prt
(
void
)
void
mp_register_gsi
(
u32
gsi
,
int
edge_level
,
int
active_high_low
)
{
struct
list_head
*
node
=
NULL
;
struct
acpi_prt_entry
*
entry
=
NULL
;
int
ioapic
=
-
1
;
int
ioapic_pin
=
0
;
int
gsi
=
0
;
int
idx
,
bit
=
0
;
int
edge_level
=
0
;
int
active_high_low
=
0
;
/*
* Parsing through the PCI Interrupt Routing Table (PRT) and program
* routing for all static (IOAPIC-direct) entries.
*/
list_for_each
(
node
,
&
acpi_prt
.
entries
)
{
entry
=
list_entry
(
node
,
struct
acpi_prt_entry
,
node
);
/* Need to get gsi for dynamic entry */
if
(
entry
->
link
.
handle
)
{
gsi
=
acpi_pci_link_get_irq
(
entry
->
link
.
handle
,
entry
->
link
.
index
,
&
edge_level
,
&
active_high_low
);
if
(
!
gsi
)
continue
;
}
else
{
/* Hardwired GSI. Assume PCI standard settings */
gsi
=
entry
->
link
.
index
;
edge_level
=
1
;
active_high_low
=
1
;
}
if
(
acpi_irq_model
!=
ACPI_IRQ_MODEL_IOAPIC
)
return
;
#ifdef CONFIG_ACPI_BUS
/* Don't set up the ACPI SCI because it's already set up */
if
(
acpi_fadt
.
sci_int
==
gsi
)
{
/* we still need to set up the entry's irq */
acpi_gsi_to_irq
(
gsi
,
&
entry
->
irq
);
continue
;
}
if
(
acpi_fadt
.
sci_int
==
gsi
)
return
;
#endif
ioapic
=
mp_find_ioapic
(
gsi
);
if
(
ioapic
<
0
)
continue
;
if
(
ioapic
<
0
)
{
printk
(
KERN_WARNING
"No IOAPIC for GSI %u
\n
"
,
gsi
);
return
;
}
ioapic_pin
=
gsi
-
mp_ioapic_routing
[
ioapic
].
gsi_start
;
/*
* Avoid pin reprogramming. PRTs typically include entries
* with redundant pin->gsi mappings (but unique PCI devices);
* we only
only program the IOAPIC on the first.
* we
only program the IOAPIC on the first.
*/
bit
=
ioapic_pin
%
32
;
idx
=
(
ioapic_pin
<
32
)
?
0
:
(
ioapic_pin
/
32
);
...
...
@@ -946,33 +922,20 @@ void __init mp_parse_prt (void)
printk
(
KERN_ERR
"Invalid reference to IOAPIC pin "
"%d-%d
\n
"
,
mp_ioapic_routing
[
ioapic
].
apic_id
,
ioapic_pin
);
continue
;
return
;
}
if
((
1
<<
bit
)
&
mp_ioapic_routing
[
ioapic
].
pin_programmed
[
idx
])
{
Dprintk
(
KERN_DEBUG
"Pin %d-%d already programmed
\n
"
,
mp_ioapic_routing
[
ioapic
].
apic_id
,
ioapic_pin
);
acpi_gsi_to_irq
(
gsi
,
&
entry
->
irq
);
continue
;
return
;
}
mp_ioapic_routing
[
ioapic
].
pin_programmed
[
idx
]
|=
(
1
<<
bit
);
if
(
!
io_apic_set_pci_routing
(
ioapic
,
ioapic_pin
,
gsi
,
edge_level
,
active_high_low
))
{
acpi_gsi_to_irq
(
gsi
,
&
entry
->
irq
);
}
printk
(
KERN_DEBUG
"%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d
\n
"
,
entry
->
id
.
segment
,
entry
->
id
.
bus
,
entry
->
id
.
device
,
(
'A'
+
entry
->
pin
),
mp_ioapic_routing
[
ioapic
].
apic_id
,
ioapic_pin
,
entry
->
irq
);
}
print_IO_APIC
();
return
;
io_apic_set_pci_routing
(
ioapic
,
ioapic_pin
,
gsi
,
edge_level
==
ACPI_EDGE_SENSITIVE
?
0
:
1
,
active_high_low
==
ACPI_ACTIVE_HIGH
?
0
:
1
);
}
#endif
/*CONFIG_ACPI_PCI*/
#endif
/*CONFIG_X86_IO_APIC*/
#endif
/*CONFIG_ACPI_BOOT*/
drivers/acpi/pci_irq.c
View file @
3a40a2c1
...
...
@@ -35,12 +35,6 @@
#include <linux/pm.h>
#include <linux/pci.h>
#include <linux/acpi.h>
#ifdef CONFIG_X86_IO_APIC
#include <asm/mpspec.h>
#endif
#ifdef CONFIG_IOSAPIC
# include <asm/iosapic.h>
#endif
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
...
...
@@ -50,10 +44,6 @@ ACPI_MODULE_NAME ("pci_irq")
struct
acpi_prt_list
acpi_prt
;
#ifdef CONFIG_X86
extern
void
eisa_set_level_irq
(
unsigned
int
irq
);
#endif
/* --------------------------------------------------------------------------
PCI IRQ Routing Table (PRT) Support
...
...
@@ -237,12 +227,18 @@ acpi_pci_irq_add_prt (
PCI Interrupt Routing Support
-------------------------------------------------------------------------- */
int
acpi_pci_irq_lookup
(
struct
pci_bus
*
bus
,
int
device
,
int
pin
)
static
int
acpi_pci_irq_lookup
(
struct
pci_bus
*
bus
,
int
device
,
int
pin
,
int
*
edge_level
,
int
*
active_high_low
)
{
struct
acpi_prt_entry
*
entry
=
NULL
;
int
segment
=
pci_domain_nr
(
bus
);
int
bus_nr
=
bus
->
number
;
int
irq
;
ACPI_FUNCTION_TRACE
(
"acpi_pci_irq_lookup"
);
...
...
@@ -256,27 +252,29 @@ acpi_pci_irq_lookup (struct pci_bus *bus, int device, int pin)
return_VALUE
(
0
);
}
if
(
!
entry
->
irq
&&
entry
->
link
.
handle
)
{
entry
->
irq
=
acpi_pci_link_get_irq
(
entry
->
link
.
handle
,
entry
->
link
.
index
,
NULL
,
NULL
);
if
(
!
entry
->
irq
)
{
if
(
entry
->
link
.
handle
)
{
irq
=
acpi_pci_link_get_irq
(
entry
->
link
.
handle
,
entry
->
link
.
index
,
edge_level
,
active_high_low
);
if
(
!
irq
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_WARN
,
"Invalid IRQ link routing entry
\n
"
));
return_VALUE
(
0
);
}
}
else
if
(
!
entry
->
irq
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Invalid static routing entry (IRQ 0)
\n
"
))
;
return_VALUE
(
0
)
;
}
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
"
,
entry
->
irq
));
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Found IRQ %d
\n
"
,
irq
));
return_VALUE
(
entry
->
irq
);
return_VALUE
(
irq
);
}
static
int
acpi_pci_irq_derive
(
struct
pci_dev
*
dev
,
int
pin
)
int
pin
,
int
*
edge_level
,
int
*
active_high_low
)
{
struct
pci_dev
*
bridge
=
dev
;
int
irq
=
0
;
...
...
@@ -308,8 +306,8 @@ acpi_pci_irq_derive (
pin
=
bridge_pin
;
}
irq
=
acpi_pci_irq_lookup
(
bridge
->
bus
,
PCI_SLOT
(
bridge
->
devfn
),
pin
);
irq
=
acpi_pci_irq_lookup
(
bridge
->
bus
,
PCI_SLOT
(
bridge
->
devfn
),
pin
,
edge_level
,
active_high_low
);
}
if
(
!
irq
)
{
...
...
@@ -330,6 +328,8 @@ acpi_pci_irq_enable (
{
int
irq
=
0
;
u8
pin
=
0
;
int
edge_level
=
ACPI_LEVEL_SENSITIVE
;
int
active_high_low
=
ACPI_ACTIVE_LOW
;
ACPI_FUNCTION_TRACE
(
"acpi_pci_irq_enable"
);
...
...
@@ -352,21 +352,22 @@ acpi_pci_irq_enable (
* First we check the PCI IRQ routing table (PRT) for an IRQ. PRT
* values override any BIOS-assigned IRQs set during boot.
*/
irq
=
acpi_pci_irq_lookup
(
dev
->
bus
,
PCI_SLOT
(
dev
->
devfn
),
pin
);
irq
=
acpi_pci_irq_lookup
(
dev
->
bus
,
PCI_SLOT
(
dev
->
devfn
),
pin
,
&
edge_level
,
&
active_high_low
);
/*
* If no PRT entry was found, we'll try to derive an IRQ from the
* device's parent bridge.
*/
if
(
!
irq
)
irq
=
acpi_pci_irq_derive
(
dev
,
pin
);
irq
=
acpi_pci_irq_derive
(
dev
,
pin
,
&
edge_level
,
&
active_high_low
);
/*
* No IRQ known to the ACPI subsystem - maybe the BIOS /
* driver reported one, then use it. Exit in any case.
*/
if
(
!
irq
)
{
printk
(
KERN_WARNING
PREFIX
"No IRQ known for interrupt pin %c of device %s"
,
(
'A'
+
pin
),
pci_name
(
dev
));
printk
(
KERN_WARNING
PREFIX
"PCI interrupt %s[%c]: no GSI"
,
pci_name
(
dev
),
(
'A'
+
pin
));
/* Interrupt Line values above 0xF are forbidden */
if
(
dev
->
irq
&&
(
dev
->
irq
<=
0xF
))
{
printk
(
" - using IRQ %d
\n
"
,
dev
->
irq
);
...
...
@@ -378,62 +379,14 @@ acpi_pci_irq_enable (
}
}
dev
->
irq
=
irq
;
dev
->
irq
=
acpi_register_gsi
(
irq
,
edge_level
,
active_high_low
)
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Device %s using IRQ %d
\n
"
,
pci_name
(
dev
),
dev
->
irq
));
/*
* Make sure all (legacy) PCI IRQs are set as level-triggered.
*/
#ifdef CONFIG_X86
{
static
u16
irq_mask
;
if
((
dev
->
irq
<
16
)
&&
!
((
1
<<
dev
->
irq
)
&
irq_mask
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Setting IRQ %d as level-triggered
\n
"
,
dev
->
irq
));
irq_mask
|=
(
1
<<
dev
->
irq
);
eisa_set_level_irq
(
dev
->
irq
);
}
}
#endif
#ifdef CONFIG_IOSAPIC
if
(
acpi_irq_model
==
ACPI_IRQ_MODEL_IOSAPIC
)
iosapic_enable_intr
(
dev
->
irq
);
#endif
printk
(
KERN_INFO
PREFIX
"PCI interrupt %s[%c] -> GSI %u "
"(%s, %s) -> IRQ %d
\n
"
,
pci_name
(
dev
),
'A'
+
pin
,
irq
,
(
edge_level
==
ACPI_LEVEL_SENSITIVE
)
?
"level"
:
"edge"
,
(
active_high_low
==
ACPI_ACTIVE_LOW
)
?
"low"
:
"high"
,
dev
->
irq
);
return_VALUE
(
dev
->
irq
);
}
int
__init
acpi_pci_irq_init
(
void
)
{
struct
pci_dev
*
dev
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_pci_irq_init"
);
if
(
!
acpi_prt
.
count
)
{
printk
(
KERN_WARNING
PREFIX
"ACPI tables contain no PCI IRQ "
"routing entries
\n
"
);
return_VALUE
(
-
ENODEV
);
}
/* Make sure all link devices have a valid IRQ. */
if
(
acpi_pci_link_check
())
{
return_VALUE
(
-
ENODEV
);
}
#ifdef CONFIG_X86_IO_APIC
/* Program IOAPICs using data from PRT entries. */
if
(
acpi_irq_model
==
ACPI_IRQ_MODEL_IOAPIC
)
mp_parse_prt
();
#endif
#ifdef CONFIG_IOSAPIC
if
(
acpi_irq_model
==
ACPI_IRQ_MODEL_IOSAPIC
)
iosapic_parse_prt
();
#endif
while
((
dev
=
pci_find_device
(
PCI_ANY_ID
,
PCI_ANY_ID
,
dev
))
!=
NULL
)
acpi_pci_irq_enable
(
dev
);
return_VALUE
(
0
);
}
drivers/acpi/pci_link.c
View file @
3a40a2c1
...
...
@@ -487,13 +487,13 @@ static int __initdata acpi_irq_penalty[ACPI_MAX_IRQS] = {
};
int
acpi_
pci_link_check
(
void
)
acpi_
irq_penalty_init
(
void
)
{
struct
list_head
*
node
=
NULL
;
struct
acpi_pci_link
*
link
=
NULL
;
int
i
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_
pci_link_check
"
);
ACPI_FUNCTION_TRACE
(
"acpi_
irq_penalty_init
"
);
/*
* Update penalties to facilitate IRQ balancing.
...
...
drivers/acpi/tables.c
View file @
3a40a2c1
...
...
@@ -131,7 +131,7 @@ acpi_table_print_madt_entry (
{
struct
acpi_table_ioapic
*
p
=
(
struct
acpi_table_ioapic
*
)
header
;
printk
(
KERN_INFO
PREFIX
"IOAPIC (id[0x%02x] address[0x%08x] g
lobal_irq_base[0x%x
])
\n
"
,
printk
(
KERN_INFO
PREFIX
"IOAPIC (id[0x%02x] address[0x%08x] g
si_base[%d
])
\n
"
,
p
->
id
,
p
->
address
,
p
->
global_irq_base
);
}
break
;
...
...
@@ -185,8 +185,8 @@ acpi_table_print_madt_entry (
{
struct
acpi_table_iosapic
*
p
=
(
struct
acpi_table_iosapic
*
)
header
;
printk
(
KERN_INFO
PREFIX
"IOSAPIC (id[0x%x]
global_irq_base[0x%x] address[%p
])
\n
"
,
p
->
id
,
p
->
global_irq_base
,
(
void
*
)
(
unsigned
long
)
p
->
address
);
printk
(
KERN_INFO
PREFIX
"IOSAPIC (id[0x%x]
address[%p] gsi_base[%d
])
\n
"
,
p
->
id
,
(
void
*
)
(
unsigned
long
)
p
->
address
,
p
->
global_irq_base
);
}
break
;
...
...
drivers/serial/8250_acpi.c
View file @
3a40a2c1
...
...
@@ -57,28 +57,18 @@ static acpi_status acpi_serial_port(struct serial_struct *req,
static
acpi_status
acpi_serial_ext_irq
(
struct
serial_struct
*
req
,
struct
acpi_resource_ext_irq
*
ext_irq
)
{
if
(
ext_irq
->
number_of_interrupts
>
0
)
{
#ifdef CONFIG_IA64
req
->
irq
=
acpi_register_irq
(
ext_irq
->
interrupts
[
0
],
ext_irq
->
active_high_low
,
ext_irq
->
edge_level
);
#else
req
->
irq
=
ext_irq
->
interrupts
[
0
];
#endif
}
if
(
ext_irq
->
number_of_interrupts
>
0
)
req
->
irq
=
acpi_register_gsi
(
ext_irq
->
interrupts
[
0
],
ext_irq
->
edge_level
,
ext_irq
->
active_high_low
);
return
AE_OK
;
}
static
acpi_status
acpi_serial_irq
(
struct
serial_struct
*
req
,
struct
acpi_resource_irq
*
irq
)
{
if
(
irq
->
number_of_interrupts
>
0
)
{
#ifdef CONFIG_IA64
req
->
irq
=
acpi_register_irq
(
irq
->
interrupts
[
0
],
irq
->
active_high_low
,
irq
->
edge_level
);
#else
req
->
irq
=
irq
->
interrupts
[
0
];
#endif
}
if
(
irq
->
number_of_interrupts
>
0
)
req
->
irq
=
acpi_register_gsi
(
irq
->
interrupts
[
0
],
irq
->
edge_level
,
irq
->
active_high_low
);
return
AE_OK
;
}
...
...
drivers/serial/8250_hcdp.c
View file @
3a40a2c1
...
...
@@ -183,16 +183,12 @@ setup_serial_hcdp(void *tablep)
}
if
(
HCDP_IRQ_SUPPORTED
(
hcdp_dev
))
{
#ifdef CONFIG_IA64
if
(
HCDP_PCI_UART
(
hcdp_dev
))
port
.
irq
=
acpi_register_
irq
(
gsi
,
ACPI_
ACTIVE_LOW
,
ACPI_LEVEL_SENSITIVE
);
port
.
irq
=
acpi_register_
gsi
(
gsi
,
ACPI_
LEVEL_SENSITIVE
,
ACPI_ACTIVE_LOW
);
else
port
.
irq
=
acpi_register_irq
(
gsi
,
ACPI_ACTIVE_HIGH
,
ACPI_EDGE_SENSITIVE
);
#else
port
.
irq
=
gsi
;
#endif
port
.
irq
=
acpi_register_gsi
(
gsi
,
ACPI_EDGE_SENSITIVE
,
ACPI_ACTIVE_HIGH
);
port
.
flags
|=
UPF_AUTO_IRQ
;
if
(
HCDP_PCI_UART
(
hcdp_dev
))
...
...
include/acpi/acpi_drivers.h
View file @
3a40a2c1
...
...
@@ -55,7 +55,7 @@
/* ACPI PCI Interrupt Link (pci_link.c) */
int
acpi_
pci_link_check
(
void
);
int
acpi_
irq_penalty_init
(
void
);
int
acpi_pci_link_get_irq
(
acpi_handle
handle
,
int
index
,
int
*
edge_level
,
int
*
active_high_low
);
/* ACPI PCI Interrupt Routing (pci_irq.c) */
...
...
include/asm-i386/mpspec.h
View file @
3a40a2c1
...
...
@@ -33,7 +33,7 @@ extern void mp_register_lapic_address (u64 address);
extern
void
mp_register_ioapic
(
u8
id
,
u32
address
,
u32
gsi_base
);
extern
void
mp_override_legacy_irq
(
u8
bus_irq
,
u8
polarity
,
u8
trigger
,
u32
gsi
);
extern
void
mp_config_acpi_legacy_irqs
(
void
);
extern
void
mp_
parse_prt
(
void
);
extern
void
mp_
register_gsi
(
u32
gsi
,
int
edge_level
,
int
active_high_low
);
#endif
/*CONFIG_ACPI_BOOT*/
#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
...
...
include/asm-ia64/iosapic.h
View file @
3a40a2c1
...
...
@@ -60,7 +60,6 @@ extern void __init iosapic_init (unsigned long address,
unsigned
int
gsi_base
);
extern
int
gsi_to_vector
(
unsigned
int
gsi
);
extern
int
gsi_to_irq
(
unsigned
int
gsi
);
extern
void
__init
iosapic_parse_prt
(
void
);
extern
void
iosapic_enable_intr
(
unsigned
int
vector
);
extern
int
iosapic_register_intr
(
unsigned
int
gsi
,
unsigned
long
polarity
,
unsigned
long
trigger
);
...
...
include/asm-x86_64/mpspec.h
View file @
3a40a2c1
...
...
@@ -189,7 +189,7 @@ extern void mp_register_lapic_address (u64 address);
extern
void
mp_register_ioapic
(
u8
id
,
u32
address
,
u32
gsi_base
);
extern
void
mp_override_legacy_irq
(
u8
bus_irq
,
u8
polarity
,
u8
trigger
,
u32
gsi
);
extern
void
mp_config_acpi_legacy_irqs
(
void
);
extern
void
mp_
parse_prt
(
void
);
extern
void
mp_
register_gsi
(
u32
gsi
,
int
edge_level
,
int
active_high_low
);
#endif
/*CONFIG_X86_IO_APIC*/
#endif
...
...
include/linux/acpi.h
View file @
3a40a2c1
...
...
@@ -413,6 +413,8 @@ static inline int acpi_boot_init(void)
#endif
/*!CONFIG_ACPI_BOOT*/
unsigned
int
acpi_register_gsi
(
u32
gsi
,
int
edge_level
,
int
active_high_low
);
int
acpi_gsi_to_irq
(
u32
gsi
,
unsigned
int
*
irq
);
#ifdef CONFIG_ACPI_PCI
...
...
@@ -437,8 +439,6 @@ extern struct acpi_prt_list acpi_prt;
struct
pci_dev
;
int
acpi_pci_irq_enable
(
struct
pci_dev
*
dev
);
int
acpi_pci_irq_init
(
void
);
int
acpi_gsi_to_irq
(
u32
gsi
,
unsigned
int
*
irq
);
struct
acpi_pci_driver
{
struct
acpi_pci_driver
*
next
;
...
...
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