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
601917b5
Commit
601917b5
authored
Mar 26, 2003
by
Anton Blanchard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ppc64: Rework pci probe to be like alpha.
parent
748a82b2
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
226 additions
and
550 deletions
+226
-550
arch/ppc64/kernel/chrp_setup.c
arch/ppc64/kernel/chrp_setup.c
+0
-13
arch/ppc64/kernel/iSeries_pci.c
arch/ppc64/kernel/iSeries_pci.c
+7
-30
arch/ppc64/kernel/iSeries_setup.c
arch/ppc64/kernel/iSeries_setup.c
+0
-5
arch/ppc64/kernel/pSeries_lpar.c
arch/ppc64/kernel/pSeries_lpar.c
+0
-1
arch/ppc64/kernel/pSeries_pci.c
arch/ppc64/kernel/pSeries_pci.c
+67
-109
arch/ppc64/kernel/pci.c
arch/ppc64/kernel/pci.c
+133
-346
arch/ppc64/kernel/pci.h
arch/ppc64/kernel/pci.h
+2
-18
include/asm-ppc64/machdep.h
include/asm-ppc64/machdep.h
+0
-16
include/asm-ppc64/pci-bridge.h
include/asm-ppc64/pci-bridge.h
+1
-1
include/asm-ppc64/pci.h
include/asm-ppc64/pci.h
+16
-11
No files found.
arch/ppc64/kernel/chrp_setup.c
View file @
601917b5
...
@@ -71,9 +71,6 @@ extern void openpic_init_IRQ(void);
...
@@ -71,9 +71,6 @@ extern void openpic_init_IRQ(void);
extern
void
init_ras_IRQ
(
void
);
extern
void
init_ras_IRQ
(
void
);
extern
void
find_and_init_phbs
(
void
);
extern
void
find_and_init_phbs
(
void
);
extern
void
pSeries_pcibios_fixup
(
void
);
extern
void
pSeries_pcibios_fixup_bus
(
struct
pci_bus
*
bus
);
extern
void
iSeries_pcibios_fixup
(
void
);
extern
void
pSeries_get_rtc_time
(
struct
rtc_time
*
rtc_time
);
extern
void
pSeries_get_rtc_time
(
struct
rtc_time
*
rtc_time
);
extern
int
pSeries_set_rtc_time
(
struct
rtc_time
*
rtc_time
);
extern
int
pSeries_set_rtc_time
(
struct
rtc_time
*
rtc_time
);
...
@@ -201,7 +198,6 @@ void __init pSeries_init_early(void)
...
@@ -201,7 +198,6 @@ void __init pSeries_init_early(void)
hpte_init_pSeries
();
hpte_init_pSeries
();
tce_init_pSeries
();
tce_init_pSeries
();
pSeries_pcibios_init_early
();
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
smp_init_pSeries
();
smp_init_pSeries
();
...
@@ -244,15 +240,6 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
...
@@ -244,15 +240,6 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
}
}
ppc_md
.
init_ras_IRQ
=
init_ras_IRQ
;
ppc_md
.
init_ras_IRQ
=
init_ras_IRQ
;
#ifndef CONFIG_PPC_ISERIES
ppc_md
.
pcibios_fixup
=
pSeries_pcibios_fixup
;
ppc_md
.
pcibios_fixup_bus
=
pSeries_pcibios_fixup_bus
;
#else
ppc_md
.
pcibios_fixup
=
NULL
;
// ppc_md.pcibios_fixup = iSeries_pcibios_fixup;
#endif
ppc_md
.
init
=
chrp_init2
;
ppc_md
.
init
=
chrp_init2
;
ppc_md
.
restart
=
rtas_restart
;
ppc_md
.
restart
=
rtas_restart
;
...
...
arch/ppc64/kernel/iSeries_pci.c
View file @
601917b5
...
@@ -84,8 +84,6 @@ struct iSeries_Device_Node* find_Device_Node(struct pci_dev* PciDev);
...
@@ -84,8 +84,6 @@ struct iSeries_Device_Node* find_Device_Node(struct pci_dev* PciDev);
struct
iSeries_Device_Node
*
get_Device_Node
(
struct
pci_dev
*
PciDev
);
struct
iSeries_Device_Node
*
get_Device_Node
(
struct
pci_dev
*
PciDev
);
unsigned
long
find_and_init_phbs
(
void
);
unsigned
long
find_and_init_phbs
(
void
);
void
fixup_resources
(
struct
pci_dev
*
dev
);
void
iSeries_pcibios_fixup
(
void
);
struct
pci_controller
*
alloc_phb
(
struct
device_node
*
dev
,
char
*
model
,
unsigned
int
addr_size_words
)
;
struct
pci_controller
*
alloc_phb
(
struct
device_node
*
dev
,
char
*
model
,
unsigned
int
addr_size_words
)
;
void
iSeries_Scan_PHBs_Slots
(
struct
pci_controller
*
Phb
);
void
iSeries_Scan_PHBs_Slots
(
struct
pci_controller
*
Phb
);
...
@@ -275,7 +273,7 @@ unsigned long __init find_and_init_phbs(void)
...
@@ -275,7 +273,7 @@ unsigned long __init find_and_init_phbs(void)
return
0
;
return
0
;
}
}
/***********************************************************************
/***********************************************************************
*
ppc64
_pcibios_init
*
iSeries
_pcibios_init
*
*
* Chance to initialize and structures or variable before PCI Bus walk.
* Chance to initialize and structures or variable before PCI Bus walk.
*
*
...
@@ -302,9 +300,9 @@ void iSeries_pcibios_init(void)
...
@@ -302,9 +300,9 @@ void iSeries_pcibios_init(void)
PPCDBG
(
PPCDBG_BUSWALK
,
"iSeries_pcibios_init Exit.
\n
"
);
PPCDBG
(
PPCDBG_BUSWALK
,
"iSeries_pcibios_init Exit.
\n
"
);
}
}
/***********************************************************************
/***********************************************************************
*
iSeries_pcibios
_fixup(void)
*
pcibios_final
_fixup(void)
***********************************************************************/
***********************************************************************/
void
__init
iSeries_pcibios
_fixup
(
void
)
void
__init
pcibios_final
_fixup
(
void
)
{
{
struct
pci_dev
*
PciDev
;
struct
pci_dev
*
PciDev
;
struct
iSeries_Device_Node
*
DeviceNode
;
struct
iSeries_Device_Node
*
DeviceNode
;
...
@@ -328,8 +326,6 @@ void __init iSeries_pcibios_fixup(void)
...
@@ -328,8 +326,6 @@ void __init iSeries_pcibios_fixup(void)
iSeries_allocateDeviceBars
(
PciDev
);
iSeries_allocateDeviceBars
(
PciDev
);
PPCDBGCALL
(
PPCDBG_BUSWALK
,
dumpPci_Dev
(
PciDev
)
);
iSeries_Device_Information
(
PciDev
,
Buffer
,
sizeof
(
Buffer
)
);
iSeries_Device_Information
(
PciDev
,
Buffer
,
sizeof
(
Buffer
)
);
printk
(
"%d. %s
\n
"
,
DeviceCount
,
Buffer
);
printk
(
"%d. %s
\n
"
,
DeviceCount
,
Buffer
);
...
@@ -345,11 +341,7 @@ void __init iSeries_pcibios_fixup(void)
...
@@ -345,11 +341,7 @@ void __init iSeries_pcibios_fixup(void)
mf_displaySrc
(
0xC9000200
);
mf_displaySrc
(
0xC9000200
);
}
}
/***********************************************************************
void
pcibios_fixup_bus
(
struct
pci_bus
*
PciBus
)
* iSeries_pcibios_fixup_bus(int Bus)
*
***********************************************************************/
void
iSeries_pcibios_fixup_bus
(
struct
pci_bus
*
PciBus
)
{
{
PPCDBG
(
PPCDBG_BUSWALK
,
"iSeries_pcibios_fixup_bus(0x%04X) Entry.
\n
"
,
PciBus
->
number
);
PPCDBG
(
PPCDBG_BUSWALK
,
"iSeries_pcibios_fixup_bus(0x%04X) Entry.
\n
"
,
PciBus
->
number
);
...
@@ -357,12 +349,12 @@ void iSeries_pcibios_fixup_bus(struct pci_bus* PciBus)
...
@@ -357,12 +349,12 @@ void iSeries_pcibios_fixup_bus(struct pci_bus* PciBus)
/***********************************************************************
/***********************************************************************
* fixup_resources(struct pci_dev *dev)
*
pcibios_
fixup_resources(struct pci_dev *dev)
*
*
***********************************************************************/
***********************************************************************/
void
fixup_resources
(
struct
pci_dev
*
PciDev
)
void
pcibios_
fixup_resources
(
struct
pci_dev
*
PciDev
)
{
{
PPCDBG
(
PPCDBG_BUSWALK
,
"fixup_resources PciDev %p
\n
"
,
PciDev
);
PPCDBG
(
PPCDBG_BUSWALK
,
"
pcibios_
fixup_resources PciDev %p
\n
"
,
PciDev
);
}
}
...
@@ -910,18 +902,3 @@ void iSeries_Write_Long(u32 Data, void* IoAddress)
...
@@ -910,18 +902,3 @@ void iSeries_Write_Long(u32 Data, void* IoAddress)
}
while
(
CheckReturnCode
(
"WWL"
,
DevNode
,
Return
.
rc
)
!=
0
);
}
while
(
CheckReturnCode
(
"WWL"
,
DevNode
,
Return
.
rc
)
!=
0
);
if
(
Pci_Trace_Flag
==
1
)
PCIFR
(
"WWL: IoAddress 0x%p = 0x%08X"
,
IoAddress
,
Data
);
if
(
Pci_Trace_Flag
==
1
)
PCIFR
(
"WWL: IoAddress 0x%p = 0x%08X"
,
IoAddress
,
Data
);
}
}
/*
* This is called very early before the page table is setup.
* There are warnings here because of type mismatches.. Okay for now. AHT
*/
void
iSeries_pcibios_init_early
(
void
)
{
//ppc_md.pcibios_read_config_byte = iSeries_Node_read_config_byte;
//ppc_md.pcibios_read_config_word = iSeries_Node_read_config_word;
//ppc_md.pcibios_read_config_dword = iSeries_Node_read_config_dword;
//ppc_md.pcibios_write_config_byte = iSeries_Node_write_config_byte;
//ppc_md.pcibios_write_config_word = iSeries_Node_write_config_word;
//ppc_md.pcibios_write_config_dword = iSeries_Node_write_config_dword;
}
arch/ppc64/kernel/iSeries_setup.c
View file @
601917b5
...
@@ -62,8 +62,6 @@ void build_valid_hpte( unsigned long vsid, unsigned long ea, unsigned long pa,
...
@@ -62,8 +62,6 @@ void build_valid_hpte( unsigned long vsid, unsigned long ea, unsigned long pa,
pte_t
*
ptep
,
unsigned
hpteflags
,
unsigned
bolted
);
pte_t
*
ptep
,
unsigned
hpteflags
,
unsigned
bolted
);
extern
void
ppcdbg_initialize
(
void
);
extern
void
ppcdbg_initialize
(
void
);
extern
void
iSeries_pcibios_init
(
void
);
extern
void
iSeries_pcibios_init
(
void
);
extern
void
iSeries_pcibios_fixup
(
void
);
extern
void
iSeries_pcibios_fixup_bus
(
int
);
static
void
iSeries_setup_dprofile
(
void
);
static
void
iSeries_setup_dprofile
(
void
);
/* Global Variables */
/* Global Variables */
...
@@ -317,9 +315,6 @@ iSeries_init_early(void)
...
@@ -317,9 +315,6 @@ iSeries_init_early(void)
ppc_md
.
get_irq
=
iSeries_get_irq
;
ppc_md
.
get_irq
=
iSeries_get_irq
;
ppc_md
.
init
=
NULL
;
ppc_md
.
init
=
NULL
;
ppc_md
.
pcibios_fixup
=
iSeries_pcibios_fixup
;
ppc_md
.
pcibios_fixup_bus
=
iSeries_pcibios_fixup_bus
;
ppc_md
.
restart
=
iSeries_restart
;
ppc_md
.
restart
=
iSeries_restart
;
ppc_md
.
power_off
=
iSeries_power_off
;
ppc_md
.
power_off
=
iSeries_power_off
;
ppc_md
.
halt
=
iSeries_halt
;
ppc_md
.
halt
=
iSeries_halt
;
...
...
arch/ppc64/kernel/pSeries_lpar.c
View file @
601917b5
...
@@ -320,7 +320,6 @@ void pSeriesLP_init_early(void)
...
@@ -320,7 +320,6 @@ void pSeriesLP_init_early(void)
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
smp_init_pSeries
();
smp_init_pSeries
();
#endif
#endif
pSeries_pcibios_init_early
();
/* The keyboard is not useful in the LPAR environment.
/* The keyboard is not useful in the LPAR environment.
* Leave all the interfaces NULL.
* Leave all the interfaces NULL.
...
...
arch/ppc64/kernel/pSeries_pci.c
View file @
601917b5
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
* pSeries_pci.c
* pSeries_pci.c
*
*
* Copyright (C) 2001 Dave Engebretsen, IBM Corporation
* Copyright (C) 2001 Dave Engebretsen, IBM Corporation
* Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
*
*
* pSeries specific routines for PCI.
* pSeries specific routines for PCI.
*
*
...
@@ -51,6 +52,8 @@ static int ibm_write_pci_config;
...
@@ -51,6 +52,8 @@ static int ibm_write_pci_config;
static
int
s7a_workaround
;
static
int
s7a_workaround
;
extern
unsigned
long
pci_probe_only
;
static
int
rtas_read_config
(
struct
device_node
*
dn
,
int
where
,
int
size
,
u32
*
val
)
static
int
rtas_read_config
(
struct
device_node
*
dn
,
int
where
,
int
size
,
u32
*
val
)
{
{
unsigned
long
returnval
=
~
0L
;
unsigned
long
returnval
=
~
0L
;
...
@@ -371,9 +374,6 @@ struct pci_controller *alloc_phb(struct device_node *dev,
...
@@ -371,9 +374,6 @@ struct pci_controller *alloc_phb(struct device_node *dev,
phb
->
last_busno
+=
(
phb
->
global_number
<<
8
);
phb
->
last_busno
+=
(
phb
->
global_number
<<
8
);
}
}
/* Dump PHB information for Debug */
PPCDBGCALL
(
PPCDBG_PHBINIT
,
dumpPci_Controller
(
phb
));
return
phb
;
return
phb
;
}
}
...
@@ -423,129 +423,96 @@ unsigned long __init find_and_init_phbs(void)
...
@@ -423,129 +423,96 @@ unsigned long __init find_and_init_phbs(void)
return
0
;
return
0
;
}
}
void
void
pcibios_name_device
(
struct
pci_dev
*
dev
)
fixup_resources
(
struct
pci_dev
*
dev
)
{
{
int
i
;
struct
pci_controller
*
phb
=
PCI_GET_PHB_PTR
(
dev
);
struct
device_node
*
dn
;
struct
device_node
*
dn
;
/* Add IBM loc code (slot) as a prefix to the device names for service */
/*
* Add IBM loc code (slot) as a prefix to the device names for service
*/
dn
=
pci_device_to_OF_node
(
dev
);
dn
=
pci_device_to_OF_node
(
dev
);
if
(
dn
)
{
if
(
dn
)
{
char
*
loc_code
=
get_property
(
dn
,
"ibm,loc-code"
,
0
);
char
*
loc_code
=
get_property
(
dn
,
"ibm,loc-code"
,
0
);
if
(
loc_code
)
{
if
(
loc_code
)
{
int
loc_len
=
strlen
(
loc_code
);
int
loc_len
=
strlen
(
loc_code
);
if
(
loc_len
<
sizeof
(
dev
->
dev
.
name
))
{
if
(
loc_len
<
sizeof
(
dev
->
dev
.
name
))
{
memmove
(
dev
->
dev
.
name
+
loc_len
+
1
,
dev
->
dev
.
name
,
sizeof
(
dev
->
dev
.
name
)
-
loc_len
-
1
);
memmove
(
dev
->
dev
.
name
+
loc_len
+
1
,
dev
->
dev
.
name
,
sizeof
(
dev
->
dev
.
name
)
-
loc_len
-
1
);
memcpy
(
dev
->
dev
.
name
,
loc_code
,
loc_len
);
memcpy
(
dev
->
dev
.
name
,
loc_code
,
loc_len
);
dev
->
dev
.
name
[
loc_len
]
=
' '
;
dev
->
dev
.
name
[
loc_len
]
=
' '
;
dev
->
dev
.
name
[
sizeof
(
dev
->
dev
.
name
)
-
1
]
=
'\0'
;
dev
->
dev
.
name
[
sizeof
(
dev
->
dev
.
name
)
-
1
]
=
'\0'
;
}
}
}
}
}
}
}
PPCDBG
(
PPCDBG_PHBINIT
,
"fixup_resources:
\n
"
);
void
__init
pcibios_fixup_device_resources
(
struct
pci_dev
*
dev
,
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
phb = 0x%016LX
\n
"
,
phb
);
struct
pci_bus
*
bus
)
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
phb->pci_io_offset = 0x%016LX
\n
"
,
phb
->
pci_io_offset
);
{
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
phb->pci_mem_offset = 0x%016LX
\n
"
,
phb
->
pci_mem_offset
);
/* Update device resources. */
struct
pci_controller
*
hose
=
PCI_GET_PHB_PTR
(
bus
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
dev->dev.name = %s
\n
"
,
dev
->
dev
.
name
);
int
i
;
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
dev->vendor:device = 0x%04X : 0x%04X
\n
"
,
dev
->
vendor
,
dev
->
device
);
if
(
phb
==
NULL
)
return
;
for
(
i
=
0
;
i
<
DEVICE_COUNT_RESOURCE
;
++
i
)
{
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
device %x.%x[%d] (flags %x) [%lx..%lx]
\n
"
,
dev
->
bus
->
number
,
dev
->
devfn
,
i
,
dev
->
resource
[
i
].
flags
,
dev
->
resource
[
i
].
start
,
dev
->
resource
[
i
].
end
);
if
((
dev
->
resource
[
i
].
start
==
0
)
&&
(
dev
->
resource
[
i
].
end
==
0
))
{
continue
;
}
if
(
dev
->
resource
[
i
].
start
>
dev
->
resource
[
i
].
end
)
{
/* Bogus resource. Just clear it out. */
dev
->
resource
[
i
].
start
=
dev
->
resource
[
i
].
end
=
0
;
continue
;
}
for
(
i
=
0
;
i
<
PCI_NUM_RESOURCES
;
i
++
)
{
if
(
dev
->
resource
[
i
].
flags
&
IORESOURCE_IO
)
{
if
(
dev
->
resource
[
i
].
flags
&
IORESOURCE_IO
)
{
unsigned
long
offset
=
(
unsigned
long
)
phb
->
io_base_virt
-
pci_io_base
;
unsigned
long
offset
=
(
unsigned
long
)
hose
->
io_base_virt
-
pci_io_base
;
dev
->
resource
[
i
].
start
+=
offset
;
dev
->
resource
[
i
].
start
+=
offset
;
dev
->
resource
[
i
].
end
+=
offset
;
dev
->
resource
[
i
].
end
+=
offset
;
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t\t
-> now [%lx .. %lx]
\n
"
,
dev
->
resource
[
i
].
start
,
dev
->
resource
[
i
].
end
);
}
else
if
(
dev
->
resource
[
i
].
flags
&
IORESOURCE_MEM
)
{
if
(
dev
->
resource
[
i
].
start
==
0
)
{
/* Bogus. Probably an unused bridge. */
dev
->
resource
[
i
].
end
=
0
;
}
else
{
dev
->
resource
[
i
].
start
+=
phb
->
pci_mem_offset
;
dev
->
resource
[
i
].
end
+=
phb
->
pci_mem_offset
;
}
}
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t\t
-> now [%lx..%lx]
\n
"
,
else
if
(
dev
->
resource
[
i
].
flags
&
IORESOURCE_MEM
)
{
dev
->
resource
[
i
].
start
,
dev
->
resource
[
i
].
end
);
dev
->
resource
[
i
].
start
+=
hose
->
pci_mem_offset
;
dev
->
resource
[
i
].
end
+=
hose
->
pci_mem_offset
;
}
else
{
continue
;
}
}
/* zap the 2nd function of the winbond chip */
if
(
dev
->
resource
[
i
].
flags
&
IORESOURCE_IO
&&
dev
->
bus
->
number
==
0
&&
dev
->
devfn
==
0x81
)
dev
->
resource
[
i
].
flags
&=
~
IORESOURCE_IO
;
}
}
}
}
void
__init
p
Series_p
cibios_fixup_bus
(
struct
pci_bus
*
bus
)
void
__init
pcibios_fixup_bus
(
struct
pci_bus
*
bus
)
{
{
struct
pci_controller
*
phb
=
PCI_GET_PHB_PTR
(
bus
);
struct
pci_controller
*
hose
=
PCI_GET_PHB_PTR
(
bus
);
struct
list_head
*
ln
;
/* XXX or bus->parent? */
struct
pci_dev
*
dev
=
bus
->
self
;
struct
resource
*
res
;
struct
resource
*
res
;
int
i
;
int
i
;
if
(
bus
->
parent
==
NULL
)
{
if
(
!
dev
)
{
/* This is a host bridge - fill in its resources */
/* Root bus. */
phb
->
bus
=
bus
;
bus
->
resource
[
0
]
=
res
=
&
phb
->
io_resource
;
hose
->
bus
=
bus
;
bus
->
resource
[
0
]
=
res
=
&
hose
->
io_resource
;
if
(
!
res
->
flags
)
if
(
!
res
->
flags
)
BUG
();
/* No I/O resource for this PHB? */
BUG
();
/* No I/O resource for this PHB? */
if
(
request_resource
(
&
ioport_resource
,
res
))
printk
(
KERN_ERR
"Failed to request IO"
"on hose %d
\n
"
,
0
/* FIXME */
);
for
(
i
=
0
;
i
<
3
;
++
i
)
{
for
(
i
=
0
;
i
<
3
;
++
i
)
{
res
=
&
phb
->
mem_resources
[
i
];
res
=
&
hose
->
mem_resources
[
i
];
if
(
!
res
->
flags
)
{
if
(
!
res
->
flags
&&
i
==
0
)
if
(
i
==
0
)
BUG
();
/* No memory resource for this PHB? */
BUG
();
/* No memory resource for this PHB? */
}
bus
->
resource
[
i
+
1
]
=
res
;
bus
->
resource
[
i
+
1
]
=
res
;
if
(
res
->
flags
&&
request_resource
(
&
iomem_resource
,
res
))
printk
(
KERN_ERR
"Failed to request MEM"
"on hose %d
\n
"
,
0
/* FIXME */
);
}
}
}
else
{
}
else
if
(
pci_probe_only
&&
(
dev
->
class
>>
8
)
==
PCI_CLASS_BRIDGE_PCI
)
{
/* This is a subordinate bridge */
/* This is a subordinate bridge */
pci_read_bridge_bases
(
bus
);
for
(
i
=
0
;
i
<
4
;
++
i
)
{
pci_read_bridge_bases
(
bus
);
if
((
res
=
bus
->
resource
[
i
])
==
NULL
)
pcibios_fixup_device_resources
(
dev
,
bus
);
continue
;
if
(
!
res
->
flags
)
continue
;
if
(
res
==
pci_find_parent_resource
(
bus
->
self
,
res
))
{
/* Transparent resource -- don't try to "fix" it. */
continue
;
}
if
(
res
->
flags
&
IORESOURCE_IO
)
{
unsigned
long
offset
=
(
unsigned
long
)
phb
->
io_base_virt
-
pci_io_base
;
res
->
start
+=
offset
;
res
->
end
+=
offset
;
}
else
if
(
phb
->
pci_mem_offset
&&
(
res
->
flags
&
IORESOURCE_MEM
))
{
if
(
res
->
start
<
phb
->
pci_mem_offset
)
{
res
->
start
+=
phb
->
pci_mem_offset
;
res
->
end
+=
phb
->
pci_mem_offset
;
}
}
}
}
/* XXX Need to check why Alpha doesnt do this - Anton */
if
(
!
pci_probe_only
)
return
;
for
(
ln
=
bus
->
devices
.
next
;
ln
!=
&
bus
->
devices
;
ln
=
ln
->
next
)
{
struct
pci_dev
*
dev
=
pci_dev_b
(
ln
);
if
((
dev
->
class
>>
8
)
!=
PCI_CLASS_BRIDGE_PCI
)
pcibios_fixup_device_resources
(
dev
,
bus
);
}
}
}
}
...
@@ -562,19 +529,20 @@ static void check_s7a(void)
...
@@ -562,19 +529,20 @@ static void check_s7a(void)
}
}
}
}
void
__init
extern
void
chrp_request_regions
(
void
);
pSeries_pcibios_fixup
(
void
)
void
__init
pcibios_final_fixup
(
void
)
{
{
struct
pci_dev
*
dev
;
struct
pci_dev
*
dev
;
PPCDBG
(
PPCDBG_PHBINIT
,
"pSeries_pcibios_fixup: start
\n
"
);
check_s7a
();
check_s7a
();
pci_for_each_dev
(
dev
)
{
pci_for_each_dev
(
dev
)
pci_read_irq_line
(
dev
);
pci_read_irq_line
(
dev
);
PPCDBGCALL
(
PPCDBG_PHBINIT
,
dumpPci_Dev
(
dev
)
);
}
chrp_request_regions
();
pci_fix_bus_sysdata
();
create_tce_tables
();
}
}
/***********************************************************************
/***********************************************************************
...
@@ -596,13 +564,3 @@ pci_find_hose_for_OF_device(struct device_node *node)
...
@@ -596,13 +564,3 @@ pci_find_hose_for_OF_device(struct device_node *node)
}
}
return
NULL
;
return
NULL
;
}
}
/*
* This is called very early before the page table is setup.
*/
void
pSeries_pcibios_init_early
(
void
)
{
ppc_md
.
pcibios_read_config
=
rtas_read_config
;
ppc_md
.
pcibios_write_config
=
rtas_write_config
;
}
arch/ppc64/kernel/pci.c
View file @
601917b5
...
@@ -2,6 +2,9 @@
...
@@ -2,6 +2,9 @@
* Port for PPC64 David Engebretsen, IBM Corp.
* Port for PPC64 David Engebretsen, IBM Corp.
* Contains common pci routines for ppc64 platform, pSeries and iSeries brands.
* Contains common pci routines for ppc64 platform, pSeries and iSeries brands.
*
*
* Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
* Rework, based on alpha PCI code.
*
* This program is free software; you can redistribute it and/or
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* as published by the Free Software Foundation; either version
...
@@ -30,31 +33,37 @@
...
@@ -30,31 +33,37 @@
#include <asm/ppcdebug.h>
#include <asm/ppcdebug.h>
#include <asm/naca.h>
#include <asm/naca.h>
#include <asm/pci_dma.h>
#include <asm/pci_dma.h>
#include <asm/machdep.h>
#include "pci.h"
#include "pci.h"
unsigned
long
pci_probe_only
=
1
;
unsigned
long
pci_assign_all_buses
=
0
;
unsigned
int
pcibios_assign_all_busses
(
void
)
{
return
pci_assign_all_buses
;
}
/* pci_io_base -- the base address from which io bars are offsets.
/* pci_io_base -- the base address from which io bars are offsets.
* This is the lowest I/O base address (so bar values are always positive),
* This is the lowest I/O base address (so bar values are always positive),
* and it *must* be the start of ISA space if an ISA bus exists because
* and it *must* be the start of ISA space if an ISA bus exists because
* ISA drivers use hard coded offsets. If no ISA bus exists a dummy
* ISA drivers use hard coded offsets. If no ISA bus exists a dummy
* page is mapped and isa_io_limit prevents access to it.
* page is mapped and isa_io_limit prevents access to it.
*/
*/
unsigned
long
isa_io_base
=
0
;
/* NULL if no ISA bus */
unsigned
long
isa_io_base
;
/* NULL if no ISA bus */
unsigned
long
pci_io_base
=
0
;
unsigned
long
pci_io_base
;
static
void
pcibios_fixup_resources
(
struct
pci_dev
*
dev
);
void
pcibios_name_device
(
struct
pci_dev
*
dev
);
void
pcibios_final_fixup
(
void
);
static
void
fixup_broken_pcnet32
(
struct
pci_dev
*
dev
);
static
void
fixup_broken_pcnet32
(
struct
pci_dev
*
dev
);
static
void
fixup_windbond_82c105
(
struct
pci_dev
*
dev
);
static
void
fixup_windbond_82c105
(
struct
pci_dev
*
dev
);
void
fixup_resources
(
struct
pci_dev
*
dev
);
void
iSeries_pcibios_init
(
void
);
void
iSeries_pcibios_init
(
void
);
struct
pci_controller
*
hose_head
;
struct
pci_controller
*
hose_head
;
struct
pci_controller
**
hose_tail
=
&
hose_head
;
struct
pci_controller
**
hose_tail
=
&
hose_head
;
int
global_phb_number
=
0
;
/* Global phb counter */
int
global_phb_number
;
/* Global phb counter */
struct
pci_controller
*
phbtab
[
PCI_MAX_PHB
];
/* Cached ISA bridge dev. */
/* Cached ISA bridge dev. */
struct
pci_dev
*
ppc64_isabridge_dev
=
NULL
;
struct
pci_dev
*
ppc64_isabridge_dev
=
NULL
;
...
@@ -62,7 +71,7 @@ struct pci_dev *ppc64_isabridge_dev = NULL;
...
@@ -62,7 +71,7 @@ struct pci_dev *ppc64_isabridge_dev = NULL;
struct
pci_fixup
pcibios_fixups
[]
=
{
struct
pci_fixup
pcibios_fixups
[]
=
{
{
PCI_FIXUP_HEADER
,
PCI_VENDOR_ID_TRIDENT
,
PCI_ANY_ID
,
fixup_broken_pcnet32
},
{
PCI_FIXUP_HEADER
,
PCI_VENDOR_ID_TRIDENT
,
PCI_ANY_ID
,
fixup_broken_pcnet32
},
{
PCI_FIXUP_HEADER
,
PCI_VENDOR_ID_WINBOND
,
PCI_DEVICE_ID_WINBOND_82C105
,
fixup_windbond_82c105
},
{
PCI_FIXUP_HEADER
,
PCI_VENDOR_ID_WINBOND
,
PCI_DEVICE_ID_WINBOND_82C105
,
fixup_windbond_82c105
},
{
PCI_FIXUP_HEADER
,
PCI_ANY_ID
,
PCI_ANY_ID
,
pcibios_
fixup_resources
},
{
PCI_FIXUP_HEADER
,
PCI_ANY_ID
,
PCI_ANY_ID
,
pcibios_
name_device
},
{
0
}
{
0
}
};
};
...
@@ -81,14 +90,21 @@ static void fixup_windbond_82c105(struct pci_dev* dev)
...
@@ -81,14 +90,21 @@ static void fixup_windbond_82c105(struct pci_dev* dev)
* p610. We should probably be more careful in case
* p610. We should probably be more careful in case
* someone tries to plug in a similar adapter.
* someone tries to plug in a similar adapter.
*/
*/
int
i
;
unsigned
int
reg
;
unsigned
int
reg
;
printk
(
"Using INTC for W82c105 IDE controller.
\n
"
);
printk
(
"Using INTC for W82c105 IDE controller.
\n
"
);
pci_read_config_dword
(
dev
,
0x40
,
&
reg
);
pci_read_config_dword
(
dev
,
0x40
,
&
reg
);
/* Enable LEGIRQ to use INTC instead of ISA interrupts */
/* Enable LEGIRQ to use INTC instead of ISA interrupts */
pci_write_config_dword
(
dev
,
0x40
,
reg
|
(
1
<<
11
));
pci_write_config_dword
(
dev
,
0x40
,
reg
|
(
1
<<
11
));
}
for
(
i
=
0
;
i
<
DEVICE_COUNT_RESOURCE
;
++
i
)
{
/* zap the 2nd function of the winbond chip */
if
(
dev
->
resource
[
i
].
flags
&
IORESOURCE_IO
&&
dev
->
bus
->
number
==
0
&&
dev
->
devfn
==
0x81
)
dev
->
resource
[
i
].
flags
&=
~
IORESOURCE_IO
;
}
}
/* Given an mmio phys address, find a pci device that implements
/* Given an mmio phys address, find a pci device that implements
* this address. This is of course expensive, but only used
* this address. This is of course expensive, but only used
...
@@ -127,12 +143,30 @@ struct pci_dev *pci_find_dev_by_addr(unsigned long addr)
...
@@ -127,12 +143,30 @@ struct pci_dev *pci_find_dev_by_addr(unsigned long addr)
return
NULL
;
return
NULL
;
}
}
static
void
void
__devinit
pcibios_fixup_resources
(
struct
pci_dev
*
dev
)
pcibios_resource_to_bus
(
struct
pci_dev
*
dev
,
struct
pci_bus_region
*
region
,
struct
resource
*
res
)
{
{
fixup_resources
(
dev
);
unsigned
long
offset
=
0
;
struct
pci_controller
*
hose
=
PCI_GET_PHB_PTR
(
dev
);
if
(
!
hose
)
return
;
if
(
res
->
flags
&
IORESOURCE_IO
)
offset
=
(
unsigned
long
)
hose
->
io_base_virt
-
pci_io_base
;
if
(
res
->
flags
&
IORESOURCE_MEM
)
offset
=
hose
->
pci_mem_offset
;
region
->
start
=
res
->
start
-
offset
;
region
->
end
=
res
->
end
-
offset
;
}
}
#ifdef CONFIG_HOTPLUG
EXPORT_SYMBOL
(
pcibios_resource_to_bus
);
#endif
/*
/*
* We need to avoid collisions with `mirrored' VGA ports
* We need to avoid collisions with `mirrored' VGA ports
* and other strange ISA hardware, so we always want the
* and other strange ISA hardware, so we always want the
...
@@ -146,180 +180,38 @@ pcibios_fixup_resources(struct pci_dev* dev)
...
@@ -146,180 +180,38 @@ pcibios_fixup_resources(struct pci_dev* dev)
* but we want to try to avoid allocating at 0x2900-0x2bff
* but we want to try to avoid allocating at 0x2900-0x2bff
* which might have be mirrored at 0x0100-0x03ff..
* which might have be mirrored at 0x0100-0x03ff..
*/
*/
void
void
pcibios_align_resource
(
void
*
data
,
struct
resource
*
res
,
pcibios_align_resource
(
void
*
data
,
struct
resource
*
res
,
unsigned
long
size
,
unsigned
long
align
)
unsigned
long
size
,
unsigned
long
align
)
{
{
struct
pci_dev
*
dev
=
data
;
struct
pci_dev
*
dev
=
data
;
struct
pci_controller
*
hose
=
PCI_GET_PHB_PTR
(
dev
);
if
(
res
->
flags
&
IORESOURCE_IO
)
{
unsigned
long
start
=
res
->
start
;
unsigned
long
start
=
res
->
start
;
unsigned
long
alignto
;
if
(
size
>
0x100
)
{
if
(
res
->
flags
&
IORESOURCE_IO
)
{
printk
(
KERN_ERR
"PCI: Can not align I/O Region %s %s because size %ld is too large.
\n
"
,
unsigned
long
offset
=
(
unsigned
long
)
hose
->
io_base_virt
-
dev
->
slot_name
,
res
->
name
,
size
);
pci_io_base
;
}
/* Make sure we start at our min on all hoses */
if
(
start
-
offset
<
PCIBIOS_MIN_IO
)
if
(
start
&
0x300
)
{
start
=
PCIBIOS_MIN_IO
+
offset
;
start
=
(
start
+
0x3ff
)
&
~
0x3ff
;
res
->
start
=
start
;
}
}
}
/*
/*
* Handle resources of PCI devices. If the world were perfect, we could
* Put everything into 0x00-0xff region modulo 0x400
* just allocate all the resource regions and do nothing more. It isn't.
* On the other hand, we cannot just re-allocate all devices, as it would
* require us to know lots of host bridge internals. So we attempt to
* keep as much of the original configuration as possible, but tweak it
* when it's found to be wrong.
*
* Known BIOS problems we have to work around:
* - I/O or memory regions not configured
* - regions configured, but not enabled in the command register
* - bogus I/O addresses above 64K used
* - expansion ROMs left enabled (this may sound harmless, but given
* the fact the PCI specs explicitly allow address decoders to be
* shared between expansion ROMs and other resource regions, it's
* at least dangerous)
*
* Our solution:
* (1) Allocate resources for all buses behind PCI-to-PCI bridges.
* This gives us fixed barriers on where we can allocate.
* (2) Allocate resources for all enabled devices. If there is
* a collision, just mark the resource as unallocated. Also
* disable expansion ROMs during this step.
* (3) Try to allocate resources for disabled devices. If the
* resources were assigned correctly, everything goes well,
* if they weren't, they won't disturb allocation of other
* resources.
* (4) Assign new addresses to resources which were either
* not configured at all or misconfigured. If explicitly
* requested by the user, configure expansion ROM address
* as well.
*/
*/
if
(
start
&
0x300
)
start
=
(
start
+
0x3ff
)
&
~
0x3ff
;
static
void
__init
}
else
if
(
res
->
flags
&
IORESOURCE_MEM
)
{
pcibios_allocate_bus_resources
(
struct
list_head
*
bus_list
)
/* Make sure we start at our min on all hoses */
{
if
(
start
-
hose
->
pci_mem_offset
<
PCIBIOS_MIN_MEM
)
struct
list_head
*
ln
;
start
=
PCIBIOS_MIN_MEM
+
hose
->
pci_mem_offset
;
struct
pci_bus
*
bus
;
int
i
;
struct
resource
*
res
,
*
pr
;
/* Depth-First Search on bus tree */
for
(
ln
=
bus_list
->
next
;
ln
!=
bus_list
;
ln
=
ln
->
next
)
{
bus
=
pci_bus_b
(
ln
);
for
(
i
=
0
;
i
<
4
;
++
i
)
{
if
((
res
=
bus
->
resource
[
i
])
==
NULL
||
!
res
->
flags
)
continue
;
if
(
bus
->
parent
==
NULL
)
pr
=
(
res
->
flags
&
IORESOURCE_IO
)
?
&
ioport_resource
:
&
iomem_resource
;
else
pr
=
pci_find_parent_resource
(
bus
->
self
,
res
);
if
(
pr
==
res
)
continue
;
/* transparent bus or undefined */
if
(
pr
&&
request_resource
(
pr
,
res
)
==
0
)
continue
;
printk
(
KERN_ERR
"PCI: Cannot allocate resource region "
"%d of PCI bridge %x
\n
"
,
i
,
bus
->
number
);
printk
(
KERN_ERR
"PCI: resource is %lx..%lx (%lx), parent %p
\n
"
,
res
->
start
,
res
->
end
,
res
->
flags
,
pr
);
}
pcibios_allocate_bus_resources
(
&
bus
->
children
);
}
}
static
void
__init
pcibios_allocate_resources
(
int
pass
)
{
struct
pci_dev
*
dev
;
int
idx
,
disabled
;
u16
command
;
struct
resource
*
r
,
*
pr
;
pci_for_each_dev
(
dev
)
{
pci_read_config_word
(
dev
,
PCI_COMMAND
,
&
command
);
for
(
idx
=
0
;
idx
<
6
;
idx
++
)
{
r
=
&
dev
->
resource
[
idx
];
if
(
r
->
parent
)
/* Already allocated */
continue
;
if
(
!
r
->
start
)
/* Address not assigned at all */
continue
;
if
(
r
->
flags
&
IORESOURCE_IO
)
disabled
=
!
(
command
&
PCI_COMMAND_IO
);
else
disabled
=
!
(
command
&
PCI_COMMAND_MEMORY
);
if
(
pass
==
disabled
)
{
PPCDBG
(
PPCDBG_PHBINIT
,
"PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)
\n
"
,
r
->
start
,
r
->
end
,
r
->
flags
,
disabled
,
pass
);
pr
=
pci_find_parent_resource
(
dev
,
r
);
if
(
!
pr
||
request_resource
(
pr
,
r
)
<
0
)
{
PPCDBG
(
PPCDBG_PHBINIT
,
"PCI: Cannot allocate resource region %d of device %s, pr = 0x%lx
\n
"
,
idx
,
dev
->
slot_name
,
pr
);
if
(
pr
)
{
PPCDBG
(
PPCDBG_PHBINIT
,
"PCI: Cannot allocate resource 0x%lx
\n
"
,
request_resource
(
pr
,
r
));
}
/* We'll assign a new address later */
r
->
end
-=
r
->
start
;
r
->
start
=
0
;
}
}
}
if
(
!
pass
)
{
r
=
&
dev
->
resource
[
PCI_ROM_RESOURCE
];
if
(
r
->
flags
&
PCI_ROM_ADDRESS_ENABLE
)
{
/* Turn the ROM off, leave the resource region, but keep it unregistered. */
u32
reg
;
r
->
flags
&=
~
PCI_ROM_ADDRESS_ENABLE
;
pci_read_config_dword
(
dev
,
dev
->
rom_base_reg
,
&
reg
);
pci_write_config_dword
(
dev
,
dev
->
rom_base_reg
,
reg
&
~
PCI_ROM_ADDRESS_ENABLE
);
}
}
}
}
static
void
__init
pcibios_assign_resources
(
void
)
{
struct
pci_dev
*
dev
;
int
idx
;
struct
resource
*
r
;
pci_for_each_dev
(
dev
)
{
int
class
=
dev
->
class
>>
8
;
/* Don't touch classless devices and host bridges */
if
(
!
class
||
class
==
PCI_CLASS_BRIDGE_HOST
)
continue
;
for
(
idx
=
0
;
idx
<
6
;
idx
++
)
{
r
=
&
dev
->
resource
[
idx
];
/*
/* Align to multiple of size of minimum base. */
* We shall assign a new address to this resource,
alignto
=
max
(
0x1000UL
,
align
);
* either because the BIOS (sic) forgot to do so
start
=
ALIGN
(
start
,
alignto
);
* or because we have decided the old address was
* unusable for some reason.
*/
if
(
!
r
->
start
&&
r
->
end
)
pci_assign_resource
(
dev
,
idx
);
}
}
#if 0 /* don't assign ROMs */
res
->
start
=
start
;
r = &dev->resource[PCI_ROM_RESOURCE];
r->end -= r->start;
r->start = 0;
if (r->end)
pci_assign_resource(dev, PCI_ROM_RESOURCE);
#endif
}
}
}
/*
/*
...
@@ -359,19 +251,48 @@ pci_alloc_pci_controller(enum phb_types controller_type)
...
@@ -359,19 +251,48 @@ pci_alloc_pci_controller(enum phb_types controller_type)
memcpy
(
hose
->
what
,
model
,
7
);
memcpy
(
hose
->
what
,
model
,
7
);
hose
->
type
=
controller_type
;
hose
->
type
=
controller_type
;
hose
->
global_number
=
global_phb_number
;
hose
->
global_number
=
global_phb_number
;
phbtab
[
global_phb_number
++
]
=
hose
;
*
hose_tail
=
hose
;
*
hose_tail
=
hose
;
hose_tail
=
&
hose
->
next
;
hose_tail
=
&
hose
->
next
;
return
hose
;
return
hose
;
}
}
static
int
__init
static
void
__init
pcibios_claim_one_bus
(
struct
pci_bus
*
b
)
pcibios_init
(
void
)
{
struct
list_head
*
ld
;
struct
pci_bus
*
child_bus
;
for
(
ld
=
b
->
devices
.
next
;
ld
!=
&
b
->
devices
;
ld
=
ld
->
next
)
{
struct
pci_dev
*
dev
=
pci_dev_b
(
ld
);
int
i
;
for
(
i
=
0
;
i
<
PCI_NUM_RESOURCES
;
i
++
)
{
struct
resource
*
r
=
&
dev
->
resource
[
i
];
if
(
r
->
parent
||
!
r
->
start
||
!
r
->
flags
)
continue
;
pci_claim_resource
(
dev
,
i
);
}
}
list_for_each_entry
(
child_bus
,
&
b
->
children
,
node
)
pcibios_claim_one_bus
(
child_bus
);
}
static
void
__init
pcibios_claim_of_setup
(
void
)
{
struct
list_head
*
lb
;
for
(
lb
=
pci_root_buses
.
next
;
lb
!=
&
pci_root_buses
;
lb
=
lb
->
next
)
{
struct
pci_bus
*
b
=
pci_bus_b
(
lb
);
pcibios_claim_one_bus
(
b
);
}
}
static
int
__init
pcibios_init
(
void
)
{
{
struct
pci_controller
*
hose
;
struct
pci_controller
*
hose
;
struct
pci_bus
*
bus
;
struct
pci_bus
*
bus
;
int
next_busno
;
#ifdef CONFIG_PPC_ISERIES
#ifdef CONFIG_PPC_ISERIES
iSeries_pcibios_init
();
iSeries_pcibios_init
();
...
@@ -379,38 +300,26 @@ pcibios_init(void)
...
@@ -379,38 +300,26 @@ pcibios_init(void)
//ppc64_boot_msg(0x40, "PCI Probe");
//ppc64_boot_msg(0x40, "PCI Probe");
printk
(
"PCI: Probing PCI hardware
\n
"
);
printk
(
"PCI: Probing PCI hardware
\n
"
);
PPCDBG
(
PPCDBG_BUSWALK
,
"PCI: Probing PCI hardware
\n
"
);
/* Scan all of the recorded PCI controllers. */
/* Scan all of the recorded PCI controllers. */
for
(
next_busno
=
0
,
hose
=
hose_head
;
hose
;
hose
=
hose
->
next
)
{
for
(
hose
=
hose_head
;
hose
;
hose
=
hose
->
next
)
{
hose
->
last_busno
=
0xff
;
hose
->
last_busno
=
0xff
;
bus
=
pci_scan_bus
(
hose
->
first_busno
,
hose
->
ops
,
hose
->
arch_data
);
bus
=
pci_scan_bus
(
hose
->
first_busno
,
hose
->
ops
,
hose
->
arch_data
);
hose
->
bus
=
bus
;
hose
->
bus
=
bus
;
hose
->
last_busno
=
bus
->
subordinate
;
hose
->
last_busno
=
bus
->
subordinate
;
if
(
next_busno
<=
hose
->
last_busno
)
next_busno
=
hose
->
last_busno
+
1
;
}
/* Call machine dependent fixup */
if
(
ppc_md
.
pcibios_fixup
)
{
ppc_md
.
pcibios_fixup
();
}
}
/* Allocate and assign resources */
if
(
pci_probe_only
)
pcibios_allocate_bus_resources
(
&
pci_root_buses
);
pcibios_claim_of_setup
();
pcibios_allocate_resources
(
0
);
else
pcibios_allocate_resources
(
1
);
/* FIXME: `else' will be removed when
pcibios_assign_resources
();
pci_assign_unassigned_resources() is able to work
correctly with [partially] allocated PCI tree. */
#ifndef CONFIG_PPC_ISERIES
pci_assign_unassigned_resources
();
void
chrp_request_regions
(
void
);
chrp_request_regions
();
pci_fix_bus_sysdata
();
create_tce_tables
();
/* Call machine dependent fixup */
PPCDBG
(
PPCDBG_BUSWALK
,
"pSeries create_tce_tables()
\n
"
);
pcibios_final_fixup
();
#endif
/* Cache the location of the ISA bridge (if we have one) */
/* Cache the location of the ISA bridge (if we have one) */
ppc64_isabridge_dev
=
pci_find_class
(
PCI_CLASS_BRIDGE_ISA
<<
8
,
NULL
);
ppc64_isabridge_dev
=
pci_find_class
(
PCI_CLASS_BRIDGE_ISA
<<
8
,
NULL
);
...
@@ -418,7 +327,6 @@ pcibios_init(void)
...
@@ -418,7 +327,6 @@ pcibios_init(void)
printk
(
"ISA bridge at %s
\n
"
,
ppc64_isabridge_dev
->
slot_name
);
printk
(
"ISA bridge at %s
\n
"
,
ppc64_isabridge_dev
->
slot_name
);
printk
(
"PCI: Probing PCI hardware done
\n
"
);
printk
(
"PCI: Probing PCI hardware done
\n
"
);
PPCDBG
(
PPCDBG_BUSWALK
,
"PCI: Probing PCI hardware done.
\n
"
);
//ppc64_boot_msg(0x41, "PCI Done");
//ppc64_boot_msg(0x41, "PCI Done");
return
0
;
return
0
;
...
@@ -426,12 +334,6 @@ pcibios_init(void)
...
@@ -426,12 +334,6 @@ pcibios_init(void)
subsys_initcall
(
pcibios_init
);
subsys_initcall
(
pcibios_init
);
void
__init
pcibios_fixup_bus
(
struct
pci_bus
*
bus
)
{
if
(
ppc_md
.
pcibios_fixup_bus
)
ppc_md
.
pcibios_fixup_bus
(
bus
);
}
char
__init
*
pcibios_setup
(
char
*
str
)
char
__init
*
pcibios_setup
(
char
*
str
)
{
{
return
str
;
return
str
;
...
@@ -439,35 +341,29 @@ char __init *pcibios_setup(char *str)
...
@@ -439,35 +341,29 @@ char __init *pcibios_setup(char *str)
int
pcibios_enable_device
(
struct
pci_dev
*
dev
,
int
mask
)
int
pcibios_enable_device
(
struct
pci_dev
*
dev
,
int
mask
)
{
{
u16
cmd
,
old_cmd
;
u16
cmd
,
oldcmd
;
int
idx
;
int
i
;
struct
resource
*
r
;
PPCDBG
(
PPCDBG_BUSWALK
,
"PCI: %s for device %s
\n
"
,
__FUNCTION__
,
dev
->
slot_name
);
pci_read_config_word
(
dev
,
PCI_COMMAND
,
&
cmd
);
pci_read_config_word
(
dev
,
PCI_COMMAND
,
&
cmd
);
old_cmd
=
cmd
;
oldcmd
=
cmd
;
for
(
idx
=
0
;
idx
<
6
;
idx
++
)
{
for
(
i
=
0
;
i
<
PCI_NUM_RESOURCES
;
i
++
)
{
struct
resource
*
res
=
&
dev
->
resource
[
i
];
/* Only set up the requested stuff */
/* Only set up the requested stuff */
if
(
!
(
mask
&
(
1
<<
i
dx
)))
if
(
!
(
mask
&
(
1
<<
i
)))
continue
;
continue
;
r
=
&
dev
->
resource
[
idx
];
if
(
res
->
flags
&
IORESOURCE_IO
)
if
(
!
r
->
start
&&
r
->
end
)
{
printk
(
KERN_ERR
"PCI: Device %s not available because of resource collisions
\n
"
,
dev
->
slot_name
);
return
-
EINVAL
;
}
if
(
r
->
flags
&
IORESOURCE_IO
)
cmd
|=
PCI_COMMAND_IO
;
cmd
|=
PCI_COMMAND_IO
;
if
(
r
->
flags
&
IORESOURCE_MEM
)
if
(
r
es
->
flags
&
IORESOURCE_MEM
)
cmd
|=
PCI_COMMAND_MEMORY
;
cmd
|=
PCI_COMMAND_MEMORY
;
}
}
if
(
cmd
!=
old_cmd
)
{
printk
(
"PCI: Enabling device %s (%04x -> %04x)
\n
"
,
if
(
cmd
!=
oldcmd
)
{
dev
->
slot_name
,
old_cmd
,
cmd
);
printk
(
KERN_DEBUG
"PCI: Enabling device: (%s), cmd %x
\n
"
,
PPCDBG
(
PPCDBG_BUSWALK
,
"PCI: Enabling device %s
\n
"
,
dev
->
slot_name
,
cmd
);
dev
->
slot_name
);
/* Enable the appropriate bits in the PCI command register. */
pci_write_config_word
(
dev
,
PCI_COMMAND
,
cmd
);
pci_write_config_word
(
dev
,
PCI_COMMAND
,
cmd
);
}
}
return
0
;
return
0
;
...
@@ -609,112 +505,3 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
...
@@ -609,112 +505,3 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
return
ret
;
return
ret
;
}
}
/*****************************************************
* Dump Resource information
*****************************************************/
void
dumpResources
(
struct
resource
*
Resource
)
{
if
(
Resource
!=
NULL
)
{
int
Flags
=
0x00000F00
&
Resource
->
flags
;
if
(
Resource
->
start
==
0
&&
Resource
->
end
==
0
)
return
;
else
if
(
Resource
->
start
==
Resource
->
end
)
return
;
else
{
if
(
Flags
==
IORESOURCE_IO
)
udbg_printf
(
"IO.:"
);
else
if
(
Flags
==
IORESOURCE_MEM
)
udbg_printf
(
"MEM:"
);
else
if
(
Flags
==
IORESOURCE_IRQ
)
udbg_printf
(
"IRQ:"
);
else
udbg_printf
(
"0x%02X:"
,
Resource
->
flags
);
}
udbg_printf
(
"0x%016LX / 0x%016LX (0x%08X)
\n
"
,
Resource
->
start
,
Resource
->
end
,
Resource
->
end
-
Resource
->
start
);
}
}
int
resourceSize
(
struct
resource
*
Resource
)
{
if
(
Resource
->
start
==
0
&&
Resource
->
end
==
0
)
return
0
;
else
if
(
Resource
->
start
==
Resource
->
end
)
return
0
;
else
return
(
Resource
->
end
-
1
)
-
Resource
->
start
;
}
/*****************************************************
* Dump PHB information for Debug
*****************************************************/
void
dumpPci_Controller
(
struct
pci_controller
*
phb
)
{
udbg_printf
(
"
\t
pci_controller= 0x%016LX
\n
"
,
phb
);
if
(
phb
!=
NULL
)
{
udbg_printf
(
"
\t
what & type = %s 0x%02X
\n
"
,
phb
->
what
,
phb
->
type
);
udbg_printf
(
"
\t
bus = "
);
if
(
phb
->
bus
!=
NULL
)
udbg_printf
(
"0x%02X
\n
"
,
phb
->
bus
->
number
);
else
udbg_printf
(
"<NULL>
\n
"
);
udbg_printf
(
"
\t
arch_data = 0x%016LX
\n
"
,
phb
->
arch_data
);
udbg_printf
(
"
\t
first_busno = 0x%02X
\n
"
,
phb
->
first_busno
);
udbg_printf
(
"
\t
last_busno = 0x%02X
\n
"
,
phb
->
last_busno
);
udbg_printf
(
"
\t
io_base_virt* = 0x%016LX
\n
"
,
phb
->
io_base_virt
);
udbg_printf
(
"
\t
io_base_phys = 0x%016LX
\n
"
,
phb
->
io_base_phys
);
udbg_printf
(
"
\t
pci_mem_offset= 0x%016LX
\n
"
,
phb
->
pci_mem_offset
);
udbg_printf
(
"
\t
pci_io_offset = 0x%016LX
\n
"
,
phb
->
pci_io_offset
);
udbg_printf
(
"
\t
Resources
\n
"
);
dumpResources
(
&
phb
->
io_resource
);
if
(
phb
->
mem_resource_count
>
0
)
dumpResources
(
&
phb
->
mem_resources
[
0
]);
if
(
phb
->
mem_resource_count
>
1
)
dumpResources
(
&
phb
->
mem_resources
[
1
]);
if
(
phb
->
mem_resource_count
>
2
)
dumpResources
(
&
phb
->
mem_resources
[
2
]);
udbg_printf
(
"
\t
global_num = 0x%02X
\n
"
,
phb
->
global_number
);
udbg_printf
(
"
\t
local_num = 0x%02X
\n
"
,
phb
->
local_number
);
}
}
/*****************************************************
* Dump PHB information for Debug
*****************************************************/
void
dumpPci_Bus
(
struct
pci_bus
*
Pci_Bus
)
{
int
i
;
udbg_printf
(
"
\t
pci_bus = 0x%016LX
\n
"
,
Pci_Bus
);
if
(
Pci_Bus
!=
NULL
)
{
udbg_printf
(
"
\t
number = 0x%02X
\n
"
,
Pci_Bus
->
number
);
udbg_printf
(
"
\t
primary = 0x%02X
\n
"
,
Pci_Bus
->
primary
);
udbg_printf
(
"
\t
secondary = 0x%02X
\n
"
,
Pci_Bus
->
secondary
);
udbg_printf
(
"
\t
subordinate = 0x%02X
\n
"
,
Pci_Bus
->
subordinate
);
for
(
i
=
0
;
i
<
4
;
++
i
)
{
if
(
Pci_Bus
->
resource
[
i
]
==
NULL
)
continue
;
if
(
Pci_Bus
->
resource
[
i
]
->
start
==
0
&&
Pci_Bus
->
resource
[
i
]
->
end
==
0
)
break
;
udbg_printf
(
"
\t
Resources[%d]"
,
i
);
dumpResources
(
Pci_Bus
->
resource
[
i
]);
}
}
}
/*****************************************************
* Dump Device information for Debug
*****************************************************/
void
dumpPci_Dev
(
struct
pci_dev
*
Pci_Dev
)
{
int
i
;
udbg_printf
(
"
\t
pci_dev* = 0x%p
\n
"
,
Pci_Dev
);
if
(
Pci_Dev
==
NULL
)
return
;
udbg_printf
(
"
\t
name = %s
\n
"
,
Pci_Dev
->
dev
.
name
);
udbg_printf
(
"
\t
bus* = 0x%p
\n
"
,
Pci_Dev
->
bus
);
udbg_printf
(
"
\t
sysdata* = 0x%p
\n
"
,
Pci_Dev
->
sysdata
);
udbg_printf
(
"
\t
Device = 0x%4X%02X:%02X.%02X 0x%04X:%04X
\n
"
,
PCI_GET_PHB_NUMBER
(
Pci_Dev
),
PCI_GET_BUS_NUMBER
(
Pci_Dev
),
PCI_SLOT
(
Pci_Dev
->
devfn
),
PCI_FUNC
(
Pci_Dev
->
devfn
),
Pci_Dev
->
vendor
,
Pci_Dev
->
device
);
udbg_printf
(
"
\t
Hdr/Irq = 0x%02X/0x%02X
\n
"
,
Pci_Dev
->
hdr_type
,
Pci_Dev
->
irq
);
for
(
i
=
0
;
i
<
DEVICE_COUNT_RESOURCE
;
++
i
)
{
if
(
Pci_Dev
->
resource
[
i
].
start
==
0
&&
Pci_Dev
->
resource
[
i
].
end
==
0
)
continue
;
udbg_printf
(
"
\t
Resources[%d] "
,
i
);
dumpResources
(
&
Pci_Dev
->
resource
[
i
]);
}
dumpResources
(
&
Pci_Dev
->
resource
[
i
]);
}
arch/ppc64/kernel/pci.h
View file @
601917b5
...
@@ -19,18 +19,14 @@ extern struct pci_controller* pci_find_hose_for_OF_device(struct device_node* no
...
@@ -19,18 +19,14 @@ extern struct pci_controller* pci_find_hose_for_OF_device(struct device_node* no
extern
struct
pci_controller
*
hose_head
;
extern
struct
pci_controller
*
hose_head
;
extern
struct
pci_controller
**
hose_tail
;
extern
struct
pci_controller
**
hose_tail
;
/* PHB's are also in a table. */
#define PCI_MAX_PHB 64
extern
int
global_phb_number
;
extern
int
global_phb_number
;
extern
struct
pci_controller
*
phbtab
[];
/*******************************************************************
/*******************************************************************
* Platform functions that are brand specific implementation.
* Platform functions that are brand specific implementation.
*******************************************************************/
*******************************************************************/
extern
unsigned
long
find_and_init_phbs
(
void
);
extern
unsigned
long
find_and_init_phbs
(
void
);
extern
void
ppc64_pcibios_init
(
void
);
extern
struct
pci_dev
*
ppc64_isabridge_dev
;
/* may be NULL if no ISA bus */
extern
struct
pci_dev
*
ppc64_isabridge_dev
;
/* may be NULL if no ISA bus */
/*******************************************************************
/*******************************************************************
...
@@ -46,10 +42,6 @@ void pci_devs_phb_init(void);
...
@@ -46,10 +42,6 @@ void pci_devs_phb_init(void);
void
pci_fix_bus_sysdata
(
void
);
void
pci_fix_bus_sysdata
(
void
);
struct
device_node
*
fetch_dev_dn
(
struct
pci_dev
*
dev
);
struct
device_node
*
fetch_dev_dn
(
struct
pci_dev
*
dev
);
void
iSeries_pcibios_init_early
(
void
);
void
pSeries_pcibios_init_early
(
void
);
void
pSeries_pcibios_init
(
void
);
/*******************************************************************
/*******************************************************************
* Helper macros for extracting data from pci structures.
* Helper macros for extracting data from pci structures.
* PCI_GET_PHB_PTR(struct pci_dev*) returns the Phb pointer.
* PCI_GET_PHB_PTR(struct pci_dev*) returns the Phb pointer.
...
@@ -60,12 +52,4 @@ void pSeries_pcibios_init(void);
...
@@ -60,12 +52,4 @@ void pSeries_pcibios_init(void);
#define PCI_GET_PHB_NUMBER(dev) (((dev)->bus->number&0x00FFFF00)>>8)
#define PCI_GET_PHB_NUMBER(dev) (((dev)->bus->number&0x00FFFF00)>>8)
#define PCI_GET_BUS_NUMBER(dev) ((dev)->bus->number&0x0000FF)
#define PCI_GET_BUS_NUMBER(dev) ((dev)->bus->number&0x0000FF)
/*******************************************************************
* Debugging Routines.
*******************************************************************/
extern
void
dumpResources
(
struct
resource
*
Resource
);
extern
void
dumpPci_Controller
(
struct
pci_controller
*
phb
);
extern
void
dumpPci_Bus
(
struct
pci_bus
*
Pci_Bus
);
extern
void
dumpPci_Dev
(
struct
pci_dev
*
Pci_Dev
);
#endif
/* __PPC_KERNEL_PCI_H__ */
#endif
/* __PPC_KERNEL_PCI_H__ */
include/asm-ppc64/machdep.h
View file @
601917b5
...
@@ -90,22 +90,6 @@ struct machdep_calls {
...
@@ -90,22 +90,6 @@ struct machdep_calls {
unsigned
char
(
*
udbg_getc
)(
void
);
unsigned
char
(
*
udbg_getc
)(
void
);
int
(
*
udbg_getc_poll
)(
void
);
int
(
*
udbg_getc_poll
)(
void
);
/* PCI interfaces */
int
(
*
pcibios_read_config
)(
struct
device_node
*
dn
,
int
where
,
int
size
,
u32
*
val
);
int
(
*
pcibios_write_config
)(
struct
device_node
*
dn
,
int
where
,
int
size
,
u32
val
);
/* Called after scanning the bus, before allocating
* resources
*/
void
(
*
pcibios_fixup
)(
void
);
/* Called for each PCI bus in the system
* when it's probed
*/
void
(
*
pcibios_fixup_bus
)(
struct
pci_bus
*
);
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
/* functions for dealing with other cpus */
/* functions for dealing with other cpus */
struct
smp_ops_t
smp_ops
;
struct
smp_ops_t
smp_ops
;
...
...
include/asm-ppc64/pci-bridge.h
View file @
601917b5
...
@@ -40,7 +40,7 @@ struct pci_controller {
...
@@ -40,7 +40,7 @@ struct pci_controller {
void
*
io_base_virt
;
void
*
io_base_virt
;
unsigned
long
io_base_phys
;
unsigned
long
io_base_phys
;
/* Some machines
(PReP)
have a non 1:1 mapping of
/* Some machines have a non 1:1 mapping of
* the PCI memory space in the CPU bus space
* the PCI memory space in the CPU bus space
*/
*/
unsigned
long
pci_mem_offset
;
unsigned
long
pci_mem_offset
;
...
...
include/asm-ppc64/pci.h
View file @
601917b5
...
@@ -16,11 +16,6 @@
...
@@ -16,11 +16,6 @@
#include <asm/io.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/prom.h>
static
inline
int
pcibios_assign_all_busses
(
void
)
{
return
0
;
}
#define PCIBIOS_MIN_IO 0x1000
#define PCIBIOS_MIN_IO 0x1000
#define PCIBIOS_MIN_MEM 0x10000000
#define PCIBIOS_MIN_MEM 0x10000000
...
@@ -36,7 +31,18 @@ static inline void pcibios_penalize_isa_irq(int irq)
...
@@ -36,7 +31,18 @@ static inline void pcibios_penalize_isa_irq(int irq)
struct
pci_dev
;
struct
pci_dev
;
extern
char
*
pci_card_location
(
struct
pci_dev
*
);
#define HAVE_ARCH_PCI_MWI 1
static
inline
int
pcibios_prep_mwi
(
struct
pci_dev
*
dev
)
{
/*
* pSeries firmware sets cacheline size and hardware treats
* MWI the same as memory write, so we dont change cacheline size
* or the MWI bit.
*/
return
1
;
}
extern
unsigned
int
pcibios_assign_all_busses
(
void
);
extern
void
*
pci_alloc_consistent
(
struct
pci_dev
*
hwdev
,
size_t
size
,
extern
void
*
pci_alloc_consistent
(
struct
pci_dev
*
hwdev
,
size_t
size
,
dma_addr_t
*
dma_handle
);
dma_addr_t
*
dma_handle
);
...
@@ -52,8 +58,6 @@ extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
...
@@ -52,8 +58,6 @@ extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
extern
void
pci_unmap_sg
(
struct
pci_dev
*
hwdev
,
struct
scatterlist
*
sg
,
extern
void
pci_unmap_sg
(
struct
pci_dev
*
hwdev
,
struct
scatterlist
*
sg
,
int
nents
,
int
direction
);
int
nents
,
int
direction
);
extern
void
pSeries_pcibios_init_early
(
void
);
static
inline
void
pci_dma_sync_single
(
struct
pci_dev
*
hwdev
,
static
inline
void
pci_dma_sync_single
(
struct
pci_dev
*
hwdev
,
dma_addr_t
dma_handle
,
dma_addr_t
dma_handle
,
size_t
size
,
int
direction
)
size_t
size
,
int
direction
)
...
@@ -122,9 +126,10 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
...
@@ -122,9 +126,10 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
*/
*/
#define PCI_DMA_BUS_IS_PHYS (0)
#define PCI_DMA_BUS_IS_PHYS (0)
#endif
/* __KERNEL__ */
extern
void
pcibios_resource_to_bus
(
struct
pci_dev
*
dev
,
struct
pci_bus_region
*
region
,
struct
resource
*
res
);
/* generic pci stuff */
#endif
/* __KERNEL__ */
#include <asm-generic/pci.h>
#endif
/* __PPC64_PCI_H */
#endif
/* __PPC64_PCI_H */
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