aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorIshizaki Kou <kou.ishizaki@toshiba.co.jp>2007-03-02 02:59:25 -0500
committerPaul Mackerras <paulus@samba.org>2007-03-07 12:09:33 -0500
commit8388374f1cd45ef67039d3ea128d250fac484df3 (patch)
tree6fee84637f5172705708ea220d73c99c3521c25a /arch/powerpc
parentc99176a230097b076c2f98e4bf963399fe114ffd (diff)
[POWERPC] Celleb: bug fix caused by not casting pointer types
This fixes a bug caused by changes of pointer type in commit f1fda89522c5aaa1bd4ef69605e85e6ee9c85faf. hose->cfg_addr type is "volatile unsigned int __iomem *", so "hose->cfg_addr + X" will not make an intended address. This patch also adds comments for usage of cfg_addr and cfg_data in pci_controller structure. We use them in irregular way, and the original code is short of explanations about them. Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/celleb/scc_epci.c82
1 files changed, 61 insertions, 21 deletions
diff --git a/arch/powerpc/platforms/celleb/scc_epci.c b/arch/powerpc/platforms/celleb/scc_epci.c
index c11b39c3776a..fb23d53eb09c 100644
--- a/arch/powerpc/platforms/celleb/scc_epci.c
+++ b/arch/powerpc/platforms/celleb/scc_epci.c
@@ -43,11 +43,34 @@
43 43
44#define iob() __asm__ __volatile__("eieio; sync":::"memory") 44#define iob() __asm__ __volatile__("eieio; sync":::"memory")
45 45
46static inline volatile void __iomem *celleb_epci_get_epci_base(
47 struct pci_controller *hose)
48{
49 /*
50 * Note:
51 * Celleb epci uses cfg_addr as a base address for
52 * epci control registers.
53 */
54
55 return hose->cfg_addr;
56}
57
58static inline volatile void __iomem *celleb_epci_get_epci_cfg(
59 struct pci_controller *hose)
60{
61 /*
62 * Note:
63 * Celleb epci uses cfg_data as a base address for
64 * configuration area for epci devices.
65 */
66
67 return hose->cfg_data;
68}
46 69
47#if 0 /* test code for epci dummy read */ 70#if 0 /* test code for epci dummy read */
48static void celleb_epci_dummy_read(struct pci_dev *dev) 71static void celleb_epci_dummy_read(struct pci_dev *dev)
49{ 72{
50 void __iomem *epci_base; 73 volatile void __iomem *epci_base;
51 struct device_node *node; 74 struct device_node *node;
52 struct pci_controller *hose; 75 struct pci_controller *hose;
53 u32 val; 76 u32 val;
@@ -58,7 +81,7 @@ static void celleb_epci_dummy_read(struct pci_dev *dev)
58 if (!hose) 81 if (!hose)
59 return; 82 return;
60 83
61 epci_base = hose->cfg_addr; 84 epci_base = celleb_epci_get_epci_base(hose);
62 85
63 val = in_be32(epci_base + SCC_EPCI_WATRP); 86 val = in_be32(epci_base + SCC_EPCI_WATRP);
64 iosync(); 87 iosync();
@@ -70,19 +93,20 @@ static void celleb_epci_dummy_read(struct pci_dev *dev)
70static inline void clear_and_disable_master_abort_interrupt( 93static inline void clear_and_disable_master_abort_interrupt(
71 struct pci_controller *hose) 94 struct pci_controller *hose)
72{ 95{
73 void __iomem *addr; 96 volatile void __iomem *epci_base, *reg;
74 addr = hose->cfg_addr + PCI_COMMAND; 97 epci_base = celleb_epci_get_epci_base(hose);
75 out_be32(addr, in_be32(addr) | (PCI_STATUS_REC_MASTER_ABORT << 16)); 98 reg = epci_base + PCI_COMMAND;
99 out_be32(reg, in_be32(reg) | (PCI_STATUS_REC_MASTER_ABORT << 16));
76} 100}
77 101
78static int celleb_epci_check_abort(struct pci_controller *hose, 102static int celleb_epci_check_abort(struct pci_controller *hose,
79 void __iomem *addr) 103 volatile void __iomem *addr)
80{ 104{
81 void __iomem *reg, *epci_base; 105 volatile void __iomem *reg, *epci_base;
82 u32 val; 106 u32 val;
83 107
84 iob(); 108 iob();
85 epci_base = hose->cfg_addr; 109 epci_base = celleb_epci_get_epci_base(hose);
86 110
87 reg = epci_base + PCI_COMMAND; 111 reg = epci_base + PCI_COMMAND;
88 val = in_be32(reg); 112 val = in_be32(reg);
@@ -108,20 +132,21 @@ static int celleb_epci_check_abort(struct pci_controller *hose,
108 return PCIBIOS_SUCCESSFUL; 132 return PCIBIOS_SUCCESSFUL;
109} 133}
110 134
111static void __iomem *celleb_epci_make_config_addr(struct pci_controller *hose, 135static volatile void __iomem *celleb_epci_make_config_addr(
136 struct pci_controller *hose,
112 unsigned int devfn, int where) 137 unsigned int devfn, int where)
113{ 138{
114 void __iomem *addr; 139 volatile void __iomem *addr;
115 struct pci_bus *bus = hose->bus; 140 struct pci_bus *bus = hose->bus;
116 141
117 if (bus->self) 142 if (bus->self)
118 addr = hose->cfg_data + 143 addr = celleb_epci_get_epci_cfg(hose) +
119 (((bus->number & 0xff) << 16) 144 (((bus->number & 0xff) << 16)
120 | ((devfn & 0xff) << 8) 145 | ((devfn & 0xff) << 8)
121 | (where & 0xff) 146 | (where & 0xff)
122 | 0x01000000); 147 | 0x01000000);
123 else 148 else
124 addr = hose->cfg_data + 149 addr = celleb_epci_get_epci_cfg(hose) +
125 (((devfn & 0xff) << 8) | (where & 0xff)); 150 (((devfn & 0xff) << 8) | (where & 0xff));
126 151
127 pr_debug("EPCI: config_addr = 0x%p\n", addr); 152 pr_debug("EPCI: config_addr = 0x%p\n", addr);
@@ -132,7 +157,7 @@ static void __iomem *celleb_epci_make_config_addr(struct pci_controller *hose,
132static int celleb_epci_read_config(struct pci_bus *bus, 157static int celleb_epci_read_config(struct pci_bus *bus,
133 unsigned int devfn, int where, int size, u32 * val) 158 unsigned int devfn, int where, int size, u32 * val)
134{ 159{
135 void __iomem *addr; 160 volatile void __iomem *epci_base, *addr;
136 struct device_node *node; 161 struct device_node *node;
137 struct pci_controller *hose; 162 struct pci_controller *hose;
138 163
@@ -142,13 +167,14 @@ static int celleb_epci_read_config(struct pci_bus *bus,
142 node = (struct device_node *)bus->sysdata; 167 node = (struct device_node *)bus->sysdata;
143 hose = pci_find_hose_for_OF_device(node); 168 hose = pci_find_hose_for_OF_device(node);
144 169
145 if (!hose->cfg_data) 170 if (!celleb_epci_get_epci_cfg(hose))
146 return PCIBIOS_DEVICE_NOT_FOUND; 171 return PCIBIOS_DEVICE_NOT_FOUND;
147 172
148 if (bus->number == hose->first_busno && devfn == 0) { 173 if (bus->number == hose->first_busno && devfn == 0) {
149 /* EPCI controller self */ 174 /* EPCI controller self */
150 175
151 addr = hose->cfg_addr + where; 176 epci_base = celleb_epci_get_epci_base(hose);
177 addr = epci_base + where;
152 178
153 switch (size) { 179 switch (size) {
154 case 1: 180 case 1:
@@ -185,7 +211,7 @@ static int celleb_epci_read_config(struct pci_bus *bus,
185 } 211 }
186 212
187 pr_debug("EPCI: " 213 pr_debug("EPCI: "
188 "addr=0x%lx, devfn=0x%x, where=0x%x, size=0x%x, val=0x%x\n", 214 "addr=0x%p, devfn=0x%x, where=0x%x, size=0x%x, val=0x%x\n",
189 addr, devfn, where, size, *val); 215 addr, devfn, where, size, *val);
190 216
191 return celleb_epci_check_abort(hose, NULL); 217 return celleb_epci_check_abort(hose, NULL);
@@ -194,7 +220,7 @@ static int celleb_epci_read_config(struct pci_bus *bus,
194static int celleb_epci_write_config(struct pci_bus *bus, 220static int celleb_epci_write_config(struct pci_bus *bus,
195 unsigned int devfn, int where, int size, u32 val) 221 unsigned int devfn, int where, int size, u32 val)
196{ 222{
197 void __iomem *addr; 223 volatile void __iomem *epci_base, *addr;
198 struct device_node *node; 224 struct device_node *node;
199 struct pci_controller *hose; 225 struct pci_controller *hose;
200 226
@@ -204,13 +230,15 @@ static int celleb_epci_write_config(struct pci_bus *bus,
204 node = (struct device_node *)bus->sysdata; 230 node = (struct device_node *)bus->sysdata;
205 hose = pci_find_hose_for_OF_device(node); 231 hose = pci_find_hose_for_OF_device(node);
206 232
207 if (!hose->cfg_data) 233
234 if (!celleb_epci_get_epci_cfg(hose))
208 return PCIBIOS_DEVICE_NOT_FOUND; 235 return PCIBIOS_DEVICE_NOT_FOUND;
209 236
210 if (bus->number == hose->first_busno && devfn == 0) { 237 if (bus->number == hose->first_busno && devfn == 0) {
211 /* EPCI controller self */ 238 /* EPCI controller self */
212 239
213 addr = hose->cfg_addr + where; 240 epci_base = celleb_epci_get_epci_base(hose);
241 addr = epci_base + where;
214 242
215 switch (size) { 243 switch (size) {
216 case 1: 244 case 1:
@@ -258,10 +286,10 @@ struct pci_ops celleb_epci_ops = {
258static int __devinit celleb_epci_init(struct pci_controller *hose) 286static int __devinit celleb_epci_init(struct pci_controller *hose)
259{ 287{
260 u32 val; 288 u32 val;
261 void __iomem *reg, *epci_base; 289 volatile void __iomem *reg, *epci_base;
262 int hwres = 0; 290 int hwres = 0;
263 291
264 epci_base = hose->cfg_addr; 292 epci_base = celleb_epci_get_epci_base(hose);
265 293
266 /* PCI core reset(Internal bus and PCI clock) */ 294 /* PCI core reset(Internal bus and PCI clock) */
267 reg = epci_base + SCC_EPCI_CKCTRL; 295 reg = epci_base + SCC_EPCI_CKCTRL;
@@ -382,6 +410,18 @@ int __devinit celleb_setup_epci(struct device_node *node,
382 410
383 pr_debug("PCI: celleb_setup_epci()\n"); 411 pr_debug("PCI: celleb_setup_epci()\n");
384 412
413 /*
414 * Note:
415 * Celleb epci uses cfg_addr and cfg_data member of
416 * pci_controller structure in irregular way.
417 *
418 * cfg_addr is used to map for control registers of
419 * celleb epci.
420 *
421 * cfg_data is used for configuration area of devices
422 * on Celleb epci buses.
423 */
424
385 if (of_address_to_resource(node, 0, &r)) 425 if (of_address_to_resource(node, 0, &r))
386 goto error; 426 goto error;
387 hose->cfg_addr = ioremap(r.start, (r.end - r.start + 1)); 427 hose->cfg_addr = ioremap(r.start, (r.end - r.start + 1));