diff options
author | Michael Ellerman <michael@ozlabs.org> | 2011-04-11 17:25:01 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-04-27 00:18:29 -0400 |
commit | 3cc30d0726d258ac336283bcde66a8ab58283b61 (patch) | |
tree | d0b6664707f2d6ee5b5a008af1c2810d5ba1390c /arch/powerpc/platforms/cell/io-workarounds.c | |
parent | 21176fed25c3b0cb17c6c42d71b4e3d68b8f9dd4 (diff) |
powerpc/pci: Move IO workarounds to the common kernel dir
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>
Diffstat (limited to 'arch/powerpc/platforms/cell/io-workarounds.c')
-rw-r--r-- | arch/powerpc/platforms/cell/io-workarounds.c | 185 |
1 files changed, 0 insertions, 185 deletions
diff --git a/arch/powerpc/platforms/cell/io-workarounds.c b/arch/powerpc/platforms/cell/io-workarounds.c deleted file mode 100644 index 5c1118e3194..00000000000 --- a/arch/powerpc/platforms/cell/io-workarounds.c +++ /dev/null | |||
@@ -1,185 +0,0 @@ | |||
1 | /* | ||
2 | * Support PCI IO workaround | ||
3 | * | ||
4 | * Copyright (C) 2006 Benjamin Herrenschmidt <benh@kernel.crashing.org> | ||
5 | * IBM, Corp. | ||
6 | * (C) Copyright 2007-2008 TOSHIBA CORPORATION | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | #undef DEBUG | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | |||
16 | #include <asm/io.h> | ||
17 | #include <asm/machdep.h> | ||
18 | #include <asm/pgtable.h> | ||
19 | #include <asm/ppc-pci.h> | ||
20 | |||
21 | #include "io-workarounds.h" | ||
22 | |||
23 | #define IOWA_MAX_BUS 8 | ||
24 | |||
25 | static struct iowa_bus iowa_busses[IOWA_MAX_BUS]; | ||
26 | static unsigned int iowa_bus_count; | ||
27 | |||
28 | static struct iowa_bus *iowa_pci_find(unsigned long vaddr, unsigned long paddr) | ||
29 | { | ||
30 | int i, j; | ||
31 | struct resource *res; | ||
32 | unsigned long vstart, vend; | ||
33 | |||
34 | for (i = 0; i < iowa_bus_count; i++) { | ||
35 | struct iowa_bus *bus = &iowa_busses[i]; | ||
36 | struct pci_controller *phb = bus->phb; | ||
37 | |||
38 | if (vaddr) { | ||
39 | vstart = (unsigned long)phb->io_base_virt; | ||
40 | vend = vstart + phb->pci_io_size - 1; | ||
41 | if ((vaddr >= vstart) && (vaddr <= vend)) | ||
42 | return bus; | ||
43 | } | ||
44 | |||
45 | if (paddr) | ||
46 | for (j = 0; j < 3; j++) { | ||
47 | res = &phb->mem_resources[j]; | ||
48 | if (paddr >= res->start && paddr <= res->end) | ||
49 | return bus; | ||
50 | } | ||
51 | } | ||
52 | |||
53 | return NULL; | ||
54 | } | ||
55 | |||
56 | struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR addr) | ||
57 | { | ||
58 | struct iowa_bus *bus; | ||
59 | int token; | ||
60 | |||
61 | token = PCI_GET_ADDR_TOKEN(addr); | ||
62 | |||
63 | if (token && token <= iowa_bus_count) | ||
64 | bus = &iowa_busses[token - 1]; | ||
65 | else { | ||
66 | unsigned long vaddr, paddr; | ||
67 | pte_t *ptep; | ||
68 | |||
69 | vaddr = (unsigned long)PCI_FIX_ADDR(addr); | ||
70 | if (vaddr < PHB_IO_BASE || vaddr >= PHB_IO_END) | ||
71 | return NULL; | ||
72 | |||
73 | ptep = find_linux_pte(init_mm.pgd, vaddr); | ||
74 | if (ptep == NULL) | ||
75 | paddr = 0; | ||
76 | else | ||
77 | paddr = pte_pfn(*ptep) << PAGE_SHIFT; | ||
78 | bus = iowa_pci_find(vaddr, paddr); | ||
79 | |||
80 | if (bus == NULL) | ||
81 | return NULL; | ||
82 | } | ||
83 | |||
84 | return bus; | ||
85 | } | ||
86 | |||
87 | struct iowa_bus *iowa_pio_find_bus(unsigned long port) | ||
88 | { | ||
89 | unsigned long vaddr = (unsigned long)pci_io_base + port; | ||
90 | return iowa_pci_find(vaddr, 0); | ||
91 | } | ||
92 | |||
93 | |||
94 | #define DEF_PCI_AC_RET(name, ret, at, al, space, aa) \ | ||
95 | static ret iowa_##name at \ | ||
96 | { \ | ||
97 | struct iowa_bus *bus; \ | ||
98 | bus = iowa_##space##_find_bus(aa); \ | ||
99 | if (bus && bus->ops && bus->ops->name) \ | ||
100 | return bus->ops->name al; \ | ||
101 | return __do_##name al; \ | ||
102 | } | ||
103 | |||
104 | #define DEF_PCI_AC_NORET(name, at, al, space, aa) \ | ||
105 | static void iowa_##name at \ | ||
106 | { \ | ||
107 | struct iowa_bus *bus; \ | ||
108 | bus = iowa_##space##_find_bus(aa); \ | ||
109 | if (bus && bus->ops && bus->ops->name) { \ | ||
110 | bus->ops->name al; \ | ||
111 | return; \ | ||
112 | } \ | ||
113 | __do_##name al; \ | ||
114 | } | ||
115 | |||
116 | #include <asm/io-defs.h> | ||
117 | |||
118 | #undef DEF_PCI_AC_RET | ||
119 | #undef DEF_PCI_AC_NORET | ||
120 | |||
121 | static const struct ppc_pci_io __devinitconst iowa_pci_io = { | ||
122 | |||
123 | #define DEF_PCI_AC_RET(name, ret, at, al, space, aa) .name = iowa_##name, | ||
124 | #define DEF_PCI_AC_NORET(name, at, al, space, aa) .name = iowa_##name, | ||
125 | |||
126 | #include <asm/io-defs.h> | ||
127 | |||
128 | #undef DEF_PCI_AC_RET | ||
129 | #undef DEF_PCI_AC_NORET | ||
130 | |||
131 | }; | ||
132 | |||
133 | static void __iomem *iowa_ioremap(phys_addr_t addr, unsigned long size, | ||
134 | unsigned long flags, void *caller) | ||
135 | { | ||
136 | struct iowa_bus *bus; | ||
137 | void __iomem *res = __ioremap_caller(addr, size, flags, caller); | ||
138 | int busno; | ||
139 | |||
140 | bus = iowa_pci_find(0, (unsigned long)addr); | ||
141 | if (bus != NULL) { | ||
142 | busno = bus - iowa_busses; | ||
143 | PCI_SET_ADDR_TOKEN(res, busno + 1); | ||
144 | } | ||
145 | return res; | ||
146 | } | ||
147 | |||
148 | /* Regist new bus to support workaround */ | ||
149 | void __devinit iowa_register_bus(struct pci_controller *phb, | ||
150 | struct ppc_pci_io *ops, | ||
151 | int (*initfunc)(struct iowa_bus *, void *), void *data) | ||
152 | { | ||
153 | struct iowa_bus *bus; | ||
154 | struct device_node *np = phb->dn; | ||
155 | |||
156 | if (iowa_bus_count >= IOWA_MAX_BUS) { | ||
157 | pr_err("IOWA:Too many pci bridges, " | ||
158 | "workarounds disabled for %s\n", np->full_name); | ||
159 | return; | ||
160 | } | ||
161 | |||
162 | bus = &iowa_busses[iowa_bus_count]; | ||
163 | bus->phb = phb; | ||
164 | bus->ops = ops; | ||
165 | |||
166 | if (initfunc) | ||
167 | if ((*initfunc)(bus, data)) | ||
168 | return; | ||
169 | |||
170 | iowa_bus_count++; | ||
171 | |||
172 | pr_debug("IOWA:[%d]Add bus, %s.\n", iowa_bus_count-1, np->full_name); | ||
173 | } | ||
174 | |||
175 | /* enable IO workaround */ | ||
176 | void __devinit io_workaround_init(void) | ||
177 | { | ||
178 | static int io_workaround_inited; | ||
179 | |||
180 | if (io_workaround_inited) | ||
181 | return; | ||
182 | ppc_pci_io = iowa_pci_io; | ||
183 | ppc_md.ioremap = iowa_ioremap; | ||
184 | io_workaround_inited = 1; | ||
185 | } | ||