aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ozlabs.org>2011-04-11 17:25:02 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-04-27 00:18:31 -0400
commitd1109b7529f362c06c47140ae09dbd2b853ffddc (patch)
tree68f00f3d6fb77d8f72ec52183bacb29fd47a873b
parent3cc30d0726d258ac336283bcde66a8ab58283b61 (diff)
powerpc/pci: Make IO workarounds init implicit when first bus is registered
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/include/asm/io-workarounds.h1
-rw-r--r--arch/powerpc/kernel/io-workarounds.c27
-rw-r--r--arch/powerpc/platforms/cell/celleb_pci.c18
-rw-r--r--arch/powerpc/platforms/cell/setup.c2
4 files changed, 20 insertions, 28 deletions
diff --git a/arch/powerpc/include/asm/io-workarounds.h b/arch/powerpc/include/asm/io-workarounds.h
index 6efc7782ebf2..fbae49286926 100644
--- a/arch/powerpc/include/asm/io-workarounds.h
+++ b/arch/powerpc/include/asm/io-workarounds.h
@@ -31,7 +31,6 @@ struct iowa_bus {
31 void *private; 31 void *private;
32}; 32};
33 33
34void __devinit io_workaround_init(void);
35void __devinit iowa_register_bus(struct pci_controller *, struct ppc_pci_io *, 34void __devinit iowa_register_bus(struct pci_controller *, struct ppc_pci_io *,
36 int (*)(struct iowa_bus *, void *), void *); 35 int (*)(struct iowa_bus *, void *), void *);
37struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR); 36struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR);
diff --git a/arch/powerpc/kernel/io-workarounds.c b/arch/powerpc/kernel/io-workarounds.c
index 7e5845798788..d36515eaa314 100644
--- a/arch/powerpc/kernel/io-workarounds.c
+++ b/arch/powerpc/kernel/io-workarounds.c
@@ -144,7 +144,19 @@ static void __iomem *iowa_ioremap(phys_addr_t addr, unsigned long size,
144 return res; 144 return res;
145} 145}
146 146
147/* Regist new bus to support workaround */ 147/* Enable IO workaround */
148static void __devinit io_workaround_init(void)
149{
150 static int io_workaround_inited;
151
152 if (io_workaround_inited)
153 return;
154 ppc_pci_io = iowa_pci_io;
155 ppc_md.ioremap = iowa_ioremap;
156 io_workaround_inited = 1;
157}
158
159/* Register new bus to support workaround */
148void __devinit iowa_register_bus(struct pci_controller *phb, 160void __devinit iowa_register_bus(struct pci_controller *phb,
149 struct ppc_pci_io *ops, 161 struct ppc_pci_io *ops,
150 int (*initfunc)(struct iowa_bus *, void *), void *data) 162 int (*initfunc)(struct iowa_bus *, void *), void *data)
@@ -152,6 +164,8 @@ void __devinit iowa_register_bus(struct pci_controller *phb,
152 struct iowa_bus *bus; 164 struct iowa_bus *bus;
153 struct device_node *np = phb->dn; 165 struct device_node *np = phb->dn;
154 166
167 io_workaround_init();
168
155 if (iowa_bus_count >= IOWA_MAX_BUS) { 169 if (iowa_bus_count >= IOWA_MAX_BUS) {
156 pr_err("IOWA:Too many pci bridges, " 170 pr_err("IOWA:Too many pci bridges, "
157 "workarounds disabled for %s\n", np->full_name); 171 "workarounds disabled for %s\n", np->full_name);
@@ -171,14 +185,3 @@ void __devinit iowa_register_bus(struct pci_controller *phb,
171 pr_debug("IOWA:[%d]Add bus, %s.\n", iowa_bus_count-1, np->full_name); 185 pr_debug("IOWA:[%d]Add bus, %s.\n", iowa_bus_count-1, np->full_name);
172} 186}
173 187
174/* enable IO workaround */
175void __devinit io_workaround_init(void)
176{
177 static int io_workaround_inited;
178
179 if (io_workaround_inited)
180 return;
181 ppc_pci_io = iowa_pci_io;
182 ppc_md.ioremap = iowa_ioremap;
183 io_workaround_inited = 1;
184}
diff --git a/arch/powerpc/platforms/cell/celleb_pci.c b/arch/powerpc/platforms/cell/celleb_pci.c
index c19b783a7c99..2904b0a6b2c5 100644
--- a/arch/powerpc/platforms/cell/celleb_pci.c
+++ b/arch/powerpc/platforms/cell/celleb_pci.c
@@ -468,18 +468,6 @@ static struct of_device_id celleb_phb_match[] __initdata = {
468 }, 468 },
469}; 469};
470 470
471static int __init celleb_io_workaround_init(struct pci_controller *phb,
472 struct celleb_phb_spec *phb_spec)
473{
474 if (phb_spec->ops) {
475 iowa_register_bus(phb, phb_spec->ops, phb_spec->iowa_init,
476 phb_spec->iowa_data);
477 io_workaround_init();
478 }
479
480 return 0;
481}
482
483int __init celleb_setup_phb(struct pci_controller *phb) 471int __init celleb_setup_phb(struct pci_controller *phb)
484{ 472{
485 struct device_node *dev = phb->dn; 473 struct device_node *dev = phb->dn;
@@ -499,7 +487,11 @@ int __init celleb_setup_phb(struct pci_controller *phb)
499 if (rc) 487 if (rc)
500 return 1; 488 return 1;
501 489
502 return celleb_io_workaround_init(phb, phb_spec); 490 if (phb_spec->ops)
491 iowa_register_bus(phb, phb_spec->ops,
492 phb_spec->iowa_init,
493 phb_spec->iowa_data);
494 return 0;
503} 495}
504 496
505int celleb_pci_probe_mode(struct pci_bus *bus) 497int celleb_pci_probe_mode(struct pci_bus *bus)
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index af7b13cd7110..c73cf4c43fc2 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -136,8 +136,6 @@ static int __devinit cell_setup_phb(struct pci_controller *phb)
136 136
137 iowa_register_bus(phb, &spiderpci_ops, &spiderpci_iowa_init, 137 iowa_register_bus(phb, &spiderpci_ops, &spiderpci_iowa_init,
138 (void *)SPIDER_PCI_REG_BASE); 138 (void *)SPIDER_PCI_REG_BASE);
139 io_workaround_init();
140
141 return 0; 139 return 0;
142} 140}
143 141