diff options
author | Kumar Gala <galak@kernel.crashing.org> | 2007-06-22 01:23:57 -0400 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2007-06-29 02:57:22 -0400 |
commit | 7d52c7b0cd46f42ae2c9df37f1a385d9aaf95842 (patch) | |
tree | 32138e13cbc3eb154db37b202044870419b56655 | |
parent | 0e302a704420afe40808fbd4ba149624c4350f31 (diff) |
[POWERPC] Pass the pci_controller into pci_exclude_device
There are times that we need to know which controller we are on to decide
how to exclude devices properly. We now pass the pci_controller that we
are going to use down to the pci_exclude_device function. This will
greatly simplify being able to exclude the PHBs in multiple controller
setups.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-rw-r--r-- | arch/powerpc/platforms/52xx/mpc52xx_pci.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/82xx/mpc82xx_ads.c | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/83xx/mpc83xx.h | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/83xx/pci.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_ads.c | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_cds.c | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/86xx/mpc86xx.h | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/86xx/pci.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/embedded6xx/holly.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | 3 | ||||
-rw-r--r-- | arch/powerpc/sysdev/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_pcie.c | 4 | ||||
-rw-r--r-- | arch/powerpc/sysdev/indirect_pci.c | 8 | ||||
-rw-r--r-- | arch/powerpc/sysdev/tsi108_pci.c | 6 | ||||
-rw-r--r-- | arch/ppc/syslib/Makefile | 1 | ||||
-rw-r--r-- | arch/ppc/syslib/indirect_pci.c | 134 | ||||
-rw-r--r-- | include/asm-powerpc/machdep.h | 2 |
17 files changed, 165 insertions, 21 deletions
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c index 57ca2feb0799..69a04217c79d 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c | |||
@@ -112,7 +112,7 @@ mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, | |||
112 | u32 value; | 112 | u32 value; |
113 | 113 | ||
114 | if (ppc_md.pci_exclude_device) | 114 | if (ppc_md.pci_exclude_device) |
115 | if (ppc_md.pci_exclude_device(bus->number, devfn)) | 115 | if (ppc_md.pci_exclude_device(hose, bus->number, devfn)) |
116 | return PCIBIOS_DEVICE_NOT_FOUND; | 116 | return PCIBIOS_DEVICE_NOT_FOUND; |
117 | 117 | ||
118 | out_be32(hose->cfg_addr, | 118 | out_be32(hose->cfg_addr, |
@@ -169,7 +169,7 @@ mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, | |||
169 | u32 value, mask; | 169 | u32 value, mask; |
170 | 170 | ||
171 | if (ppc_md.pci_exclude_device) | 171 | if (ppc_md.pci_exclude_device) |
172 | if (ppc_md.pci_exclude_device(bus->number, devfn)) | 172 | if (ppc_md.pci_exclude_device(hose, bus->number, devfn)) |
173 | return PCIBIOS_DEVICE_NOT_FOUND; | 173 | return PCIBIOS_DEVICE_NOT_FOUND; |
174 | 174 | ||
175 | out_be32(hose->cfg_addr, | 175 | out_be32(hose->cfg_addr, |
diff --git a/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/arch/powerpc/platforms/82xx/mpc82xx_ads.c index 04bf57079c1e..715107b6d784 100644 --- a/arch/powerpc/platforms/82xx/mpc82xx_ads.c +++ b/arch/powerpc/platforms/82xx/mpc82xx_ads.c | |||
@@ -507,7 +507,8 @@ void m82xx_pci_init_irq(void) | |||
507 | return; | 507 | return; |
508 | } | 508 | } |
509 | 509 | ||
510 | static int m82xx_pci_exclude_device(u_char bus, u_char devfn) | 510 | static int m82xx_pci_exclude_device(struct pci_controller *hose, |
511 | u_char bus, u_char devfn) | ||
511 | { | 512 | { |
512 | if (bus == 0 && PCI_SLOT(devfn) == 0) | 513 | if (bus == 0 && PCI_SLOT(devfn) == 0) |
513 | return PCIBIOS_DEVICE_NOT_FOUND; | 514 | return PCIBIOS_DEVICE_NOT_FOUND; |
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h index 9bd85f5e9a56..f5c5034a8461 100644 --- a/arch/powerpc/platforms/83xx/mpc83xx.h +++ b/arch/powerpc/platforms/83xx/mpc83xx.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/init.h> | 4 | #include <linux/init.h> |
5 | #include <linux/device.h> | 5 | #include <linux/device.h> |
6 | #include <asm/pci-bridge.h> | ||
6 | 7 | ||
7 | /* System Clock Control Register */ | 8 | /* System Clock Control Register */ |
8 | #define MPC83XX_SCCR_OFFS 0xA08 | 9 | #define MPC83XX_SCCR_OFFS 0xA08 |
@@ -28,7 +29,8 @@ | |||
28 | */ | 29 | */ |
29 | 30 | ||
30 | extern int mpc83xx_add_bridge(struct device_node *dev); | 31 | extern int mpc83xx_add_bridge(struct device_node *dev); |
31 | extern int mpc83xx_exclude_device(u_char bus, u_char devfn); | 32 | extern int mpc83xx_exclude_device(struct pci_controller *hose, |
33 | u_char bus, u_char devfn); | ||
32 | extern void mpc83xx_restart(char *cmd); | 34 | extern void mpc83xx_restart(char *cmd); |
33 | extern long mpc83xx_time_init(void); | 35 | extern long mpc83xx_time_init(void); |
34 | 36 | ||
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c index 34716024ed1a..f92e71f2ed6b 100644 --- a/arch/powerpc/platforms/83xx/pci.c +++ b/arch/powerpc/platforms/83xx/pci.c | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | int mpc83xx_pci2_busno; | 36 | int mpc83xx_pci2_busno; |
37 | 37 | ||
38 | int mpc83xx_exclude_device(u_char bus, u_char devfn) | 38 | int mpc83xx_exclude_device(struct pci_controller *hose, u_char bus, u_char devfn) |
39 | { | 39 | { |
40 | if (bus == 0 && PCI_SLOT(devfn) == 0) | 40 | if (bus == 0 && PCI_SLOT(devfn) == 0) |
41 | return PCIBIOS_DEVICE_NOT_FOUND; | 41 | return PCIBIOS_DEVICE_NOT_FOUND; |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 4100e17f4cb2..1262d1b8a442 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c | |||
@@ -39,7 +39,8 @@ | |||
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #ifdef CONFIG_PCI | 41 | #ifdef CONFIG_PCI |
42 | static int mpc85xx_exclude_device(u_char bus, u_char devfn) | 42 | static int mpc85xx_exclude_device(struct pci_controller *hose, |
43 | u_char bus, u_char devfn) | ||
43 | { | 44 | { |
44 | if (bus == 0 && PCI_SLOT(devfn) == 0) | 45 | if (bus == 0 && PCI_SLOT(devfn) == 0) |
45 | return PCIBIOS_DEVICE_NOT_FOUND; | 46 | return PCIBIOS_DEVICE_NOT_FOUND; |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index fa6b6be6cada..fcea5ab5eb77 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c | |||
@@ -57,7 +57,8 @@ static volatile u8 *cadmus; | |||
57 | 57 | ||
58 | extern int mpc85xx_pci2_busno; | 58 | extern int mpc85xx_pci2_busno; |
59 | 59 | ||
60 | static int mpc85xx_exclude_device(u_char bus, u_char devfn) | 60 | static int mpc85xx_exclude_device(struct pci_controller *hose, |
61 | u_char bus, u_char devfn) | ||
61 | { | 62 | { |
62 | if (bus == 0 && PCI_SLOT(devfn) == 0) | 63 | if (bus == 0 && PCI_SLOT(devfn) == 0) |
63 | return PCIBIOS_DEVICE_NOT_FOUND; | 64 | return PCIBIOS_DEVICE_NOT_FOUND; |
diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h index dc2f6fdc8de4..4c2789de045e 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx.h +++ b/arch/powerpc/platforms/86xx/mpc86xx.h | |||
@@ -17,7 +17,8 @@ | |||
17 | 17 | ||
18 | extern int mpc86xx_add_bridge(struct device_node *dev); | 18 | extern int mpc86xx_add_bridge(struct device_node *dev); |
19 | 19 | ||
20 | extern int mpc86xx_exclude_device(u_char bus, u_char devfn); | 20 | extern int mpc86xx_exclude_device(struct pci_controller *hose, |
21 | u_char bus, u_char devfn); | ||
21 | 22 | ||
22 | extern void setup_indirect_pcie(struct pci_controller *hose, | 23 | extern void setup_indirect_pcie(struct pci_controller *hose, |
23 | u32 cfg_addr, u32 cfg_data); | 24 | u32 cfg_addr, u32 cfg_data); |
diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c index 1e47c145d54d..7659259cc974 100644 --- a/arch/powerpc/platforms/86xx/pci.c +++ b/arch/powerpc/platforms/86xx/pci.c | |||
@@ -140,7 +140,7 @@ mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) | |||
140 | early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps); | 140 | early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps); |
141 | } | 141 | } |
142 | 142 | ||
143 | int mpc86xx_exclude_device(u_char bus, u_char devfn) | 143 | int mpc86xx_exclude_device(struct pci_controller *hose, u_char bus, u_char devfn) |
144 | { | 144 | { |
145 | if (bus == 0 && PCI_SLOT(devfn) == 0) | 145 | if (bus == 0 && PCI_SLOT(devfn) == 0) |
146 | return PCIBIOS_DEVICE_NOT_FOUND; | 146 | return PCIBIOS_DEVICE_NOT_FOUND; |
diff --git a/arch/powerpc/platforms/embedded6xx/holly.c b/arch/powerpc/platforms/embedded6xx/holly.c index 3a0b4a01401c..6292e36dc577 100644 --- a/arch/powerpc/platforms/embedded6xx/holly.c +++ b/arch/powerpc/platforms/embedded6xx/holly.c | |||
@@ -45,7 +45,7 @@ | |||
45 | 45 | ||
46 | #define HOLLY_PCI_CFG_PHYS 0x7c000000 | 46 | #define HOLLY_PCI_CFG_PHYS 0x7c000000 |
47 | 47 | ||
48 | int holly_exclude_device(u_char bus, u_char devfn) | 48 | int holly_exclude_device(struct pci_controller *hose, u_char bus, u_char devfn) |
49 | { | 49 | { |
50 | if (bus == 0 && PCI_SLOT(devfn) == 0) | 50 | if (bus == 0 && PCI_SLOT(devfn) == 0) |
51 | return PCIBIOS_DEVICE_NOT_FOUND; | 51 | return PCIBIOS_DEVICE_NOT_FOUND; |
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index 69eab173ae09..1e3cc69487b5 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | |||
@@ -56,7 +56,8 @@ | |||
56 | 56 | ||
57 | extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); | 57 | extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); |
58 | 58 | ||
59 | int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) | 59 | int mpc7448_hpc2_exclude_device(struct pci_controller *hose, |
60 | u_char bus, u_char devfn) | ||
60 | { | 61 | { |
61 | if (bus == 0 && PCI_SLOT(devfn) == 0) | 62 | if (bus == 0 && PCI_SLOT(devfn) == 0) |
62 | return PCIBIOS_DEVICE_NOT_FOUND; | 63 | return PCIBIOS_DEVICE_NOT_FOUND; |
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 31da3b3dc993..337b56a73247 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile | |||
@@ -5,7 +5,6 @@ endif | |||
5 | mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o | 5 | mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o |
6 | obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y) | 6 | obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y) |
7 | 7 | ||
8 | obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o | ||
9 | obj-$(CONFIG_PPC_MPC106) += grackle.o | 8 | obj-$(CONFIG_PPC_MPC106) += grackle.o |
10 | obj-$(CONFIG_PPC_DCR) += dcr.o | 9 | obj-$(CONFIG_PPC_DCR) += dcr.o |
11 | obj-$(CONFIG_PPC_DCR_NATIVE) += dcr-low.o | 10 | obj-$(CONFIG_PPC_DCR_NATIVE) += dcr-low.o |
@@ -25,6 +24,7 @@ obj-$(CONFIG_PM) += timer.o | |||
25 | endif | 24 | endif |
26 | 25 | ||
27 | ifeq ($(CONFIG_PPC_MERGE),y) | 26 | ifeq ($(CONFIG_PPC_MERGE),y) |
27 | obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o | ||
28 | obj-$(CONFIG_PPC_I8259) += i8259.o | 28 | obj-$(CONFIG_PPC_I8259) += i8259.o |
29 | obj-$(CONFIG_PPC_83xx) += ipic.o | 29 | obj-$(CONFIG_PPC_83xx) += ipic.o |
30 | obj-$(CONFIG_4xx) += uic.o | 30 | obj-$(CONFIG_4xx) += uic.o |
diff --git a/arch/powerpc/sysdev/fsl_pcie.c b/arch/powerpc/sysdev/fsl_pcie.c index 041c07e8b665..6bbd7f84b4e2 100644 --- a/arch/powerpc/sysdev/fsl_pcie.c +++ b/arch/powerpc/sysdev/fsl_pcie.c | |||
@@ -39,7 +39,7 @@ indirect_read_config_pcie(struct pci_bus *bus, unsigned int devfn, int offset, | |||
39 | u32 temp; | 39 | u32 temp; |
40 | 40 | ||
41 | if (ppc_md.pci_exclude_device) | 41 | if (ppc_md.pci_exclude_device) |
42 | if (ppc_md.pci_exclude_device(bus->number, devfn)) | 42 | if (ppc_md.pci_exclude_device(hose, bus->number, devfn)) |
43 | return PCIBIOS_DEVICE_NOT_FOUND; | 43 | return PCIBIOS_DEVICE_NOT_FOUND; |
44 | 44 | ||
45 | /* Possible artifact of CDCpp50937 needs further investigation */ | 45 | /* Possible artifact of CDCpp50937 needs further investigation */ |
@@ -90,7 +90,7 @@ indirect_write_config_pcie(struct pci_bus *bus, unsigned int devfn, int offset, | |||
90 | u32 temp; | 90 | u32 temp; |
91 | 91 | ||
92 | if (ppc_md.pci_exclude_device) | 92 | if (ppc_md.pci_exclude_device) |
93 | if (ppc_md.pci_exclude_device(bus->number, devfn)) | 93 | if (ppc_md.pci_exclude_device(hose, bus->number, devfn)) |
94 | return PCIBIOS_DEVICE_NOT_FOUND; | 94 | return PCIBIOS_DEVICE_NOT_FOUND; |
95 | 95 | ||
96 | /* Possible artifact of CDCpp50937 needs further investigation */ | 96 | /* Possible artifact of CDCpp50937 needs further investigation */ |
diff --git a/arch/powerpc/sysdev/indirect_pci.c b/arch/powerpc/sysdev/indirect_pci.c index e71488469704..3dedf8f5bfb4 100644 --- a/arch/powerpc/sysdev/indirect_pci.c +++ b/arch/powerpc/sysdev/indirect_pci.c | |||
@@ -35,14 +35,14 @@ indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | |||
35 | u8 cfg_type = 0; | 35 | u8 cfg_type = 0; |
36 | 36 | ||
37 | if (ppc_md.pci_exclude_device) | 37 | if (ppc_md.pci_exclude_device) |
38 | if (ppc_md.pci_exclude_device(bus->number, devfn)) | 38 | if (ppc_md.pci_exclude_device(hose, bus->number, devfn)) |
39 | return PCIBIOS_DEVICE_NOT_FOUND; | 39 | return PCIBIOS_DEVICE_NOT_FOUND; |
40 | 40 | ||
41 | if (hose->set_cfg_type) | 41 | if (hose->set_cfg_type) |
42 | if (bus->number != hose->first_busno) | 42 | if (bus->number != hose->first_busno) |
43 | cfg_type = 1; | 43 | cfg_type = 1; |
44 | 44 | ||
45 | PCI_CFG_OUT(hose->cfg_addr, | 45 | PCI_CFG_OUT(hose->cfg_addr, |
46 | (0x80000000 | ((bus->number - hose->bus_offset) << 16) | 46 | (0x80000000 | ((bus->number - hose->bus_offset) << 16) |
47 | | (devfn << 8) | ((offset & 0xfc) | cfg_type))); | 47 | | (devfn << 8) | ((offset & 0xfc) | cfg_type))); |
48 | 48 | ||
@@ -74,14 +74,14 @@ indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset, | |||
74 | u8 cfg_type = 0; | 74 | u8 cfg_type = 0; |
75 | 75 | ||
76 | if (ppc_md.pci_exclude_device) | 76 | if (ppc_md.pci_exclude_device) |
77 | if (ppc_md.pci_exclude_device(bus->number, devfn)) | 77 | if (ppc_md.pci_exclude_device(hose, bus->number, devfn)) |
78 | return PCIBIOS_DEVICE_NOT_FOUND; | 78 | return PCIBIOS_DEVICE_NOT_FOUND; |
79 | 79 | ||
80 | if (hose->set_cfg_type) | 80 | if (hose->set_cfg_type) |
81 | if (bus->number != hose->first_busno) | 81 | if (bus->number != hose->first_busno) |
82 | cfg_type = 1; | 82 | cfg_type = 1; |
83 | 83 | ||
84 | PCI_CFG_OUT(hose->cfg_addr, | 84 | PCI_CFG_OUT(hose->cfg_addr, |
85 | (0x80000000 | ((bus->number - hose->bus_offset) << 16) | 85 | (0x80000000 | ((bus->number - hose->bus_offset) << 16) |
86 | | (devfn << 8) | ((offset & 0xfc) | cfg_type))); | 86 | | (devfn << 8) | ((offset & 0xfc) | cfg_type))); |
87 | 87 | ||
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c index 33177b60c7ed..298e2dd34e89 100644 --- a/arch/powerpc/sysdev/tsi108_pci.c +++ b/arch/powerpc/sysdev/tsi108_pci.c | |||
@@ -64,9 +64,10 @@ tsi108_direct_write_config(struct pci_bus *bus, unsigned int devfunc, | |||
64 | int offset, int len, u32 val) | 64 | int offset, int len, u32 val) |
65 | { | 65 | { |
66 | volatile unsigned char *cfg_addr; | 66 | volatile unsigned char *cfg_addr; |
67 | struct pci_controller *hose = bus->sysdata; | ||
67 | 68 | ||
68 | if (ppc_md.pci_exclude_device) | 69 | if (ppc_md.pci_exclude_device) |
69 | if (ppc_md.pci_exclude_device(bus->number, devfunc)) | 70 | if (ppc_md.pci_exclude_device(hose, bus->number, devfunc)) |
70 | return PCIBIOS_DEVICE_NOT_FOUND; | 71 | return PCIBIOS_DEVICE_NOT_FOUND; |
71 | 72 | ||
72 | cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number, | 73 | cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number, |
@@ -149,10 +150,11 @@ tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | |||
149 | int len, u32 * val) | 150 | int len, u32 * val) |
150 | { | 151 | { |
151 | volatile unsigned char *cfg_addr; | 152 | volatile unsigned char *cfg_addr; |
153 | struct pci_controller *hose = bus->sysdata; | ||
152 | u32 temp; | 154 | u32 temp; |
153 | 155 | ||
154 | if (ppc_md.pci_exclude_device) | 156 | if (ppc_md.pci_exclude_device) |
155 | if (ppc_md.pci_exclude_device(bus->number, devfn)) | 157 | if (ppc_md.pci_exclude_device(hose, bus->number, devfn)) |
156 | return PCIBIOS_DEVICE_NOT_FOUND; | 158 | return PCIBIOS_DEVICE_NOT_FOUND; |
157 | 159 | ||
158 | cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number, | 160 | cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number, |
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index 95694159b226..543795be58c8 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile | |||
@@ -7,6 +7,7 @@ CFLAGS_btext.o += -fPIC | |||
7 | 7 | ||
8 | wdt-mpc8xx-$(CONFIG_8xx_WDT) += m8xx_wdt.o | 8 | wdt-mpc8xx-$(CONFIG_8xx_WDT) += m8xx_wdt.o |
9 | 9 | ||
10 | obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o | ||
10 | obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o | 11 | obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o |
11 | obj-$(CONFIG_PPC_OCP) += ocp.o | 12 | obj-$(CONFIG_PPC_OCP) += ocp.o |
12 | obj-$(CONFIG_IBM_OCP) += ibm_ocp.o | 13 | obj-$(CONFIG_IBM_OCP) += ibm_ocp.o |
diff --git a/arch/ppc/syslib/indirect_pci.c b/arch/ppc/syslib/indirect_pci.c new file mode 100644 index 000000000000..83b323a7d029 --- /dev/null +++ b/arch/ppc/syslib/indirect_pci.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | * Support for indirect PCI bridges. | ||
3 | * | ||
4 | * Copyright (C) 1998 Gabriel Paubert. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/pci.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/string.h> | ||
16 | #include <linux/init.h> | ||
17 | |||
18 | #include <asm/io.h> | ||
19 | #include <asm/prom.h> | ||
20 | #include <asm/pci-bridge.h> | ||
21 | #include <asm/machdep.h> | ||
22 | |||
23 | #ifdef CONFIG_PPC_INDIRECT_PCI_BE | ||
24 | #define PCI_CFG_OUT out_be32 | ||
25 | #else | ||
26 | #define PCI_CFG_OUT out_le32 | ||
27 | #endif | ||
28 | |||
29 | static int | ||
30 | indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
31 | int len, u32 *val) | ||
32 | { | ||
33 | struct pci_controller *hose = bus->sysdata; | ||
34 | volatile void __iomem *cfg_data; | ||
35 | u8 cfg_type = 0; | ||
36 | |||
37 | if (ppc_md.pci_exclude_device) | ||
38 | if (ppc_md.pci_exclude_device(bus->number, devfn)) | ||
39 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
40 | |||
41 | if (hose->set_cfg_type) | ||
42 | if (bus->number != hose->first_busno) | ||
43 | cfg_type = 1; | ||
44 | |||
45 | PCI_CFG_OUT(hose->cfg_addr, | ||
46 | (0x80000000 | ((bus->number - hose->bus_offset) << 16) | ||
47 | | (devfn << 8) | ((offset & 0xfc) | cfg_type))); | ||
48 | |||
49 | /* | ||
50 | * Note: the caller has already checked that offset is | ||
51 | * suitably aligned and that len is 1, 2 or 4. | ||
52 | */ | ||
53 | cfg_data = hose->cfg_data + (offset & 3); | ||
54 | switch (len) { | ||
55 | case 1: | ||
56 | *val = in_8(cfg_data); | ||
57 | break; | ||
58 | case 2: | ||
59 | *val = in_le16(cfg_data); | ||
60 | break; | ||
61 | default: | ||
62 | *val = in_le32(cfg_data); | ||
63 | break; | ||
64 | } | ||
65 | return PCIBIOS_SUCCESSFUL; | ||
66 | } | ||
67 | |||
68 | static int | ||
69 | indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
70 | int len, u32 val) | ||
71 | { | ||
72 | struct pci_controller *hose = bus->sysdata; | ||
73 | volatile void __iomem *cfg_data; | ||
74 | u8 cfg_type = 0; | ||
75 | |||
76 | if (ppc_md.pci_exclude_device) | ||
77 | if (ppc_md.pci_exclude_device(bus->number, devfn)) | ||
78 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
79 | |||
80 | if (hose->set_cfg_type) | ||
81 | if (bus->number != hose->first_busno) | ||
82 | cfg_type = 1; | ||
83 | |||
84 | PCI_CFG_OUT(hose->cfg_addr, | ||
85 | (0x80000000 | ((bus->number - hose->bus_offset) << 16) | ||
86 | | (devfn << 8) | ((offset & 0xfc) | cfg_type))); | ||
87 | |||
88 | /* | ||
89 | * Note: the caller has already checked that offset is | ||
90 | * suitably aligned and that len is 1, 2 or 4. | ||
91 | */ | ||
92 | cfg_data = hose->cfg_data + (offset & 3); | ||
93 | switch (len) { | ||
94 | case 1: | ||
95 | out_8(cfg_data, val); | ||
96 | break; | ||
97 | case 2: | ||
98 | out_le16(cfg_data, val); | ||
99 | break; | ||
100 | default: | ||
101 | out_le32(cfg_data, val); | ||
102 | break; | ||
103 | } | ||
104 | return PCIBIOS_SUCCESSFUL; | ||
105 | } | ||
106 | |||
107 | static struct pci_ops indirect_pci_ops = | ||
108 | { | ||
109 | indirect_read_config, | ||
110 | indirect_write_config | ||
111 | }; | ||
112 | |||
113 | void __init | ||
114 | setup_indirect_pci_nomap(struct pci_controller* hose, void __iomem * cfg_addr, | ||
115 | void __iomem * cfg_data) | ||
116 | { | ||
117 | hose->cfg_addr = cfg_addr; | ||
118 | hose->cfg_data = cfg_data; | ||
119 | hose->ops = &indirect_pci_ops; | ||
120 | } | ||
121 | |||
122 | void __init | ||
123 | setup_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data) | ||
124 | { | ||
125 | unsigned long base = cfg_addr & PAGE_MASK; | ||
126 | void __iomem *mbase, *addr, *data; | ||
127 | |||
128 | mbase = ioremap(base, PAGE_SIZE); | ||
129 | addr = mbase + (cfg_addr & ~PAGE_MASK); | ||
130 | if ((cfg_data & PAGE_MASK) != base) | ||
131 | mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE); | ||
132 | data = mbase + (cfg_data & ~PAGE_MASK); | ||
133 | setup_indirect_pci_nomap(hose, addr, data); | ||
134 | } | ||
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h index 6cf1a831f550..71c6e7eb2a26 100644 --- a/include/asm-powerpc/machdep.h +++ b/include/asm-powerpc/machdep.h | |||
@@ -218,7 +218,7 @@ struct machdep_calls { | |||
218 | int (*pcibios_enable_device_hook)(struct pci_dev *, int initial); | 218 | int (*pcibios_enable_device_hook)(struct pci_dev *, int initial); |
219 | 219 | ||
220 | /* Called in indirect_* to avoid touching devices */ | 220 | /* Called in indirect_* to avoid touching devices */ |
221 | int (*pci_exclude_device)(unsigned char, unsigned char); | 221 | int (*pci_exclude_device)(struct pci_controller *, unsigned char, unsigned char); |
222 | 222 | ||
223 | /* Called at then very end of pcibios_init() */ | 223 | /* Called at then very end of pcibios_init() */ |
224 | void (*pcibios_after_init)(void); | 224 | void (*pcibios_after_init)(void); |