Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
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