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
0f5646a6
Commit
0f5646a6
authored
Mar 05, 2003
by
Anton Blanchard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ppc64: rework pci PHB probe code
parent
af92a648
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
222 additions
and
285 deletions
+222
-285
arch/ppc64/kernel/pSeries_pci.c
arch/ppc64/kernel/pSeries_pci.c
+200
-281
arch/ppc64/kernel/pci.c
arch/ppc64/kernel/pci.c
+19
-2
arch/ppc64/kernel/pci.h
arch/ppc64/kernel/pci.h
+1
-1
include/asm-ppc64/pci-bridge.h
include/asm-ppc64/pci-bridge.h
+2
-1
No files found.
arch/ppc64/kernel/pSeries_pci.c
View file @
0f5646a6
...
@@ -43,12 +43,6 @@
...
@@ -43,12 +43,6 @@
#include "open_pic.h"
#include "open_pic.h"
#include "pci.h"
#include "pci.h"
/*******************************************************************
* Forward declares of prototypes.
*******************************************************************/
struct
pci_controller
*
alloc_phb
(
struct
device_node
*
dev
,
char
*
model
,
unsigned
int
addr_size_words
)
;
/* RTAS tokens */
/* RTAS tokens */
static
int
read_pci_config
;
static
int
read_pci_config
;
static
int
write_pci_config
;
static
int
write_pci_config
;
...
@@ -144,275 +138,126 @@ struct pci_ops rtas_pci_ops = {
...
@@ -144,275 +138,126 @@ struct pci_ops rtas_pci_ops = {
* openfirmware and sets it in the pci_dev and pci_config line.
* openfirmware and sets it in the pci_dev and pci_config line.
*
*
******************************************************************/
******************************************************************/
int
int
pci_read_irq_line
(
struct
pci_dev
*
pci_dev
)
pci_read_irq_line
(
struct
pci_dev
*
Pci_Dev
)
{
{
u8
InterruptPin
;
u8
intpin
;
struct
device_node
*
Node
;
struct
device_node
*
node
;
pci_read_config_byte
(
pci_dev
,
PCI_INTERRUPT_PIN
,
&
intpin
);
pci_read_config_byte
(
Pci_Dev
,
PCI_INTERRUPT_PIN
,
&
InterruptPin
);
if
(
intpin
==
0
)
{
if
(
InterruptPin
==
0
)
{
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s No Interrupt used by device.
\n
"
,
pci_dev
->
slot_name
);
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s No Interrupt used by device.
\n
"
,
Pci_Dev
->
slot_name
);
return
0
;
return
0
;
}
}
Node
=
pci_device_to_OF_node
(
Pci_Dev
);
if
(
Node
==
NULL
)
{
node
=
pci_device_to_OF_node
(
pci_dev
);
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s Device Node not found.
\n
"
,
Pci_Dev
->
slot_name
);
if
(
node
==
NULL
)
{
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s Device Node not found.
\n
"
,
pci_dev
->
slot_name
);
return
-
1
;
return
-
1
;
}
}
if
(
N
ode
->
n_intrs
==
0
)
{
if
(
n
ode
->
n_intrs
==
0
)
{
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s No Device OF interrupts defined.
\n
"
,
Pci_D
ev
->
slot_name
);
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s No Device OF interrupts defined.
\n
"
,
pci_d
ev
->
slot_name
);
return
-
1
;
return
-
1
;
}
}
Pci_Dev
->
irq
=
N
ode
->
intrs
[
0
].
line
;
pci_dev
->
irq
=
n
ode
->
intrs
[
0
].
line
;
if
(
s7a_workaround
)
{
if
(
s7a_workaround
)
{
if
(
Pci_D
ev
->
irq
>
16
)
if
(
pci_d
ev
->
irq
>
16
)
Pci_D
ev
->
irq
-=
3
;
pci_d
ev
->
irq
-=
3
;
}
}
pci_write_config_byte
(
Pci_Dev
,
PCI_INTERRUPT_LINE
,
Pci_D
ev
->
irq
);
pci_write_config_byte
(
pci_dev
,
PCI_INTERRUPT_LINE
,
pci_d
ev
->
irq
);
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s pci_dev->irq = 0x%02X
\n
"
,
Pci_Dev
->
slot_name
,
Pci_Dev
->
irq
);
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s pci_dev->irq = 0x%02X
\n
"
,
pci_dev
->
slot_name
,
pci_dev
->
irq
);
return
0
;
return
0
;
}
}
/******************************************************************
static
void
__init
pci_process_bridge_OF_ranges
(
struct
pci_controller
*
hose
,
* Find all PHBs in the system and initialize a set of data
struct
device_node
*
dev
,
* structures to represent them.
int
primary
)
******************************************************************/
unsigned
long
__init
find_and_init_phbs
(
void
)
{
{
struct
device_node
*
Pci_Node
;
unsigned
int
*
ranges
;
struct
pci_controller
*
phb
;
unsigned
long
size
;
unsigned
int
root_addr_size_words
=
0
,
this_addr_size_words
=
0
;
int
rlen
=
0
;
unsigned
int
this_addr_count
=
0
,
range_stride
;
int
memno
=
0
;
unsigned
int
*
ui_ptr
=
NULL
,
*
ranges
;
char
*
model
;
struct
pci_range64
range
;
struct
resource
*
res
;
struct
resource
*
res
;
unsigned
int
memno
,
rlen
,
i
,
index
;
int
np
,
na
=
prom_n_addr_cells
(
dev
);
unsigned
int
*
opprop
;
unsigned
long
pci_addr
,
cpu_phys_addr
;
int
has_isa
=
0
;
PPCDBG
(
PPCDBG_PHBINIT
,
"find_and_init_phbs
\n
"
);
read_pci_config
=
rtas_token
(
"read-pci-config"
);
write_pci_config
=
rtas_token
(
"write-pci-config"
);
ibm_read_pci_config
=
rtas_token
(
"ibm,read-pci-config"
);
ibm_write_pci_config
=
rtas_token
(
"ibm,write-pci-config"
);
if
(
naca
->
interrupt_controller
==
IC_OPEN_PIC
)
{
opprop
=
(
unsigned
int
*
)
get_property
(
find_path_device
(
"/"
),
"platform-open-pic"
,
NULL
);
}
/* Get the root address word size. */
np
=
na
+
5
;
ui_ptr
=
(
unsigned
int
*
)
get_property
(
find_path_device
(
"/"
),
"#size-cells"
,
NULL
);
if
(
ui_ptr
)
{
root_addr_size_words
=
*
ui_ptr
;
}
else
{
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
get #size-cells failed.
\n
"
);
return
(
-
1
);
}
if
(
find_type_devices
(
"isa"
))
{
/*
has_isa
=
1
;
* The ranges property is laid out as an array of elements,
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
Found an ISA bus.
\n
"
);
* each of which comprises:
}
* cells 0 - 2: a PCI address
* cells 3 or 3+4: a CPU physical address
index
=
0
;
* (size depending on dev->n_addr_cells)
* cells 4+5 or 5+6: the size of the range
/******************************************************************
*/
* Find all PHB devices and create an object for them.
rlen
=
0
;
******************************************************************/
hose
->
io_base_phys
=
0
;
for
(
Pci_Node
=
find_devices
(
"pci"
);
Pci_Node
!=
NULL
;
Pci_Node
=
Pci_Node
->
next
)
{
ranges
=
(
unsigned
int
*
)
get_property
(
dev
,
"ranges"
,
&
rlen
);
model
=
(
char
*
)
get_property
(
Pci_Node
,
"model"
,
NULL
);
while
((
rlen
-=
np
*
sizeof
(
unsigned
int
))
>=
0
)
{
if
(
model
!=
NULL
)
{
res
=
NULL
;
phb
=
alloc_phb
(
Pci_Node
,
model
,
root_addr_size_words
);
pci_addr
=
(
unsigned
long
)
ranges
[
1
]
<<
32
|
ranges
[
2
];
if
(
phb
==
NULL
)
return
(
-
1
);
}
else
{
continue
;
}
/* Get this node's address word size. */
ui_ptr
=
(
unsigned
int
*
)
get_property
(
Pci_Node
,
"#size-cells"
,
NULL
);
if
(
ui_ptr
)
this_addr_size_words
=
*
ui_ptr
;
else
this_addr_size_words
=
1
;
/* Get this node's address word count. */
ui_ptr
=
(
unsigned
int
*
)
get_property
(
Pci_Node
,
"#address-cells"
,
NULL
);
if
(
ui_ptr
)
this_addr_count
=
*
ui_ptr
;
else
this_addr_count
=
3
;
range_stride
=
this_addr_count
+
root_addr_size_words
+
this_addr_size_words
;
memno
=
0
;
phb
->
io_base_phys
=
0
;
ranges
=
(
unsigned
int
*
)
get_property
(
Pci_Node
,
"ranges"
,
&
rlen
);
cpu_phys_addr
=
ranges
[
3
];
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
range_stride = 0x%lx, rlen = 0x%x
\n
"
,
range_stride
,
rlen
);
if
(
na
==
2
)
cpu_phys_addr
=
cpu_phys_addr
<<
32
|
ranges
[
4
];
for
(
i
=
0
;
i
<
(
rlen
/
sizeof
(
*
ranges
));
i
+=
range_stride
)
{
size
=
(
unsigned
long
)
ranges
[
na
+
3
]
<<
32
|
ranges
[
na
+
4
];
/* Put the PCI addr part of the current element into a
* '64' struct.
*/
range
=
*
((
struct
pci_range64
*
)(
ranges
+
i
));
/* If this is a '32' element, map into a 64 struct. */
if
((
range_stride
*
sizeof
(
int
))
==
sizeof
(
struct
pci_range32
))
{
range
.
parent_addr
=
(
unsigned
long
)(
*
(
ranges
+
i
+
3
));
range
.
size
=
(((
unsigned
long
)(
*
(
ranges
+
i
+
4
)))
<<
32
)
|
(
*
(
ranges
+
i
+
5
));
}
else
{
range
.
parent_addr
=
(((
unsigned
long
)(
*
(
ranges
+
i
+
3
)))
<<
32
)
|
(
*
(
ranges
+
i
+
4
));
range
.
size
=
(((
unsigned
long
)(
*
(
ranges
+
i
+
5
)))
<<
32
)
|
(
*
(
ranges
+
i
+
6
));
}
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
range.parent_addr = 0x%lx
\n
"
,
range
.
parent_addr
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
range.child_addr.hi = 0x%lx
\n
"
,
range
.
child_addr
.
a_hi
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
range.child_addr.mid = 0x%lx
\n
"
,
range
.
child_addr
.
a_mid
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
range.child_addr.lo = 0x%lx
\n
"
,
range
.
child_addr
.
a_lo
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
range.size = 0x%lx
\n
"
,
range
.
size
);
res
=
NULL
;
switch
(
ranges
[
0
]
>>
24
)
{
switch
((
range
.
child_addr
.
a_hi
>>
24
)
&
0x3
)
{
case
1
:
/* I/O space */
case
1
:
/* I/O space */
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
IO Space
\n
"
);
hose
->
io_base_phys
=
cpu_phys_addr
;
phb
->
io_base_phys
=
range
.
parent_addr
;
hose
->
io_base_virt
=
__ioremap
(
hose
->
io_base_phys
,
res
=
&
phb
->
io_resource
;
size
,
_PAGE_NO_CACHE
);
res
->
name
=
Pci_Node
->
full_name
;
if
(
primary
)
{
res
->
flags
=
IORESOURCE_IO
;
pci_io_base
=
(
unsigned
long
)
hose
->
io_base_virt
;
phb
->
io_base_virt
=
__ioremap
(
phb
->
io_base_phys
,
range
.
size
,
_PAGE_NO_CACHE
);
if
(
find_type_devices
(
"isa"
))
if
(
!
pci_io_base
)
{
pci_io_base
=
(
unsigned
long
)
phb
->
io_base_virt
;
if
(
has_isa
)
isa_io_base
=
pci_io_base
;
isa_io_base
=
pci_io_base
;
}
}
res
->
start
=
((((
unsigned
long
)
range
.
child_addr
.
a_mid
)
<<
32
)
|
(
range
.
child_addr
.
a_lo
));
res
->
start
+=
(
unsigned
long
)
phb
->
io_base_virt
-
pci_io_base
;
res
=
&
hose
->
io_resource
;
res
->
end
=
res
->
start
+
range
.
size
-
1
;
res
->
flags
=
IORESOURCE_IO
;
res
->
parent
=
NULL
;
res
->
start
=
pci_addr
;
res
->
sibling
=
NULL
;
res
->
start
+=
(
unsigned
long
)
hose
->
io_base_virt
-
res
->
child
=
NULL
;
pci_io_base
;
phb
->
pci_io_offset
=
range
.
parent_addr
-
((((
unsigned
long
)
range
.
child_addr
.
a_mid
)
<<
32
)
|
(
range
.
child_addr
.
a_lo
));
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
pci_io_offset = 0x%lx
\n
"
,
phb
->
pci_io_offset
);
break
;
break
;
case
2
:
/* mem space */
case
2
:
/* memory space */
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
Mem Space
\n
"
);
memno
=
0
;
phb
->
pci_mem_offset
=
range
.
parent_addr
-
while
(
memno
<
3
&&
hose
->
mem_resources
[
memno
].
flags
)
((((
unsigned
long
)
range
.
child_addr
.
a_mid
)
<<
32
)
|
(
range
.
child_addr
.
a_lo
));
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
pci_mem_offset = 0x%lx
\n
"
,
phb
->
pci_mem_offset
);
if
(
memno
<
sizeof
(
phb
->
mem_resources
)
/
sizeof
(
phb
->
mem_resources
[
0
]))
{
res
=
&
(
phb
->
mem_resources
[
memno
]);
++
memno
;
++
memno
;
res
->
name
=
Pci_Node
->
full_name
;
if
(
memno
==
0
)
hose
->
pci_mem_offset
=
cpu_phys_addr
-
pci_addr
;
if
(
memno
<
3
)
{
res
=
&
hose
->
mem_resources
[
memno
];
res
->
flags
=
IORESOURCE_MEM
;
res
->
flags
=
IORESOURCE_MEM
;
res
->
start
=
range
.
parent_addr
;
res
->
start
=
cpu_phys_addr
;
res
->
end
=
range
.
parent_addr
+
range
.
size
-
1
;
res
->
parent
=
NULL
;
res
->
sibling
=
NULL
;
res
->
child
=
NULL
;
}
}
break
;
break
;
}
}
if
(
res
!=
NULL
)
{
res
->
name
=
dev
->
full_name
;
res
->
end
=
res
->
start
+
size
-
1
;
res
->
parent
=
NULL
;
res
->
sibling
=
NULL
;
res
->
child
=
NULL
;
}
}
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
phb->io_base_phys = 0x%lx
\n
"
,
ranges
+=
np
;
phb
->
io_base_phys
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
phb->pci_mem_offset = 0x%lx
\n
"
,
phb
->
pci_mem_offset
);
if
(
naca
->
interrupt_controller
==
IC_OPEN_PIC
)
{
int
addr
=
root_addr_size_words
*
(
index
+
2
)
-
1
;
openpic_setup_ISU
(
index
,
opprop
[
addr
]);
}
index
++
;
}
}
pci_devs_phb_init
();
return
0
;
/*Success */
}
}
/******************************************************************
static
void
python_countermeasures
(
unsigned
long
addr
)
*
* Allocate and partially initialize a structure to represent a PHB.
*
******************************************************************/
struct
pci_controller
*
alloc_phb
(
struct
device_node
*
dev
,
char
*
model
,
unsigned
int
addr_size_words
)
{
{
struct
pci_controller
*
phb
;
unsigned
int
*
ui_ptr
=
NULL
,
len
;
struct
reg_property64
reg_struct
;
int
*
bus_range
;
int
*
buid_vals
;
PPCDBG
(
PPCDBG_PHBINIT
,
"alloc_phb: %s
\n
"
,
dev
->
full_name
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
dev = 0x%lx
\n
"
,
dev
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
model = 0x%lx
\n
"
,
model
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
addr_size_words = 0x%lx
\n
"
,
addr_size_words
);
/* Found a PHB, now figure out where his registers are mapped. */
ui_ptr
=
(
unsigned
int
*
)
get_property
(
dev
,
"reg"
,
&
len
);
if
(
ui_ptr
==
NULL
)
{
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
get reg failed.
\n
"
);
return
(
NULL
);
}
if
(
addr_size_words
==
1
)
{
reg_struct
.
address
=
((
struct
reg_property32
*
)
ui_ptr
)
->
address
;
reg_struct
.
size
=
((
struct
reg_property32
*
)
ui_ptr
)
->
size
;
}
else
{
reg_struct
=
*
((
struct
reg_property64
*
)
ui_ptr
);
}
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
reg_struct.address = 0x%lx
\n
"
,
reg_struct
.
address
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
reg_struct.size = 0x%lx
\n
"
,
reg_struct
.
size
);
/***************************************************************
* Set chip specific data in the phb, including types &
* register pointers.
***************************************************************/
/****************************************************************
* Python
***************************************************************/
if
(
strstr
(
model
,
"Python"
))
{
void
*
chip_regs
;
void
*
chip_regs
;
volatile
u32
*
tmp
,
i
;
volatile
u32
*
tmp
,
i
;
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
Create python
\n
"
);
phb
=
pci_alloc_pci_controller
(
"PHB PY"
,
phb_type_python
);
if
(
phb
==
NULL
)
return
NULL
;
/* Python's register file is 1 MB in size. */
/* Python's register file is 1 MB in size. */
chip_regs
=
ioremap
(
reg_struct
.
address
&
~
(
0xfffffUL
),
chip_regs
=
ioremap
(
addr
&
~
(
0xfffffUL
),
0x100000
);
0x100000
);
/*
/*
* Firmware doesn't always clear this bit which is critical
* Firmware doesn't always clear this bit which is critical
...
@@ -424,7 +269,7 @@ alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
...
@@ -424,7 +269,7 @@ alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
tmp
=
(
u32
*
)((
unsigned
long
)
chip_regs
+
0xf6030
);
tmp
=
(
u32
*
)((
unsigned
long
)
chip_regs
+
0xf6030
);
if
(
*
tmp
&
PRG_CL_RESET_VALID
)
{
if
(
*
tmp
&
PRG_CL_RESET_VALID
)
{
printk
(
"Python workaround: "
);
printk
(
KERN_INFO
"Python workaround: "
);
*
tmp
&=
~
PRG_CL_RESET_VALID
;
*
tmp
&=
~
PRG_CL_RESET_VALID
;
/*
/*
* We must read it back for changes to
* We must read it back for changes to
...
@@ -434,38 +279,65 @@ alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
...
@@ -434,38 +279,65 @@ alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
printk
(
"reg0: %x
\n
"
,
i
);
printk
(
"reg0: %x
\n
"
,
i
);
}
}
/***************************************************************
iounmap
(
chip_regs
);
* Speedwagon
}
* include Winnipeg as well for the time being.
***************************************************************/
struct
pci_controller
*
alloc_phb
(
struct
device_node
*
dev
,
}
else
if
((
strstr
(
model
,
"Speedwagon"
))
||
unsigned
int
addr_size_words
)
(
strstr
(
model
,
"Winnipeg"
)))
{
{
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
Create speedwagon
\n
"
);
struct
pci_controller
*
phb
;
phb
=
pci_alloc_pci_controller
(
"PHB SW"
,
phb_type_speedwagon
);
unsigned
int
*
ui_ptr
=
NULL
,
len
;
if
(
phb
==
NULL
)
struct
reg_property64
reg_struct
;
int
*
bus_range
;
int
*
buid_vals
;
char
*
model
;
enum
phb_types
phb_type
;
model
=
(
char
*
)
get_property
(
dev
,
"model"
,
NULL
);
if
(
!
model
)
{
printk
(
KERN_ERR
"alloc_phb: phb has no model property
\n
"
);
model
=
"<empty>"
;
}
/* Found a PHB, now figure out where his registers are mapped. */
ui_ptr
=
(
unsigned
int
*
)
get_property
(
dev
,
"reg"
,
&
len
);
if
(
ui_ptr
==
NULL
)
{
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
get reg failed.
\n
"
);
return
NULL
;
return
NULL
;
}
phb
->
local_number
=
((
reg_struct
.
address
>>
12
)
&
0xf
)
-
0x8
;
if
(
addr_size_words
==
1
)
{
reg_struct
.
address
=
((
struct
reg_property32
*
)
ui_ptr
)
->
address
;
reg_struct
.
size
=
((
struct
reg_property32
*
)
ui_ptr
)
->
size
;
}
else
{
reg_struct
=
*
((
struct
reg_property64
*
)
ui_ptr
);
}
/***************************************************************
if
(
strstr
(
model
,
"Python"
))
{
* Trying to build a known just gets the code in trouble.
phb_type
=
phb_type_python
;
***************************************************************/
}
else
if
(
strstr
(
model
,
"Speedwagon"
))
{
phb_type
=
phb_type_speedwagon
;
}
else
if
(
strstr
(
model
,
"Winnipeg"
))
{
phb_type
=
phb_type_winnipeg
;
}
else
{
}
else
{
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
Unknown PHB Type!
\n
"
);
printk
(
KERN_ERR
"alloc_phb: unknown PHB %s
\n
"
,
model
);
printk
(
"PCI: Unknown Phb Type!
\n
"
);
phb_type
=
phb_type_unknown
;
return
NULL
;
}
}
phb
=
pci_alloc_pci_controller
(
phb_type
);
if
(
phb
==
NULL
)
return
NULL
;
if
(
phb_type
==
phb_type_python
)
python_countermeasures
(
reg_struct
.
address
);
bus_range
=
(
int
*
)
get_property
(
dev
,
"bus-range"
,
&
len
);
bus_range
=
(
int
*
)
get_property
(
dev
,
"bus-range"
,
&
len
);
if
(
bus_range
==
NULL
||
len
<
2
*
sizeof
(
int
))
{
if
(
bus_range
==
NULL
||
len
<
2
*
sizeof
(
int
))
{
PPCDBG
(
PPCDBG_PHBINIT
,
"Can't get bus-range for %s
\n
"
,
dev
->
full_name
);
kfree
(
phb
);
kfree
(
phb
);
return
(
NULL
)
;
return
NULL
;
}
}
/***************************************************************
* Finished with the initialization
***************************************************************/
phb
->
first_busno
=
bus_range
[
0
];
phb
->
first_busno
=
bus_range
[
0
];
phb
->
last_busno
=
bus_range
[
1
];
phb
->
last_busno
=
bus_range
[
1
];
...
@@ -489,7 +361,8 @@ alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
...
@@ -489,7 +361,8 @@ alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
}
}
if
(
len
<
2
*
sizeof
(
int
))
if
(
len
<
2
*
sizeof
(
int
))
phb
->
buid
=
(
unsigned
long
)
buid_vals
[
0
];
// Support for new OF that only has 1 integer for buid.
// Support for new OF that only has 1 integer for buid.
phb
->
buid
=
(
unsigned
long
)
buid_vals
[
0
];
else
else
phb
->
buid
=
(((
unsigned
long
)
buid_vals
[
0
])
<<
32UL
)
|
phb
->
buid
=
(((
unsigned
long
)
buid_vals
[
0
])
<<
32UL
)
|
(((
unsigned
long
)
buid_vals
[
1
])
&
0xffffffff
);
(((
unsigned
long
)
buid_vals
[
1
])
&
0xffffffff
);
...
@@ -499,11 +372,57 @@ alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
...
@@ -499,11 +372,57 @@ alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
}
}
/* Dump PHB information for Debug */
/* Dump PHB information for Debug */
PPCDBGCALL
(
PPCDBG_PHBINIT
,
dumpPci_Controller
(
phb
)
);
PPCDBGCALL
(
PPCDBG_PHBINIT
,
dumpPci_Controller
(
phb
)
);
return
phb
;
return
phb
;
}
}
unsigned
long
__init
find_and_init_phbs
(
void
)
{
struct
device_node
*
node
;
struct
pci_controller
*
phb
;
unsigned
int
root_size_cells
=
0
;
unsigned
int
index
;
unsigned
int
*
opprop
;
struct
device_node
*
root
=
find_path_device
(
"/"
);
read_pci_config
=
rtas_token
(
"read-pci-config"
);
write_pci_config
=
rtas_token
(
"write-pci-config"
);
ibm_read_pci_config
=
rtas_token
(
"ibm,read-pci-config"
);
ibm_write_pci_config
=
rtas_token
(
"ibm,write-pci-config"
);
if
(
naca
->
interrupt_controller
==
IC_OPEN_PIC
)
{
opprop
=
(
unsigned
int
*
)
get_property
(
root
,
"platform-open-pic"
,
NULL
);
}
root_size_cells
=
prom_n_size_cells
(
root
);
index
=
0
;
for
(
node
=
root
->
child
;
node
!=
NULL
;
node
=
node
->
sibling
)
{
if
(
node
->
type
==
NULL
||
strcmp
(
node
->
type
,
"pci"
)
!=
0
)
continue
;
phb
=
alloc_phb
(
node
,
root_size_cells
);
if
(
!
phb
)
continue
;
pci_process_bridge_OF_ranges
(
phb
,
node
,
index
==
0
);
if
(
naca
->
interrupt_controller
==
IC_OPEN_PIC
)
{
int
addr
=
root_size_cells
*
(
index
+
2
)
-
1
;
openpic_setup_ISU
(
index
,
opprop
[
addr
]);
}
index
++
;
}
pci_devs_phb_init
();
return
0
;
}
void
void
fixup_resources
(
struct
pci_dev
*
dev
)
fixup_resources
(
struct
pci_dev
*
dev
)
{
{
...
...
arch/ppc64/kernel/pci.c
View file @
0f5646a6
...
@@ -363,16 +363,33 @@ pcibios_assign_resources(void)
...
@@ -363,16 +363,33 @@ pcibios_assign_resources(void)
* Allocate pci_controller(phb) initialized common variables.
* Allocate pci_controller(phb) initialized common variables.
*/
*/
struct
pci_controller
*
__init
struct
pci_controller
*
__init
pci_alloc_pci_controller
(
char
*
model
,
enum
phb_types
controller_type
)
pci_alloc_pci_controller
(
enum
phb_types
controller_type
)
{
{
struct
pci_controller
*
hose
;
struct
pci_controller
*
hose
;
PPCDBG
(
PPCDBG_PHBINIT
,
"PCI: Allocate pci_controller for %s
\n
"
,
model
);
char
*
model
;
hose
=
(
struct
pci_controller
*
)
alloc_bootmem
(
sizeof
(
struct
pci_controller
));
hose
=
(
struct
pci_controller
*
)
alloc_bootmem
(
sizeof
(
struct
pci_controller
));
if
(
hose
==
NULL
)
{
if
(
hose
==
NULL
)
{
printk
(
KERN_ERR
"PCI: Allocate pci_controller failed.
\n
"
);
printk
(
KERN_ERR
"PCI: Allocate pci_controller failed.
\n
"
);
return
NULL
;
return
NULL
;
}
}
memset
(
hose
,
0
,
sizeof
(
struct
pci_controller
));
memset
(
hose
,
0
,
sizeof
(
struct
pci_controller
));
switch
(
controller_type
)
{
case
phb_type_python
:
model
=
"PHB PY"
;
break
;
case
phb_type_speedwagon
:
model
=
"PHB SW"
;
break
;
case
phb_type_winnipeg
:
model
=
"PHB WP"
;
break
;
default:
model
=
"PHB UK"
;
break
;
}
if
(
strlen
(
model
)
<
8
)
if
(
strlen
(
model
)
<
8
)
strcpy
(
hose
->
what
,
model
);
strcpy
(
hose
->
what
,
model
);
else
else
...
...
arch/ppc64/kernel/pci.h
View file @
0f5646a6
...
@@ -14,7 +14,7 @@
...
@@ -14,7 +14,7 @@
extern
unsigned
long
isa_io_base
;
extern
unsigned
long
isa_io_base
;
extern
struct
pci_controller
*
pci_alloc_pci_controller
(
char
*
model
,
enum
phb_types
controller_type
);
extern
struct
pci_controller
*
pci_alloc_pci_controller
(
enum
phb_types
controller_type
);
extern
struct
pci_controller
*
pci_find_hose_for_OF_device
(
struct
device_node
*
node
);
extern
struct
pci_controller
*
pci_find_hose_for_OF_device
(
struct
device_node
*
node
);
extern
struct
pci_controller
*
hose_head
;
extern
struct
pci_controller
*
hose_head
;
...
...
include/asm-ppc64/pci-bridge.h
View file @
0f5646a6
...
@@ -20,7 +20,8 @@ enum phb_types {
...
@@ -20,7 +20,8 @@ enum phb_types {
phb_type_unknown
=
0x0
,
phb_type_unknown
=
0x0
,
phb_type_hypervisor
=
0x1
,
phb_type_hypervisor
=
0x1
,
phb_type_python
=
0x10
,
phb_type_python
=
0x10
,
phb_type_speedwagon
=
0x11
phb_type_speedwagon
=
0x11
,
phb_type_winnipeg
=
0x12
};
};
/*
/*
...
...
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