diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/ppc/syslib/mpc10x_common.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/ppc/syslib/mpc10x_common.c')
-rw-r--r-- | arch/ppc/syslib/mpc10x_common.c | 510 |
1 files changed, 510 insertions, 0 deletions
diff --git a/arch/ppc/syslib/mpc10x_common.c b/arch/ppc/syslib/mpc10x_common.c new file mode 100644 index 000000000000..fd93adfd464c --- /dev/null +++ b/arch/ppc/syslib/mpc10x_common.c | |||
@@ -0,0 +1,510 @@ | |||
1 | /* | ||
2 | * arch/ppc/syslib/mpc10x_common.c | ||
3 | * | ||
4 | * Common routines for the Motorola SPS MPC106, MPC107 and MPC8240 Host bridge, | ||
5 | * Mem ctlr, EPIC, etc. | ||
6 | * | ||
7 | * Author: Mark A. Greer | ||
8 | * mgreer@mvista.com | ||
9 | * | ||
10 | * 2001 (c) MontaVista, Software, Inc. This file is licensed under | ||
11 | * the terms of the GNU General Public License version 2. This program | ||
12 | * is licensed "as is" without any warranty of any kind, whether express | ||
13 | * or implied. | ||
14 | */ | ||
15 | |||
16 | /* | ||
17 | * *** WARNING - A BAT MUST be set to access the PCI config addr/data regs *** | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/pci.h> | ||
23 | #include <linux/slab.h> | ||
24 | |||
25 | #include <asm/byteorder.h> | ||
26 | #include <asm/io.h> | ||
27 | #include <asm/irq.h> | ||
28 | #include <asm/uaccess.h> | ||
29 | #include <asm/machdep.h> | ||
30 | #include <asm/pci-bridge.h> | ||
31 | #include <asm/open_pic.h> | ||
32 | #include <asm/mpc10x.h> | ||
33 | #include <asm/ocp.h> | ||
34 | |||
35 | /* The OCP structure is fixed by code below, before OCP initialises. | ||
36 | paddr depends on where the board places the EUMB. | ||
37 | - fixed in mpc10x_bridge_init(). | ||
38 | irq depends on two things: | ||
39 | > does the board use the EPIC at all? (PCORE does not). | ||
40 | > is the EPIC in serial or parallel mode? | ||
41 | - fixed in mpc10x_set_openpic(). | ||
42 | */ | ||
43 | |||
44 | #ifdef CONFIG_MPC10X_OPENPIC | ||
45 | #ifdef CONFIG_EPIC_SERIAL_MODE | ||
46 | #define EPIC_IRQ_BASE (epic_serial_mode ? 16 : 5) | ||
47 | #else | ||
48 | #define EPIC_IRQ_BASE 5 | ||
49 | #endif | ||
50 | #define MPC10X_I2C_IRQ (EPIC_IRQ_BASE + NUM_8259_INTERRUPTS) | ||
51 | #define MPC10X_DMA0_IRQ (EPIC_IRQ_BASE + 1 + NUM_8259_INTERRUPTS) | ||
52 | #define MPC10X_DMA1_IRQ (EPIC_IRQ_BASE + 2 + NUM_8259_INTERRUPTS) | ||
53 | #else | ||
54 | #define MPC10X_I2C_IRQ OCP_IRQ_NA | ||
55 | #define MPC10X_DMA0_IRQ OCP_IRQ_NA | ||
56 | #define MPC10X_DMA1_IRQ OCP_IRQ_NA | ||
57 | #endif | ||
58 | |||
59 | |||
60 | struct ocp_def core_ocp[] = { | ||
61 | { .vendor = OCP_VENDOR_INVALID | ||
62 | } | ||
63 | }; | ||
64 | |||
65 | static struct ocp_fs_i2c_data mpc10x_i2c_data = { | ||
66 | .flags = 0 | ||
67 | }; | ||
68 | static struct ocp_def mpc10x_i2c_ocp = { | ||
69 | .vendor = OCP_VENDOR_MOTOROLA, | ||
70 | .function = OCP_FUNC_IIC, | ||
71 | .index = 0, | ||
72 | .additions = &mpc10x_i2c_data | ||
73 | }; | ||
74 | |||
75 | static struct ocp_def mpc10x_dma_ocp[2] = { | ||
76 | { .vendor = OCP_VENDOR_MOTOROLA, | ||
77 | .function = OCP_FUNC_DMA, | ||
78 | .index = 0 }, | ||
79 | { .vendor = OCP_VENDOR_MOTOROLA, | ||
80 | .function = OCP_FUNC_DMA, | ||
81 | .index = 1 } | ||
82 | }; | ||
83 | |||
84 | /* Set resources to match bridge memory map */ | ||
85 | void __init | ||
86 | mpc10x_bridge_set_resources(int map, struct pci_controller *hose) | ||
87 | { | ||
88 | |||
89 | switch (map) { | ||
90 | case MPC10X_MEM_MAP_A: | ||
91 | pci_init_resource(&hose->io_resource, | ||
92 | 0x00000000, | ||
93 | 0x3f7fffff, | ||
94 | IORESOURCE_IO, | ||
95 | "PCI host bridge"); | ||
96 | |||
97 | pci_init_resource (&hose->mem_resources[0], | ||
98 | 0xc0000000, | ||
99 | 0xfeffffff, | ||
100 | IORESOURCE_MEM, | ||
101 | "PCI host bridge"); | ||
102 | break; | ||
103 | case MPC10X_MEM_MAP_B: | ||
104 | pci_init_resource(&hose->io_resource, | ||
105 | 0x00000000, | ||
106 | 0x00bfffff, | ||
107 | IORESOURCE_IO, | ||
108 | "PCI host bridge"); | ||
109 | |||
110 | pci_init_resource (&hose->mem_resources[0], | ||
111 | 0x80000000, | ||
112 | 0xfcffffff, | ||
113 | IORESOURCE_MEM, | ||
114 | "PCI host bridge"); | ||
115 | break; | ||
116 | default: | ||
117 | printk("mpc10x_bridge_set_resources: " | ||
118 | "Invalid map specified\n"); | ||
119 | if (ppc_md.progress) | ||
120 | ppc_md.progress("mpc10x:exit1", 0x100); | ||
121 | } | ||
122 | } | ||
123 | /* | ||
124 | * Do some initialization and put the EUMB registers at the specified address | ||
125 | * (also map the EPIC registers into virtual space--OpenPIC_Addr will be set). | ||
126 | * | ||
127 | * The EPIC is not on the 106, only the 8240 and 107. | ||
128 | */ | ||
129 | int __init | ||
130 | mpc10x_bridge_init(struct pci_controller *hose, | ||
131 | uint current_map, | ||
132 | uint new_map, | ||
133 | uint phys_eumb_base) | ||
134 | { | ||
135 | int host_bridge, picr1, picr1_bit; | ||
136 | ulong pci_config_addr, pci_config_data; | ||
137 | u_char pir, byte; | ||
138 | |||
139 | if (ppc_md.progress) ppc_md.progress("mpc10x:enter", 0x100); | ||
140 | |||
141 | /* Set up for current map so we can get at config regs */ | ||
142 | switch (current_map) { | ||
143 | case MPC10X_MEM_MAP_A: | ||
144 | setup_indirect_pci(hose, | ||
145 | MPC10X_MAPA_CNFG_ADDR, | ||
146 | MPC10X_MAPA_CNFG_DATA); | ||
147 | break; | ||
148 | case MPC10X_MEM_MAP_B: | ||
149 | setup_indirect_pci(hose, | ||
150 | MPC10X_MAPB_CNFG_ADDR, | ||
151 | MPC10X_MAPB_CNFG_DATA); | ||
152 | break; | ||
153 | default: | ||
154 | printk("mpc10x_bridge_init: %s\n", | ||
155 | "Invalid current map specified"); | ||
156 | if (ppc_md.progress) | ||
157 | ppc_md.progress("mpc10x:exit1", 0x100); | ||
158 | return -1; | ||
159 | } | ||
160 | |||
161 | /* Make sure it's a supported bridge */ | ||
162 | early_read_config_dword(hose, | ||
163 | 0, | ||
164 | PCI_DEVFN(0,0), | ||
165 | PCI_VENDOR_ID, | ||
166 | &host_bridge); | ||
167 | |||
168 | switch (host_bridge) { | ||
169 | case MPC10X_BRIDGE_106: | ||
170 | case MPC10X_BRIDGE_8240: | ||
171 | case MPC10X_BRIDGE_107: | ||
172 | case MPC10X_BRIDGE_8245: | ||
173 | break; | ||
174 | default: | ||
175 | if (ppc_md.progress) | ||
176 | ppc_md.progress("mpc10x:exit2", 0x100); | ||
177 | return -1; | ||
178 | } | ||
179 | |||
180 | switch (new_map) { | ||
181 | case MPC10X_MEM_MAP_A: | ||
182 | MPC10X_SETUP_HOSE(hose, A); | ||
183 | pci_config_addr = MPC10X_MAPA_CNFG_ADDR; | ||
184 | pci_config_data = MPC10X_MAPA_CNFG_DATA; | ||
185 | picr1_bit = MPC10X_CFG_PICR1_ADDR_MAP_A; | ||
186 | break; | ||
187 | case MPC10X_MEM_MAP_B: | ||
188 | MPC10X_SETUP_HOSE(hose, B); | ||
189 | pci_config_addr = MPC10X_MAPB_CNFG_ADDR; | ||
190 | pci_config_data = MPC10X_MAPB_CNFG_DATA; | ||
191 | picr1_bit = MPC10X_CFG_PICR1_ADDR_MAP_B; | ||
192 | break; | ||
193 | default: | ||
194 | printk("mpc10x_bridge_init: %s\n", | ||
195 | "Invalid new map specified"); | ||
196 | if (ppc_md.progress) | ||
197 | ppc_md.progress("mpc10x:exit3", 0x100); | ||
198 | return -1; | ||
199 | } | ||
200 | |||
201 | /* Make bridge use the 'new_map', if not already usng it */ | ||
202 | if (current_map != new_map) { | ||
203 | early_read_config_dword(hose, | ||
204 | 0, | ||
205 | PCI_DEVFN(0,0), | ||
206 | MPC10X_CFG_PICR1_REG, | ||
207 | &picr1); | ||
208 | |||
209 | picr1 = (picr1 & ~MPC10X_CFG_PICR1_ADDR_MAP_MASK) | | ||
210 | picr1_bit; | ||
211 | |||
212 | early_write_config_dword(hose, | ||
213 | 0, | ||
214 | PCI_DEVFN(0,0), | ||
215 | MPC10X_CFG_PICR1_REG, | ||
216 | picr1); | ||
217 | |||
218 | asm volatile("sync"); | ||
219 | |||
220 | /* Undo old mappings & map in new cfg data/addr regs */ | ||
221 | iounmap((void *)hose->cfg_addr); | ||
222 | iounmap((void *)hose->cfg_data); | ||
223 | |||
224 | setup_indirect_pci(hose, | ||
225 | pci_config_addr, | ||
226 | pci_config_data); | ||
227 | } | ||
228 | |||
229 | /* Setup resources to match map */ | ||
230 | mpc10x_bridge_set_resources(new_map, hose); | ||
231 | |||
232 | /* | ||
233 | * Want processor accesses of 0xFDxxxxxx to be mapped | ||
234 | * to PCI memory space at 0x00000000. Do not want | ||
235 | * host bridge to respond to PCI memory accesses of | ||
236 | * 0xFDxxxxxx. Do not want host bridge to respond | ||
237 | * to PCI memory addresses 0xFD000000-0xFDFFFFFF; | ||
238 | * want processor accesses from 0x000A0000-0x000BFFFF | ||
239 | * to be forwarded to system memory. | ||
240 | * | ||
241 | * Only valid if not in agent mode and using MAP B. | ||
242 | */ | ||
243 | if (new_map == MPC10X_MEM_MAP_B) { | ||
244 | early_read_config_byte(hose, | ||
245 | 0, | ||
246 | PCI_DEVFN(0,0), | ||
247 | MPC10X_CFG_MAPB_OPTIONS_REG, | ||
248 | &byte); | ||
249 | |||
250 | byte &= ~(MPC10X_CFG_MAPB_OPTIONS_PFAE | | ||
251 | MPC10X_CFG_MAPB_OPTIONS_PCICH | | ||
252 | MPC10X_CFG_MAPB_OPTIONS_PROCCH); | ||
253 | |||
254 | if (host_bridge != MPC10X_BRIDGE_106) { | ||
255 | byte |= MPC10X_CFG_MAPB_OPTIONS_CFAE; | ||
256 | } | ||
257 | |||
258 | early_write_config_byte(hose, | ||
259 | 0, | ||
260 | PCI_DEVFN(0,0), | ||
261 | MPC10X_CFG_MAPB_OPTIONS_REG, | ||
262 | byte); | ||
263 | } | ||
264 | |||
265 | if (host_bridge != MPC10X_BRIDGE_106) { | ||
266 | early_read_config_byte(hose, | ||
267 | 0, | ||
268 | PCI_DEVFN(0,0), | ||
269 | MPC10X_CFG_PIR_REG, | ||
270 | &pir); | ||
271 | |||
272 | if (pir != MPC10X_CFG_PIR_HOST_BRIDGE) { | ||
273 | printk("Host bridge in Agent mode\n"); | ||
274 | /* Read or Set LMBAR & PCSRBAR? */ | ||
275 | } | ||
276 | |||
277 | /* Set base addr of the 8240/107 EUMB. */ | ||
278 | early_write_config_dword(hose, | ||
279 | 0, | ||
280 | PCI_DEVFN(0,0), | ||
281 | MPC10X_CFG_EUMBBAR, | ||
282 | phys_eumb_base); | ||
283 | #ifdef CONFIG_MPC10X_OPENPIC | ||
284 | /* Map EPIC register part of EUMB into vitual memory - PCORE | ||
285 | uses an i8259 instead of EPIC. */ | ||
286 | OpenPIC_Addr = | ||
287 | ioremap(phys_eumb_base + MPC10X_EUMB_EPIC_OFFSET, | ||
288 | MPC10X_EUMB_EPIC_SIZE); | ||
289 | #endif | ||
290 | mpc10x_i2c_ocp.paddr = phys_eumb_base + MPC10X_EUMB_I2C_OFFSET; | ||
291 | mpc10x_i2c_ocp.irq = MPC10X_I2C_IRQ; | ||
292 | ocp_add_one_device(&mpc10x_i2c_ocp); | ||
293 | mpc10x_dma_ocp[0].paddr = phys_eumb_base + | ||
294 | MPC10X_EUMB_DMA_OFFSET + 0x100; | ||
295 | mpc10x_dma_ocp[0].irq = MPC10X_DMA0_IRQ; | ||
296 | ocp_add_one_device(&mpc10x_dma_ocp[0]); | ||
297 | mpc10x_dma_ocp[1].paddr = phys_eumb_base + | ||
298 | MPC10X_EUMB_DMA_OFFSET + 0x200; | ||
299 | mpc10x_dma_ocp[1].irq = MPC10X_DMA1_IRQ; | ||
300 | ocp_add_one_device(&mpc10x_dma_ocp[1]); | ||
301 | } | ||
302 | |||
303 | #ifdef CONFIG_MPC10X_STORE_GATHERING | ||
304 | mpc10x_enable_store_gathering(hose); | ||
305 | #else | ||
306 | mpc10x_disable_store_gathering(hose); | ||
307 | #endif | ||
308 | |||
309 | /* | ||
310 | * 8240 erratum 26, 8241/8245 erratum 29, 107 erratum 23: speculative | ||
311 | * PCI reads may return stale data so turn off. | ||
312 | */ | ||
313 | if ((host_bridge == MPC10X_BRIDGE_8240) | ||
314 | || (host_bridge == MPC10X_BRIDGE_8245) | ||
315 | || (host_bridge == MPC10X_BRIDGE_107)) { | ||
316 | |||
317 | early_read_config_dword(hose, 0, PCI_DEVFN(0,0), | ||
318 | MPC10X_CFG_PICR1_REG, &picr1); | ||
319 | |||
320 | picr1 &= ~MPC10X_CFG_PICR1_SPEC_PCI_RD; | ||
321 | |||
322 | early_write_config_dword(hose, 0, PCI_DEVFN(0,0), | ||
323 | MPC10X_CFG_PICR1_REG, picr1); | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | * 8241/8245 erratum 28: PCI reads from local memory may return | ||
328 | * stale data. Workaround by setting PICR2[0] to disable copyback | ||
329 | * optimization. Oddly, the latest available user manual for the | ||
330 | * 8245 (Rev 2., dated 10/2003) says PICR2[0] is reserverd. | ||
331 | */ | ||
332 | if (host_bridge == MPC10X_BRIDGE_8245) { | ||
333 | ulong picr2; | ||
334 | |||
335 | early_read_config_dword(hose, 0, PCI_DEVFN(0,0), | ||
336 | MPC10X_CFG_PICR2_REG, &picr2); | ||
337 | |||
338 | picr2 |= MPC10X_CFG_PICR2_COPYBACK_OPT; | ||
339 | |||
340 | early_write_config_dword(hose, 0, PCI_DEVFN(0,0), | ||
341 | MPC10X_CFG_PICR2_REG, picr2); | ||
342 | } | ||
343 | |||
344 | if (ppc_md.progress) ppc_md.progress("mpc10x:exit", 0x100); | ||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | /* | ||
349 | * Need to make our own PCI config space access macros because | ||
350 | * mpc10x_get_mem_size() is called before the data structures are set up for | ||
351 | * the 'early_xxx' and 'indirect_xxx' routines to work. | ||
352 | * Assumes bus 0. | ||
353 | */ | ||
354 | #define MPC10X_CFG_read(val, addr, type, op) *val = op((type)(addr)) | ||
355 | #define MPC10X_CFG_write(val, addr, type, op) op((type *)(addr), (val)) | ||
356 | |||
357 | #define MPC10X_PCI_OP(rw, size, type, op, mask) \ | ||
358 | static void \ | ||
359 | mpc10x_##rw##_config_##size(uint *cfg_addr, uint *cfg_data, int devfn, int offset, type val) \ | ||
360 | { \ | ||
361 | out_be32(cfg_addr, \ | ||
362 | ((offset & 0xfc) << 24) | (devfn << 16) \ | ||
363 | | (0 << 8) | 0x80); \ | ||
364 | MPC10X_CFG_##rw(val, cfg_data + (offset & mask), type, op); \ | ||
365 | return; \ | ||
366 | } | ||
367 | |||
368 | MPC10X_PCI_OP(read, byte, u8 *, in_8, 3) | ||
369 | MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0) | ||
370 | #if 0 /* Not used */ | ||
371 | MPC10X_PCI_OP(write, byte, u8, out_8, 3) | ||
372 | MPC10X_PCI_OP(read, word, u16 *, in_le16, 2) | ||
373 | MPC10X_PCI_OP(write, word, u16, out_le16, 2) | ||
374 | MPC10X_PCI_OP(write, dword, u32, out_le32, 0) | ||
375 | #endif | ||
376 | |||
377 | /* | ||
378 | * Read the memory controller registers to determine the amount of memory in | ||
379 | * the system. This assumes that the firmware has correctly set up the memory | ||
380 | * controller registers. | ||
381 | */ | ||
382 | unsigned long __init | ||
383 | mpc10x_get_mem_size(uint mem_map) | ||
384 | { | ||
385 | uint *config_addr, *config_data, val; | ||
386 | ulong start, end, total, offset; | ||
387 | int i; | ||
388 | u_char bank_enables; | ||
389 | |||
390 | switch (mem_map) { | ||
391 | case MPC10X_MEM_MAP_A: | ||
392 | config_addr = (uint *)MPC10X_MAPA_CNFG_ADDR; | ||
393 | config_data = (uint *)MPC10X_MAPA_CNFG_DATA; | ||
394 | break; | ||
395 | case MPC10X_MEM_MAP_B: | ||
396 | config_addr = (uint *)MPC10X_MAPB_CNFG_ADDR; | ||
397 | config_data = (uint *)MPC10X_MAPB_CNFG_DATA; | ||
398 | break; | ||
399 | default: | ||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | mpc10x_read_config_byte(config_addr, | ||
404 | config_data, | ||
405 | PCI_DEVFN(0,0), | ||
406 | MPC10X_MCTLR_MEM_BANK_ENABLES, | ||
407 | &bank_enables); | ||
408 | |||
409 | total = 0; | ||
410 | |||
411 | for (i=0; i<8; i++) { | ||
412 | if (bank_enables & (1 << i)) { | ||
413 | offset = MPC10X_MCTLR_MEM_START_1 + ((i > 3) ? 4 : 0); | ||
414 | mpc10x_read_config_dword(config_addr, | ||
415 | config_data, | ||
416 | PCI_DEVFN(0,0), | ||
417 | offset, | ||
418 | &val); | ||
419 | start = (val >> ((i & 3) << 3)) & 0xff; | ||
420 | |||
421 | offset = MPC10X_MCTLR_EXT_MEM_START_1 + ((i>3) ? 4 : 0); | ||
422 | mpc10x_read_config_dword(config_addr, | ||
423 | config_data, | ||
424 | PCI_DEVFN(0,0), | ||
425 | offset, | ||
426 | &val); | ||
427 | val = (val >> ((i & 3) << 3)) & 0x03; | ||
428 | start = (val << 28) | (start << 20); | ||
429 | |||
430 | offset = MPC10X_MCTLR_MEM_END_1 + ((i > 3) ? 4 : 0); | ||
431 | mpc10x_read_config_dword(config_addr, | ||
432 | config_data, | ||
433 | PCI_DEVFN(0,0), | ||
434 | offset, | ||
435 | &val); | ||
436 | end = (val >> ((i & 3) << 3)) & 0xff; | ||
437 | |||
438 | offset = MPC10X_MCTLR_EXT_MEM_END_1 + ((i > 3) ? 4 : 0); | ||
439 | mpc10x_read_config_dword(config_addr, | ||
440 | config_data, | ||
441 | PCI_DEVFN(0,0), | ||
442 | offset, | ||
443 | &val); | ||
444 | val = (val >> ((i & 3) << 3)) & 0x03; | ||
445 | end = (val << 28) | (end << 20) | 0xfffff; | ||
446 | |||
447 | total += (end - start + 1); | ||
448 | } | ||
449 | } | ||
450 | |||
451 | return total; | ||
452 | } | ||
453 | |||
454 | int __init | ||
455 | mpc10x_enable_store_gathering(struct pci_controller *hose) | ||
456 | { | ||
457 | uint picr1; | ||
458 | |||
459 | early_read_config_dword(hose, | ||
460 | 0, | ||
461 | PCI_DEVFN(0,0), | ||
462 | MPC10X_CFG_PICR1_REG, | ||
463 | &picr1); | ||
464 | |||
465 | picr1 |= MPC10X_CFG_PICR1_ST_GATH_EN; | ||
466 | |||
467 | early_write_config_dword(hose, | ||
468 | 0, | ||
469 | PCI_DEVFN(0,0), | ||
470 | MPC10X_CFG_PICR1_REG, | ||
471 | picr1); | ||
472 | |||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | int __init | ||
477 | mpc10x_disable_store_gathering(struct pci_controller *hose) | ||
478 | { | ||
479 | uint picr1; | ||
480 | |||
481 | early_read_config_dword(hose, | ||
482 | 0, | ||
483 | PCI_DEVFN(0,0), | ||
484 | MPC10X_CFG_PICR1_REG, | ||
485 | &picr1); | ||
486 | |||
487 | picr1 &= ~MPC10X_CFG_PICR1_ST_GATH_EN; | ||
488 | |||
489 | early_write_config_dword(hose, | ||
490 | 0, | ||
491 | PCI_DEVFN(0,0), | ||
492 | MPC10X_CFG_PICR1_REG, | ||
493 | picr1); | ||
494 | |||
495 | return 0; | ||
496 | } | ||
497 | |||
498 | #ifdef CONFIG_MPC10X_OPENPIC | ||
499 | void __init mpc10x_set_openpic(void) | ||
500 | { | ||
501 | /* Map external IRQs */ | ||
502 | openpic_set_sources(0, EPIC_IRQ_BASE, OpenPIC_Addr + 0x10200); | ||
503 | /* Skip reserved space and map i2c and DMA Ch[01] */ | ||
504 | openpic_set_sources(EPIC_IRQ_BASE, 3, OpenPIC_Addr + 0x11020); | ||
505 | /* Skip reserved space and map Message Unit Interrupt (I2O) */ | ||
506 | openpic_set_sources(EPIC_IRQ_BASE + 3, 1, OpenPIC_Addr + 0x110C0); | ||
507 | |||
508 | openpic_init(NUM_8259_INTERRUPTS); | ||
509 | } | ||
510 | #endif | ||