diff options
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r-- | arch/powerpc/sysdev/Makefile | 5 | ||||
-rw-r--r-- | arch/powerpc/sysdev/dart_iommu.c | 34 | ||||
-rw-r--r-- | arch/powerpc/sysdev/dcr-low.S | 39 | ||||
-rw-r--r-- | arch/powerpc/sysdev/dcr.c | 137 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_soc.c | 28 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 172 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe.c | 3 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/ucc_fast.c | 4 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/ucc_slow.c | 4 | ||||
-rw-r--r-- | arch/powerpc/sysdev/rom.c | 31 | ||||
-rw-r--r-- | arch/powerpc/sysdev/todc.c | 392 | ||||
-rw-r--r-- | arch/powerpc/sysdev/tsi108_pci.c | 48 |
12 files changed, 404 insertions, 493 deletions
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 91f052d8cce..6cc34597a62 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile | |||
@@ -5,14 +5,13 @@ endif | |||
5 | obj-$(CONFIG_MPIC) += mpic.o | 5 | obj-$(CONFIG_MPIC) += mpic.o |
6 | obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o | 6 | obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o |
7 | obj-$(CONFIG_PPC_MPC106) += grackle.o | 7 | obj-$(CONFIG_PPC_MPC106) += grackle.o |
8 | obj-$(CONFIG_BOOKE) += dcr.o | 8 | obj-$(CONFIG_PPC_DCR) += dcr.o dcr-low.o |
9 | obj-$(CONFIG_40x) += dcr.o | ||
10 | obj-$(CONFIG_U3_DART) += dart_iommu.o | 9 | obj-$(CONFIG_U3_DART) += dart_iommu.o |
11 | obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o | 10 | obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o |
12 | obj-$(CONFIG_FSL_SOC) += fsl_soc.o | 11 | obj-$(CONFIG_FSL_SOC) += fsl_soc.o |
13 | obj-$(CONFIG_PPC_TODC) += todc.o | ||
14 | obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o | 12 | obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o |
15 | obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ | 13 | obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ |
14 | obj-$(CONFIG_MTD) += rom.o | ||
16 | 15 | ||
17 | ifeq ($(CONFIG_PPC_MERGE),y) | 16 | ifeq ($(CONFIG_PPC_MERGE),y) |
18 | obj-$(CONFIG_PPC_I8259) += i8259.o | 17 | obj-$(CONFIG_PPC_I8259) += i8259.o |
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 572b7846cc7..1488535b0e1 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c | |||
@@ -48,9 +48,6 @@ | |||
48 | 48 | ||
49 | #include "dart.h" | 49 | #include "dart.h" |
50 | 50 | ||
51 | extern int iommu_is_off; | ||
52 | extern int iommu_force_on; | ||
53 | |||
54 | /* Physical base address and size of the DART table */ | 51 | /* Physical base address and size of the DART table */ |
55 | unsigned long dart_tablebase; /* exported to htab_initialize */ | 52 | unsigned long dart_tablebase; /* exported to htab_initialize */ |
56 | static unsigned long dart_tablesize; | 53 | static unsigned long dart_tablesize; |
@@ -289,24 +286,15 @@ static void iommu_table_dart_setup(void) | |||
289 | set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map); | 286 | set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map); |
290 | } | 287 | } |
291 | 288 | ||
292 | static void iommu_dev_setup_dart(struct pci_dev *dev) | 289 | static void pci_dma_dev_setup_dart(struct pci_dev *dev) |
293 | { | 290 | { |
294 | struct device_node *dn; | ||
295 | |||
296 | /* We only have one iommu table on the mac for now, which makes | 291 | /* We only have one iommu table on the mac for now, which makes |
297 | * things simple. Setup all PCI devices to point to this table | 292 | * things simple. Setup all PCI devices to point to this table |
298 | * | ||
299 | * We must use pci_device_to_OF_node() to make sure that | ||
300 | * we get the real "final" pointer to the device in the | ||
301 | * pci_dev sysdata and not the temporary PHB one | ||
302 | */ | 293 | */ |
303 | dn = pci_device_to_OF_node(dev); | 294 | dev->dev.archdata.dma_data = &iommu_table_dart; |
304 | |||
305 | if (dn) | ||
306 | PCI_DN(dn)->iommu_table = &iommu_table_dart; | ||
307 | } | 295 | } |
308 | 296 | ||
309 | static void iommu_bus_setup_dart(struct pci_bus *bus) | 297 | static void pci_dma_bus_setup_dart(struct pci_bus *bus) |
310 | { | 298 | { |
311 | struct device_node *dn; | 299 | struct device_node *dn; |
312 | 300 | ||
@@ -321,9 +309,6 @@ static void iommu_bus_setup_dart(struct pci_bus *bus) | |||
321 | PCI_DN(dn)->iommu_table = &iommu_table_dart; | 309 | PCI_DN(dn)->iommu_table = &iommu_table_dart; |
322 | } | 310 | } |
323 | 311 | ||
324 | static void iommu_dev_setup_null(struct pci_dev *dev) { } | ||
325 | static void iommu_bus_setup_null(struct pci_bus *bus) { } | ||
326 | |||
327 | void iommu_init_early_dart(void) | 312 | void iommu_init_early_dart(void) |
328 | { | 313 | { |
329 | struct device_node *dn; | 314 | struct device_node *dn; |
@@ -344,22 +329,21 @@ void iommu_init_early_dart(void) | |||
344 | 329 | ||
345 | /* Initialize the DART HW */ | 330 | /* Initialize the DART HW */ |
346 | if (dart_init(dn) == 0) { | 331 | if (dart_init(dn) == 0) { |
347 | ppc_md.iommu_dev_setup = iommu_dev_setup_dart; | 332 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_dart; |
348 | ppc_md.iommu_bus_setup = iommu_bus_setup_dart; | 333 | ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_dart; |
349 | 334 | ||
350 | /* Setup pci_dma ops */ | 335 | /* Setup pci_dma ops */ |
351 | pci_iommu_init(); | 336 | pci_dma_ops = &dma_iommu_ops; |
352 | |||
353 | return; | 337 | return; |
354 | } | 338 | } |
355 | 339 | ||
356 | bail: | 340 | bail: |
357 | /* If init failed, use direct iommu and null setup functions */ | 341 | /* If init failed, use direct iommu and null setup functions */ |
358 | ppc_md.iommu_dev_setup = iommu_dev_setup_null; | 342 | ppc_md.pci_dma_dev_setup = NULL; |
359 | ppc_md.iommu_bus_setup = iommu_bus_setup_null; | 343 | ppc_md.pci_dma_bus_setup = NULL; |
360 | 344 | ||
361 | /* Setup pci_dma ops */ | 345 | /* Setup pci_dma ops */ |
362 | pci_direct_iommu_init(); | 346 | pci_dma_ops = &dma_direct_ops; |
363 | } | 347 | } |
364 | 348 | ||
365 | 349 | ||
diff --git a/arch/powerpc/sysdev/dcr-low.S b/arch/powerpc/sysdev/dcr-low.S new file mode 100644 index 00000000000..2078f39e2f1 --- /dev/null +++ b/arch/powerpc/sysdev/dcr-low.S | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * "Indirect" DCR access | ||
3 | * | ||
4 | * Copyright (c) 2004 Eugene Surovegin <ebs@ebshome.net> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <asm/ppc_asm.h> | ||
13 | #include <asm/processor.h> | ||
14 | |||
15 | #define DCR_ACCESS_PROLOG(table) \ | ||
16 | rlwinm r3,r3,4,18,27; \ | ||
17 | lis r5,table@h; \ | ||
18 | ori r5,r5,table@l; \ | ||
19 | add r3,r3,r5; \ | ||
20 | mtctr r3; \ | ||
21 | bctr | ||
22 | |||
23 | _GLOBAL(__mfdcr) | ||
24 | DCR_ACCESS_PROLOG(__mfdcr_table) | ||
25 | |||
26 | _GLOBAL(__mtdcr) | ||
27 | DCR_ACCESS_PROLOG(__mtdcr_table) | ||
28 | |||
29 | __mfdcr_table: | ||
30 | mfdcr r3,0; blr | ||
31 | __mtdcr_table: | ||
32 | mtdcr 0,r4; blr | ||
33 | |||
34 | dcr = 1 | ||
35 | .rept 1023 | ||
36 | mfdcr r3,dcr; blr | ||
37 | mtdcr dcr,r4; blr | ||
38 | dcr = dcr + 1 | ||
39 | .endr | ||
diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c new file mode 100644 index 00000000000..dffeeaeca1d --- /dev/null +++ b/arch/powerpc/sysdev/dcr.c | |||
@@ -0,0 +1,137 @@ | |||
1 | /* | ||
2 | * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp. | ||
3 | * <benh@kernel.crashing.org> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
13 | * the GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #undef DEBUG | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <asm/prom.h> | ||
24 | #include <asm/dcr.h> | ||
25 | |||
26 | unsigned int dcr_resource_start(struct device_node *np, unsigned int index) | ||
27 | { | ||
28 | unsigned int ds; | ||
29 | const u32 *dr = get_property(np, "dcr-reg", &ds); | ||
30 | |||
31 | if (dr == NULL || ds & 1 || index >= (ds / 8)) | ||
32 | return 0; | ||
33 | |||
34 | return dr[index * 2]; | ||
35 | } | ||
36 | |||
37 | unsigned int dcr_resource_len(struct device_node *np, unsigned int index) | ||
38 | { | ||
39 | unsigned int ds; | ||
40 | const u32 *dr = get_property(np, "dcr-reg", &ds); | ||
41 | |||
42 | if (dr == NULL || ds & 1 || index >= (ds / 8)) | ||
43 | return 0; | ||
44 | |||
45 | return dr[index * 2 + 1]; | ||
46 | } | ||
47 | |||
48 | #ifndef CONFIG_PPC_DCR_NATIVE | ||
49 | |||
50 | static struct device_node * find_dcr_parent(struct device_node * node) | ||
51 | { | ||
52 | struct device_node *par, *tmp; | ||
53 | const u32 *p; | ||
54 | |||
55 | for (par = of_node_get(node); par;) { | ||
56 | if (get_property(par, "dcr-controller", NULL)) | ||
57 | break; | ||
58 | p = get_property(par, "dcr-parent", NULL); | ||
59 | tmp = par; | ||
60 | if (p == NULL) | ||
61 | par = of_get_parent(par); | ||
62 | else | ||
63 | par = of_find_node_by_phandle(*p); | ||
64 | of_node_put(tmp); | ||
65 | } | ||
66 | return par; | ||
67 | } | ||
68 | |||
69 | u64 of_translate_dcr_address(struct device_node *dev, | ||
70 | unsigned int dcr_n, | ||
71 | unsigned int *out_stride) | ||
72 | { | ||
73 | struct device_node *dp; | ||
74 | const u32 *p; | ||
75 | unsigned int stride; | ||
76 | u64 ret; | ||
77 | |||
78 | dp = find_dcr_parent(dev); | ||
79 | if (dp == NULL) | ||
80 | return OF_BAD_ADDR; | ||
81 | |||
82 | /* Stride is not properly defined yet, default to 0x10 for Axon */ | ||
83 | p = get_property(dp, "dcr-mmio-stride", NULL); | ||
84 | stride = (p == NULL) ? 0x10 : *p; | ||
85 | |||
86 | /* XXX FIXME: Which property name is to use of the 2 following ? */ | ||
87 | p = get_property(dp, "dcr-mmio-range", NULL); | ||
88 | if (p == NULL) | ||
89 | p = get_property(dp, "dcr-mmio-space", NULL); | ||
90 | if (p == NULL) | ||
91 | return OF_BAD_ADDR; | ||
92 | |||
93 | /* Maybe could do some better range checking here */ | ||
94 | ret = of_translate_address(dp, p); | ||
95 | if (ret != OF_BAD_ADDR) | ||
96 | ret += (u64)(stride) * (u64)dcr_n; | ||
97 | if (out_stride) | ||
98 | *out_stride = stride; | ||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n, | ||
103 | unsigned int dcr_c) | ||
104 | { | ||
105 | dcr_host_t ret = { .token = NULL, .stride = 0 }; | ||
106 | u64 addr; | ||
107 | |||
108 | pr_debug("dcr_map(%s, 0x%x, 0x%x)\n", | ||
109 | dev->full_name, dcr_n, dcr_c); | ||
110 | |||
111 | addr = of_translate_dcr_address(dev, dcr_n, &ret.stride); | ||
112 | pr_debug("translates to addr: 0x%lx, stride: 0x%x\n", | ||
113 | addr, ret.stride); | ||
114 | if (addr == OF_BAD_ADDR) | ||
115 | return ret; | ||
116 | pr_debug("mapping 0x%x bytes\n", dcr_c * ret.stride); | ||
117 | ret.token = ioremap(addr, dcr_c * ret.stride); | ||
118 | if (ret.token == NULL) | ||
119 | return ret; | ||
120 | pr_debug("mapped at 0x%p -> base is 0x%p\n", | ||
121 | ret.token, ret.token - dcr_n * ret.stride); | ||
122 | ret.token -= dcr_n * ret.stride; | ||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c) | ||
127 | { | ||
128 | dcr_host_t h = host; | ||
129 | |||
130 | if (h.token == NULL) | ||
131 | return; | ||
132 | h.token -= dcr_n * h.stride; | ||
133 | iounmap(h.token); | ||
134 | h.token = NULL; | ||
135 | } | ||
136 | |||
137 | #endif /* !defined(CONFIG_PPC_DCR_NATIVE) */ | ||
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index dbe92ae2033..ad31e56e892 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/device.h> | 23 | #include <linux/device.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/phy.h> | ||
25 | #include <linux/fsl_devices.h> | 26 | #include <linux/fsl_devices.h> |
26 | #include <linux/fs_enet_pd.h> | 27 | #include <linux/fs_enet_pd.h> |
27 | #include <linux/fs_uart_pd.h> | 28 | #include <linux/fs_uart_pd.h> |
@@ -146,7 +147,7 @@ static int __init gfar_mdio_of_init(void) | |||
146 | } | 147 | } |
147 | 148 | ||
148 | for (k = 0; k < 32; k++) | 149 | for (k = 0; k < 32; k++) |
149 | mdio_data.irq[k] = -1; | 150 | mdio_data.irq[k] = PHY_POLL; |
150 | 151 | ||
151 | while ((child = of_get_next_child(np, child)) != NULL) { | 152 | while ((child = of_get_next_child(np, child)) != NULL) { |
152 | int irq = irq_of_parse_and_map(child, 0); | 153 | int irq = irq_of_parse_and_map(child, 0); |
@@ -177,6 +178,7 @@ static const char *gfar_tx_intr = "tx"; | |||
177 | static const char *gfar_rx_intr = "rx"; | 178 | static const char *gfar_rx_intr = "rx"; |
178 | static const char *gfar_err_intr = "error"; | 179 | static const char *gfar_err_intr = "error"; |
179 | 180 | ||
181 | |||
180 | static int __init gfar_of_init(void) | 182 | static int __init gfar_of_init(void) |
181 | { | 183 | { |
182 | struct device_node *np; | 184 | struct device_node *np; |
@@ -204,8 +206,7 @@ static int __init gfar_of_init(void) | |||
204 | if (ret) | 206 | if (ret) |
205 | goto err; | 207 | goto err; |
206 | 208 | ||
207 | r[1].start = r[1].end = irq_of_parse_and_map(np, 0); | 209 | of_irq_to_resource(np, 0, &r[1]); |
208 | r[1].flags = IORESOURCE_IRQ; | ||
209 | 210 | ||
210 | model = get_property(np, "model", NULL); | 211 | model = get_property(np, "model", NULL); |
211 | 212 | ||
@@ -214,12 +215,10 @@ static int __init gfar_of_init(void) | |||
214 | r[1].name = gfar_tx_intr; | 215 | r[1].name = gfar_tx_intr; |
215 | 216 | ||
216 | r[2].name = gfar_rx_intr; | 217 | r[2].name = gfar_rx_intr; |
217 | r[2].start = r[2].end = irq_of_parse_and_map(np, 1); | 218 | of_irq_to_resource(np, 1, &r[2]); |
218 | r[2].flags = IORESOURCE_IRQ; | ||
219 | 219 | ||
220 | r[3].name = gfar_err_intr; | 220 | r[3].name = gfar_err_intr; |
221 | r[3].start = r[3].end = irq_of_parse_and_map(np, 2); | 221 | of_irq_to_resource(np, 2, &r[3]); |
222 | r[3].flags = IORESOURCE_IRQ; | ||
223 | 222 | ||
224 | n_res += 2; | 223 | n_res += 2; |
225 | } | 224 | } |
@@ -323,8 +322,7 @@ static int __init fsl_i2c_of_init(void) | |||
323 | if (ret) | 322 | if (ret) |
324 | goto err; | 323 | goto err; |
325 | 324 | ||
326 | r[1].start = r[1].end = irq_of_parse_and_map(np, 0); | 325 | of_irq_to_resource(np, 0, &r[1]); |
327 | r[1].flags = IORESOURCE_IRQ; | ||
328 | 326 | ||
329 | i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2); | 327 | i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2); |
330 | if (IS_ERR(i2c_dev)) { | 328 | if (IS_ERR(i2c_dev)) { |
@@ -459,8 +457,7 @@ static int __init fsl_usb_of_init(void) | |||
459 | if (ret) | 457 | if (ret) |
460 | goto err; | 458 | goto err; |
461 | 459 | ||
462 | r[1].start = r[1].end = irq_of_parse_and_map(np, 0); | 460 | of_irq_to_resource(np, 0, &r[1]); |
463 | r[1].flags = IORESOURCE_IRQ; | ||
464 | 461 | ||
465 | usb_dev_mph = | 462 | usb_dev_mph = |
466 | platform_device_register_simple("fsl-ehci", i, r, 2); | 463 | platform_device_register_simple("fsl-ehci", i, r, 2); |
@@ -507,8 +504,7 @@ static int __init fsl_usb_of_init(void) | |||
507 | if (ret) | 504 | if (ret) |
508 | goto unreg_mph; | 505 | goto unreg_mph; |
509 | 506 | ||
510 | r[1].start = r[1].end = irq_of_parse_and_map(np, 0); | 507 | of_irq_to_resource(np, 0, &r[1]); |
511 | r[1].flags = IORESOURCE_IRQ; | ||
512 | 508 | ||
513 | usb_dev_dr = | 509 | usb_dev_dr = |
514 | platform_device_register_simple("fsl-ehci", i, r, 2); | 510 | platform_device_register_simple("fsl-ehci", i, r, 2); |
@@ -591,8 +587,7 @@ static int __init fs_enet_of_init(void) | |||
591 | r[2].name = fcc_regs_c; | 587 | r[2].name = fcc_regs_c; |
592 | fs_enet_data.fcc_regs_c = r[2].start; | 588 | fs_enet_data.fcc_regs_c = r[2].start; |
593 | 589 | ||
594 | r[3].start = r[3].end = irq_of_parse_and_map(np, 0); | 590 | of_irq_to_resource(np, 0, &r[3]); |
595 | r[3].flags = IORESOURCE_IRQ; | ||
596 | 591 | ||
597 | fs_enet_dev = | 592 | fs_enet_dev = |
598 | platform_device_register_simple("fsl-cpm-fcc", i, &r[0], 4); | 593 | platform_device_register_simple("fsl-cpm-fcc", i, &r[0], 4); |
@@ -754,8 +749,7 @@ static int __init cpm_uart_of_init(void) | |||
754 | goto err; | 749 | goto err; |
755 | r[1].name = scc_pram; | 750 | r[1].name = scc_pram; |
756 | 751 | ||
757 | r[2].start = r[2].end = irq_of_parse_and_map(np, 0); | 752 | of_irq_to_resource(np, 0, &r[2]); |
758 | r[2].flags = IORESOURCE_IRQ; | ||
759 | 753 | ||
760 | cpm_uart_dev = | 754 | cpm_uart_dev = |
761 | platform_device_register_simple("fsl-cpm-scc:uart", i, &r[0], 3); | 755 | platform_device_register_simple("fsl-cpm-scc:uart", i, &r[0], 3); |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index ba4833f57d4..411480d5c62 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -147,33 +147,51 @@ static u32 mpic_infos[][MPIC_IDX_END] = { | |||
147 | */ | 147 | */ |
148 | 148 | ||
149 | 149 | ||
150 | static inline u32 _mpic_read(unsigned int be, volatile u32 __iomem *base, | 150 | static inline u32 _mpic_read(enum mpic_reg_type type, |
151 | unsigned int reg) | 151 | struct mpic_reg_bank *rb, |
152 | unsigned int reg) | ||
152 | { | 153 | { |
153 | if (be) | 154 | switch(type) { |
154 | return in_be32(base + (reg >> 2)); | 155 | #ifdef CONFIG_PPC_DCR |
155 | else | 156 | case mpic_access_dcr: |
156 | return in_le32(base + (reg >> 2)); | 157 | return dcr_read(rb->dhost, |
158 | rb->dbase + reg + rb->doff); | ||
159 | #endif | ||
160 | case mpic_access_mmio_be: | ||
161 | return in_be32(rb->base + (reg >> 2)); | ||
162 | case mpic_access_mmio_le: | ||
163 | default: | ||
164 | return in_le32(rb->base + (reg >> 2)); | ||
165 | } | ||
157 | } | 166 | } |
158 | 167 | ||
159 | static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base, | 168 | static inline void _mpic_write(enum mpic_reg_type type, |
160 | unsigned int reg, u32 value) | 169 | struct mpic_reg_bank *rb, |
170 | unsigned int reg, u32 value) | ||
161 | { | 171 | { |
162 | if (be) | 172 | switch(type) { |
163 | out_be32(base + (reg >> 2), value); | 173 | #ifdef CONFIG_PPC_DCR |
164 | else | 174 | case mpic_access_dcr: |
165 | out_le32(base + (reg >> 2), value); | 175 | return dcr_write(rb->dhost, |
176 | rb->dbase + reg + rb->doff, value); | ||
177 | #endif | ||
178 | case mpic_access_mmio_be: | ||
179 | return out_be32(rb->base + (reg >> 2), value); | ||
180 | case mpic_access_mmio_le: | ||
181 | default: | ||
182 | return out_le32(rb->base + (reg >> 2), value); | ||
183 | } | ||
166 | } | 184 | } |
167 | 185 | ||
168 | static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi) | 186 | static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi) |
169 | { | 187 | { |
170 | unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0; | 188 | enum mpic_reg_type type = mpic->reg_type; |
171 | unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) + | 189 | unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) + |
172 | (ipi * MPIC_INFO(GREG_IPI_STRIDE)); | 190 | (ipi * MPIC_INFO(GREG_IPI_STRIDE)); |
173 | 191 | ||
174 | if (mpic->flags & MPIC_BROKEN_IPI) | 192 | if ((mpic->flags & MPIC_BROKEN_IPI) && type == mpic_access_mmio_le) |
175 | be = !be; | 193 | type = mpic_access_mmio_be; |
176 | return _mpic_read(be, mpic->gregs, offset); | 194 | return _mpic_read(type, &mpic->gregs, offset); |
177 | } | 195 | } |
178 | 196 | ||
179 | static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value) | 197 | static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value) |
@@ -181,7 +199,7 @@ static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 valu | |||
181 | unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) + | 199 | unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) + |
182 | (ipi * MPIC_INFO(GREG_IPI_STRIDE)); | 200 | (ipi * MPIC_INFO(GREG_IPI_STRIDE)); |
183 | 201 | ||
184 | _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value); | 202 | _mpic_write(mpic->reg_type, &mpic->gregs, offset, value); |
185 | } | 203 | } |
186 | 204 | ||
187 | static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg) | 205 | static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg) |
@@ -190,8 +208,7 @@ static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg) | |||
190 | 208 | ||
191 | if (mpic->flags & MPIC_PRIMARY) | 209 | if (mpic->flags & MPIC_PRIMARY) |
192 | cpu = hard_smp_processor_id(); | 210 | cpu = hard_smp_processor_id(); |
193 | return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, | 211 | return _mpic_read(mpic->reg_type, &mpic->cpuregs[cpu], reg); |
194 | mpic->cpuregs[cpu], reg); | ||
195 | } | 212 | } |
196 | 213 | ||
197 | static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 value) | 214 | static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 value) |
@@ -201,7 +218,7 @@ static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 valu | |||
201 | if (mpic->flags & MPIC_PRIMARY) | 218 | if (mpic->flags & MPIC_PRIMARY) |
202 | cpu = hard_smp_processor_id(); | 219 | cpu = hard_smp_processor_id(); |
203 | 220 | ||
204 | _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->cpuregs[cpu], reg, value); | 221 | _mpic_write(mpic->reg_type, &mpic->cpuregs[cpu], reg, value); |
205 | } | 222 | } |
206 | 223 | ||
207 | static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigned int reg) | 224 | static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigned int reg) |
@@ -209,7 +226,7 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigne | |||
209 | unsigned int isu = src_no >> mpic->isu_shift; | 226 | unsigned int isu = src_no >> mpic->isu_shift; |
210 | unsigned int idx = src_no & mpic->isu_mask; | 227 | unsigned int idx = src_no & mpic->isu_mask; |
211 | 228 | ||
212 | return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], | 229 | return _mpic_read(mpic->reg_type, &mpic->isus[isu], |
213 | reg + (idx * MPIC_INFO(IRQ_STRIDE))); | 230 | reg + (idx * MPIC_INFO(IRQ_STRIDE))); |
214 | } | 231 | } |
215 | 232 | ||
@@ -219,12 +236,12 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, | |||
219 | unsigned int isu = src_no >> mpic->isu_shift; | 236 | unsigned int isu = src_no >> mpic->isu_shift; |
220 | unsigned int idx = src_no & mpic->isu_mask; | 237 | unsigned int idx = src_no & mpic->isu_mask; |
221 | 238 | ||
222 | _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], | 239 | _mpic_write(mpic->reg_type, &mpic->isus[isu], |
223 | reg + (idx * MPIC_INFO(IRQ_STRIDE)), value); | 240 | reg + (idx * MPIC_INFO(IRQ_STRIDE)), value); |
224 | } | 241 | } |
225 | 242 | ||
226 | #define mpic_read(b,r) _mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r)) | 243 | #define mpic_read(b,r) _mpic_read(mpic->reg_type,&(b),(r)) |
227 | #define mpic_write(b,r,v) _mpic_write(mpic->flags & MPIC_BIG_ENDIAN,(b),(r),(v)) | 244 | #define mpic_write(b,r,v) _mpic_write(mpic->reg_type,&(b),(r),(v)) |
228 | #define mpic_ipi_read(i) _mpic_ipi_read(mpic,(i)) | 245 | #define mpic_ipi_read(i) _mpic_ipi_read(mpic,(i)) |
229 | #define mpic_ipi_write(i,v) _mpic_ipi_write(mpic,(i),(v)) | 246 | #define mpic_ipi_write(i,v) _mpic_ipi_write(mpic,(i),(v)) |
230 | #define mpic_cpu_read(i) _mpic_cpu_read(mpic,(i)) | 247 | #define mpic_cpu_read(i) _mpic_cpu_read(mpic,(i)) |
@@ -238,6 +255,38 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, | |||
238 | */ | 255 | */ |
239 | 256 | ||
240 | 257 | ||
258 | static void _mpic_map_mmio(struct mpic *mpic, unsigned long phys_addr, | ||
259 | struct mpic_reg_bank *rb, unsigned int offset, | ||
260 | unsigned int size) | ||
261 | { | ||
262 | rb->base = ioremap(phys_addr + offset, size); | ||
263 | BUG_ON(rb->base == NULL); | ||
264 | } | ||
265 | |||
266 | #ifdef CONFIG_PPC_DCR | ||
267 | static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb, | ||
268 | unsigned int offset, unsigned int size) | ||
269 | { | ||
270 | rb->dbase = mpic->dcr_base; | ||
271 | rb->doff = offset; | ||
272 | rb->dhost = dcr_map(mpic->of_node, rb->dbase + rb->doff, size); | ||
273 | BUG_ON(!DCR_MAP_OK(rb->dhost)); | ||
274 | } | ||
275 | |||
276 | static inline void mpic_map(struct mpic *mpic, unsigned long phys_addr, | ||
277 | struct mpic_reg_bank *rb, unsigned int offset, | ||
278 | unsigned int size) | ||
279 | { | ||
280 | if (mpic->flags & MPIC_USES_DCR) | ||
281 | _mpic_map_dcr(mpic, rb, offset, size); | ||
282 | else | ||
283 | _mpic_map_mmio(mpic, phys_addr, rb, offset, size); | ||
284 | } | ||
285 | #else /* CONFIG_PPC_DCR */ | ||
286 | #define mpic_map(m,p,b,o,s) _mpic_map_mmio(m,p,b,o,s) | ||
287 | #endif /* !CONFIG_PPC_DCR */ | ||
288 | |||
289 | |||
241 | 290 | ||
242 | /* Check if we have one of those nice broken MPICs with a flipped endian on | 291 | /* Check if we have one of those nice broken MPICs with a flipped endian on |
243 | * reads from IPI registers | 292 | * reads from IPI registers |
@@ -845,7 +894,7 @@ static struct irq_host_ops mpic_host_ops = { | |||
845 | */ | 894 | */ |
846 | 895 | ||
847 | struct mpic * __init mpic_alloc(struct device_node *node, | 896 | struct mpic * __init mpic_alloc(struct device_node *node, |
848 | unsigned long phys_addr, | 897 | phys_addr_t phys_addr, |
849 | unsigned int flags, | 898 | unsigned int flags, |
850 | unsigned int isu_size, | 899 | unsigned int isu_size, |
851 | unsigned int irq_count, | 900 | unsigned int irq_count, |
@@ -855,6 +904,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
855 | u32 reg; | 904 | u32 reg; |
856 | const char *vers; | 905 | const char *vers; |
857 | int i; | 906 | int i; |
907 | u64 paddr = phys_addr; | ||
858 | 908 | ||
859 | mpic = alloc_bootmem(sizeof(struct mpic)); | 909 | mpic = alloc_bootmem(sizeof(struct mpic)); |
860 | if (mpic == NULL) | 910 | if (mpic == NULL) |
@@ -883,6 +933,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
883 | if (flags & MPIC_PRIMARY) | 933 | if (flags & MPIC_PRIMARY) |
884 | mpic->hc_ht_irq.set_affinity = mpic_set_affinity; | 934 | mpic->hc_ht_irq.set_affinity = mpic_set_affinity; |
885 | #endif /* CONFIG_MPIC_BROKEN_U3 */ | 935 | #endif /* CONFIG_MPIC_BROKEN_U3 */ |
936 | |||
886 | #ifdef CONFIG_SMP | 937 | #ifdef CONFIG_SMP |
887 | mpic->hc_ipi = mpic_ipi_chip; | 938 | mpic->hc_ipi = mpic_ipi_chip; |
888 | mpic->hc_ipi.typename = name; | 939 | mpic->hc_ipi.typename = name; |
@@ -893,15 +944,52 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
893 | mpic->irq_count = irq_count; | 944 | mpic->irq_count = irq_count; |
894 | mpic->num_sources = 0; /* so far */ | 945 | mpic->num_sources = 0; /* so far */ |
895 | 946 | ||
947 | /* Check for "big-endian" in device-tree */ | ||
948 | if (node && get_property(node, "big-endian", NULL) != NULL) | ||
949 | mpic->flags |= MPIC_BIG_ENDIAN; | ||
950 | |||
951 | |||
896 | #ifdef CONFIG_MPIC_WEIRD | 952 | #ifdef CONFIG_MPIC_WEIRD |
897 | mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)]; | 953 | mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)]; |
898 | #endif | 954 | #endif |
899 | 955 | ||
956 | /* default register type */ | ||
957 | mpic->reg_type = (flags & MPIC_BIG_ENDIAN) ? | ||
958 | mpic_access_mmio_be : mpic_access_mmio_le; | ||
959 | |||
960 | /* If no physical address is passed in, a device-node is mandatory */ | ||
961 | BUG_ON(paddr == 0 && node == NULL); | ||
962 | |||
963 | /* If no physical address passed in, check if it's dcr based */ | ||
964 | if (paddr == 0 && get_property(node, "dcr-reg", NULL) != NULL) | ||
965 | mpic->flags |= MPIC_USES_DCR; | ||
966 | |||
967 | #ifdef CONFIG_PPC_DCR | ||
968 | if (mpic->flags & MPIC_USES_DCR) { | ||
969 | const u32 *dbasep; | ||
970 | dbasep = get_property(node, "dcr-reg", NULL); | ||
971 | BUG_ON(dbasep == NULL); | ||
972 | mpic->dcr_base = *dbasep; | ||
973 | mpic->reg_type = mpic_access_dcr; | ||
974 | } | ||
975 | #else | ||
976 | BUG_ON (mpic->flags & MPIC_USES_DCR); | ||
977 | #endif /* CONFIG_PPC_DCR */ | ||
978 | |||
979 | /* If the MPIC is not DCR based, and no physical address was passed | ||
980 | * in, try to obtain one | ||
981 | */ | ||
982 | if (paddr == 0 && !(mpic->flags & MPIC_USES_DCR)) { | ||
983 | const u32 *reg; | ||
984 | reg = get_property(node, "reg", NULL); | ||
985 | BUG_ON(reg == NULL); | ||
986 | paddr = of_translate_address(node, reg); | ||
987 | BUG_ON(paddr == OF_BAD_ADDR); | ||
988 | } | ||
989 | |||
900 | /* Map the global registers */ | 990 | /* Map the global registers */ |
901 | mpic->gregs = ioremap(phys_addr + MPIC_INFO(GREG_BASE), 0x1000); | 991 | mpic_map(mpic, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); |
902 | mpic->tmregs = mpic->gregs + | 992 | mpic_map(mpic, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); |
903 | ((MPIC_INFO(TIMER_BASE) - MPIC_INFO(GREG_BASE)) >> 2); | ||
904 | BUG_ON(mpic->gregs == NULL); | ||
905 | 993 | ||
906 | /* Reset */ | 994 | /* Reset */ |
907 | if (flags & MPIC_WANTS_RESET) { | 995 | if (flags & MPIC_WANTS_RESET) { |
@@ -926,17 +1014,16 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
926 | 1014 | ||
927 | /* Map the per-CPU registers */ | 1015 | /* Map the per-CPU registers */ |
928 | for (i = 0; i < mpic->num_cpus; i++) { | 1016 | for (i = 0; i < mpic->num_cpus; i++) { |
929 | mpic->cpuregs[i] = ioremap(phys_addr + MPIC_INFO(CPU_BASE) + | 1017 | mpic_map(mpic, paddr, &mpic->cpuregs[i], |
930 | i * MPIC_INFO(CPU_STRIDE), 0x1000); | 1018 | MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE), |
931 | BUG_ON(mpic->cpuregs[i] == NULL); | 1019 | 0x1000); |
932 | } | 1020 | } |
933 | 1021 | ||
934 | /* Initialize main ISU if none provided */ | 1022 | /* Initialize main ISU if none provided */ |
935 | if (mpic->isu_size == 0) { | 1023 | if (mpic->isu_size == 0) { |
936 | mpic->isu_size = mpic->num_sources; | 1024 | mpic->isu_size = mpic->num_sources; |
937 | mpic->isus[0] = ioremap(phys_addr + MPIC_INFO(IRQ_BASE), | 1025 | mpic_map(mpic, paddr, &mpic->isus[0], |
938 | MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); | 1026 | MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); |
939 | BUG_ON(mpic->isus[0] == NULL); | ||
940 | } | 1027 | } |
941 | mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); | 1028 | mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); |
942 | mpic->isu_mask = (1 << mpic->isu_shift) - 1; | 1029 | mpic->isu_mask = (1 << mpic->isu_shift) - 1; |
@@ -956,10 +1043,11 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
956 | vers = "<unknown>"; | 1043 | vers = "<unknown>"; |
957 | break; | 1044 | break; |
958 | } | 1045 | } |
959 | printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %lx, max %d CPUs\n", | 1046 | printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx," |
960 | name, vers, phys_addr, mpic->num_cpus); | 1047 | " max %d CPUs\n", |
961 | printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", mpic->isu_size, | 1048 | name, vers, (unsigned long long)paddr, mpic->num_cpus); |
962 | mpic->isu_shift, mpic->isu_mask); | 1049 | printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", |
1050 | mpic->isu_size, mpic->isu_shift, mpic->isu_mask); | ||
963 | 1051 | ||
964 | mpic->next = mpics; | 1052 | mpic->next = mpics; |
965 | mpics = mpic; | 1053 | mpics = mpic; |
@@ -973,14 +1061,14 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
973 | } | 1061 | } |
974 | 1062 | ||
975 | void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, | 1063 | void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, |
976 | unsigned long phys_addr) | 1064 | phys_addr_t paddr) |
977 | { | 1065 | { |
978 | unsigned int isu_first = isu_num * mpic->isu_size; | 1066 | unsigned int isu_first = isu_num * mpic->isu_size; |
979 | 1067 | ||
980 | BUG_ON(isu_num >= MPIC_MAX_ISU); | 1068 | BUG_ON(isu_num >= MPIC_MAX_ISU); |
981 | 1069 | ||
982 | mpic->isus[isu_num] = ioremap(phys_addr, | 1070 | mpic_map(mpic, paddr, &mpic->isus[isu_num], 0, |
983 | MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); | 1071 | MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); |
984 | if ((isu_first + mpic->isu_size) > mpic->num_sources) | 1072 | if ((isu_first + mpic->isu_size) > mpic->num_sources) |
985 | mpic->num_sources = isu_first + mpic->isu_size; | 1073 | mpic->num_sources = isu_first + mpic->isu_size; |
986 | } | 1074 | } |
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index e4223226a7a..e3d71e083f3 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c | |||
@@ -174,8 +174,7 @@ void qe_setbrg(u32 brg, u32 rate) | |||
174 | u32 divisor, tempval; | 174 | u32 divisor, tempval; |
175 | int div16 = 0; | 175 | int div16 = 0; |
176 | 176 | ||
177 | bp = &qe_immr->brg.brgc1; | 177 | bp = &qe_immr->brg.brgc[brg]; |
178 | bp += brg; | ||
179 | 178 | ||
180 | divisor = (get_brg_clk() / rate); | 179 | divisor = (get_brg_clk() / rate); |
181 | if (divisor > QE_BRGC_DIVISOR_MAX + 1) { | 180 | if (divisor > QE_BRGC_DIVISOR_MAX + 1) { |
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c index 75fa3104a43..e657559bea9 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c +++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c | |||
@@ -216,14 +216,12 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc | |||
216 | return -EINVAL; | 216 | return -EINVAL; |
217 | } | 217 | } |
218 | 218 | ||
219 | uccf = (struct ucc_fast_private *) | 219 | uccf = kzalloc(sizeof(struct ucc_fast_private), GFP_KERNEL); |
220 | kmalloc(sizeof(struct ucc_fast_private), GFP_KERNEL); | ||
221 | if (!uccf) { | 220 | if (!uccf) { |
222 | uccf_err | 221 | uccf_err |
223 | ("ucc_fast_init: No memory for UCC slow data structure!"); | 222 | ("ucc_fast_init: No memory for UCC slow data structure!"); |
224 | return -ENOMEM; | 223 | return -ENOMEM; |
225 | } | 224 | } |
226 | memset(uccf, 0, sizeof(struct ucc_fast_private)); | ||
227 | 225 | ||
228 | /* Fill fast UCC structure */ | 226 | /* Fill fast UCC structure */ |
229 | uccf->uf_info = uf_info; | 227 | uccf->uf_info = uf_info; |
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c index a49da6b73ec..47b56203f47 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc_slow.c +++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c | |||
@@ -168,14 +168,12 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc | |||
168 | return -EINVAL; | 168 | return -EINVAL; |
169 | } | 169 | } |
170 | 170 | ||
171 | uccs = (struct ucc_slow_private *) | 171 | uccs = kzalloc(sizeof(struct ucc_slow_private), GFP_KERNEL); |
172 | kmalloc(sizeof(struct ucc_slow_private), GFP_KERNEL); | ||
173 | if (!uccs) { | 172 | if (!uccs) { |
174 | uccs_err | 173 | uccs_err |
175 | ("ucc_slow_init: No memory for UCC slow data structure!"); | 174 | ("ucc_slow_init: No memory for UCC slow data structure!"); |
176 | return -ENOMEM; | 175 | return -ENOMEM; |
177 | } | 176 | } |
178 | memset(uccs, 0, sizeof(struct ucc_slow_private)); | ||
179 | 177 | ||
180 | /* Fill slow UCC structure */ | 178 | /* Fill slow UCC structure */ |
181 | uccs->us_info = us_info; | 179 | uccs->us_info = us_info; |
diff --git a/arch/powerpc/sysdev/rom.c b/arch/powerpc/sysdev/rom.c new file mode 100644 index 00000000000..bf5b3f10e6c --- /dev/null +++ b/arch/powerpc/sysdev/rom.c | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * ROM device registration | ||
3 | * | ||
4 | * (C) 2006 MontaVista Software, Inc. This file is licensed under | ||
5 | * the terms of the GNU General Public License version 2. This program | ||
6 | * is licensed "as is" without any warranty of any kind, whether express | ||
7 | * or implied. | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <asm/of_device.h> | ||
12 | |||
13 | static int __init powerpc_flash_init(void) | ||
14 | { | ||
15 | struct device_node *node = NULL; | ||
16 | |||
17 | /* | ||
18 | * Register all the devices which type is "rom" | ||
19 | */ | ||
20 | while ((node = of_find_node_by_type(node, "rom")) != NULL) { | ||
21 | if (node->name == NULL) { | ||
22 | printk(KERN_WARNING "powerpc_flash_init: found 'rom' " | ||
23 | "device, but with no name, skipping...\n"); | ||
24 | continue; | ||
25 | } | ||
26 | of_platform_device_create(node, node->name, NULL); | ||
27 | } | ||
28 | return 0; | ||
29 | } | ||
30 | |||
31 | arch_initcall(powerpc_flash_init); | ||
diff --git a/arch/powerpc/sysdev/todc.c b/arch/powerpc/sysdev/todc.c deleted file mode 100644 index 0a65980efb5..00000000000 --- a/arch/powerpc/sysdev/todc.c +++ /dev/null | |||
@@ -1,392 +0,0 @@ | |||
1 | /* | ||
2 | * Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818 | ||
3 | * Real Time Clocks/Timekeepers. | ||
4 | * | ||
5 | * Author: Mark A. Greer <mgreer@mvista.com> | ||
6 | * | ||
7 | * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under | ||
8 | * the terms of the GNU General Public License version 2. This program | ||
9 | * is licensed "as is" without any warranty of any kind, whether express | ||
10 | * or implied. | ||
11 | */ | ||
12 | #include <linux/errno.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/time.h> | ||
16 | #include <linux/timex.h> | ||
17 | #include <linux/bcd.h> | ||
18 | #include <linux/mc146818rtc.h> | ||
19 | |||
20 | #include <asm/machdep.h> | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/time.h> | ||
23 | #include <asm/todc.h> | ||
24 | |||
25 | /* | ||
26 | * Depending on the hardware on your board and your board design, the | ||
27 | * RTC/NVRAM may be accessed either directly (like normal memory) or via | ||
28 | * address/data registers. If your board uses the direct method, set | ||
29 | * 'nvram_data' to the base address of your nvram and leave 'nvram_as0' and | ||
30 | * 'nvram_as1' NULL. If your board uses address/data regs to access nvram, | ||
31 | * set 'nvram_as0' to the address of the lower byte, set 'nvram_as1' to the | ||
32 | * address of the upper byte (leave NULL if using mc146818), and set | ||
33 | * 'nvram_data' to the address of the 8-bit data register. | ||
34 | * | ||
35 | * Note: Even though the documentation for the various RTC chips say that it | ||
36 | * take up to a second before it starts updating once the 'R' bit is | ||
37 | * cleared, they always seem to update even though we bang on it many | ||
38 | * times a second. This is true, except for the Dallas Semi 1746/1747 | ||
39 | * (possibly others). Those chips seem to have a real problem whenever | ||
40 | * we set the 'R' bit before reading them, they basically stop counting. | ||
41 | * --MAG | ||
42 | */ | ||
43 | |||
44 | /* | ||
45 | * 'todc_info' should be initialized in your *_setup.c file to | ||
46 | * point to a fully initialized 'todc_info_t' structure. | ||
47 | * This structure holds all the register offsets for your particular | ||
48 | * TODC/RTC chip. | ||
49 | * TODC_ALLOC()/TODC_INIT() will allocate and initialize this table for you. | ||
50 | */ | ||
51 | |||
52 | #ifdef RTC_FREQ_SELECT | ||
53 | #undef RTC_FREQ_SELECT | ||
54 | #define RTC_FREQ_SELECT control_b /* Register A */ | ||
55 | #endif | ||
56 | |||
57 | #ifdef RTC_CONTROL | ||
58 | #undef RTC_CONTROL | ||
59 | #define RTC_CONTROL control_a /* Register B */ | ||
60 | #endif | ||
61 | |||
62 | #ifdef RTC_INTR_FLAGS | ||
63 | #undef RTC_INTR_FLAGS | ||
64 | #define RTC_INTR_FLAGS watchdog /* Register C */ | ||
65 | #endif | ||
66 | |||
67 | #ifdef RTC_VALID | ||
68 | #undef RTC_VALID | ||
69 | #define RTC_VALID interrupts /* Register D */ | ||
70 | #endif | ||
71 | |||
72 | /* Access routines when RTC accessed directly (like normal memory) */ | ||
73 | u_char | ||
74 | todc_direct_read_val(int addr) | ||
75 | { | ||
76 | return readb((void __iomem *)(todc_info->nvram_data + addr)); | ||
77 | } | ||
78 | |||
79 | void | ||
80 | todc_direct_write_val(int addr, unsigned char val) | ||
81 | { | ||
82 | writeb(val, (void __iomem *)(todc_info->nvram_data + addr)); | ||
83 | return; | ||
84 | } | ||
85 | |||
86 | /* Access routines for accessing m48txx type chips via addr/data regs */ | ||
87 | u_char | ||
88 | todc_m48txx_read_val(int addr) | ||
89 | { | ||
90 | outb(addr, todc_info->nvram_as0); | ||
91 | outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); | ||
92 | return inb(todc_info->nvram_data); | ||
93 | } | ||
94 | |||
95 | void | ||
96 | todc_m48txx_write_val(int addr, unsigned char val) | ||
97 | { | ||
98 | outb(addr, todc_info->nvram_as0); | ||
99 | outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); | ||
100 | outb(val, todc_info->nvram_data); | ||
101 | return; | ||
102 | } | ||
103 | |||
104 | /* Access routines for accessing mc146818 type chips via addr/data regs */ | ||
105 | u_char | ||
106 | todc_mc146818_read_val(int addr) | ||
107 | { | ||
108 | outb_p(addr, todc_info->nvram_as0); | ||
109 | return inb_p(todc_info->nvram_data); | ||
110 | } | ||
111 | |||
112 | void | ||
113 | todc_mc146818_write_val(int addr, unsigned char val) | ||
114 | { | ||
115 | outb_p(addr, todc_info->nvram_as0); | ||
116 | outb_p(val, todc_info->nvram_data); | ||
117 | } | ||
118 | |||
119 | |||
120 | /* | ||
121 | * Routines to make RTC chips with NVRAM buried behind an addr/data pair | ||
122 | * have the NVRAM and clock regs appear at the same level. | ||
123 | * The NVRAM will appear to start at addr 0 and the clock regs will appear | ||
124 | * to start immediately after the NVRAM (actually, start at offset | ||
125 | * todc_info->nvram_size). | ||
126 | */ | ||
127 | static inline u_char | ||
128 | todc_read_val(int addr) | ||
129 | { | ||
130 | u_char val; | ||
131 | |||
132 | if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) { | ||
133 | if (addr < todc_info->nvram_size) { /* NVRAM */ | ||
134 | ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr); | ||
135 | val = ppc_md.rtc_read_val(todc_info->nvram_data_reg); | ||
136 | } else { /* Clock Reg */ | ||
137 | addr -= todc_info->nvram_size; | ||
138 | val = ppc_md.rtc_read_val(addr); | ||
139 | } | ||
140 | } else | ||
141 | val = ppc_md.rtc_read_val(addr); | ||
142 | |||
143 | return val; | ||
144 | } | ||
145 | |||
146 | static inline void | ||
147 | todc_write_val(int addr, u_char val) | ||
148 | { | ||
149 | if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) { | ||
150 | if (addr < todc_info->nvram_size) { /* NVRAM */ | ||
151 | ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr); | ||
152 | ppc_md.rtc_write_val(todc_info->nvram_data_reg, val); | ||
153 | } else { /* Clock Reg */ | ||
154 | addr -= todc_info->nvram_size; | ||
155 | ppc_md.rtc_write_val(addr, val); | ||
156 | } | ||
157 | } else | ||
158 | ppc_md.rtc_write_val(addr, val); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * TODC routines | ||
163 | * | ||
164 | * There is some ugly stuff in that there are assumptions for the mc146818. | ||
165 | * | ||
166 | * Assumptions: | ||
167 | * - todc_info->control_a has the offset as mc146818 Register B reg | ||
168 | * - todc_info->control_b has the offset as mc146818 Register A reg | ||
169 | * - m48txx control reg's write enable or 'W' bit is same as | ||
170 | * mc146818 Register B 'SET' bit (i.e., 0x80) | ||
171 | * | ||
172 | * These assumptions were made to make the code simpler. | ||
173 | */ | ||
174 | long __init | ||
175 | todc_time_init(void) | ||
176 | { | ||
177 | u_char cntl_b; | ||
178 | |||
179 | if (!ppc_md.rtc_read_val) | ||
180 | ppc_md.rtc_read_val = ppc_md.nvram_read_val; | ||
181 | if (!ppc_md.rtc_write_val) | ||
182 | ppc_md.rtc_write_val = ppc_md.nvram_write_val; | ||
183 | |||
184 | cntl_b = todc_read_val(todc_info->control_b); | ||
185 | |||
186 | if (todc_info->rtc_type == TODC_TYPE_MC146818) { | ||
187 | if ((cntl_b & 0x70) != 0x20) { | ||
188 | printk(KERN_INFO "TODC real-time-clock was stopped." | ||
189 | " Now starting..."); | ||
190 | cntl_b &= ~0x70; | ||
191 | cntl_b |= 0x20; | ||
192 | } | ||
193 | |||
194 | todc_write_val(todc_info->control_b, cntl_b); | ||
195 | } else if (todc_info->rtc_type == TODC_TYPE_DS17285) { | ||
196 | u_char mode; | ||
197 | |||
198 | mode = todc_read_val(TODC_TYPE_DS17285_CNTL_A); | ||
199 | /* Make sure countdown clear is not set */ | ||
200 | mode &= ~0x40; | ||
201 | /* Enable oscillator, extended register set */ | ||
202 | mode |= 0x30; | ||
203 | todc_write_val(TODC_TYPE_DS17285_CNTL_A, mode); | ||
204 | |||
205 | } else if (todc_info->rtc_type == TODC_TYPE_DS1501) { | ||
206 | u_char month; | ||
207 | |||
208 | todc_info->enable_read = TODC_DS1501_CNTL_B_TE; | ||
209 | todc_info->enable_write = TODC_DS1501_CNTL_B_TE; | ||
210 | |||
211 | month = todc_read_val(todc_info->month); | ||
212 | |||
213 | if ((month & 0x80) == 0x80) { | ||
214 | printk(KERN_INFO "TODC %s %s\n", | ||
215 | "real-time-clock was stopped.", | ||
216 | "Now starting..."); | ||
217 | month &= ~0x80; | ||
218 | todc_write_val(todc_info->month, month); | ||
219 | } | ||
220 | |||
221 | cntl_b &= ~TODC_DS1501_CNTL_B_TE; | ||
222 | todc_write_val(todc_info->control_b, cntl_b); | ||
223 | } else { /* must be a m48txx type */ | ||
224 | u_char cntl_a; | ||
225 | |||
226 | todc_info->enable_read = TODC_MK48TXX_CNTL_A_R; | ||
227 | todc_info->enable_write = TODC_MK48TXX_CNTL_A_W; | ||
228 | |||
229 | cntl_a = todc_read_val(todc_info->control_a); | ||
230 | |||
231 | /* Check & clear STOP bit in control B register */ | ||
232 | if (cntl_b & TODC_MK48TXX_DAY_CB) { | ||
233 | printk(KERN_INFO "TODC %s %s\n", | ||
234 | "real-time-clock was stopped.", | ||
235 | "Now starting..."); | ||
236 | |||
237 | cntl_a |= todc_info->enable_write; | ||
238 | cntl_b &= ~TODC_MK48TXX_DAY_CB;/* Start Oscil */ | ||
239 | |||
240 | todc_write_val(todc_info->control_a, cntl_a); | ||
241 | todc_write_val(todc_info->control_b, cntl_b); | ||
242 | } | ||
243 | |||
244 | /* Make sure READ & WRITE bits are cleared. */ | ||
245 | cntl_a &= ~(todc_info->enable_write | todc_info->enable_read); | ||
246 | todc_write_val(todc_info->control_a, cntl_a); | ||
247 | } | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * There is some ugly stuff in that there are assumptions that for a mc146818, | ||
254 | * the todc_info->control_a has the offset of the mc146818 Register B reg and | ||
255 | * that the register'ss 'SET' bit is the same as the m48txx's write enable | ||
256 | * bit in the control register of the m48txx (i.e., 0x80). | ||
257 | * | ||
258 | * It was done to make the code look simpler. | ||
259 | */ | ||
260 | void | ||
261 | todc_get_rtc_time(struct rtc_time *tm) | ||
262 | { | ||
263 | uint year = 0, mon = 0, mday = 0, hour = 0, min = 0, sec = 0; | ||
264 | uint limit, i; | ||
265 | u_char save_control, uip = 0; | ||
266 | extern void GregorianDay(struct rtc_time *); | ||
267 | |||
268 | spin_lock(&rtc_lock); | ||
269 | save_control = todc_read_val(todc_info->control_a); | ||
270 | |||
271 | if (todc_info->rtc_type != TODC_TYPE_MC146818) { | ||
272 | limit = 1; | ||
273 | |||
274 | switch (todc_info->rtc_type) { | ||
275 | case TODC_TYPE_DS1553: | ||
276 | case TODC_TYPE_DS1557: | ||
277 | case TODC_TYPE_DS1743: | ||
278 | case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ | ||
279 | case TODC_TYPE_DS1747: | ||
280 | case TODC_TYPE_DS17285: | ||
281 | break; | ||
282 | default: | ||
283 | todc_write_val(todc_info->control_a, | ||
284 | (save_control | todc_info->enable_read)); | ||
285 | } | ||
286 | } else | ||
287 | limit = 100000000; | ||
288 | |||
289 | for (i=0; i<limit; i++) { | ||
290 | if (todc_info->rtc_type == TODC_TYPE_MC146818) | ||
291 | uip = todc_read_val(todc_info->RTC_FREQ_SELECT); | ||
292 | |||
293 | sec = todc_read_val(todc_info->seconds) & 0x7f; | ||
294 | min = todc_read_val(todc_info->minutes) & 0x7f; | ||
295 | hour = todc_read_val(todc_info->hours) & 0x3f; | ||
296 | mday = todc_read_val(todc_info->day_of_month) & 0x3f; | ||
297 | mon = todc_read_val(todc_info->month) & 0x1f; | ||
298 | year = todc_read_val(todc_info->year) & 0xff; | ||
299 | |||
300 | if (todc_info->rtc_type == TODC_TYPE_MC146818) { | ||
301 | uip |= todc_read_val(todc_info->RTC_FREQ_SELECT); | ||
302 | if ((uip & RTC_UIP) == 0) | ||
303 | break; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | if (todc_info->rtc_type != TODC_TYPE_MC146818) { | ||
308 | switch (todc_info->rtc_type) { | ||
309 | case TODC_TYPE_DS1553: | ||
310 | case TODC_TYPE_DS1557: | ||
311 | case TODC_TYPE_DS1743: | ||
312 | case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ | ||
313 | case TODC_TYPE_DS1747: | ||
314 | case TODC_TYPE_DS17285: | ||
315 | break; | ||
316 | default: | ||
317 | save_control &= ~(todc_info->enable_read); | ||
318 | todc_write_val(todc_info->control_a, save_control); | ||
319 | } | ||
320 | } | ||
321 | spin_unlock(&rtc_lock); | ||
322 | |||
323 | if ((todc_info->rtc_type != TODC_TYPE_MC146818) | ||
324 | || ((save_control & RTC_DM_BINARY) == 0) | ||
325 | || RTC_ALWAYS_BCD) { | ||
326 | BCD_TO_BIN(sec); | ||
327 | BCD_TO_BIN(min); | ||
328 | BCD_TO_BIN(hour); | ||
329 | BCD_TO_BIN(mday); | ||
330 | BCD_TO_BIN(mon); | ||
331 | BCD_TO_BIN(year); | ||
332 | } | ||
333 | |||
334 | if ((year + 1900) < 1970) { | ||
335 | year += 100; | ||
336 | } | ||
337 | |||
338 | tm->tm_sec = sec; | ||
339 | tm->tm_min = min; | ||
340 | tm->tm_hour = hour; | ||
341 | tm->tm_mday = mday; | ||
342 | tm->tm_mon = mon; | ||
343 | tm->tm_year = year; | ||
344 | |||
345 | GregorianDay(tm); | ||
346 | } | ||
347 | |||
348 | int | ||
349 | todc_set_rtc_time(struct rtc_time *tm) | ||
350 | { | ||
351 | u_char save_control, save_freq_select = 0; | ||
352 | |||
353 | spin_lock(&rtc_lock); | ||
354 | save_control = todc_read_val(todc_info->control_a); | ||
355 | |||
356 | /* Assuming MK48T59_RTC_CA_WRITE & RTC_SET are equal */ | ||
357 | todc_write_val(todc_info->control_a, | ||
358 | (save_control | todc_info->enable_write)); | ||
359 | save_control &= ~(todc_info->enable_write); /* in case it was set */ | ||
360 | |||
361 | if (todc_info->rtc_type == TODC_TYPE_MC146818) { | ||
362 | save_freq_select = todc_read_val(todc_info->RTC_FREQ_SELECT); | ||
363 | todc_write_val(todc_info->RTC_FREQ_SELECT, | ||
364 | save_freq_select | RTC_DIV_RESET2); | ||
365 | } | ||
366 | |||
367 | if ((todc_info->rtc_type != TODC_TYPE_MC146818) | ||
368 | || ((save_control & RTC_DM_BINARY) == 0) | ||
369 | || RTC_ALWAYS_BCD) { | ||
370 | BIN_TO_BCD(tm->tm_sec); | ||
371 | BIN_TO_BCD(tm->tm_min); | ||
372 | BIN_TO_BCD(tm->tm_hour); | ||
373 | BIN_TO_BCD(tm->tm_mon); | ||
374 | BIN_TO_BCD(tm->tm_mday); | ||
375 | BIN_TO_BCD(tm->tm_year); | ||
376 | } | ||
377 | |||
378 | todc_write_val(todc_info->seconds, tm->tm_sec); | ||
379 | todc_write_val(todc_info->minutes, tm->tm_min); | ||
380 | todc_write_val(todc_info->hours, tm->tm_hour); | ||
381 | todc_write_val(todc_info->month, tm->tm_mon); | ||
382 | todc_write_val(todc_info->day_of_month, tm->tm_mday); | ||
383 | todc_write_val(todc_info->year, tm->tm_year); | ||
384 | |||
385 | todc_write_val(todc_info->control_a, save_control); | ||
386 | |||
387 | if (todc_info->rtc_type == TODC_TYPE_MC146818) | ||
388 | todc_write_val(todc_info->RTC_FREQ_SELECT, save_freq_select); | ||
389 | |||
390 | spin_unlock(&rtc_lock); | ||
391 | return 0; | ||
392 | } | ||
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c index 322f86e93de..ae249c6bbbc 100644 --- a/arch/powerpc/sysdev/tsi108_pci.c +++ b/arch/powerpc/sysdev/tsi108_pci.c | |||
@@ -3,6 +3,8 @@ | |||
3 | * | 3 | * |
4 | * 2004-2005 (c) Tundra Semiconductor Corp. | 4 | * 2004-2005 (c) Tundra Semiconductor Corp. |
5 | * Author: Alex Bounine (alexandreb@tundra.com) | 5 | * Author: Alex Bounine (alexandreb@tundra.com) |
6 | * Author: Roy Zang (tie-fei.zang@freescale.com) | ||
7 | * Add pci interrupt router host | ||
6 | * | 8 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License as published by the Free | 10 | * under the terms of the GNU General Public License as published by the Free |
@@ -48,6 +50,8 @@ | |||
48 | 50 | ||
49 | u32 tsi108_pci_cfg_base; | 51 | u32 tsi108_pci_cfg_base; |
50 | u32 tsi108_csr_vir_base; | 52 | u32 tsi108_csr_vir_base; |
53 | static struct device_node *pci_irq_node; | ||
54 | static struct irq_host *pci_irq_host; | ||
51 | 55 | ||
52 | extern u32 get_vir_csrbase(void); | 56 | extern u32 get_vir_csrbase(void); |
53 | extern u32 tsi108_read_reg(u32 reg_offset); | 57 | extern u32 tsi108_read_reg(u32 reg_offset); |
@@ -378,6 +382,38 @@ static struct irq_chip tsi108_pci_irq = { | |||
378 | .unmask = tsi108_pci_irq_enable, | 382 | .unmask = tsi108_pci_irq_enable, |
379 | }; | 383 | }; |
380 | 384 | ||
385 | static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct, | ||
386 | u32 *intspec, unsigned int intsize, | ||
387 | irq_hw_number_t *out_hwirq, unsigned int *out_flags) | ||
388 | { | ||
389 | *out_hwirq = intspec[0]; | ||
390 | *out_flags = IRQ_TYPE_LEVEL_HIGH; | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static int pci_irq_host_map(struct irq_host *h, unsigned int virq, | ||
395 | irq_hw_number_t hw) | ||
396 | { unsigned int irq; | ||
397 | DBG("%s(%d, 0x%lx)\n", __FUNCTION__, virq, hw); | ||
398 | if ((virq >= 1) && (virq <= 4)){ | ||
399 | irq = virq + IRQ_PCI_INTAD_BASE - 1; | ||
400 | get_irq_desc(irq)->status |= IRQ_LEVEL; | ||
401 | set_irq_chip(irq, &tsi108_pci_irq); | ||
402 | } | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static int pci_irq_host_match(struct irq_host *h, struct device_node *node) | ||
407 | { | ||
408 | return pci_irq_node == node; | ||
409 | } | ||
410 | |||
411 | static struct irq_host_ops pci_irq_host_ops = { | ||
412 | .match = pci_irq_host_match, | ||
413 | .map = pci_irq_host_map, | ||
414 | .xlate = pci_irq_host_xlate, | ||
415 | }; | ||
416 | |||
381 | /* | 417 | /* |
382 | * Exported functions | 418 | * Exported functions |
383 | */ | 419 | */ |
@@ -391,15 +427,15 @@ static struct irq_chip tsi108_pci_irq = { | |||
391 | * to the MPIC. | 427 | * to the MPIC. |
392 | */ | 428 | */ |
393 | 429 | ||
394 | void __init tsi108_pci_int_init(void) | 430 | void __init tsi108_pci_int_init(struct device_node *node) |
395 | { | 431 | { |
396 | u_int i; | ||
397 | |||
398 | DBG("Tsi108_pci_int_init: initializing PCI interrupts\n"); | 432 | DBG("Tsi108_pci_int_init: initializing PCI interrupts\n"); |
399 | 433 | ||
400 | for (i = 0; i < NUM_PCI_IRQS; i++) { | 434 | pci_irq_node = of_node_get(node); |
401 | irq_desc[i + IRQ_PCI_INTAD_BASE].chip = &tsi108_pci_irq; | 435 | pci_irq_host = irq_alloc_host(IRQ_HOST_MAP_LEGACY, 0, &pci_irq_host_ops, 0); |
402 | irq_desc[i + IRQ_PCI_INTAD_BASE].status |= IRQ_LEVEL; | 436 | if (pci_irq_host == NULL) { |
437 | printk(KERN_ERR "pci_irq_host: failed to allocate irq host !\n"); | ||
438 | return; | ||
403 | } | 439 | } |
404 | 440 | ||
405 | init_pci_source(); | 441 | init_pci_source(); |