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
2f766895
Commit
2f766895
authored
Sep 04, 2002
by
Paul Mackerras
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PPC32: Convert the various PCI config space accessors to the new API.
parent
bd039e05
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
337 additions
and
357 deletions
+337
-357
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
-0
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 @
2f766895
...
@@ -60,7 +60,7 @@ obj-$(CONFIG_ADIR) += i8259.o indirect_pci.o pci_auto.o \
...
@@ -60,7 +60,7 @@ obj-$(CONFIG_ADIR) += i8259.o indirect_pci.o pci_auto.o \
todc_time.o
todc_time.o
obj-$(CONFIG_EV64260)
+=
gt64260_common.o gt64260_pic.o
\
obj-$(CONFIG_EV64260)
+=
gt64260_common.o gt64260_pic.o
\
indirect_pci.o todc_time.o pci_auto.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
\
obj-$(CONFIG_K2)
+=
i8259.o indirect_pci.o todc_time.o
\
pci_auto.o
pci_auto.o
obj-$(CONFIG_LOPEC)
+=
mpc10x_common.o indirect_pci.o pci_auto.o
\
obj-$(CONFIG_LOPEC)
+=
mpc10x_common.o indirect_pci.o pci_auto.o
\
...
...
arch/ppc/kernel/indirect_pci.c
View file @
2f766895
...
@@ -24,48 +24,88 @@
...
@@ -24,48 +24,88 @@
#include <asm/pci-bridge.h>
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
#include <asm/machdep.h>
#define cfg_read(val, addr, type, op) *val = op((type)(addr))
static
int
#define cfg_write(val, addr, type, op) op((type *)(addr), (val))
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) \
out_be32
(
hose
->
cfg_addr
,
static int \
((
offset
&
0xfc
)
<<
24
)
|
(
devfn
<<
16
)
indirect_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
|
((
bus
->
number
-
hose
->
bus_offset
)
<<
8
)
|
0x80
);
{ \
/*
struct pci_controller *hose = dev->sysdata; \
* Note: the caller has already checked that offset is
\
* suitably aligned and that len is 1, 2 or 4.
if (ppc_md.pci_exclude_device) \
*/
if (ppc_md.pci_exclude_device(dev->bus->number, dev->devfn)) \
cfg_data
=
hose
->
cfg_data
+
(
offset
&
3
);
return PCIBIOS_DEVICE_NOT_FOUND; \
switch
(
len
)
{
\
case
1
:
out_be32(hose->cfg_addr, \
*
val
=
in_8
((
u8
*
)
cfg_data
);
((offset & 0xfc) << 24) | (dev->devfn << 16) \
break
;
| ((dev->bus->number - hose->bus_offset) << 8) | 0x80); \
case
2
:
cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \
*
val
=
in_le16
((
u16
*
)
cfg_data
);
return PCIBIOS_SUCCESSFUL; \
break
;
default:
*
val
=
in_le32
((
u32
*
)
cfg_data
);
break
;
}
return
PCIBIOS_SUCCESSFUL
;
}
}
INDIRECT_PCI_OP
(
read
,
byte
,
u8
*
,
in_8
,
3
)
static
int
INDIRECT_PCI_OP
(
read
,
word
,
u16
*
,
in_le16
,
2
)
indirect_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
INDIRECT_PCI_OP
(
read
,
dword
,
u32
*
,
in_le32
,
0
)
int
len
,
u32
val
)
INDIRECT_PCI_OP
(
write
,
byte
,
u8
,
out_8
,
3
)
{
INDIRECT_PCI_OP
(
write
,
word
,
u16
,
out_le16
,
2
)
struct
pci_controller
*
hose
=
bus
->
sysdata
;
INDIRECT_PCI_OP
(
write
,
dword
,
u32
,
out_le32
,
0
)
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
=
static
struct
pci_ops
indirect_pci_ops
=
{
{
indirect_read_config_byte
,
indirect_read_config
,
indirect_read_config_word
,
indirect_write_config
indirect_read_config_dword
,
indirect_write_config_byte
,
indirect_write_config_word
,
indirect_write_config_dword
};
};
void
__init
void
__init
setup_indirect_pci
(
struct
pci_controller
*
hose
,
u32
cfg_addr
,
u32
cfg_data
)
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
->
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 @
2f766895
...
@@ -816,19 +816,19 @@ scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn)
...
@@ -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
* Scans the OF tree for a device node matching a PCI device
*/
*/
struct
device_node
*
struct
device_node
*
pci_
device_to_OF_node
(
struct
pci_dev
*
dev
)
pci_
busdev_to_OF_node
(
struct
pci_bus
*
bus
,
int
devfn
)
{
{
struct
pci_controller
*
hose
;
struct
pci_controller
*
hose
;
struct
device_node
*
node
;
struct
device_node
*
node
;
int
bus
;
int
bus
nr
;
if
(
!
have_of
)
if
(
!
have_of
)
return
NULL
;
return
NULL
;
/* Lookup the hose */
/* Lookup the hose */
bus
=
dev
->
bus
->
number
;
bus
nr
=
bus
->
number
;
hose
=
pci_bus_to_hose
(
bus
);
hose
=
pci_bus_to_hose
(
bus
nr
);
if
(
!
hose
)
if
(
!
hose
)
return
NULL
;
return
NULL
;
...
@@ -839,12 +839,18 @@ pci_device_to_OF_node(struct pci_dev *dev)
...
@@ -839,12 +839,18 @@ pci_device_to_OF_node(struct pci_dev *dev)
/* Fixup bus number according to what OF think it is. */
/* Fixup bus number according to what OF think it is. */
if
(
pci_to_OF_bus_map
)
if
(
pci_to_OF_bus_map
)
bus
=
pci_to_OF_bus_map
[
bus
];
bus
nr
=
pci_to_OF_bus_map
[
busnr
];
if
(
bus
==
0xff
)
if
(
bus
nr
==
0xff
)
return
NULL
;
return
NULL
;
/* Now, lookup childs of the hose */
/* 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
/* 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) \
...
@@ -1512,31 +1518,33 @@ null_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
return PCIBIOS_DEVICE_NOT_FOUND; \
return PCIBIOS_DEVICE_NOT_FOUND; \
}
}
NULL_PCI_OP
(
read
,
byte
,
u8
*
)
static
int
NULL_PCI_OP
(
read
,
word
,
u16
*
)
null_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
NULL_PCI_OP
(
read
,
dword
,
u32
*
)
int
len
,
u32
*
val
)
NULL_PCI_OP
(
write
,
byte
,
u8
)
{
NULL_PCI_OP
(
write
,
word
,
u16
)
return
PCIBIOS_DEVICE_NOT_FOUND
;
NULL_PCI_OP
(
write
,
dword
,
u32
)
}
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
=
static
struct
pci_ops
null_pci_ops
=
{
{
null_read_config_byte
,
null_read_config
,
null_read_config_word
,
null_write_config
null_read_config_dword
,
null_write_config_byte
,
null_write_config_word
,
null_write_config_dword
};
};
/*
/*
* These functions are used early on before PCI scanning is done
* These functions are used early on before PCI scanning is done
* and all of the pci_dev and pci_bus structures have been created.
* and all of the pci_dev and pci_bus structures have been created.
*/
*/
static
struct
pci_
dev
*
static
struct
pci_
bus
*
fake_pci_
dev
(
struct
pci_controller
*
hose
,
int
busnr
,
int
devfn
)
fake_pci_
bus
(
struct
pci_controller
*
hose
,
int
busnr
)
{
{
static
struct
pci_dev
dev
;
static
struct
pci_bus
bus
;
static
struct
pci_bus
bus
;
if
(
hose
==
0
)
{
if
(
hose
==
0
)
{
...
@@ -1544,20 +1552,17 @@ fake_pci_dev(struct pci_controller *hose, int busnr, int devfn)
...
@@ -1544,20 +1552,17 @@ fake_pci_dev(struct pci_controller *hose, int busnr, int devfn)
if
(
hose
==
0
)
if
(
hose
==
0
)
printk
(
KERN_ERR
"Can't find hose for PCI bus %d!
\n
"
,
busnr
);
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
.
number
=
busnr
;
bus
.
ops
=
hose
?
hose
->
ops
:
&
null_pci_ops
;
bus
.
ops
=
hose
?
hose
->
ops
:
&
null_pci_ops
;
return
&
dev
;
return
&
bus
;
}
}
#define EARLY_PCI_OP(rw, size, type) \
#define EARLY_PCI_OP(rw, size, type) \
int early_##rw##_config_##size(struct pci_controller *hose, int bus, \
int early_##rw##_config_##size(struct pci_controller *hose, int bus, \
int devfn, int offset, type value) \
int devfn, int offset, type value) \
{ \
{ \
return pci_
##rw##_config_##size(fake_pci_dev(hose, bus, devfn
), \
return pci_
bus_##rw##_config_##size(fake_pci_bus(hose, bus
), \
offset, value);
\
devfn, offset, value);
\
}
}
EARLY_PCI_OP
(
read
,
byte
,
u8
*
)
EARLY_PCI_OP
(
read
,
byte
,
u8
*
)
...
...
arch/ppc/kernel/ppc_ksyms.c
View file @
2f766895
...
@@ -250,6 +250,7 @@ EXPORT_SYMBOL(find_all_nodes);
...
@@ -250,6 +250,7 @@ EXPORT_SYMBOL(find_all_nodes);
EXPORT_SYMBOL
(
get_property
);
EXPORT_SYMBOL
(
get_property
);
EXPORT_SYMBOL
(
request_OF_resource
);
EXPORT_SYMBOL
(
request_OF_resource
);
EXPORT_SYMBOL
(
release_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_to_OF_node
);
EXPORT_SYMBOL
(
pci_device_from_OF_node
);
EXPORT_SYMBOL
(
pci_device_from_OF_node
);
EXPORT_SYMBOL
(
pmac_newworld
);
EXPORT_SYMBOL
(
pmac_newworld
);
...
...
arch/ppc/platforms/apus_pci.c
View file @
2f766895
...
@@ -61,49 +61,72 @@ void *pci_io_base(unsigned int bus)
...
@@ -61,49 +61,72 @@ void *pci_io_base(unsigned int bus)
}
}
#define cfg_read(val, addr, type, op) *val = op((type)(addr))
int
#define cfg_write(val, addr, type, op) op((val), (type *)(addr)); DEFW()
apus_pcibios_read_config
(
struct
pci_bus
*
bus
,
int
devfn
,
int
offset
,
#define cfg_read_bad *val = ~0;
int
len
,
u32
*
val
)
#define cfg_write_bad ;
{
#define cfg_read_val(val) *val
int
fnno
=
FNNO
(
devfn
);
#define cfg_write_val(val) val
int
devno
=
DEVNO
(
devfn
);
volatile
unsigned
char
*
cfg_data
;
#define APUS_PCI_OP(rw, size, type, op, mask) \
int \
if
(
bus
->
number
>
0
||
devno
!=
1
)
{
apus_pcibios_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
*
val
=
~
0
;
{ \
return
PCIBIOS_DEVICE_NOT_FOUND
;
int fnno = FNNO(dev->devfn); \
}
int devno = DEVNO(dev->devfn); \
/* base address + function offset + offset ^ endianness conversion */
\
/* XXX the fnno<<5 bit seems wacky -- paulus */
if (dev->bus->number > 0 || devno != 1) { \
cfg_data
=
apus_hose
->
cfg_data
+
(
fnno
<<
5
)
+
(
offset
^
(
len
-
1
));
cfg_##rw##_bad; \
switch
(
len
)
{
return PCIBIOS_DEVICE_NOT_FOUND; \
case
1
:
} \
*
val
=
readb
(
cfg_data
);
/* base address + function offset + offset ^ endianness conversion */
\
break
;
cfg_##rw(val, apus_hose->cfg_data + (fnno<<5) + (offset ^ mask), \
case
2
:
type, op); \
*
val
=
readw
(
cfg_data
);
\
break
;
DPRINTK(#op " b: 0x%x, d: 0x%x, f: 0x%x, o: 0x%x, v: 0x%x\n", \
default:
dev->bus->number, dev->devfn>>3, dev->devfn&7, \
*
val
=
readl
(
cfg_data
);
offset, cfg_##rw##_val(val)); \
break
;
return PCIBIOS_SUCCESSFUL; \
}
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
)
int
APUS_PCI_OP
(
read
,
word
,
u16
*
,
readw
,
2
)
apus_pcibios_write_config
(
struct
pci_bus
*
bus
,
int
devfn
,
int
offset
,
APUS_PCI_OP
(
read
,
dword
,
u32
*
,
readl
,
0
)
int
len
,
u32
*
val
)
APUS_PCI_OP
(
write
,
byte
,
u8
,
writeb
,
3
)
{
APUS_PCI_OP
(
write
,
word
,
u16
,
writew
,
2
)
int
fnno
=
FNNO
(
devfn
);
APUS_PCI_OP
(
write
,
dword
,
u32
,
writel
,
0
)
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
=
{
static
struct
pci_ops
apus_pci_ops
=
{
apus_pcibios_read_config_byte
,
apus_pcibios_read_config
,
apus_pcibios_read_config_word
,
apus_pcibios_write_config
apus_pcibios_read_config_dword
,
apus_pcibios_write_config_byte
,
apus_pcibios_write_config_word
,
apus_pcibios_write_config_dword
};
};
static
struct
resource
pci_mem
=
{
"B/CVisionPPC PCI mem"
,
CVPPC_FB_APERTURE_ONE
,
CVPPC_PCI_CONFIG
,
IORESOURCE_MEM
};
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 @
2f766895
...
@@ -28,136 +28,108 @@
...
@@ -28,136 +28,108 @@
/* LongTrail */
/* LongTrail */
unsigned
long
gg2_pci_config_base
;
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
* The VLSI Golden Gate II has only 512K of PCI configuration space, so we
* limit the bus number to 3 bits
* limit the bus number to 3 bits
*/
*/
#define cfg_read(val, addr, type, op) *val = op((type)(addr))
int
__chrp
gg2_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
off
,
#define cfg_write(val, addr, type, op) op((type *)(addr), (val))
int
len
,
u32
*
val
)
{
#define cfg_read_bad(val, size) *val = bad_##size;
volatile
unsigned
char
*
cfg_data
;
#define cfg_write_bad(val, size)
struct
pci_controller
*
hose
=
bus
->
sysdata
;
#define bad_byte 0xff
#define bad_word 0xffff
#define bad_dword 0xffffffffU
#define GG2_PCI_OP(rw, size, type, op) \
if
(
bus
->
number
>
7
)
int __chrp gg2_##rw##_config_##size(struct pci_dev *dev, int off, type val) \
return
PCIBIOS_DEVICE_NOT_FOUND
;
{ \
/*
if (dev->bus->number > 7) { \
* Note: the caller has already checked that off is
cfg_##rw##_bad(val, size) \
* suitably aligned and that len is 1, 2 or 4.
return PCIBIOS_DEVICE_NOT_FOUND; \
*/
} \
cfg_data
=
hose
->
cfg_data
+
((
bus
->
number
<<
16
)
|
(
devfn
<<
8
)
|
off
);
cfg_##rw(val, pci_config_addr(dev, off), type, op); \
switch
(
len
)
{
return PCIBIOS_SUCCESSFUL; \
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
)
int
__chrp
gg2_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
off
,
GG2_PCI_OP
(
read
,
word
,
u16
*
,
in_le16
)
int
len
,
u32
val
)
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
=
{
{
gg2_read_config_byte
,
volatile
unsigned
char
*
cfg_data
;
gg2_read_config_word
,
struct
pci_controller
*
hose
=
bus
->
sysdata
;
gg2_read_config_dword
,
gg2_write_config_byte
,
gg2_write_config_word
,
gg2_write_config_dword
};
/*
if
(
bus
->
number
>
7
)
* Access functions for PCI config space on IBM "python" host bridges.
return
PCIBIOS_DEVICE_NOT_FOUND
;
/*
* Note: the caller has already checked that off is
* suitably aligned and that len is 1, 2 or 4.
*/
*/
#define PYTHON_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \
cfg_data
=
hose
->
cfg_data
+
((
bus
->
number
<<
16
)
|
(
devfn
<<
8
)
|
off
);
| (((o) & ~3) << 24))
switch
(
len
)
{
case
1
:
#define PYTHON_PCI_OP(rw, size, type, op, mask) \
out_8
((
u8
*
)
cfg_data
,
val
);
int __chrp \
break
;
python_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
case
2
:
{ \
out_le16
((
u16
*
)
cfg_data
,
val
);
struct pci_controller *hose = dev->sysdata; \
break
;
\
default:
out_be32(hose->cfg_addr, \
out_le32
((
u32
*
)
cfg_data
,
val
);
PYTHON_CFA(dev->bus->number, dev->devfn, offset)); \
break
;
cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \
}
return PCIBIOS_SUCCESSFUL;
\
return
PCIBIOS_SUCCESSFUL
;
}
}
PYTHON_PCI_OP
(
read
,
byte
,
u8
*
,
in_8
,
3
)
static
struct
pci_ops
gg2_pci_ops
=
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
=
{
{
python_read_config_byte
,
gg2_read_config
,
python_read_config_word
,
gg2_write_config
python_read_config_dword
,
python_write_config_byte
,
python_write_config_word
,
python_write_config_dword
};
};
/*
/*
* Access functions for PCI config space using RTAS calls.
* Access functions for PCI config space using RTAS calls.
*/
*/
#define RTAS_PCI_READ_OP(size, type, nbytes) \
int
__chrp
int __chrp \
rtas_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
rtas_read_config_##size(struct pci_dev *dev, int offset, type val) \
int
len
,
u32
*
val
)
{
\
{
unsigned long addr = (offset & 0xff) | ((dev
->devfn & 0xff) << 8) \
unsigned
long
addr
=
(
offset
&
0xff
)
|
((
dev
fn
&
0xff
)
<<
8
)
| ((
dev->bus->number & 0xff) << 16); \
|
((
bus
->
number
&
0xff
)
<<
16
);
unsigned long ret = ~0UL; \
unsigned
long
ret
=
~
0UL
;
int rval;
\
int
rval
;
\
rval = call_rtas("read-pci-config", 2, 2, &ret, addr,
nbytes); \
rval
=
call_rtas
(
"read-pci-config"
,
2
,
2
,
&
ret
,
addr
,
len
);
*val = ret;
\
*
val
=
ret
;
return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
\
return
rval
?
PCIBIOS_DEVICE_NOT_FOUND
:
PCIBIOS_SUCCESSFUL
;
}
}
#define RTAS_PCI_WRITE_OP(size, type, nbytes) \
int
__chrp
int __chrp \
rtas_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
rtas_write_config_##size(struct pci_dev *dev, int offset, type val) \
int
len
,
u32
val
)
{ \
{
unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \
unsigned
long
addr
=
(
offset
&
0xff
)
|
((
devfn
&
0xff
)
<<
8
)
| ((dev->bus->number & 0xff) << 16); \
|
((
bus
->
number
&
0xff
)
<<
16
);
int rval; \
int
rval
;
\
rval = call_rtas("write-pci-config", 3, 1, NULL, \
addr, nbytes, (ulong)val); \
return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; \
}
RTAS_PCI_READ_OP
(
byte
,
u8
*
,
1
)
rval
=
call_rtas
(
"write-pci-config"
,
3
,
1
,
NULL
,
addr
,
len
,
val
);
RTAS_PCI_READ_OP
(
word
,
u16
*
,
2
)
return
rval
?
PCIBIOS_DEVICE_NOT_FOUND
:
PCIBIOS_SUCCESSFUL
;
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
)
static
struct
pci_ops
rtas_pci_ops
=
static
struct
pci_ops
rtas_pci_ops
=
{
{
rtas_read_config_byte
,
rtas_read_config
,
rtas_read_config_word
,
rtas_write_config
rtas_read_config_dword
,
rtas_write_config_byte
,
rtas_write_config_word
,
rtas_write_config_dword
};
};
volatile
struct
Hydra
*
Hydra
=
NULL
;
int
__init
int
__init
hydra_init
(
void
)
hydra_init
(
void
)
{
{
...
@@ -203,12 +175,9 @@ static void __init
...
@@ -203,12 +175,9 @@ static void __init
setup_python
(
struct
pci_controller
*
hose
,
struct
device_node
*
dev
)
setup_python
(
struct
pci_controller
*
hose
,
struct
device_node
*
dev
)
{
{
u32
*
reg
,
val
;
u32
*
reg
,
val
;
volatile
unsigned
char
*
cfg
;
unsigned
long
addr
=
dev
->
addrs
[
0
].
address
;
hose
->
ops
=
&
python_pci_ops
;
setup_indirect_pci
(
hose
,
addr
+
0xf8000
,
addr
+
0xf8010
);
cfg
=
ioremap
(
dev
->
addrs
[
0
].
address
+
0xf8000
,
0x20
);
hose
->
cfg_addr
=
(
volatile
unsigned
int
*
)
cfg
;
hose
->
cfg_data
=
cfg
+
0x10
;
/* Clear the magic go-slow bit */
/* Clear the magic go-slow bit */
reg
=
(
u32
*
)
ioremap
(
dev
->
addrs
[
0
].
address
+
0xf6000
,
0x40
);
reg
=
(
u32
*
)
ioremap
(
dev
->
addrs
[
0
].
address
+
0xf6000
,
0x40
);
...
@@ -288,8 +257,9 @@ chrp_find_bridges(void)
...
@@ -288,8 +257,9 @@ chrp_find_bridges(void)
setup_grackle
(
hose
);
setup_grackle
(
hose
);
}
else
if
(
is_longtrail
)
{
}
else
if
(
is_longtrail
)
{
hose
->
ops
=
&
gg2_pci_ops
;
hose
->
ops
=
&
gg2_pci_ops
;
gg2_pci_config_base
=
(
unsigned
long
)
hose
->
cfg_data
=
(
unsigned
char
*
)
ioremap
(
GG2_PCI_CONFIG_BASE
,
0x80000
);
ioremap
(
GG2_PCI_CONFIG_BASE
,
0x80000
);
gg2_pci_config_base
=
(
unsigned
long
)
hose
->
cfg_data
;
}
else
{
}
else
{
printk
(
"No methods for %s (model %s), using RTAS
\n
"
,
printk
(
"No methods for %s (model %s), using RTAS
\n
"
,
dev
->
full_name
,
model
);
dev
->
full_name
,
model
);
...
...
arch/ppc/platforms/gemini_pci.c
View file @
2f766895
...
@@ -13,84 +13,6 @@
...
@@ -13,84 +13,6 @@
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <asm/pci-bridge.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
)
void
__init
gemini_pcibios_fixup
(
void
)
{
{
int
i
;
int
i
;
...
@@ -118,5 +40,5 @@ void __init gemini_find_bridges(void)
...
@@ -118,5 +40,5 @@ void __init gemini_find_bridges(void)
hose
=
pcibios_alloc_controller
();
hose
=
pcibios_alloc_controller
();
if
(
!
hose
)
if
(
!
hose
)
return
;
return
;
hose
->
ops
=
&
gemini_pci_ops
;
setup_indirect_pci
(
hose
,
0xfec00000
,
0xfee00000
)
;
}
}
arch/ppc/platforms/pmac_pci.c
View file @
2f766895
...
@@ -137,101 +137,118 @@ macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset)
...
@@ -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 ! */
/* Uninorth will return garbage if we don't read back the value ! */
do
{
do
{
out_le32
(
hose
->
cfg_addr
,
caddr
);
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
;
offset
&=
has_uninorth
?
0x07
:
0x03
;
return
(
unsigned
int
)(
hose
->
cfg_data
)
+
(
unsigned
int
)
offset
;
return
(
unsigned
int
)(
hose
->
cfg_data
)
+
(
unsigned
int
)
offset
;
}
}
#define cfg_read(val, addr, type, op, op2) \
static
int
__pmac
*val = op((type)(addr))
macrisc_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
#define cfg_write(val, addr, type, op, op2) \
int
len
,
u32
*
val
)
op((type *)(addr), (val)); (void) op2((type *)(addr))
{
struct
pci_controller
*
hose
=
bus
->
sysdata
;
#define cfg_read_bad(val, size) *val = bad_##size
;
unsigned
int
addr
;
#define cfg_write_bad(val, size)
addr
=
macrisc_cfg_access
(
hose
,
bus
->
number
,
devfn
,
offset
);
#define bad_byte 0xff
if
(
!
addr
)
#define bad_word 0xffff
return
PCIBIOS_DEVICE_NOT_FOUND
;
#define bad_dword 0xffffffffU
/*
* Note: the caller has already checked that offset is
#define MACRISC_PCI_OP(rw, size, type, op, op2) \
* suitably aligned and that len is 1, 2 or 4.
static int __pmac \
*/
macrisc_##rw##_config_##size(struct pci_dev *dev, int off, type val) \
switch
(
len
)
{
{ \
case
1
:
struct pci_controller *hose = dev->sysdata; \
*
val
=
in_8
((
u8
*
)
addr
);
unsigned int addr; \
break
;
\
case
2
:
addr = macrisc_cfg_access(hose, dev->bus->number, dev->devfn, off); \
*
val
=
in_le16
((
u16
*
)
addr
);
if (!addr) { \
break
;
cfg_##rw##_bad(val, size) \
default:
return PCIBIOS_DEVICE_NOT_FOUND; \
*
val
=
in_le32
((
u32
*
)
addr
);
} \
break
;
cfg_##rw(val, addr, type, op, op2); \
}
return PCIBIOS_SUCCESSFUL;
\
return
PCIBIOS_SUCCESSFUL
;
}
}
MACRISC_PCI_OP
(
read
,
byte
,
u8
*
,
in_8
,
x
)
static
int
__pmac
MACRISC_PCI_OP
(
read
,
word
,
u16
*
,
in_le16
,
x
)
macrisc_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
MACRISC_PCI_OP
(
read
,
dword
,
u32
*
,
in_le32
,
x
)
int
len
,
u32
val
)
MACRISC_PCI_OP
(
write
,
byte
,
u8
,
out_8
,
in_8
)
{
MACRISC_PCI_OP
(
write
,
word
,
u16
,
out_le16
,
in_le16
)
struct
pci_controller
*
hose
=
bus
->
sysdata
;
MACRISC_PCI_OP
(
write
,
dword
,
u32
,
out_le32
,
in_le32
)
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
=
static
struct
pci_ops
macrisc_pci_ops
=
{
{
macrisc_read_config_byte
,
macrisc_read_config
,
macrisc_read_config_word
,
macrisc_write_config
macrisc_read_config_dword
,
macrisc_write_config_byte
,
macrisc_write_config_word
,
macrisc_write_config_dword
};
};
/*
/*
* Verifiy that a specific (bus, dev_fn) exists on chaos
* Verifiy that a specific (bus, dev_fn) exists on chaos
*/
*/
static
int
__pmac
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
;
return
PCIBIOS_DEVICE_NOT_FOUND
;
if
((
dev
->
vendor
==
0x106b
)
&&
(
dev
->
device
==
3
)
&&
(
offset
>=
0x10
)
&&
if
(
/*(dev->vendor == 0x106b) && (dev->device == 3) &&*/
(
offset
>=
0x10
)
(
offset
!=
0x14
)
&&
(
offset
!=
0x18
)
&&
(
offset
<=
0x24
))
{
&&
(
offset
!=
0x14
)
&&
(
offset
!=
0x18
)
&&
(
offset
<=
0x24
))
{
return
PCIBIOS_BAD_REGISTER_NUMBER
;
return
PCIBIOS_BAD_REGISTER_NUMBER
;
}
}
return
PCIBIOS_SUCCESSFUL
;
return
PCIBIOS_SUCCESSFUL
;
}
}
#define CHAOS_PCI_OP(rw, size, type) \
static
int
__pmac
static int __pmac \
chaos_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
chaos_##rw##_config_##size(struct pci_dev *dev, int off, type val) \
int
len
,
u32
*
val
)
{ \
{
int result = chaos_validate_dev(dev, off); \
int
result
=
chaos_validate_dev
(
bus
,
devfn
,
offset
);
if(result == PCIBIOS_BAD_REGISTER_NUMBER) { \
if
(
result
==
PCIBIOS_BAD_REGISTER_NUMBER
)
cfg_##rw##_bad(val, size) \
*
val
=
~
0U
;
return PCIBIOS_BAD_REGISTER_NUMBER; \
if
(
result
!=
PCIBIOS_SUCCESSFUL
)
} \
return
result
;
if(result == PCIBIOS_SUCCESSFUL) \
return
macrisc_read_config
(
bus
,
devfn
,
offset
,
len
,
val
);
return macrisc_##rw##_config_##size(dev, off, val); \
return result; \
}
}
CHAOS_PCI_OP
(
read
,
byte
,
u8
*
)
static
int
__pmac
CHAOS_PCI_OP
(
read
,
word
,
u16
*
)
chaos_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
offset
,
CHAOS_PCI_OP
(
read
,
dword
,
u32
*
)
int
len
,
u32
val
)
CHAOS_PCI_OP
(
write
,
byte
,
u8
)
{
CHAOS_PCI_OP
(
write
,
word
,
u16
)
int
result
=
chaos_validate_dev
(
bus
,
devfn
,
offset
);
CHAOS_PCI_OP
(
write
,
dword
,
u32
)
if
(
result
!=
PCIBIOS_SUCCESSFUL
)
return
result
;
return
macrisc_write_config
(
bus
,
devfn
,
offset
,
len
,
val
);
}
static
struct
pci_ops
chaos_pci_ops
=
static
struct
pci_ops
chaos_pci_ops
=
{
{
chaos_read_config_byte
,
chaos_read_config
,
chaos_read_config_word
,
chaos_write_config
chaos_read_config_dword
,
chaos_write_config_byte
,
chaos_write_config_word
,
chaos_write_config_dword
};
};
...
@@ -489,7 +506,8 @@ pcibios_fixup_OF_interrupts(void)
...
@@ -489,7 +506,8 @@ pcibios_fixup_OF_interrupts(void)
* obtained from the OF device-tree
* obtained from the OF device-tree
*/
*/
pci_for_each_dev
(
dev
)
{
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 */
/* this is the node, see if it has interrupts */
if
(
node
&&
node
->
n_intrs
>
0
)
if
(
node
&&
node
->
n_intrs
>
0
)
dev
->
irq
=
node
->
intrs
[
0
].
line
;
dev
->
irq
=
node
->
intrs
[
0
].
line
;
...
...
include/asm-ppc/pci-bridge.h
View file @
2f766895
...
@@ -31,6 +31,7 @@ extern void pci_init_resource(struct resource *res, unsigned long start,
...
@@ -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
,
extern
int
pci_device_from_OF_node
(
struct
device_node
*
node
,
u8
*
bus
,
u8
*
devfn
);
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
struct
device_node
*
pci_device_to_OF_node
(
struct
pci_dev
*
);
extern
void
pci_create_OF_bus_map
(
void
);
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