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
535b1d68
Commit
535b1d68
authored
Sep 05, 2002
by
Paul Mackerras
Browse files
Options
Browse Files
Download
Plain Diff
Merge au1.ibm.com:/fuego/paulus/kernel/linux-2.5
into au1.ibm.com:/fuego/paulus/kernel/for-linus-ppc
parents
97460db9
d9836d1d
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
341 additions
and
365 deletions
+341
-365
arch/ppc/kernel/Makefile
arch/ppc/kernel/Makefile
+1
-1
arch/ppc/kernel/indirect_pci.c
arch/ppc/kernel/indirect_pci.c
+72
-32
arch/ppc/kernel/pci.c
arch/ppc/kernel/pci.c
+34
-29
arch/ppc/kernel/ppc_ksyms.c
arch/ppc/kernel/ppc_ksyms.c
+1
-4
arch/ppc/kernel/process.c
arch/ppc/kernel/process.c
+3
-3
arch/ppc/kernel/smp.c
arch/ppc/kernel/smp.c
+1
-1
arch/ppc/platforms/apus_pci.c
arch/ppc/platforms/apus_pci.c
+61
-38
arch/ppc/platforms/chrp_pci.c
arch/ppc/platforms/chrp_pci.c
+80
-110
arch/ppc/platforms/gemini_pci.c
arch/ppc/platforms/gemini_pci.c
+1
-79
arch/ppc/platforms/pmac_pci.c
arch/ppc/platforms/pmac_pci.c
+86
-68
include/asm-ppc/pci-bridge.h
include/asm-ppc/pci-bridge.h
+1
-0
No files found.
arch/ppc/kernel/Makefile
View file @
535b1d68
...
...
@@ -60,7 +60,7 @@ obj-$(CONFIG_ADIR) += i8259.o indirect_pci.o pci_auto.o \
todc_time.o
obj-$(CONFIG_EV64260)
+=
gt64260_common.o gt64260_pic.o
\
indirect_pci.o todc_time.o pci_auto.o
obj-$(CONFIG_GEMINI)
+=
open_pic.o i8259.o
obj-$(CONFIG_GEMINI)
+=
open_pic.o i8259.o
indirect_pci.o
obj-$(CONFIG_K2)
+=
i8259.o indirect_pci.o todc_time.o
\
pci_auto.o
obj-$(CONFIG_LOPEC)
+=
mpc10x_common.o indirect_pci.o pci_auto.o
\
...
...
arch/ppc/kernel/indirect_pci.c
View file @
535b1d68
...
...
@@ -24,48 +24,88 @@
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
#define cfg_read(val, addr, type, op) *val = op((type)(addr))
#define cfg_write(val, addr, type, op) op((type *)(addr), (val))
static
int
indirect_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
int
len
,
u32
*
val
)
{
struct
pci_controller
*
hose
=
bus
->
sysdata
;
volatile
unsigned
char
*
cfg_data
;
if
(
ppc_md
.
pci_exclude_device
)
if
(
ppc_md
.
pci_exclude_device
(
bus
->
number
,
devfn
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
#define INDIRECT_PCI_OP(rw, size, type, op, mask) \
static int \
indirect_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
{ \
struct pci_controller *hose = dev->sysdata; \
\
if (ppc_md.pci_exclude_device) \
if (ppc_md.pci_exclude_device(dev->bus->number, dev->devfn)) \
return PCIBIOS_DEVICE_NOT_FOUND; \
\
out_be32(hose->cfg_addr, \
((offset & 0xfc) << 24) | (dev->devfn << 16) \
| ((dev->bus->number - hose->bus_offset) << 8) | 0x80); \
cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \
return PCIBIOS_SUCCESSFUL; \
out_be32
(
hose
->
cfg_addr
,
((
offset
&
0xfc
)
<<
24
)
|
(
devfn
<<
16
)
|
((
bus
->
number
-
hose
->
bus_offset
)
<<
8
)
|
0x80
);
/*
* Note: the caller has already checked that offset is
* suitably aligned and that len is 1, 2 or 4.
*/
cfg_data
=
hose
->
cfg_data
+
(
offset
&
3
);
switch
(
len
)
{
case
1
:
*
val
=
in_8
((
u8
*
)
cfg_data
);
break
;
case
2
:
*
val
=
in_le16
((
u16
*
)
cfg_data
);
break
;
default:
*
val
=
in_le32
((
u32
*
)
cfg_data
);
break
;
}
return
PCIBIOS_SUCCESSFUL
;
}
INDIRECT_PCI_OP
(
read
,
byte
,
u8
*
,
in_8
,
3
)
INDIRECT_PCI_OP
(
read
,
word
,
u16
*
,
in_le16
,
2
)
INDIRECT_PCI_OP
(
read
,
dword
,
u32
*
,
in_le32
,
0
)
INDIRECT_PCI_OP
(
write
,
byte
,
u8
,
out_8
,
3
)
INDIRECT_PCI_OP
(
write
,
word
,
u16
,
out_le16
,
2
)
INDIRECT_PCI_OP
(
write
,
dword
,
u32
,
out_le32
,
0
)
static
int
indirect_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
int
len
,
u32
val
)
{
struct
pci_controller
*
hose
=
bus
->
sysdata
;
volatile
unsigned
char
*
cfg_data
;
if
(
ppc_md
.
pci_exclude_device
)
if
(
ppc_md
.
pci_exclude_device
(
bus
->
number
,
devfn
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
out_be32
(
hose
->
cfg_addr
,
((
offset
&
0xfc
)
<<
24
)
|
(
devfn
<<
16
)
|
((
bus
->
number
-
hose
->
bus_offset
)
<<
8
)
|
0x80
);
/*
* Note: the caller has already checked that offset is
* suitably aligned and that len is 1, 2 or 4.
*/
cfg_data
=
hose
->
cfg_data
+
(
offset
&
3
);
switch
(
len
)
{
case
1
:
out_8
((
u8
*
)
cfg_data
,
val
);
break
;
case
2
:
out_le16
((
u16
*
)
cfg_data
,
val
);
break
;
default:
out_le32
((
u32
*
)
cfg_data
,
val
);
break
;
}
return
PCIBIOS_SUCCESSFUL
;
}
static
struct
pci_ops
indirect_pci_ops
=
{
indirect_read_config_byte
,
indirect_read_config_word
,
indirect_read_config_dword
,
indirect_write_config_byte
,
indirect_write_config_word
,
indirect_write_config_dword
indirect_read_config
,
indirect_write_config
};
void
__init
setup_indirect_pci
(
struct
pci_controller
*
hose
,
u32
cfg_addr
,
u32
cfg_data
)
{
unsigned
long
base
=
cfg_addr
&
PAGE_MASK
;
char
*
mbase
;
mbase
=
ioremap
(
base
,
PAGE_SIZE
);
hose
->
cfg_addr
=
(
unsigned
int
*
)(
mbase
+
(
cfg_addr
&
~
PAGE_MASK
));
if
((
cfg_data
&
PAGE_MASK
)
!=
base
)
mbase
=
ioremap
(
cfg_data
&
PAGE_MASK
,
PAGE_SIZE
);
hose
->
cfg_data
=
(
unsigned
char
*
)(
mbase
+
(
cfg_data
&
~
PAGE_MASK
));
hose
->
ops
=
&
indirect_pci_ops
;
hose
->
cfg_addr
=
(
unsigned
int
*
)
ioremap
(
cfg_addr
,
4
);
hose
->
cfg_data
=
(
unsigned
char
*
)
ioremap
(
cfg_data
,
4
);
}
arch/ppc/kernel/pci.c
View file @
535b1d68
...
...
@@ -816,19 +816,19 @@ scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn)
/*
* Scans the OF tree for a device node matching a PCI device
*/
struct
device_node
*
pci_
device_to_OF_node
(
struct
pci_dev
*
dev
)
struct
device_node
*
pci_
busdev_to_OF_node
(
struct
pci_bus
*
bus
,
int
devfn
)
{
struct
pci_controller
*
hose
;
struct
device_node
*
node
;
int
bus
;
int
bus
nr
;
if
(
!
have_of
)
return
NULL
;
/* Lookup the hose */
bus
=
dev
->
bus
->
number
;
hose
=
pci_bus_to_hose
(
bus
);
bus
nr
=
bus
->
number
;
hose
=
pci_bus_to_hose
(
bus
nr
);
if
(
!
hose
)
return
NULL
;
...
...
@@ -839,12 +839,18 @@ pci_device_to_OF_node(struct pci_dev *dev)
/* Fixup bus number according to what OF think it is. */
if
(
pci_to_OF_bus_map
)
bus
=
pci_to_OF_bus_map
[
bus
];
if
(
bus
==
0xff
)
bus
nr
=
pci_to_OF_bus_map
[
busnr
];
if
(
bus
nr
==
0xff
)
return
NULL
;
/* Now, lookup childs of the hose */
return
scan_OF_childs_for_device
(
node
->
child
,
bus
,
dev
->
devfn
);
return
scan_OF_childs_for_device
(
node
->
child
,
busnr
,
devfn
);
}
struct
device_node
*
pci_device_to_OF_node
(
struct
pci_dev
*
dev
)
{
return
pci_busdev_to_OF_node
(
dev
->
bus
,
dev
->
devfn
);
}
/* This routine is meant to be used early during boot, when the
...
...
@@ -1512,31 +1518,33 @@ null_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
return PCIBIOS_DEVICE_NOT_FOUND; \
}
NULL_PCI_OP
(
read
,
byte
,
u8
*
)
NULL_PCI_OP
(
read
,
word
,
u16
*
)
NULL_PCI_OP
(
read
,
dword
,
u32
*
)
NULL_PCI_OP
(
write
,
byte
,
u8
)
NULL_PCI_OP
(
write
,
word
,
u16
)
NULL_PCI_OP
(
write
,
dword
,
u32
)
static
int
null_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
int
len
,
u32
*
val
)
{
return
PCIBIOS_DEVICE_NOT_FOUND
;
}
static
int
null_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
int
len
,
u32
val
)
{
return
PCIBIOS_DEVICE_NOT_FOUND
;
}
static
struct
pci_ops
null_pci_ops
=
{
null_read_config_byte
,
null_read_config_word
,
null_read_config_dword
,
null_write_config_byte
,
null_write_config_word
,
null_write_config_dword
null_read_config
,
null_write_config
};
/*
* These functions are used early on before PCI scanning is done
* and all of the pci_dev and pci_bus structures have been created.
*/
static
struct
pci_
dev
*
fake_pci_
dev
(
struct
pci_controller
*
hose
,
int
busnr
,
int
devfn
)
static
struct
pci_
bus
*
fake_pci_
bus
(
struct
pci_controller
*
hose
,
int
busnr
)
{
static
struct
pci_dev
dev
;
static
struct
pci_bus
bus
;
if
(
hose
==
0
)
{
...
...
@@ -1544,20 +1552,17 @@ fake_pci_dev(struct pci_controller *hose, int busnr, int devfn)
if
(
hose
==
0
)
printk
(
KERN_ERR
"Can't find hose for PCI bus %d!
\n
"
,
busnr
);
}
dev
.
bus
=
&
bus
;
dev
.
sysdata
=
hose
;
dev
.
devfn
=
devfn
;
bus
.
number
=
busnr
;
bus
.
ops
=
hose
?
hose
->
ops
:
&
null_pci_ops
;
return
&
dev
;
return
&
bus
;
}
#define EARLY_PCI_OP(rw, size, type) \
int early_##rw##_config_##size(struct pci_controller *hose, int bus, \
int devfn, int offset, type value) \
{ \
return pci_
##rw##_config_##size(fake_pci_dev(hose, bus, devfn
), \
offset, value);
\
return pci_
bus_##rw##_config_##size(fake_pci_bus(hose, bus
), \
devfn, offset, value);
\
}
EARLY_PCI_OP
(
read
,
byte
,
u8
*
)
...
...
arch/ppc/kernel/ppc_ksyms.c
View file @
535b1d68
...
...
@@ -42,10 +42,6 @@
#include <asm/nvram.h>
#include <asm/mmu_context.h>
#include <asm/backlight.h>
#ifdef CONFIG_SMP
#include <asm/smplock.h>
#include <asm/smp.h>
#endif
/* CONFIG_SMP */
#include <asm/time.h>
#include <asm/cputable.h>
#include <asm/btext.h>
...
...
@@ -250,6 +246,7 @@ EXPORT_SYMBOL(find_all_nodes);
EXPORT_SYMBOL
(
get_property
);
EXPORT_SYMBOL
(
request_OF_resource
);
EXPORT_SYMBOL
(
release_OF_resource
);
EXPORT_SYMBOL
(
pci_busdev_to_OF_node
);
EXPORT_SYMBOL
(
pci_device_to_OF_node
);
EXPORT_SYMBOL
(
pci_device_from_OF_node
);
EXPORT_SYMBOL
(
pmac_newworld
);
...
...
arch/ppc/kernel/process.c
View file @
535b1d68
...
...
@@ -445,7 +445,7 @@ int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6,
{
struct
task_struct
*
p
;
CHECK_FULL_REGS
(
regs
);
p
=
do_fork
(
p1
&
~
CLONE_IDLETASK
,
regs
->
gpr
[
1
],
regs
,
0
);
p
=
do_fork
(
p1
&
~
CLONE_IDLETASK
,
p2
,
regs
,
0
,
(
int
*
)
p3
);
return
IS_ERR
(
p
)
?
PTR_ERR
(
p
)
:
p
->
pid
;
}
...
...
@@ -454,7 +454,7 @@ int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
{
struct
task_struct
*
p
;
CHECK_FULL_REGS
(
regs
);
p
=
do_fork
(
SIGCHLD
,
regs
->
gpr
[
1
],
regs
,
0
);
p
=
do_fork
(
SIGCHLD
,
regs
->
gpr
[
1
],
regs
,
0
,
NULL
);
return
IS_ERR
(
p
)
?
PTR_ERR
(
p
)
:
p
->
pid
;
}
...
...
@@ -463,7 +463,7 @@ int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,
{
struct
task_struct
*
p
;
CHECK_FULL_REGS
(
regs
);
p
=
do_fork
(
CLONE_VFORK
|
CLONE_VM
|
SIGCHLD
,
regs
->
gpr
[
1
],
regs
,
0
);
p
=
do_fork
(
CLONE_VFORK
|
CLONE_VM
|
SIGCHLD
,
regs
->
gpr
[
1
],
regs
,
0
,
NULL
);
return
IS_ERR
(
p
)
?
PTR_ERR
(
p
)
:
p
->
pid
;
}
...
...
arch/ppc/kernel/smp.c
View file @
535b1d68
...
...
@@ -392,7 +392,7 @@ int __cpu_up(unsigned int cpu)
/* create a process for the processor */
/* only regs.msr is actually used, and 0 is OK for it */
memset
(
&
regs
,
0
,
sizeof
(
struct
pt_regs
));
p
=
do_fork
(
CLONE_VM
|
CLONE_IDLETASK
,
0
,
&
regs
,
0
);
p
=
do_fork
(
CLONE_VM
|
CLONE_IDLETASK
,
0
,
&
regs
,
0
,
NULL
);
if
(
IS_ERR
(
p
))
panic
(
"failed fork for CPU %u: %li"
,
cpu
,
PTR_ERR
(
p
));
...
...
arch/ppc/platforms/apus_pci.c
View file @
535b1d68
...
...
@@ -61,49 +61,72 @@ void *pci_io_base(unsigned int bus)
}
#define cfg_read(val, addr, type, op) *val = op((type)(addr))
#define cfg_write(val, addr, type, op) op((val), (type *)(addr)); DEFW()
#define cfg_read_bad *val = ~0;
#define cfg_write_bad ;
#define cfg_read_val(val) *val
#define cfg_write_val(val) val
#define APUS_PCI_OP(rw, size, type, op, mask) \
int \
apus_pcibios_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
{ \
int fnno = FNNO(dev->devfn); \
int devno = DEVNO(dev->devfn); \
\
if (dev->bus->number > 0 || devno != 1) { \
cfg_##rw##_bad; \
return PCIBIOS_DEVICE_NOT_FOUND; \
} \
/* base address + function offset + offset ^ endianness conversion */
\
cfg_##rw(val, apus_hose->cfg_data + (fnno<<5) + (offset ^ mask), \
type, op); \
\
DPRINTK(#op " b: 0x%x, d: 0x%x, f: 0x%x, o: 0x%x, v: 0x%x\n", \
dev->bus->number, dev->devfn>>3, dev->devfn&7, \
offset, cfg_##rw##_val(val)); \
return PCIBIOS_SUCCESSFUL; \
int
apus_pcibios_read_config
(
struct
pci_bus
*
bus
,
int
devfn
,
int
offset
,
int
len
,
u32
*
val
)
{
int
fnno
=
FNNO
(
devfn
);
int
devno
=
DEVNO
(
devfn
);
volatile
unsigned
char
*
cfg_data
;
if
(
bus
->
number
>
0
||
devno
!=
1
)
{
*
val
=
~
0
;
return
PCIBIOS_DEVICE_NOT_FOUND
;
}
/* base address + function offset + offset ^ endianness conversion */
/* XXX the fnno<<5 bit seems wacky -- paulus */
cfg_data
=
apus_hose
->
cfg_data
+
(
fnno
<<
5
)
+
(
offset
^
(
len
-
1
));
switch
(
len
)
{
case
1
:
*
val
=
readb
(
cfg_data
);
break
;
case
2
:
*
val
=
readw
(
cfg_data
);
break
;
default:
*
val
=
readl
(
cfg_data
);
break
;
}
DPRINTK
(
"read b: 0x%x, d: 0x%x, f: 0x%x, o: 0x%x, l: %d, v: 0x%x
\n
"
,
bus
->
number
,
devfn
>>
3
,
devfn
&
7
,
offset
,
len
,
*
val
);
return
PCIBIOS_SUCCESSFUL
;
}
APUS_PCI_OP
(
read
,
byte
,
u8
*
,
readb
,
3
)
APUS_PCI_OP
(
read
,
word
,
u16
*
,
readw
,
2
)
APUS_PCI_OP
(
read
,
dword
,
u32
*
,
readl
,
0
)
APUS_PCI_OP
(
write
,
byte
,
u8
,
writeb
,
3
)
APUS_PCI_OP
(
write
,
word
,
u16
,
writew
,
2
)
APUS_PCI_OP
(
write
,
dword
,
u32
,
writel
,
0
)
int
apus_pcibios_write_config
(
struct
pci_bus
*
bus
,
int
devfn
,
int
offset
,
int
len
,
u32
*
val
)
{
int
fnno
=
FNNO
(
devfn
);
int
devno
=
DEVNO
(
devfn
);
volatile
unsigned
char
*
cfg_data
;
if
(
bus
->
number
>
0
||
devno
!=
1
)
{
return
PCIBIOS_DEVICE_NOT_FOUND
;
}
/* base address + function offset + offset ^ endianness conversion */
/* XXX the fnno<<5 bit seems wacky -- paulus */
cfg_data
=
apus_hose
->
cfg_data
+
(
fnno
<<
5
)
+
(
offset
^
(
len
-
1
));
switch
(
len
)
{
case
1
:
writeb
(
val
,
cfg_data
);
DEFW
();
break
;
case
2
:
writew
(
val
,
cfg_data
);
DEFW
();
break
;
default:
writel
(
val
,
cfg_data
);
DEFW
();
break
;
}
DPRINTK
(
"write b: 0x%x, d: 0x%x, f: 0x%x, o: 0x%x, l: %d, v: 0x%x
\n
"
,
bus
->
number
,
devfn
>>
3
,
devfn
&
7
,
offset
,
len
,
val
);
return
PCIBIOS_SUCCESSFUL
;
}
static
struct
pci_ops
apus_pci_ops
=
{
apus_pcibios_read_config_byte
,
apus_pcibios_read_config_word
,
apus_pcibios_read_config_dword
,
apus_pcibios_write_config_byte
,
apus_pcibios_write_config_word
,
apus_pcibios_write_config_dword
apus_pcibios_read_config
,
apus_pcibios_write_config
};
static
struct
resource
pci_mem
=
{
"B/CVisionPPC PCI mem"
,
CVPPC_FB_APERTURE_ONE
,
CVPPC_PCI_CONFIG
,
IORESOURCE_MEM
};
...
...
arch/ppc/platforms/chrp_pci.c
View file @
535b1d68
...
...
@@ -28,136 +28,108 @@
/* LongTrail */
unsigned
long
gg2_pci_config_base
;
#define pci_config_addr(dev, offset) \
(gg2_pci_config_base | ((dev->bus->number)<<16) | ((dev->devfn)<<8) | (offset))
volatile
struct
Hydra
*
Hydra
=
NULL
;
/*
* The VLSI Golden Gate II has only 512K of PCI configuration space, so we
* limit the bus number to 3 bits
*/
#define cfg_read(val, addr, type, op) *val = op((type)(addr))
#define cfg_write(val, addr, type, op) op((type *)(addr), (val))
#define cfg_read_bad(val, size) *val = bad_##size;
#define cfg_write_bad(val, size)
#define bad_byte 0xff
#define bad_word 0xffff
#define bad_dword 0xffffffffU
int
__chrp
gg2_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
off
,
int
len
,
u32
*
val
)
{
volatile
unsigned
char
*
cfg_data
;
struct
pci_controller
*
hose
=
bus
->
sysdata
;
#define GG2_PCI_OP(rw, size, type, op) \
int __chrp gg2_##rw##_config_##size(struct pci_dev *dev, int off, type val) \
{ \
if (dev->bus->number > 7) { \
cfg_##rw##_bad(val, size) \
return PCIBIOS_DEVICE_NOT_FOUND; \
} \
cfg_##rw(val, pci_config_addr(dev, off), type, op); \
return PCIBIOS_SUCCESSFUL; \
if
(
bus
->
number
>
7
)
return
PCIBIOS_DEVICE_NOT_FOUND
;
/*
* Note: the caller has already checked that off is
* suitably aligned and that len is 1, 2 or 4.
*/
cfg_data
=
hose
->
cfg_data
+
((
bus
->
number
<<
16
)
|
(
devfn
<<
8
)
|
off
);
switch
(
len
)
{
case
1
:
*
val
=
in_8
((
u8
*
)
cfg_data
);
break
;
case
2
:
*
val
=
in_le16
((
u16
*
)
cfg_data
);
break
;
default:
*
val
=
in_le32
((
u32
*
)
cfg_data
);
break
;
}
return
PCIBIOS_SUCCESSFUL
;
}
GG2_PCI_OP
(
read
,
byte
,
u8
*
,
in_8
)
GG2_PCI_OP
(
read
,
word
,
u16
*
,
in_le16
)
GG2_PCI_OP
(
read
,
dword
,
u32
*
,
in_le32
)
GG2_PCI_OP
(
write
,
byte
,
u8
,
out_8
)
GG2_PCI_OP
(
write
,
word
,
u16
,
out_le16
)
GG2_PCI_OP
(
write
,
dword
,
u32
,
out_le32
)
static
struct
pci_ops
gg2_pci_ops
=
int
__chrp
gg2_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
off
,
int
len
,
u32
val
)
{
gg2_read_config_byte
,
gg2_read_config_word
,
gg2_read_config_dword
,
gg2_write_config_byte
,
gg2_write_config_word
,
gg2_write_config_dword
};
/*
* Access functions for PCI config space on IBM "python" host bridges.
*/
#define PYTHON_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \
| (((o) & ~3) << 24))
volatile
unsigned
char
*
cfg_data
;
struct
pci_controller
*
hose
=
bus
->
sysdata
;
#define PYTHON_PCI_OP(rw, size, type, op, mask) \
int __chrp \
python_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
{ \
struct pci_controller *hose = dev->sysdata; \
\
out_be32(hose->cfg_addr, \
PYTHON_CFA(dev->bus->number, dev->devfn, offset)); \
cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \
return PCIBIOS_SUCCESSFUL; \
if
(
bus
->
number
>
7
)
return
PCIBIOS_DEVICE_NOT_FOUND
;
/*
* Note: the caller has already checked that off is
* suitably aligned and that len is 1, 2 or 4.
*/
cfg_data
=
hose
->
cfg_data
+
((
bus
->
number
<<
16
)
|
(
devfn
<<
8
)
|
off
);
switch
(
len
)
{
case
1
:
out_8
((
u8
*
)
cfg_data
,
val
);
break
;
case
2
:
out_le16
((
u16
*
)
cfg_data
,
val
);
break
;
default:
out_le32
((
u32
*
)
cfg_data
,
val
);
break
;
}
return
PCIBIOS_SUCCESSFUL
;
}
PYTHON_PCI_OP
(
read
,
byte
,
u8
*
,
in_8
,
3
)
PYTHON_PCI_OP
(
read
,
word
,
u16
*
,
in_le16
,
2
)
PYTHON_PCI_OP
(
read
,
dword
,
u32
*
,
in_le32
,
0
)
PYTHON_PCI_OP
(
write
,
byte
,
u8
,
out_8
,
3
)
PYTHON_PCI_OP
(
write
,
word
,
u16
,
out_le16
,
2
)
PYTHON_PCI_OP
(
write
,
dword
,
u32
,
out_le32
,
0
)
static
struct
pci_ops
python_pci_ops
=
static
struct
pci_ops
gg2_pci_ops
=
{
python_read_config_byte
,
python_read_config_word
,
python_read_config_dword
,
python_write_config_byte
,
python_write_config_word
,
python_write_config_dword
gg2_read_config
,
gg2_write_config
};
/*
* Access functions for PCI config space using RTAS calls.
*/
#define RTAS_PCI_READ_OP(size, type, nbytes) \
int __chrp \
rtas_read_config_##size(struct pci_dev *dev, int offset, type val) \
{
\
unsigned long addr = (offset & 0xff) | ((dev
->devfn & 0xff) << 8) \
| ((
dev->bus->number & 0xff) << 16); \
unsigned long ret = ~0UL; \
int rval;
\
\
rval = call_rtas("read-pci-config", 2, 2, &ret, addr,
nbytes); \
*val = ret;
\
return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
\
int
__chrp
rtas_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
int
len
,
u32
*
val
)
{
unsigned
long
addr
=
(
offset
&
0xff
)
|
((
dev
fn
&
0xff
)
<<
8
)
|
((
bus
->
number
&
0xff
)
<<
16
);
unsigned
long
ret
=
~
0UL
;
int
rval
;
rval
=
call_rtas
(
"read-pci-config"
,
2
,
2
,
&
ret
,
addr
,
len
);
*
val
=
ret
;
return
rval
?
PCIBIOS_DEVICE_NOT_FOUND
:
PCIBIOS_SUCCESSFUL
;
}
#define RTAS_PCI_WRITE_OP(size, type, nbytes) \
int __chrp \
rtas_write_config_##size(struct pci_dev *dev, int offset, type val) \
{ \
unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \
| ((dev->bus->number & 0xff) << 16); \
int rval; \
\
rval = call_rtas("write-pci-config", 3, 1, NULL, \
addr, nbytes, (ulong)val); \
return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; \
}
int
__chrp
rtas_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
int
len
,
u32
val
)
{
unsigned
long
addr
=
(
offset
&
0xff
)
|
((
devfn
&
0xff
)
<<
8
)
|
((
bus
->
number
&
0xff
)
<<
16
);
int
rval
;
RTAS_PCI_READ_OP
(
byte
,
u8
*
,
1
)
RTAS_PCI_READ_OP
(
word
,
u16
*
,
2
)
RTAS_PCI_READ_OP
(
dword
,
u32
*
,
4
)
RTAS_PCI_WRITE_OP
(
byte
,
u8
,
1
)
RTAS_PCI_WRITE_OP
(
word
,
u16
,
2
)
RTAS_PCI_WRITE_OP
(
dword
,
u32
,
4
)
rval
=
call_rtas
(
"write-pci-config"
,
3
,
1
,
NULL
,
addr
,
len
,
val
);
return
rval
?
PCIBIOS_DEVICE_NOT_FOUND
:
PCIBIOS_SUCCESSFUL
;
}
static
struct
pci_ops
rtas_pci_ops
=
{
rtas_read_config_byte
,
rtas_read_config_word
,
rtas_read_config_dword
,
rtas_write_config_byte
,
rtas_write_config_word
,
rtas_write_config_dword
rtas_read_config
,
rtas_write_config
};
volatile
struct
Hydra
*
Hydra
=
NULL
;
int
__init
hydra_init
(
void
)
{
...
...
@@ -203,12 +175,9 @@ static void __init
setup_python
(
struct
pci_controller
*
hose
,
struct
device_node
*
dev
)
{
u32
*
reg
,
val
;
volatile
unsigned
char
*
cfg
;
unsigned
long
addr
=
dev
->
addrs
[
0
].
address
;
hose
->
ops
=
&
python_pci_ops
;
cfg
=
ioremap
(
dev
->
addrs
[
0
].
address
+
0xf8000
,
0x20
);
hose
->
cfg_addr
=
(
volatile
unsigned
int
*
)
cfg
;
hose
->
cfg_data
=
cfg
+
0x10
;
setup_indirect_pci
(
hose
,
addr
+
0xf8000
,
addr
+
0xf8010
);
/* Clear the magic go-slow bit */
reg
=
(
u32
*
)
ioremap
(
dev
->
addrs
[
0
].
address
+
0xf6000
,
0x40
);
...
...
@@ -288,8 +257,9 @@ chrp_find_bridges(void)
setup_grackle
(
hose
);
}
else
if
(
is_longtrail
)
{
hose
->
ops
=
&
gg2_pci_ops
;
gg2_pci_config_base
=
(
unsigned
long
)
hose
->
cfg_data
=
(
unsigned
char
*
)
ioremap
(
GG2_PCI_CONFIG_BASE
,
0x80000
);
gg2_pci_config_base
=
(
unsigned
long
)
hose
->
cfg_data
;
}
else
{
printk
(
"No methods for %s (model %s), using RTAS
\n
"
,
dev
->
full_name
,
model
);
...
...
arch/ppc/platforms/gemini_pci.c
View file @
535b1d68
...
...
@@ -13,84 +13,6 @@
#include <asm/uaccess.h>
#include <asm/pci-bridge.h>
#define pci_config_addr(bus,dev,offset) \
(0x80000000 | (bus<<16) | (dev<<8) | offset)
int
gemini_pcibios_read_config_byte
(
struct
pci_dev
*
dev
,
int
offset
,
u8
*
val
)
{
unsigned
long
reg
;
reg
=
grackle_read
(
pci_config_addr
(
dev
->
bus
->
number
,
dev
->
devfn
,
(
offset
&
~
(
0x3
))));
*
val
=
((
reg
>>
((
offset
&
0x3
)
<<
3
))
&
0xff
);
return
PCIBIOS_SUCCESSFUL
;
}
int
gemini_pcibios_read_config_word
(
struct
pci_dev
*
dev
,
int
offset
,
u16
*
val
)
{
unsigned
long
reg
;
reg
=
grackle_read
(
pci_config_addr
(
dev
->
bus
->
number
,
dev
->
devfn
,
(
offset
&
~
(
0x3
))));
*
val
=
((
reg
>>
((
offset
&
0x3
)
<<
3
))
&
0xffff
);
return
PCIBIOS_SUCCESSFUL
;
}
int
gemini_pcibios_read_config_dword
(
struct
pci_dev
*
dev
,
int
offset
,
u32
*
val
)
{
*
val
=
grackle_read
(
pci_config_addr
(
dev
->
bus
->
number
,
dev
->
devfn
,
(
offset
&
~
(
0x3
))));
return
PCIBIOS_SUCCESSFUL
;
}
int
gemini_pcibios_write_config_byte
(
struct
pci_dev
*
dev
,
int
offset
,
u8
val
)
{
unsigned
long
reg
;
int
shifts
=
offset
&
0x3
;
unsigned
int
addr
=
pci_config_addr
(
dev
->
bus
->
number
,
dev
->
devfn
,
(
offset
&
~
(
0x3
)));
reg
=
grackle_read
(
addr
);
reg
=
(
reg
&
~
(
0xff
<<
(
shifts
<<
3
)))
|
(
val
<<
(
shifts
<<
3
));
grackle_write
(
addr
,
reg
);
return
PCIBIOS_SUCCESSFUL
;
}
int
gemini_pcibios_write_config_word
(
struct
pci_dev
*
dev
,
int
offset
,
u16
val
)
{
unsigned
long
reg
;
int
shifts
=
offset
&
0x3
;
unsigned
int
addr
=
pci_config_addr
(
dev
->
bus
->
number
,
dev
->
devfn
,
(
offset
&
~
(
0x3
)));
reg
=
grackle_read
(
addr
);
reg
=
(
reg
&
~
(
0xffff
<<
(
shifts
<<
3
)))
|
(
val
<<
(
shifts
<<
3
));
grackle_write
(
addr
,
reg
);
return
PCIBIOS_SUCCESSFUL
;
}
int
gemini_pcibios_write_config_dword
(
struct
pci_dev
*
dev
,
int
offset
,
u32
val
)
{
grackle_write
(
pci_config_addr
(
dev
->
bus
->
number
,
dev
->
devfn
,
(
offset
&
~
(
0x3
))),
val
);
return
PCIBIOS_SUCCESSFUL
;
}
static
struct
pci_ops
gemini_pci_ops
=
{
gemini_pcibios_read_config_byte
,
gemini_pcibios_read_config_word
,
gemini_pcibios_read_config_dword
,
gemini_pcibios_write_config_byte
,
gemini_pcibios_write_config_word
,
gemini_pcibios_write_config_dword
};
void
__init
gemini_pcibios_fixup
(
void
)
{
int
i
;
...
...
@@ -118,5 +40,5 @@ void __init gemini_find_bridges(void)
hose
=
pcibios_alloc_controller
();
if
(
!
hose
)
return
;
hose
->
ops
=
&
gemini_pci_ops
;
setup_indirect_pci
(
hose
,
0xfec00000
,
0xfee00000
)
;
}
arch/ppc/platforms/pmac_pci.c
View file @
535b1d68
...
...
@@ -137,101 +137,118 @@ macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset)
/* Uninorth will return garbage if we don't read back the value ! */
do
{
out_le32
(
hose
->
cfg_addr
,
caddr
);
}
while
(
in_le32
(
hose
->
cfg_addr
)
!=
caddr
);
}
while
(
in_le32
(
hose
->
cfg_addr
)
!=
caddr
);
offset
&=
has_uninorth
?
0x07
:
0x03
;
return
(
unsigned
int
)(
hose
->
cfg_data
)
+
(
unsigned
int
)
offset
;
}
#define cfg_read(val, addr, type, op, op2) \
*val = op((type)(addr))
#define cfg_write(val, addr, type, op, op2) \
op((type *)(addr), (val)); (void) op2((type *)(addr))
#define cfg_read_bad(val, size) *val = bad_##size
;
#define cfg_write_bad(val, size)
#define bad_byte 0xff
#define bad_word 0xffff
#define bad_dword 0xffffffffU
#define MACRISC_PCI_OP(rw, size, type, op, op2) \
static int __pmac \
macrisc_##rw##_config_##size(struct pci_dev *dev, int off, type val) \
{ \
struct pci_controller *hose = dev->sysdata; \
unsigned int addr; \
\
addr = macrisc_cfg_access(hose, dev->bus->number, dev->devfn, off); \
if (!addr) { \
cfg_##rw##_bad(val, size) \
return PCIBIOS_DEVICE_NOT_FOUND; \
} \
cfg_##rw(val, addr, type, op, op2); \
return PCIBIOS_SUCCESSFUL;
\
static
int
__pmac
macrisc_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
int
len
,
u32
*
val
)
{
struct
pci_controller
*
hose
=
bus
->
sysdata
;
unsigned
int
addr
;
addr
=
macrisc_cfg_access
(
hose
,
bus
->
number
,
devfn
,
offset
);
if
(
!
addr
)
return
PCIBIOS_DEVICE_NOT_FOUND
;
/*
* Note: the caller has already checked that offset is
* suitably aligned and that len is 1, 2 or 4.
*/
switch
(
len
)
{
case
1
:
*
val
=
in_8
((
u8
*
)
addr
);
break
;
case
2
:
*
val
=
in_le16
((
u16
*
)
addr
);
break
;
default:
*
val
=
in_le32
((
u32
*
)
addr
);
break
;
}
return
PCIBIOS_SUCCESSFUL
;
}
MACRISC_PCI_OP
(
read
,
byte
,
u8
*
,
in_8
,
x
)
MACRISC_PCI_OP
(
read
,
word
,
u16
*
,
in_le16
,
x
)
MACRISC_PCI_OP
(
read
,
dword
,
u32
*
,
in_le32
,
x
)
MACRISC_PCI_OP
(
write
,
byte
,
u8
,
out_8
,
in_8
)
MACRISC_PCI_OP
(
write
,
word
,
u16
,
out_le16
,
in_le16
)
MACRISC_PCI_OP
(
write
,
dword
,
u32
,
out_le32
,
in_le32
)
static
int
__pmac
macrisc_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
int
len
,
u32
val
)
{
struct
pci_controller
*
hose
=
bus
->
sysdata
;
unsigned
int
addr
;
addr
=
macrisc_cfg_access
(
hose
,
bus
->
number
,
devfn
,
offset
);
if
(
!
addr
)
return
PCIBIOS_DEVICE_NOT_FOUND
;
/*
* Note: the caller has already checked that offset is
* suitably aligned and that len is 1, 2 or 4.
*/
switch
(
len
)
{
case
1
:
out_8
((
u8
*
)
addr
,
val
);
(
void
)
in_8
((
u8
*
)
addr
);
break
;
case
2
:
out_le16
((
u16
*
)
addr
,
val
);
(
void
)
in_le16
((
u16
*
)
addr
);
break
;
default:
out_le32
((
u32
*
)
addr
,
val
);
(
void
)
in_le32
((
u32
*
)
addr
);
break
;
}
return
PCIBIOS_SUCCESSFUL
;
}
static
struct
pci_ops
macrisc_pci_ops
=
{
macrisc_read_config_byte
,
macrisc_read_config_word
,
macrisc_read_config_dword
,
macrisc_write_config_byte
,
macrisc_write_config_word
,
macrisc_write_config_dword
macrisc_read_config
,
macrisc_write_config
};
/*
* Verifiy that a specific (bus, dev_fn) exists on chaos
*/
static
int
__pmac
chaos_validate_dev
(
struct
pci_
dev
*
dev
,
int
offset
)
chaos_validate_dev
(
struct
pci_
bus
*
bus
,
int
devfn
,
int
offset
)
{
if
(
pci_device_to_OF_node
(
dev
)
==
0
)
if
(
pci_busdev_to_OF_node
(
bus
,
devfn
)
==
0
)
return
PCIBIOS_DEVICE_NOT_FOUND
;
if
((
dev
->
vendor
==
0x106b
)
&&
(
dev
->
device
==
3
)
&&
(
offset
>=
0x10
)
&&
(
offset
!=
0x14
)
&&
(
offset
!=
0x18
)
&&
(
offset
<=
0x24
))
{
if
(
/*(dev->vendor == 0x106b) && (dev->device == 3) &&*/
(
offset
>=
0x10
)
&&
(
offset
!=
0x14
)
&&
(
offset
!=
0x18
)
&&
(
offset
<=
0x24
))
{
return
PCIBIOS_BAD_REGISTER_NUMBER
;
}
return
PCIBIOS_SUCCESSFUL
;
}
#define CHAOS_PCI_OP(rw, size, type) \
static int __pmac \
chaos_##rw##_config_##size(struct pci_dev *dev, int off, type val) \
{ \
int result = chaos_validate_dev(dev, off); \
if(result == PCIBIOS_BAD_REGISTER_NUMBER) { \
cfg_##rw##_bad(val, size) \
return PCIBIOS_BAD_REGISTER_NUMBER; \
} \
if(result == PCIBIOS_SUCCESSFUL) \
return macrisc_##rw##_config_##size(dev, off, val); \
return result; \
static
int
__pmac
chaos_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
int
len
,
u32
*
val
)
{
int
result
=
chaos_validate_dev
(
bus
,
devfn
,
offset
);
if
(
result
==
PCIBIOS_BAD_REGISTER_NUMBER
)
*
val
=
~
0U
;
if
(
result
!=
PCIBIOS_SUCCESSFUL
)
return
result
;
return
macrisc_read_config
(
bus
,
devfn
,
offset
,
len
,
val
);
}
CHAOS_PCI_OP
(
read
,
byte
,
u8
*
)
CHAOS_PCI_OP
(
read
,
word
,
u16
*
)
CHAOS_PCI_OP
(
read
,
dword
,
u32
*
)
CHAOS_PCI_OP
(
write
,
byte
,
u8
)
CHAOS_PCI_OP
(
write
,
word
,
u16
)
CHAOS_PCI_OP
(
write
,
dword
,
u32
)
static
int
__pmac
chaos_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
int
len
,
u32
val
)
{
int
result
=
chaos_validate_dev
(
bus
,
devfn
,
offset
);
if
(
result
!=
PCIBIOS_SUCCESSFUL
)
return
result
;
return
macrisc_write_config
(
bus
,
devfn
,
offset
,
len
,
val
);
}
static
struct
pci_ops
chaos_pci_ops
=
{
chaos_read_config_byte
,
chaos_read_config_word
,
chaos_read_config_dword
,
chaos_write_config_byte
,
chaos_write_config_word
,
chaos_write_config_dword
chaos_read_config
,
chaos_write_config
};
...
...
@@ -489,7 +506,8 @@ pcibios_fixup_OF_interrupts(void)
* obtained from the OF device-tree
*/
pci_for_each_dev
(
dev
)
{
struct
device_node
*
node
=
pci_device_to_OF_node
(
dev
);
struct
device_node
*
node
;
node
=
pci_device_to_OF_node
(
dev
);
/* this is the node, see if it has interrupts */
if
(
node
&&
node
->
n_intrs
>
0
)
dev
->
irq
=
node
->
intrs
[
0
].
line
;
...
...
include/asm-ppc/pci-bridge.h
View file @
535b1d68
...
...
@@ -31,6 +31,7 @@ extern void pci_init_resource(struct resource *res, unsigned long start,
*/
extern
int
pci_device_from_OF_node
(
struct
device_node
*
node
,
u8
*
bus
,
u8
*
devfn
);
extern
struct
device_node
*
pci_busdev_to_OF_node
(
struct
pci_bus
*
,
int
);
extern
struct
device_node
*
pci_device_to_OF_node
(
struct
pci_dev
*
);
extern
void
pci_create_OF_bus_map
(
void
);
...
...
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