aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-30 11:10:12 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-30 11:10:12 -0400
commit24a77daf3d80bddcece044e6dc3675e427eef3f3 (patch)
tree2c5e0b0bea394d6fe62c5d5857c252e83e48ac48 /arch/powerpc/sysdev
parente389f9aec689209724105ae80a6c91fd2e747bc9 (diff)
parentf900e9777fc9b65140cb9570438597bc8fae56ab (diff)
Merge branch 'for-2.6.22' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'for-2.6.22' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (255 commits) [POWERPC] Remove dev_dbg redefinition in drivers/ps3/vuart.c [POWERPC] remove kernel module option for booke wdt [POWERPC] Avoid putting cpu node twice [POWERPC] Spinlock initializer cleanup [POWERPC] ppc4xx_sgdma needs dma-mapping.h [POWERPC] arch/powerpc/sysdev/timer.c build fix [POWERPC] get_property cleanups [POWERPC] Remove the unused HTDMSOUND driver [POWERPC] cell: cbe_cpufreq cleanup and crash fix [POWERPC] Declare enable_kernel_spe in a header [POWERPC] Add dt_xlate_addr() to bootwrapper [POWERPC] bootwrapper: CONFIG_ -> CONFIG_DEVICE_TREE [POWERPC] Don't define a custom bd_t for Xilixn Virtex based boards. [POWERPC] Add sane defaults for Xilinx EDK generated xparameters files [POWERPC] Add uartlite boot console driver for the zImage wrapper [POWERPC] Stop using ppc_sys for Xilinx Virtex boards [POWERPC] New registration for common Xilinx Virtex ppc405 platform devices [POWERPC] Merge common virtex header files [POWERPC] Rework Kconfig dependancies for Xilinx Virtex ppc405 platform [POWERPC] Clean up cpufreq Kconfig dependencies ...
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r--arch/powerpc/sysdev/Makefile5
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c4
-rw-r--r--arch/powerpc/sysdev/dcr.c14
-rw-r--r--arch/powerpc/sysdev/fsl_pcie.c171
-rw-r--r--arch/powerpc/sysdev/fsl_pcie.h94
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c90
-rw-r--r--arch/powerpc/sysdev/mpic.c32
-rw-r--r--arch/powerpc/sysdev/pmi.c29
-rw-r--r--arch/powerpc/sysdev/qe_lib/Kconfig10
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe.c4
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_io.c6
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc_slow.c4
-rw-r--r--arch/powerpc/sysdev/timer.c71
-rw-r--r--arch/powerpc/sysdev/tsi108_dev.c16
-rw-r--r--arch/powerpc/sysdev/tsi108_pci.c2
-rw-r--r--arch/powerpc/sysdev/uic.c342
16 files changed, 784 insertions, 110 deletions
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 26ca3ffbc1de..e96ca9618dbb 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -11,12 +11,17 @@ obj-$(CONFIG_PPC_PMI) += pmi.o
11obj-$(CONFIG_U3_DART) += dart_iommu.o 11obj-$(CONFIG_U3_DART) += dart_iommu.o
12obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o 12obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
13obj-$(CONFIG_FSL_SOC) += fsl_soc.o 13obj-$(CONFIG_FSL_SOC) += fsl_soc.o
14obj-$(CONFIG_FSL_PCIE) += fsl_pcie.o
14obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o 15obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
15obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ 16obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
16 17
18# contains only the suspend handler for time
19obj-$(CONFIG_PM) += timer.o
20
17ifeq ($(CONFIG_PPC_MERGE),y) 21ifeq ($(CONFIG_PPC_MERGE),y)
18obj-$(CONFIG_PPC_I8259) += i8259.o 22obj-$(CONFIG_PPC_I8259) += i8259.o
19obj-$(CONFIG_PPC_83xx) += ipic.o 23obj-$(CONFIG_PPC_83xx) += ipic.o
24obj-$(CONFIG_4xx) += uic.o
20endif 25endif
21 26
22# Temporary hack until we have migrated to asm-powerpc 27# Temporary hack until we have migrated to asm-powerpc
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 1488535b0e13..336186dd7f10 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -333,7 +333,7 @@ void iommu_init_early_dart(void)
333 ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_dart; 333 ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_dart;
334 334
335 /* Setup pci_dma ops */ 335 /* Setup pci_dma ops */
336 pci_dma_ops = &dma_iommu_ops; 336 set_pci_dma_ops(&dma_iommu_ops);
337 return; 337 return;
338 } 338 }
339 339
@@ -343,7 +343,7 @@ void iommu_init_early_dart(void)
343 ppc_md.pci_dma_bus_setup = NULL; 343 ppc_md.pci_dma_bus_setup = NULL;
344 344
345 /* Setup pci_dma ops */ 345 /* Setup pci_dma ops */
346 pci_dma_ops = &dma_direct_ops; 346 set_pci_dma_ops(&dma_direct_ops);
347} 347}
348 348
349 349
diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c
index 1fc5819e7d18..574b6ef44e0b 100644
--- a/arch/powerpc/sysdev/dcr.c
+++ b/arch/powerpc/sysdev/dcr.c
@@ -26,7 +26,7 @@
26unsigned int dcr_resource_start(struct device_node *np, unsigned int index) 26unsigned int dcr_resource_start(struct device_node *np, unsigned int index)
27{ 27{
28 unsigned int ds; 28 unsigned int ds;
29 const u32 *dr = get_property(np, "dcr-reg", &ds); 29 const u32 *dr = of_get_property(np, "dcr-reg", &ds);
30 30
31 if (dr == NULL || ds & 1 || index >= (ds / 8)) 31 if (dr == NULL || ds & 1 || index >= (ds / 8))
32 return 0; 32 return 0;
@@ -37,7 +37,7 @@ unsigned int dcr_resource_start(struct device_node *np, unsigned int index)
37unsigned int dcr_resource_len(struct device_node *np, unsigned int index) 37unsigned int dcr_resource_len(struct device_node *np, unsigned int index)
38{ 38{
39 unsigned int ds; 39 unsigned int ds;
40 const u32 *dr = get_property(np, "dcr-reg", &ds); 40 const u32 *dr = of_get_property(np, "dcr-reg", &ds);
41 41
42 if (dr == NULL || ds & 1 || index >= (ds / 8)) 42 if (dr == NULL || ds & 1 || index >= (ds / 8))
43 return 0; 43 return 0;
@@ -53,9 +53,9 @@ static struct device_node * find_dcr_parent(struct device_node * node)
53 const u32 *p; 53 const u32 *p;
54 54
55 for (par = of_node_get(node); par;) { 55 for (par = of_node_get(node); par;) {
56 if (get_property(par, "dcr-controller", NULL)) 56 if (of_get_property(par, "dcr-controller", NULL))
57 break; 57 break;
58 p = get_property(par, "dcr-parent", NULL); 58 p = of_get_property(par, "dcr-parent", NULL);
59 tmp = par; 59 tmp = par;
60 if (p == NULL) 60 if (p == NULL)
61 par = of_get_parent(par); 61 par = of_get_parent(par);
@@ -80,13 +80,13 @@ u64 of_translate_dcr_address(struct device_node *dev,
80 return OF_BAD_ADDR; 80 return OF_BAD_ADDR;
81 81
82 /* Stride is not properly defined yet, default to 0x10 for Axon */ 82 /* Stride is not properly defined yet, default to 0x10 for Axon */
83 p = get_property(dp, "dcr-mmio-stride", NULL); 83 p = of_get_property(dp, "dcr-mmio-stride", NULL);
84 stride = (p == NULL) ? 0x10 : *p; 84 stride = (p == NULL) ? 0x10 : *p;
85 85
86 /* XXX FIXME: Which property name is to use of the 2 following ? */ 86 /* XXX FIXME: Which property name is to use of the 2 following ? */
87 p = get_property(dp, "dcr-mmio-range", NULL); 87 p = of_get_property(dp, "dcr-mmio-range", NULL);
88 if (p == NULL) 88 if (p == NULL)
89 p = get_property(dp, "dcr-mmio-space", NULL); 89 p = of_get_property(dp, "dcr-mmio-space", NULL);
90 if (p == NULL) 90 if (p == NULL)
91 return OF_BAD_ADDR; 91 return OF_BAD_ADDR;
92 92
diff --git a/arch/powerpc/sysdev/fsl_pcie.c b/arch/powerpc/sysdev/fsl_pcie.c
new file mode 100644
index 000000000000..041c07e8b665
--- /dev/null
+++ b/arch/powerpc/sysdev/fsl_pcie.c
@@ -0,0 +1,171 @@
1/*
2 * Support for indirect PCI bridges.
3 *
4 * Copyright (C) 1998 Gabriel Paubert.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * "Temporary" MPC8548 Errata file -
12 * The standard indirect_pci code should work with future silicon versions.
13 */
14
15#include <linux/kernel.h>
16#include <linux/pci.h>
17#include <linux/delay.h>
18#include <linux/string.h>
19#include <linux/init.h>
20#include <linux/bootmem.h>
21
22#include <asm/io.h>
23#include <asm/prom.h>
24#include <asm/pci-bridge.h>
25#include <asm/machdep.h>
26
27#define PCI_CFG_OUT out_be32
28
29/* ERRATA PCI-Ex 14 PCIE Controller timeout */
30#define PCIE_FIX out_be32(hose->cfg_addr+0x4, 0x0400ffff)
31
32
33static int
34indirect_read_config_pcie(struct pci_bus *bus, unsigned int devfn, int offset,
35 int len, u32 *val)
36{
37 struct pci_controller *hose = bus->sysdata;
38 volatile void __iomem *cfg_data;
39 u32 temp;
40
41 if (ppc_md.pci_exclude_device)
42 if (ppc_md.pci_exclude_device(bus->number, devfn))
43 return PCIBIOS_DEVICE_NOT_FOUND;
44
45 /* Possible artifact of CDCpp50937 needs further investigation */
46 if (devfn != 0x0 && bus->number == 0xff)
47 return PCIBIOS_DEVICE_NOT_FOUND;
48
49 PCIE_FIX;
50 if (bus->number == 0xff) {
51 PCI_CFG_OUT(hose->cfg_addr,
52 (0x80000000 | ((offset & 0xf00) << 16) |
53 ((bus->number - hose->bus_offset) << 16)
54 | (devfn << 8) | ((offset & 0xfc) )));
55 } else {
56 PCI_CFG_OUT(hose->cfg_addr,
57 (0x80000001 | ((offset & 0xf00) << 16) |
58 ((bus->number - hose->bus_offset) << 16)
59 | (devfn << 8) | ((offset & 0xfc) )));
60 }
61
62 /*
63 * Note: the caller has already checked that offset is
64 * suitably aligned and that len is 1, 2 or 4.
65 */
66 /* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
67 cfg_data = hose->cfg_data;
68 PCIE_FIX;
69 temp = in_le32(cfg_data);
70 switch (len) {
71 case 1:
72 *val = (temp >> (((offset & 3))*8)) & 0xff;
73 break;
74 case 2:
75 *val = (temp >> (((offset & 3))*8)) & 0xffff;
76 break;
77 default:
78 *val = temp;
79 break;
80 }
81 return PCIBIOS_SUCCESSFUL;
82}
83
84static int
85indirect_write_config_pcie(struct pci_bus *bus, unsigned int devfn, int offset,
86 int len, u32 val)
87{
88 struct pci_controller *hose = bus->sysdata;
89 volatile void __iomem *cfg_data;
90 u32 temp;
91
92 if (ppc_md.pci_exclude_device)
93 if (ppc_md.pci_exclude_device(bus->number, devfn))
94 return PCIBIOS_DEVICE_NOT_FOUND;
95
96 /* Possible artifact of CDCpp50937 needs further investigation */
97 if (devfn != 0x0 && bus->number == 0xff)
98 return PCIBIOS_DEVICE_NOT_FOUND;
99
100 PCIE_FIX;
101 if (bus->number == 0xff) {
102 PCI_CFG_OUT(hose->cfg_addr,
103 (0x80000000 | ((offset & 0xf00) << 16) |
104 ((bus->number - hose->bus_offset) << 16)
105 | (devfn << 8) | ((offset & 0xfc) )));
106 } else {
107 PCI_CFG_OUT(hose->cfg_addr,
108 (0x80000001 | ((offset & 0xf00) << 16) |
109 ((bus->number - hose->bus_offset) << 16)
110 | (devfn << 8) | ((offset & 0xfc) )));
111 }
112
113 /*
114 * Note: the caller has already checked that offset is
115 * suitably aligned and that len is 1, 2 or 4.
116 */
117 /* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
118 cfg_data = hose->cfg_data;
119 switch (len) {
120 case 1:
121 PCIE_FIX;
122 temp = in_le32(cfg_data);
123 temp = (temp & ~(0xff << ((offset & 3) * 8))) |
124 (val << ((offset & 3) * 8));
125 PCIE_FIX;
126 out_le32(cfg_data, temp);
127 break;
128 case 2:
129 PCIE_FIX;
130 temp = in_le32(cfg_data);
131 temp = (temp & ~(0xffff << ((offset & 3) * 8)));
132 temp |= (val << ((offset & 3) * 8)) ;
133 PCIE_FIX;
134 out_le32(cfg_data, temp);
135 break;
136 default:
137 PCIE_FIX;
138 out_le32(cfg_data, val);
139 break;
140 }
141 PCIE_FIX;
142 return PCIBIOS_SUCCESSFUL;
143}
144
145static struct pci_ops indirect_pcie_ops = {
146 indirect_read_config_pcie,
147 indirect_write_config_pcie
148};
149
150void __init
151setup_indirect_pcie_nomap(struct pci_controller* hose, void __iomem * cfg_addr,
152 void __iomem * cfg_data)
153{
154 hose->cfg_addr = cfg_addr;
155 hose->cfg_data = cfg_data;
156 hose->ops = &indirect_pcie_ops;
157}
158
159void __init
160setup_indirect_pcie(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
161{
162 unsigned long base = cfg_addr & PAGE_MASK;
163 void __iomem *mbase, *addr, *data;
164
165 mbase = ioremap(base, PAGE_SIZE);
166 addr = mbase + (cfg_addr & ~PAGE_MASK);
167 if ((cfg_data & PAGE_MASK) != base)
168 mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE);
169 data = mbase + (cfg_data & ~PAGE_MASK);
170 setup_indirect_pcie_nomap(hose, addr, data);
171}
diff --git a/arch/powerpc/sysdev/fsl_pcie.h b/arch/powerpc/sysdev/fsl_pcie.h
new file mode 100644
index 000000000000..8d9779c84bea
--- /dev/null
+++ b/arch/powerpc/sysdev/fsl_pcie.h
@@ -0,0 +1,94 @@
1/*
2 * MPC85xx/86xx PCI Express structure define
3 *
4 * Copyright 2007 Freescale Semiconductor, Inc
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
13#ifdef __KERNEL__
14#ifndef __POWERPC_FSL_PCIE_H
15#define __POWERPC_FSL_PCIE_H
16
17/* PCIE Express IO block registers in 85xx/86xx */
18
19struct ccsr_pex {
20 __be32 __iomem pex_config_addr; /* 0x.000 - PCI Express Configuration Address Register */
21 __be32 __iomem pex_config_data; /* 0x.004 - PCI Express Configuration Data Register */
22 u8 __iomem res1[4];
23 __be32 __iomem pex_otb_cpl_tor; /* 0x.00c - PCI Express Outbound completion timeout register */
24 __be32 __iomem pex_conf_tor; /* 0x.010 - PCI Express configuration timeout register */
25 u8 __iomem res2[12];
26 __be32 __iomem pex_pme_mes_dr; /* 0x.020 - PCI Express PME and message detect register */
27 __be32 __iomem pex_pme_mes_disr; /* 0x.024 - PCI Express PME and message disable register */
28 __be32 __iomem pex_pme_mes_ier; /* 0x.028 - PCI Express PME and message interrupt enable register */
29 __be32 __iomem pex_pmcr; /* 0x.02c - PCI Express power management command register */
30 u8 __iomem res3[3024];
31 __be32 __iomem pexotar0; /* 0x.c00 - PCI Express outbound translation address register 0 */
32 __be32 __iomem pexotear0; /* 0x.c04 - PCI Express outbound translation extended address register 0*/
33 u8 __iomem res4[8];
34 __be32 __iomem pexowar0; /* 0x.c10 - PCI Express outbound window attributes register 0*/
35 u8 __iomem res5[12];
36 __be32 __iomem pexotar1; /* 0x.c20 - PCI Express outbound translation address register 1 */
37 __be32 __iomem pexotear1; /* 0x.c24 - PCI Express outbound translation extended address register 1*/
38 __be32 __iomem pexowbar1; /* 0x.c28 - PCI Express outbound window base address register 1*/
39 u8 __iomem res6[4];
40 __be32 __iomem pexowar1; /* 0x.c30 - PCI Express outbound window attributes register 1*/
41 u8 __iomem res7[12];
42 __be32 __iomem pexotar2; /* 0x.c40 - PCI Express outbound translation address register 2 */
43 __be32 __iomem pexotear2; /* 0x.c44 - PCI Express outbound translation extended address register 2*/
44 __be32 __iomem pexowbar2; /* 0x.c48 - PCI Express outbound window base address register 2*/
45 u8 __iomem res8[4];
46 __be32 __iomem pexowar2; /* 0x.c50 - PCI Express outbound window attributes register 2*/
47 u8 __iomem res9[12];
48 __be32 __iomem pexotar3; /* 0x.c60 - PCI Express outbound translation address register 3 */
49 __be32 __iomem pexotear3; /* 0x.c64 - PCI Express outbound translation extended address register 3*/
50 __be32 __iomem pexowbar3; /* 0x.c68 - PCI Express outbound window base address register 3*/
51 u8 __iomem res10[4];
52 __be32 __iomem pexowar3; /* 0x.c70 - PCI Express outbound window attributes register 3*/
53 u8 __iomem res11[12];
54 __be32 __iomem pexotar4; /* 0x.c80 - PCI Express outbound translation address register 4 */
55 __be32 __iomem pexotear4; /* 0x.c84 - PCI Express outbound translation extended address register 4*/
56 __be32 __iomem pexowbar4; /* 0x.c88 - PCI Express outbound window base address register 4*/
57 u8 __iomem res12[4];
58 __be32 __iomem pexowar4; /* 0x.c90 - PCI Express outbound window attributes register 4*/
59 u8 __iomem res13[12];
60 u8 __iomem res14[256];
61 __be32 __iomem pexitar3; /* 0x.da0 - PCI Express inbound translation address register 3 */
62 u8 __iomem res15[4];
63 __be32 __iomem pexiwbar3; /* 0x.da8 - PCI Express inbound window base address register 3 */
64 __be32 __iomem pexiwbear3; /* 0x.dac - PCI Express inbound window base extended address register 3 */
65 __be32 __iomem pexiwar3; /* 0x.db0 - PCI Express inbound window attributes register 3 */
66 u8 __iomem res16[12];
67 __be32 __iomem pexitar2; /* 0x.dc0 - PCI Express inbound translation address register 2 */
68 u8 __iomem res17[4];
69 __be32 __iomem pexiwbar2; /* 0x.dc8 - PCI Express inbound window base address register 2 */
70 __be32 __iomem pexiwbear2; /* 0x.dcc - PCI Express inbound window base extended address register 2 */
71 __be32 __iomem pexiwar2; /* 0x.dd0 - PCI Express inbound window attributes register 2 */
72 u8 __iomem res18[12];
73 __be32 __iomem pexitar1; /* 0x.de0 - PCI Express inbound translation address register 2 */
74 u8 __iomem res19[4];
75 __be32 __iomem pexiwbar1; /* 0x.de8 - PCI Express inbound window base address register 2 */
76 __be32 __iomem pexiwbear1; /* 0x.dec - PCI Express inbound window base extended address register 2 */
77 __be32 __iomem pexiwar1; /* 0x.df0 - PCI Express inbound window attributes register 2 */
78 u8 __iomem res20[12];
79 __be32 __iomem pex_err_dr; /* 0x.e00 - PCI Express error detect register */
80 u8 __iomem res21[4];
81 __be32 __iomem pex_err_en; /* 0x.e08 - PCI Express error interrupt enable register */
82 u8 __iomem res22[4];
83 __be32 __iomem pex_err_disr; /* 0x.e10 - PCI Express error disable register */
84 u8 __iomem res23[12];
85 __be32 __iomem pex_err_cap_stat; /* 0x.e20 - PCI Express error capture status register */
86 u8 __iomem res24[4];
87 __be32 __iomem pex_err_cap_r0; /* 0x.e28 - PCI Express error capture register 0 */
88 __be32 __iomem pex_err_cap_r1; /* 0x.e2c - PCI Express error capture register 0 */
89 __be32 __iomem pex_err_cap_r2; /* 0x.e30 - PCI Express error capture register 0 */
90 __be32 __iomem pex_err_cap_r3; /* 0x.e34 - PCI Express error capture register 0 */
91};
92
93#endif /* __POWERPC_FSL_PCIE_H */
94#endif /* __KERNEL__ */
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index d20f02927f72..8a123c71449f 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -52,7 +52,7 @@ phys_addr_t get_immrbase(void)
52 soc = of_find_node_by_type(NULL, "soc"); 52 soc = of_find_node_by_type(NULL, "soc");
53 if (soc) { 53 if (soc) {
54 unsigned int size; 54 unsigned int size;
55 const void *prop = get_property(soc, "reg", &size); 55 const void *prop = of_get_property(soc, "reg", &size);
56 56
57 if (prop) 57 if (prop)
58 immrbase = of_translate_address(soc, prop); 58 immrbase = of_translate_address(soc, prop);
@@ -78,8 +78,8 @@ u32 get_brgfreq(void)
78 node = of_find_node_by_type(NULL, "cpm"); 78 node = of_find_node_by_type(NULL, "cpm");
79 if (node) { 79 if (node) {
80 unsigned int size; 80 unsigned int size;
81 const unsigned int *prop = get_property(node, "brg-frequency", 81 const unsigned int *prop = of_get_property(node,
82 &size); 82 "brg-frequency", &size);
83 83
84 if (prop) 84 if (prop)
85 brgfreq = *prop; 85 brgfreq = *prop;
@@ -103,8 +103,8 @@ u32 get_baudrate(void)
103 node = of_find_node_by_type(NULL, "serial"); 103 node = of_find_node_by_type(NULL, "serial");
104 if (node) { 104 if (node) {
105 unsigned int size; 105 unsigned int size;
106 const unsigned int *prop = get_property(node, "current-speed", 106 const unsigned int *prop = of_get_property(node,
107 &size); 107 "current-speed", &size);
108 108
109 if (prop) 109 if (prop)
110 fs_baudrate = *prop; 110 fs_baudrate = *prop;
@@ -153,7 +153,8 @@ static int __init gfar_mdio_of_init(void)
153 while ((child = of_get_next_child(np, child)) != NULL) { 153 while ((child = of_get_next_child(np, child)) != NULL) {
154 int irq = irq_of_parse_and_map(child, 0); 154 int irq = irq_of_parse_and_map(child, 0);
155 if (irq != NO_IRQ) { 155 if (irq != NO_IRQ) {
156 const u32 *id = get_property(child, "reg", NULL); 156 const u32 *id = of_get_property(child,
157 "reg", NULL);
157 mdio_data.irq[*id] = irq; 158 mdio_data.irq[*id] = irq;
158 } 159 }
159 } 160 }
@@ -209,7 +210,7 @@ static int __init gfar_of_init(void)
209 210
210 of_irq_to_resource(np, 0, &r[1]); 211 of_irq_to_resource(np, 0, &r[1]);
211 212
212 model = get_property(np, "model", NULL); 213 model = of_get_property(np, "model", NULL);
213 214
214 /* If we aren't the FEC we have multiple interrupts */ 215 /* If we aren't the FEC we have multiple interrupts */
215 if (model && strcasecmp(model, "FEC")) { 216 if (model && strcasecmp(model, "FEC")) {
@@ -253,7 +254,7 @@ static int __init gfar_of_init(void)
253 FSL_GIANFAR_DEV_HAS_VLAN | 254 FSL_GIANFAR_DEV_HAS_VLAN |
254 FSL_GIANFAR_DEV_HAS_EXTENDED_HASH; 255 FSL_GIANFAR_DEV_HAS_EXTENDED_HASH;
255 256
256 ph = get_property(np, "phy-handle", NULL); 257 ph = of_get_property(np, "phy-handle", NULL);
257 phy = of_find_node_by_phandle(*ph); 258 phy = of_find_node_by_phandle(*ph);
258 259
259 if (phy == NULL) { 260 if (phy == NULL) {
@@ -263,7 +264,7 @@ static int __init gfar_of_init(void)
263 264
264 mdio = of_get_parent(phy); 265 mdio = of_get_parent(phy);
265 266
266 id = get_property(phy, "reg", NULL); 267 id = of_get_property(phy, "reg", NULL);
267 ret = of_address_to_resource(mdio, 0, &res); 268 ret = of_address_to_resource(mdio, 0, &res);
268 if (ret) { 269 if (ret) {
269 of_node_put(phy); 270 of_node_put(phy);
@@ -325,11 +326,11 @@ static int __init fsl_i2c_of_init(void)
325 } 326 }
326 327
327 i2c_data.device_flags = 0; 328 i2c_data.device_flags = 0;
328 flags = get_property(np, "dfsrr", NULL); 329 flags = of_get_property(np, "dfsrr", NULL);
329 if (flags) 330 if (flags)
330 i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR; 331 i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
331 332
332 flags = get_property(np, "fsl5200-clocking", NULL); 333 flags = of_get_property(np, "fsl5200-clocking", NULL);
333 if (flags) 334 if (flags)
334 i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200; 335 i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200;
335 336
@@ -374,7 +375,7 @@ static int __init mpc83xx_wdt_init(void)
374 goto nosoc; 375 goto nosoc;
375 } 376 }
376 377
377 freq = get_property(soc, "bus-frequency", NULL); 378 freq = of_get_property(soc, "bus-frequency", NULL);
378 if (!freq) { 379 if (!freq) {
379 ret = -ENODEV; 380 ret = -ENODEV;
380 goto err; 381 goto err;
@@ -466,15 +467,15 @@ static int __init fsl_usb_of_init(void)
466 467
467 usb_data.operating_mode = FSL_USB2_MPH_HOST; 468 usb_data.operating_mode = FSL_USB2_MPH_HOST;
468 469
469 prop = get_property(np, "port0", NULL); 470 prop = of_get_property(np, "port0", NULL);
470 if (prop) 471 if (prop)
471 usb_data.port_enables |= FSL_USB2_PORT0_ENABLED; 472 usb_data.port_enables |= FSL_USB2_PORT0_ENABLED;
472 473
473 prop = get_property(np, "port1", NULL); 474 prop = of_get_property(np, "port1", NULL);
474 if (prop) 475 if (prop)
475 usb_data.port_enables |= FSL_USB2_PORT1_ENABLED; 476 usb_data.port_enables |= FSL_USB2_PORT1_ENABLED;
476 477
477 prop = get_property(np, "phy_type", NULL); 478 prop = of_get_property(np, "phy_type", NULL);
478 usb_data.phy_mode = determine_usb_phy(prop); 479 usb_data.phy_mode = determine_usb_phy(prop);
479 480
480 ret = 481 ret =
@@ -501,7 +502,7 @@ static int __init fsl_usb_of_init(void)
501 502
502 of_irq_to_resource(np, 0, &r[1]); 503 of_irq_to_resource(np, 0, &r[1]);
503 504
504 prop = get_property(np, "dr_mode", NULL); 505 prop = of_get_property(np, "dr_mode", NULL);
505 506
506 if (!prop || !strcmp(prop, "host")) { 507 if (!prop || !strcmp(prop, "host")) {
507 usb_data.operating_mode = FSL_USB2_DR_HOST; 508 usb_data.operating_mode = FSL_USB2_DR_HOST;
@@ -538,7 +539,7 @@ static int __init fsl_usb_of_init(void)
538 goto err; 539 goto err;
539 } 540 }
540 541
541 prop = get_property(np, "phy_type", NULL); 542 prop = of_get_property(np, "phy_type", NULL);
542 usb_data.phy_mode = determine_usb_phy(prop); 543 usb_data.phy_mode = determine_usb_phy(prop);
543 544
544 if (usb_dev_dr_host) { 545 if (usb_dev_dr_host) {
@@ -633,7 +634,7 @@ static int __init fs_enet_of_init(void)
633 goto err; 634 goto err;
634 } 635 }
635 636
636 model = get_property(np, "model", NULL); 637 model = of_get_property(np, "model", NULL);
637 if (model == NULL) { 638 if (model == NULL) {
638 ret = -ENODEV; 639 ret = -ENODEV;
639 goto unreg; 640 goto unreg;
@@ -643,7 +644,7 @@ static int __init fs_enet_of_init(void)
643 if (mac_addr) 644 if (mac_addr)
644 memcpy(fs_enet_data.macaddr, mac_addr, 6); 645 memcpy(fs_enet_data.macaddr, mac_addr, 6);
645 646
646 ph = get_property(np, "phy-handle", NULL); 647 ph = of_get_property(np, "phy-handle", NULL);
647 phy = of_find_node_by_phandle(*ph); 648 phy = of_find_node_by_phandle(*ph);
648 649
649 if (phy == NULL) { 650 if (phy == NULL) {
@@ -651,12 +652,12 @@ static int __init fs_enet_of_init(void)
651 goto unreg; 652 goto unreg;
652 } 653 }
653 654
654 phy_addr = get_property(phy, "reg", NULL); 655 phy_addr = of_get_property(phy, "reg", NULL);
655 fs_enet_data.phy_addr = *phy_addr; 656 fs_enet_data.phy_addr = *phy_addr;
656 657
657 phy_irq = get_property(phy, "interrupts", NULL); 658 phy_irq = of_get_property(phy, "interrupts", NULL);
658 659
659 id = get_property(np, "device-id", NULL); 660 id = of_get_property(np, "device-id", NULL);
660 fs_enet_data.fs_no = *id; 661 fs_enet_data.fs_no = *id;
661 strcpy(fs_enet_data.fs_type, model); 662 strcpy(fs_enet_data.fs_type, model);
662 663
@@ -668,8 +669,10 @@ static int __init fs_enet_of_init(void)
668 goto unreg; 669 goto unreg;
669 } 670 }
670 671
671 fs_enet_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL)); 672 fs_enet_data.clk_rx = *((u32 *)of_get_property(np,
672 fs_enet_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL)); 673 "rx-clock", NULL));
674 fs_enet_data.clk_tx = *((u32 *)of_get_property(np,
675 "tx-clock", NULL));
673 676
674 if (strstr(model, "FCC")) { 677 if (strstr(model, "FCC")) {
675 int fcc_index = *id - 1; 678 int fcc_index = *id - 1;
@@ -690,7 +693,7 @@ static int __init fs_enet_of_init(void)
690 fs_enet_data.bus_id = (char*)&bus_id[(*id)]; 693 fs_enet_data.bus_id = (char*)&bus_id[(*id)];
691 fs_enet_data.init_ioports = init_fcc_ioports; 694 fs_enet_data.init_ioports = init_fcc_ioports;
692 695
693 mdio_bb_prop = get_property(phy, "bitbang", NULL); 696 mdio_bb_prop = of_get_property(phy, "bitbang", NULL);
694 if (mdio_bb_prop) { 697 if (mdio_bb_prop) {
695 struct platform_device *fs_enet_mdio_bb_dev; 698 struct platform_device *fs_enet_mdio_bb_dev;
696 struct fs_mii_bb_platform_info fs_enet_mdio_bb_data; 699 struct fs_mii_bb_platform_info fs_enet_mdio_bb_data;
@@ -796,10 +799,10 @@ static int __init cpm_uart_of_init(void)
796 goto err; 799 goto err;
797 } 800 }
798 801
799 id = get_property(np, "device-id", NULL); 802 id = of_get_property(np, "device-id", NULL);
800 cpm_uart_data.fs_no = *id; 803 cpm_uart_data.fs_no = *id;
801 804
802 model = (char*)get_property(np, "model", NULL); 805 model = of_get_property(np, "model", NULL);
803 strcpy(cpm_uart_data.fs_type, model); 806 strcpy(cpm_uart_data.fs_type, model);
804 807
805 cpm_uart_data.uart_clk = ppc_proc_freq; 808 cpm_uart_data.uart_clk = ppc_proc_freq;
@@ -808,8 +811,10 @@ static int __init cpm_uart_of_init(void)
808 cpm_uart_data.tx_buf_size = 32; 811 cpm_uart_data.tx_buf_size = 32;
809 cpm_uart_data.rx_num_fifo = 4; 812 cpm_uart_data.rx_num_fifo = 4;
810 cpm_uart_data.rx_buf_size = 32; 813 cpm_uart_data.rx_buf_size = 32;
811 cpm_uart_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL)); 814 cpm_uart_data.clk_rx = *((u32 *)of_get_property(np,
812 cpm_uart_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL)); 815 "rx-clock", NULL));
816 cpm_uart_data.clk_tx = *((u32 *)of_get_property(np,
817 "tx-clock", NULL));
813 818
814 ret = 819 ret =
815 platform_device_add_data(cpm_uart_dev, &cpm_uart_data, 820 platform_device_add_data(cpm_uart_dev, &cpm_uart_data,
@@ -833,7 +838,7 @@ arch_initcall(cpm_uart_of_init);
833#ifdef CONFIG_8xx 838#ifdef CONFIG_8xx
834 839
835extern void init_scc_ioports(struct fs_platform_info*); 840extern void init_scc_ioports(struct fs_platform_info*);
836extern int platform_device_skip(char *model, int id); 841extern int platform_device_skip(const char *model, int id);
837 842
838static int __init fs_enet_mdio_of_init(void) 843static int __init fs_enet_mdio_of_init(void)
839{ 844{
@@ -900,21 +905,22 @@ static int __init fs_enet_of_init(void)
900 struct resource r[4]; 905 struct resource r[4];
901 struct device_node *phy = NULL, *mdio = NULL; 906 struct device_node *phy = NULL, *mdio = NULL;
902 struct fs_platform_info fs_enet_data; 907 struct fs_platform_info fs_enet_data;
903 unsigned int *id, *phy_addr; 908 const unsigned int *id;
909 const unsigned int *phy_addr;
904 void *mac_addr; 910 void *mac_addr;
905 phandle *ph; 911 const phandle *ph;
906 char *model; 912 const char *model;
907 913
908 memset(r, 0, sizeof(r)); 914 memset(r, 0, sizeof(r));
909 memset(&fs_enet_data, 0, sizeof(fs_enet_data)); 915 memset(&fs_enet_data, 0, sizeof(fs_enet_data));
910 916
911 model = (char *)get_property(np, "model", NULL); 917 model = of_get_property(np, "model", NULL);
912 if (model == NULL) { 918 if (model == NULL) {
913 ret = -ENODEV; 919 ret = -ENODEV;
914 goto unreg; 920 goto unreg;
915 } 921 }
916 922
917 id = (u32 *) get_property(np, "device-id", NULL); 923 id = of_get_property(np, "device-id", NULL);
918 fs_enet_data.fs_no = *id; 924 fs_enet_data.fs_no = *id;
919 925
920 if (platform_device_skip(model, *id)) 926 if (platform_device_skip(model, *id))
@@ -929,12 +935,12 @@ static int __init fs_enet_of_init(void)
929 if (mac_addr) 935 if (mac_addr)
930 memcpy(fs_enet_data.macaddr, mac_addr, 6); 936 memcpy(fs_enet_data.macaddr, mac_addr, 6);
931 937
932 ph = (phandle *) get_property(np, "phy-handle", NULL); 938 ph = of_get_property(np, "phy-handle", NULL);
933 if (ph != NULL) 939 if (ph != NULL)
934 phy = of_find_node_by_phandle(*ph); 940 phy = of_find_node_by_phandle(*ph);
935 941
936 if (phy != NULL) { 942 if (phy != NULL) {
937 phy_addr = (u32 *) get_property(phy, "reg", NULL); 943 phy_addr = of_get_property(phy, "reg", NULL);
938 fs_enet_data.phy_addr = *phy_addr; 944 fs_enet_data.phy_addr = *phy_addr;
939 fs_enet_data.has_phy = 1; 945 fs_enet_data.has_phy = 1;
940 946
@@ -947,7 +953,7 @@ static int __init fs_enet_of_init(void)
947 } 953 }
948 } 954 }
949 955
950 model = (char*)get_property(np, "model", NULL); 956 model = of_get_property(np, "model", NULL);
951 strcpy(fs_enet_data.fs_type, model); 957 strcpy(fs_enet_data.fs_type, model);
952 958
953 if (strstr(model, "FEC")) { 959 if (strstr(model, "FEC")) {
@@ -1038,8 +1044,8 @@ static int __init cpm_smc_uart_of_init(void)
1038 i++) { 1044 i++) {
1039 struct resource r[3]; 1045 struct resource r[3];
1040 struct fs_uart_platform_info cpm_uart_data; 1046 struct fs_uart_platform_info cpm_uart_data;
1041 int *id; 1047 const int *id;
1042 char *model; 1048 const char *model;
1043 1049
1044 memset(r, 0, sizeof(r)); 1050 memset(r, 0, sizeof(r));
1045 memset(&cpm_uart_data, 0, sizeof(cpm_uart_data)); 1051 memset(&cpm_uart_data, 0, sizeof(cpm_uart_data));
@@ -1066,10 +1072,10 @@ static int __init cpm_smc_uart_of_init(void)
1066 goto err; 1072 goto err;
1067 } 1073 }
1068 1074
1069 model = (char*)get_property(np, "model", NULL); 1075 model = of_get_property(np, "model", NULL);
1070 strcpy(cpm_uart_data.fs_type, model); 1076 strcpy(cpm_uart_data.fs_type, model);
1071 1077
1072 id = (int*)get_property(np, "device-id", NULL); 1078 id = of_get_property(np, "device-id", NULL);
1073 cpm_uart_data.fs_no = *id; 1079 cpm_uart_data.fs_no = *id;
1074 cpm_uart_data.uart_clk = ppc_proc_freq; 1080 cpm_uart_data.uart_clk = ppc_proc_freq;
1075 1081
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index bcfb900481f8..0b84b7c775d8 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -304,7 +304,7 @@ static void __init mpic_test_broken_ipi(struct mpic *mpic)
304 } 304 }
305} 305}
306 306
307#ifdef CONFIG_MPIC_BROKEN_U3 307#ifdef CONFIG_MPIC_U3_HT_IRQS
308 308
309/* Test if an interrupt is sourced from HyperTransport (used on broken U3s) 309/* Test if an interrupt is sourced from HyperTransport (used on broken U3s)
310 * to force the edge setting on the MPIC and do the ack workaround. 310 * to force the edge setting on the MPIC and do the ack workaround.
@@ -476,7 +476,7 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
476 } 476 }
477} 477}
478 478
479#else /* CONFIG_MPIC_BROKEN_U3 */ 479#else /* CONFIG_MPIC_U3_HT_IRQS */
480 480
481static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source) 481static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source)
482{ 482{
@@ -487,7 +487,7 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
487{ 487{
488} 488}
489 489
490#endif /* CONFIG_MPIC_BROKEN_U3 */ 490#endif /* CONFIG_MPIC_U3_HT_IRQS */
491 491
492 492
493#define mpic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq) 493#define mpic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
@@ -615,7 +615,7 @@ static void mpic_end_irq(unsigned int irq)
615 mpic_eoi(mpic); 615 mpic_eoi(mpic);
616} 616}
617 617
618#ifdef CONFIG_MPIC_BROKEN_U3 618#ifdef CONFIG_MPIC_U3_HT_IRQS
619 619
620static void mpic_unmask_ht_irq(unsigned int irq) 620static void mpic_unmask_ht_irq(unsigned int irq)
621{ 621{
@@ -665,7 +665,7 @@ static void mpic_end_ht_irq(unsigned int irq)
665 mpic_ht_end_irq(mpic, src); 665 mpic_ht_end_irq(mpic, src);
666 mpic_eoi(mpic); 666 mpic_eoi(mpic);
667} 667}
668#endif /* !CONFIG_MPIC_BROKEN_U3 */ 668#endif /* !CONFIG_MPIC_U3_HT_IRQS */
669 669
670#ifdef CONFIG_SMP 670#ifdef CONFIG_SMP
671 671
@@ -788,7 +788,7 @@ static struct irq_chip mpic_ipi_chip = {
788}; 788};
789#endif /* CONFIG_SMP */ 789#endif /* CONFIG_SMP */
790 790
791#ifdef CONFIG_MPIC_BROKEN_U3 791#ifdef CONFIG_MPIC_U3_HT_IRQS
792static struct irq_chip mpic_irq_ht_chip = { 792static struct irq_chip mpic_irq_ht_chip = {
793 .startup = mpic_startup_ht_irq, 793 .startup = mpic_startup_ht_irq,
794 .shutdown = mpic_shutdown_ht_irq, 794 .shutdown = mpic_shutdown_ht_irq,
@@ -797,7 +797,7 @@ static struct irq_chip mpic_irq_ht_chip = {
797 .eoi = mpic_end_ht_irq, 797 .eoi = mpic_end_ht_irq,
798 .set_type = mpic_set_irq_type, 798 .set_type = mpic_set_irq_type,
799}; 799};
800#endif /* CONFIG_MPIC_BROKEN_U3 */ 800#endif /* CONFIG_MPIC_U3_HT_IRQS */
801 801
802 802
803static int mpic_host_match(struct irq_host *h, struct device_node *node) 803static int mpic_host_match(struct irq_host *h, struct device_node *node)
@@ -837,11 +837,11 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
837 /* Default chip */ 837 /* Default chip */
838 chip = &mpic->hc_irq; 838 chip = &mpic->hc_irq;
839 839
840#ifdef CONFIG_MPIC_BROKEN_U3 840#ifdef CONFIG_MPIC_U3_HT_IRQS
841 /* Check for HT interrupts, override vecpri */ 841 /* Check for HT interrupts, override vecpri */
842 if (mpic_is_ht_interrupt(mpic, hw)) 842 if (mpic_is_ht_interrupt(mpic, hw))
843 chip = &mpic->hc_ht_irq; 843 chip = &mpic->hc_ht_irq;
844#endif /* CONFIG_MPIC_BROKEN_U3 */ 844#endif /* CONFIG_MPIC_U3_HT_IRQS */
845 845
846 DBG("mpic: mapping to irq chip @%p\n", chip); 846 DBG("mpic: mapping to irq chip @%p\n", chip);
847 847
@@ -937,12 +937,12 @@ struct mpic * __init mpic_alloc(struct device_node *node,
937 mpic->hc_irq.typename = name; 937 mpic->hc_irq.typename = name;
938 if (flags & MPIC_PRIMARY) 938 if (flags & MPIC_PRIMARY)
939 mpic->hc_irq.set_affinity = mpic_set_affinity; 939 mpic->hc_irq.set_affinity = mpic_set_affinity;
940#ifdef CONFIG_MPIC_BROKEN_U3 940#ifdef CONFIG_MPIC_U3_HT_IRQS
941 mpic->hc_ht_irq = mpic_irq_ht_chip; 941 mpic->hc_ht_irq = mpic_irq_ht_chip;
942 mpic->hc_ht_irq.typename = name; 942 mpic->hc_ht_irq.typename = name;
943 if (flags & MPIC_PRIMARY) 943 if (flags & MPIC_PRIMARY)
944 mpic->hc_ht_irq.set_affinity = mpic_set_affinity; 944 mpic->hc_ht_irq.set_affinity = mpic_set_affinity;
945#endif /* CONFIG_MPIC_BROKEN_U3 */ 945#endif /* CONFIG_MPIC_U3_HT_IRQS */
946 946
947#ifdef CONFIG_SMP 947#ifdef CONFIG_SMP
948 mpic->hc_ipi = mpic_ipi_chip; 948 mpic->hc_ipi = mpic_ipi_chip;
@@ -970,7 +970,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
970 mpic->spurious_vec = intvec_top; 970 mpic->spurious_vec = intvec_top;
971 971
972 /* Check for "big-endian" in device-tree */ 972 /* Check for "big-endian" in device-tree */
973 if (node && get_property(node, "big-endian", NULL) != NULL) 973 if (node && of_get_property(node, "big-endian", NULL) != NULL)
974 mpic->flags |= MPIC_BIG_ENDIAN; 974 mpic->flags |= MPIC_BIG_ENDIAN;
975 975
976 976
@@ -986,13 +986,13 @@ struct mpic * __init mpic_alloc(struct device_node *node,
986 BUG_ON(paddr == 0 && node == NULL); 986 BUG_ON(paddr == 0 && node == NULL);
987 987
988 /* If no physical address passed in, check if it's dcr based */ 988 /* If no physical address passed in, check if it's dcr based */
989 if (paddr == 0 && get_property(node, "dcr-reg", NULL) != NULL) 989 if (paddr == 0 && of_get_property(node, "dcr-reg", NULL) != NULL)
990 mpic->flags |= MPIC_USES_DCR; 990 mpic->flags |= MPIC_USES_DCR;
991 991
992#ifdef CONFIG_PPC_DCR 992#ifdef CONFIG_PPC_DCR
993 if (mpic->flags & MPIC_USES_DCR) { 993 if (mpic->flags & MPIC_USES_DCR) {
994 const u32 *dbasep; 994 const u32 *dbasep;
995 dbasep = get_property(node, "dcr-reg", NULL); 995 dbasep = of_get_property(node, "dcr-reg", NULL);
996 BUG_ON(dbasep == NULL); 996 BUG_ON(dbasep == NULL);
997 mpic->dcr_base = *dbasep; 997 mpic->dcr_base = *dbasep;
998 mpic->reg_type = mpic_access_dcr; 998 mpic->reg_type = mpic_access_dcr;
@@ -1006,7 +1006,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1006 */ 1006 */
1007 if (paddr == 0 && !(mpic->flags & MPIC_USES_DCR)) { 1007 if (paddr == 0 && !(mpic->flags & MPIC_USES_DCR)) {
1008 const u32 *reg; 1008 const u32 *reg;
1009 reg = get_property(node, "reg", NULL); 1009 reg = of_get_property(node, "reg", NULL);
1010 BUG_ON(reg == NULL); 1010 BUG_ON(reg == NULL);
1011 paddr = of_translate_address(node, reg); 1011 paddr = of_translate_address(node, reg);
1012 BUG_ON(paddr == OF_BAD_ADDR); 1012 BUG_ON(paddr == OF_BAD_ADDR);
@@ -1142,7 +1142,7 @@ void __init mpic_init(struct mpic *mpic)
1142 1142
1143 /* Do the HT PIC fixups on U3 broken mpic */ 1143 /* Do the HT PIC fixups on U3 broken mpic */
1144 DBG("MPIC flags: %x\n", mpic->flags); 1144 DBG("MPIC flags: %x\n", mpic->flags);
1145 if ((mpic->flags & MPIC_BROKEN_U3) && (mpic->flags & MPIC_PRIMARY)) 1145 if ((mpic->flags & MPIC_U3_HT_IRQS) && (mpic->flags & MPIC_PRIMARY))
1146 mpic_scan_ht_pics(mpic); 1146 mpic_scan_ht_pics(mpic);
1147 1147
1148 for (i = 0; i < mpic->num_sources; i++) { 1148 for (i = 0; i < mpic->num_sources; i++) {
diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c
index a5282011d39e..85a7c99c1003 100644
--- a/arch/powerpc/sysdev/pmi.c
+++ b/arch/powerpc/sysdev/pmi.c
@@ -33,7 +33,7 @@
33#include <asm/of_platform.h> 33#include <asm/of_platform.h>
34#include <asm/io.h> 34#include <asm/io.h>
35#include <asm/pmi.h> 35#include <asm/pmi.h>
36 36#include <asm/prom.h>
37 37
38struct pmi_data { 38struct pmi_data {
39 struct list_head handler; 39 struct list_head handler;
@@ -49,21 +49,6 @@ struct pmi_data {
49}; 49};
50 50
51 51
52
53static void __iomem *of_iomap(struct device_node *np)
54{
55 struct resource res;
56
57 if (of_address_to_resource(np, 0, &res))
58 return NULL;
59
60 pr_debug("Resource start: 0x%lx\n", res.start);
61 pr_debug("Resource end: 0x%lx\n", res.end);
62
63 return ioremap(res.start, 1 + res.end - res.start);
64}
65
66
67static int pmi_irq_handler(int irq, void *dev_id) 52static int pmi_irq_handler(int irq, void *dev_id)
68{ 53{
69 struct pmi_data *data; 54 struct pmi_data *data;
@@ -118,6 +103,7 @@ out:
118 103
119static struct of_device_id pmi_match[] = { 104static struct of_device_id pmi_match[] = {
120 { .type = "ibm,pmi", .name = "ibm,pmi" }, 105 { .type = "ibm,pmi", .name = "ibm,pmi" },
106 { .type = "ibm,pmi" },
121 {}, 107 {},
122}; 108};
123 109
@@ -153,7 +139,7 @@ static int pmi_of_probe(struct of_device *dev,
153 goto out; 139 goto out;
154 } 140 }
155 141
156 data->pmi_reg = of_iomap(np); 142 data->pmi_reg = of_iomap(np, 0);
157 if (!data->pmi_reg) { 143 if (!data->pmi_reg) {
158 printk(KERN_ERR "pmi: invalid register address.\n"); 144 printk(KERN_ERR "pmi: invalid register address.\n");
159 rc = -EFAULT; 145 rc = -EFAULT;
@@ -279,6 +265,9 @@ void pmi_register_handler(struct of_device *device,
279 struct pmi_data *data; 265 struct pmi_data *data;
280 data = device->dev.driver_data; 266 data = device->dev.driver_data;
281 267
268 if (!data)
269 return;
270
282 spin_lock(&data->handler_spinlock); 271 spin_lock(&data->handler_spinlock);
283 list_add_tail(&handler->node, &data->handler); 272 list_add_tail(&handler->node, &data->handler);
284 spin_unlock(&data->handler_spinlock); 273 spin_unlock(&data->handler_spinlock);
@@ -289,10 +278,12 @@ void pmi_unregister_handler(struct of_device *device,
289 struct pmi_handler *handler) 278 struct pmi_handler *handler)
290{ 279{
291 struct pmi_data *data; 280 struct pmi_data *data;
281 data = device->dev.driver_data;
292 282
293 pr_debug("pmi: unregistering handler %p\n", handler); 283 if (!data)
284 return;
294 285
295 data = device->dev.driver_data; 286 pr_debug("pmi: unregistering handler %p\n", handler);
296 287
297 spin_lock(&data->handler_spinlock); 288 spin_lock(&data->handler_spinlock);
298 list_del(&handler->node); 289 list_del(&handler->node);
diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/arch/powerpc/sysdev/qe_lib/Kconfig
index a725e80befa8..887739f3badc 100644
--- a/arch/powerpc/sysdev/qe_lib/Kconfig
+++ b/arch/powerpc/sysdev/qe_lib/Kconfig
@@ -2,11 +2,8 @@
2# QE Communication options 2# QE Communication options
3# 3#
4 4
5menu "QE Options"
6 depends on QUICC_ENGINE
7
8config UCC_SLOW 5config UCC_SLOW
9 bool "UCC Slow Protocols Support" 6 bool
10 default n 7 default n
11 select UCC 8 select UCC
12 help 9 help
@@ -14,10 +11,9 @@ config UCC_SLOW
14 protocols: UART, BISYNC, QMC 11 protocols: UART, BISYNC, QMC
15 12
16config UCC_FAST 13config UCC_FAST
17 bool "UCC Fast Protocols Support" 14 bool
18 default n 15 default n
19 select UCC 16 select UCC
20 select UCC_SLOW
21 help 17 help
22 This option provides qe_lib support to UCC fast 18 This option provides qe_lib support to UCC fast
23 protocols: HDLC, Ethernet, ATM, transparent 19 protocols: HDLC, Ethernet, ATM, transparent
@@ -26,5 +22,3 @@ config UCC
26 bool 22 bool
27 default y if UCC_FAST || UCC_SLOW 23 default y if UCC_FAST || UCC_SLOW
28 24
29endmenu
30
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 43f6cc9d7ea0..7f4c07543961 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -71,7 +71,7 @@ phys_addr_t get_qe_base(void)
71 qe = of_find_node_by_type(NULL, "qe"); 71 qe = of_find_node_by_type(NULL, "qe");
72 if (qe) { 72 if (qe) {
73 unsigned int size; 73 unsigned int size;
74 const void *prop = get_property(qe, "reg", &size); 74 const void *prop = of_get_property(qe, "reg", &size);
75 qebase = of_translate_address(qe, prop); 75 qebase = of_translate_address(qe, prop);
76 of_node_put(qe); 76 of_node_put(qe);
77 }; 77 };
@@ -158,7 +158,7 @@ unsigned int get_brg_clk(void)
158 qe = of_find_node_by_type(NULL, "qe"); 158 qe = of_find_node_by_type(NULL, "qe");
159 if (qe) { 159 if (qe) {
160 unsigned int size; 160 unsigned int size;
161 const u32 *prop = get_property(qe, "brg-frequency", &size); 161 const u32 *prop = of_get_property(qe, "brg-frequency", &size);
162 brg_clk = *prop; 162 brg_clk = *prop;
163 of_node_put(qe); 163 of_node_put(qe);
164 }; 164 };
diff --git a/arch/powerpc/sysdev/qe_lib/qe_io.c b/arch/powerpc/sysdev/qe_lib/qe_io.c
index 0afe6bfe3714..e32b45bf9ff5 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_io.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_io.c
@@ -53,7 +53,7 @@ int par_io_init(struct device_node *np)
53 return ret; 53 return ret;
54 par_io = ioremap(res.start, res.end - res.start + 1); 54 par_io = ioremap(res.start, res.end - res.start + 1);
55 55
56 num_ports = get_property(np, "num-ports", NULL); 56 num_ports = of_get_property(np, "num-ports", NULL);
57 if (num_ports) 57 if (num_ports)
58 num_par_io_ports = *num_ports; 58 num_par_io_ports = *num_ports;
59 59
@@ -161,7 +161,7 @@ int par_io_of_config(struct device_node *np)
161 return -1; 161 return -1;
162 } 162 }
163 163
164 ph = get_property(np, "pio-handle", NULL); 164 ph = of_get_property(np, "pio-handle", NULL);
165 if (ph == 0) { 165 if (ph == 0) {
166 printk(KERN_ERR "pio-handle not available \n"); 166 printk(KERN_ERR "pio-handle not available \n");
167 return -1; 167 return -1;
@@ -169,7 +169,7 @@ int par_io_of_config(struct device_node *np)
169 169
170 pio = of_find_node_by_phandle(*ph); 170 pio = of_find_node_by_phandle(*ph);
171 171
172 pio_map = get_property(pio, "pio-map", &pio_map_len); 172 pio_map = of_get_property(pio, "pio-map", &pio_map_len);
173 if (pio_map == NULL) { 173 if (pio_map == NULL) {
174 printk(KERN_ERR "pio-map is not set! \n"); 174 printk(KERN_ERR "pio-map is not set! \n");
175 return -1; 175 return -1;
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
index 817df73ecf56..b930d686a4d1 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc_slow.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
@@ -187,7 +187,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
187 uccs->us_pram = qe_muram_addr(uccs->us_pram_offset); 187 uccs->us_pram = qe_muram_addr(uccs->us_pram_offset);
188 188
189 /* Init Guemr register */ 189 /* Init Guemr register */
190 if ((ret = ucc_init_guemr((struct ucc_common *) (us_info->regs)))) { 190 if ((ret = ucc_init_guemr((struct ucc_common *) us_regs))) {
191 printk(KERN_ERR "%s: cannot init GUEMR", __FUNCTION__); 191 printk(KERN_ERR "%s: cannot init GUEMR", __FUNCTION__);
192 ucc_slow_free(uccs); 192 ucc_slow_free(uccs);
193 return ret; 193 return ret;
@@ -195,7 +195,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
195 195
196 /* Set UCC to slow type */ 196 /* Set UCC to slow type */
197 if ((ret = ucc_set_type(us_info->ucc_num, 197 if ((ret = ucc_set_type(us_info->ucc_num,
198 (struct ucc_common *) (us_info->regs), 198 (struct ucc_common *) us_regs,
199 UCC_SPEED_TYPE_SLOW))) { 199 UCC_SPEED_TYPE_SLOW))) {
200 printk(KERN_ERR "%s: cannot set UCC type", __FUNCTION__); 200 printk(KERN_ERR "%s: cannot set UCC type", __FUNCTION__);
201 ucc_slow_free(uccs); 201 ucc_slow_free(uccs);
diff --git a/arch/powerpc/sysdev/timer.c b/arch/powerpc/sysdev/timer.c
new file mode 100644
index 000000000000..4a01748b4217
--- /dev/null
+++ b/arch/powerpc/sysdev/timer.c
@@ -0,0 +1,71 @@
1/*
2 * Common code to keep time when machine suspends.
3 *
4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPLv2
7 */
8
9#include <linux/time.h>
10#include <linux/sysdev.h>
11#include <asm/rtc.h>
12
13static unsigned long suspend_rtc_time;
14
15/*
16 * Reset the time after a sleep.
17 */
18static int timer_resume(struct sys_device *dev)
19{
20 struct timeval tv;
21 struct timespec ts;
22 struct rtc_time cur_rtc_tm;
23 unsigned long cur_rtc_time, diff;
24
25 /* get current RTC time and convert to seconds */
26 get_rtc_time(&cur_rtc_tm);
27 rtc_tm_to_time(&cur_rtc_tm, &cur_rtc_time);
28
29 diff = cur_rtc_time - suspend_rtc_time;
30
31 /* adjust time of day by seconds that elapsed while
32 * we were suspended */
33 do_gettimeofday(&tv);
34 ts.tv_sec = tv.tv_sec + diff;
35 ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC;
36 do_settimeofday(&ts);
37
38 return 0;
39}
40
41static int timer_suspend(struct sys_device *dev, pm_message_t state)
42{
43 struct rtc_time suspend_rtc_tm;
44 WARN_ON(!ppc_md.get_rtc_time);
45
46 get_rtc_time(&suspend_rtc_tm);
47 rtc_tm_to_time(&suspend_rtc_tm, &suspend_rtc_time);
48
49 return 0;
50}
51
52static struct sysdev_class timer_sysclass = {
53 .resume = timer_resume,
54 .suspend = timer_suspend,
55 set_kset_name("timer"),
56};
57
58static struct sys_device device_timer = {
59 .id = 0,
60 .cls = &timer_sysclass,
61};
62
63static int time_init_device(void)
64{
65 int error = sysdev_class_register(&timer_sysclass);
66 if (!error)
67 error = sysdev_register(&device_timer);
68 return error;
69}
70
71device_initcall(time_init_device);
diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c
index 97f37ef4bbbf..337039ee51e6 100644
--- a/arch/powerpc/sysdev/tsi108_dev.c
+++ b/arch/powerpc/sysdev/tsi108_dev.c
@@ -48,7 +48,7 @@ phys_addr_t get_csrbase(void)
48 tsi = of_find_node_by_type(NULL, "tsi-bridge"); 48 tsi = of_find_node_by_type(NULL, "tsi-bridge");
49 if (tsi) { 49 if (tsi) {
50 unsigned int size; 50 unsigned int size;
51 const void *prop = get_property(tsi, "reg", &size); 51 const void *prop = of_get_property(tsi, "reg", &size);
52 tsi108_csr_base = of_translate_address(tsi, prop); 52 tsi108_csr_base = of_translate_address(tsi, prop);
53 of_node_put(tsi); 53 of_node_put(tsi);
54 }; 54 };
@@ -77,10 +77,10 @@ static int __init tsi108_eth_of_init(void)
77 struct resource r[2]; 77 struct resource r[2];
78 struct device_node *phy; 78 struct device_node *phy;
79 hw_info tsi_eth_data; 79 hw_info tsi_eth_data;
80 unsigned int *id; 80 const unsigned int *id;
81 unsigned int *phy_id; 81 const unsigned int *phy_id;
82 const void *mac_addr; 82 const void *mac_addr;
83 phandle *ph; 83 const phandle *ph;
84 84
85 memset(r, 0, sizeof(r)); 85 memset(r, 0, sizeof(r));
86 memset(&tsi_eth_data, 0, sizeof(tsi_eth_data)); 86 memset(&tsi_eth_data, 0, sizeof(tsi_eth_data));
@@ -107,10 +107,10 @@ static int __init tsi108_eth_of_init(void)
107 goto err; 107 goto err;
108 } 108 }
109 109
110 mac_addr = get_property(np, "address", NULL); 110 mac_addr = of_get_property(np, "address", NULL);
111 memcpy(tsi_eth_data.mac_addr, mac_addr, 6); 111 memcpy(tsi_eth_data.mac_addr, mac_addr, 6);
112 112
113 ph = (phandle *) get_property(np, "phy-handle", NULL); 113 ph = of_get_property(np, "phy-handle", NULL);
114 phy = of_find_node_by_phandle(*ph); 114 phy = of_find_node_by_phandle(*ph);
115 115
116 if (phy == NULL) { 116 if (phy == NULL) {
@@ -118,8 +118,8 @@ static int __init tsi108_eth_of_init(void)
118 goto unreg; 118 goto unreg;
119 } 119 }
120 120
121 id = (u32 *) get_property(phy, "reg", NULL); 121 id = of_get_property(phy, "reg", NULL);
122 phy_id = (u32 *) get_property(phy, "phy-id", NULL); 122 phy_id = of_get_property(phy, "phy-id", NULL);
123 ret = of_address_to_resource(phy, 0, &res); 123 ret = of_address_to_resource(phy, 0, &res);
124 if (ret) { 124 if (ret) {
125 of_node_put(phy); 125 of_node_put(phy);
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index ae249c6bbbcf..58b9e7f8abf2 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -211,7 +211,7 @@ int __init tsi108_setup_pci(struct device_node *dev)
211 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); 211 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
212 212
213 /* Get bus range if any */ 213 /* Get bus range if any */
214 bus_range = get_property(dev, "bus-range", &len); 214 bus_range = of_get_property(dev, "bus-range", &len);
215 if (bus_range == NULL || len < 2 * sizeof(int)) { 215 if (bus_range == NULL || len < 2 * sizeof(int)) {
216 printk(KERN_WARNING "Can't get bus-range for %s, assume" 216 printk(KERN_WARNING "Can't get bus-range for %s, assume"
217 " bus 0\n", dev->full_name); 217 " bus 0\n", dev->full_name);
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
new file mode 100644
index 000000000000..968fb40af9dc
--- /dev/null
+++ b/arch/powerpc/sysdev/uic.c
@@ -0,0 +1,342 @@
1/*
2 * arch/powerpc/sysdev/uic.c
3 *
4 * IBM PowerPC 4xx Universal Interrupt Controller
5 *
6 * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/errno.h>
16#include <linux/reboot.h>
17#include <linux/slab.h>
18#include <linux/stddef.h>
19#include <linux/sched.h>
20#include <linux/signal.h>
21#include <linux/sysdev.h>
22#include <linux/device.h>
23#include <linux/bootmem.h>
24#include <linux/spinlock.h>
25#include <linux/irq.h>
26#include <linux/interrupt.h>
27#include <asm/irq.h>
28#include <asm/io.h>
29#include <asm/prom.h>
30#include <asm/dcr.h>
31
32#define NR_UIC_INTS 32
33
34#define UIC_SR 0x0
35#define UIC_ER 0x2
36#define UIC_CR 0x3
37#define UIC_PR 0x4
38#define UIC_TR 0x5
39#define UIC_MSR 0x6
40#define UIC_VR 0x7
41#define UIC_VCR 0x8
42
43#define uic_irq_to_hw(virq) (irq_map[virq].hwirq)
44
45struct uic *primary_uic;
46
47struct uic {
48 int index;
49 int dcrbase;
50
51 spinlock_t lock;
52
53 /* The remapper for this UIC */
54 struct irq_host *irqhost;
55
56 /* For secondary UICs, the cascade interrupt's irqaction */
57 struct irqaction cascade;
58
59 /* The device node of the interrupt controller */
60 struct device_node *of_node;
61};
62
63static void uic_unmask_irq(unsigned int virq)
64{
65 struct uic *uic = get_irq_chip_data(virq);
66 unsigned int src = uic_irq_to_hw(virq);
67 unsigned long flags;
68 u32 er;
69
70 spin_lock_irqsave(&uic->lock, flags);
71 er = mfdcr(uic->dcrbase + UIC_ER);
72 er |= 1 << (31 - src);
73 mtdcr(uic->dcrbase + UIC_ER, er);
74 spin_unlock_irqrestore(&uic->lock, flags);
75}
76
77static void uic_mask_irq(unsigned int virq)
78{
79 struct uic *uic = get_irq_chip_data(virq);
80 unsigned int src = uic_irq_to_hw(virq);
81 unsigned long flags;
82 u32 er;
83
84 spin_lock_irqsave(&uic->lock, flags);
85 er = mfdcr(uic->dcrbase + UIC_ER);
86 er &= ~(1 << (31 - src));
87 mtdcr(uic->dcrbase + UIC_ER, er);
88 spin_unlock_irqrestore(&uic->lock, flags);
89}
90
91static void uic_ack_irq(unsigned int virq)
92{
93 struct uic *uic = get_irq_chip_data(virq);
94 unsigned int src = uic_irq_to_hw(virq);
95 unsigned long flags;
96
97 spin_lock_irqsave(&uic->lock, flags);
98 mtdcr(uic->dcrbase + UIC_SR, 1 << (31-src));
99 spin_unlock_irqrestore(&uic->lock, flags);
100}
101
102static int uic_set_irq_type(unsigned int virq, unsigned int flow_type)
103{
104 struct uic *uic = get_irq_chip_data(virq);
105 unsigned int src = uic_irq_to_hw(virq);
106 struct irq_desc *desc = get_irq_desc(virq);
107 unsigned long flags;
108 int trigger, polarity;
109 u32 tr, pr, mask;
110
111 switch (flow_type & IRQ_TYPE_SENSE_MASK) {
112 case IRQ_TYPE_NONE:
113 uic_mask_irq(virq);
114 return 0;
115
116 case IRQ_TYPE_EDGE_RISING:
117 trigger = 1; polarity = 1;
118 break;
119 case IRQ_TYPE_EDGE_FALLING:
120 trigger = 1; polarity = 0;
121 break;
122 case IRQ_TYPE_LEVEL_HIGH:
123 trigger = 0; polarity = 1;
124 break;
125 case IRQ_TYPE_LEVEL_LOW:
126 trigger = 0; polarity = 0;
127 break;
128 default:
129 return -EINVAL;
130 }
131
132 mask = ~(1 << (31 - src));
133
134 spin_lock_irqsave(&uic->lock, flags);
135 tr = mfdcr(uic->dcrbase + UIC_TR);
136 pr = mfdcr(uic->dcrbase + UIC_PR);
137 tr = (tr & mask) | (trigger << (31-src));
138 pr = (pr & mask) | (polarity << (31-src));
139
140 mtdcr(uic->dcrbase + UIC_PR, pr);
141 mtdcr(uic->dcrbase + UIC_TR, tr);
142
143 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
144 desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
145 if (trigger)
146 desc->status |= IRQ_LEVEL;
147
148 spin_unlock_irqrestore(&uic->lock, flags);
149
150 return 0;
151}
152
153static struct irq_chip uic_irq_chip = {
154 .typename = " UIC ",
155 .unmask = uic_unmask_irq,
156 .mask = uic_mask_irq,
157/* .mask_ack = uic_mask_irq_and_ack, */
158 .ack = uic_ack_irq,
159 .set_type = uic_set_irq_type,
160};
161
162static int uic_host_match(struct irq_host *h, struct device_node *node)
163{
164 struct uic *uic = h->host_data;
165 return uic->of_node == node;
166}
167
168static int uic_host_map(struct irq_host *h, unsigned int virq,
169 irq_hw_number_t hw)
170{
171 struct uic *uic = h->host_data;
172
173 set_irq_chip_data(virq, uic);
174 /* Despite the name, handle_level_irq() works for both level
175 * and edge irqs on UIC. FIXME: check this is correct */
176 set_irq_chip_and_handler(virq, &uic_irq_chip, handle_level_irq);
177
178 /* Set default irq type */
179 set_irq_type(virq, IRQ_TYPE_NONE);
180
181 return 0;
182}
183
184static int uic_host_xlate(struct irq_host *h, struct device_node *ct,
185 u32 *intspec, unsigned int intsize,
186 irq_hw_number_t *out_hwirq, unsigned int *out_type)
187
188{
189 /* UIC intspecs must have 2 cells */
190 BUG_ON(intsize != 2);
191 *out_hwirq = intspec[0];
192 *out_type = intspec[1];
193 return 0;
194}
195
196static struct irq_host_ops uic_host_ops = {
197 .match = uic_host_match,
198 .map = uic_host_map,
199 .xlate = uic_host_xlate,
200};
201
202irqreturn_t uic_cascade(int virq, void *data)
203{
204 struct uic *uic = data;
205 u32 msr;
206 int src;
207 int subvirq;
208
209 msr = mfdcr(uic->dcrbase + UIC_MSR);
210 src = 32 - ffs(msr);
211
212 subvirq = irq_linear_revmap(uic->irqhost, src);
213 generic_handle_irq(subvirq);
214
215 return IRQ_HANDLED;
216}
217
218static struct uic * __init uic_init_one(struct device_node *node)
219{
220 struct uic *uic;
221 const u32 *indexp, *dcrreg;
222 int len;
223
224 BUG_ON(! device_is_compatible(node, "ibm,uic"));
225
226 uic = alloc_bootmem(sizeof(*uic));
227 if (! uic)
228 return NULL; /* FIXME: panic? */
229
230 memset(uic, 0, sizeof(*uic));
231 spin_lock_init(&uic->lock);
232 uic->of_node = of_node_get(node);
233 indexp = of_get_property(node, "cell-index", &len);
234 if (!indexp || (len != sizeof(u32))) {
235 printk(KERN_ERR "uic: Device node %s has missing or invalid "
236 "cell-index property\n", node->full_name);
237 return NULL;
238 }
239 uic->index = *indexp;
240
241 dcrreg = of_get_property(node, "dcr-reg", &len);
242 if (!dcrreg || (len != 2*sizeof(u32))) {
243 printk(KERN_ERR "uic: Device node %s has missing or invalid "
244 "dcr-reg property\n", node->full_name);
245 return NULL;
246 }
247 uic->dcrbase = *dcrreg;
248
249 uic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, NR_UIC_INTS,
250 &uic_host_ops, -1);
251 if (! uic->irqhost) {
252 of_node_put(node);
253 return NULL; /* FIXME: panic? */
254 }
255
256 uic->irqhost->host_data = uic;
257
258 /* Start with all interrupts disabled, level and non-critical */
259 mtdcr(uic->dcrbase + UIC_ER, 0);
260 mtdcr(uic->dcrbase + UIC_CR, 0);
261 mtdcr(uic->dcrbase + UIC_TR, 0);
262 /* Clear any pending interrupts, in case the firmware left some */
263 mtdcr(uic->dcrbase + UIC_SR, 0xffffffff);
264
265 printk ("UIC%d (%d IRQ sources) at DCR 0x%x\n", uic->index,
266 NR_UIC_INTS, uic->dcrbase);
267
268 return uic;
269}
270
271void __init uic_init_tree(void)
272{
273 struct device_node *np;
274 struct uic *uic;
275 const u32 *interrupts;
276
277 /* First locate and initialize the top-level UIC */
278
279 np = of_find_compatible_node(NULL, NULL, "ibm,uic");
280 while (np) {
281 interrupts = of_get_property(np, "interrupts", NULL);
282 if (! interrupts)
283 break;
284
285 np = of_find_compatible_node(np, NULL, "ibm,uic");
286 }
287
288 BUG_ON(!np); /* uic_init_tree() assumes there's a UIC as the
289 * top-level interrupt controller */
290 primary_uic = uic_init_one(np);
291 if (! primary_uic)
292 panic("Unable to initialize primary UIC %s\n", np->full_name);
293
294 irq_set_default_host(primary_uic->irqhost);
295 of_node_put(np);
296
297 /* The scan again for cascaded UICs */
298 np = of_find_compatible_node(NULL, NULL, "ibm,uic");
299 while (np) {
300 interrupts = of_get_property(np, "interrupts", NULL);
301 if (interrupts) {
302 /* Secondary UIC */
303 int cascade_virq;
304 int ret;
305
306 uic = uic_init_one(np);
307 if (! uic)
308 panic("Unable to initialize a secondary UIC %s\n",
309 np->full_name);
310
311 cascade_virq = irq_of_parse_and_map(np, 0);
312
313 uic->cascade.handler = uic_cascade;
314 uic->cascade.name = "UIC cascade";
315 uic->cascade.dev_id = uic;
316
317 ret = setup_irq(cascade_virq, &uic->cascade);
318 if (ret)
319 printk(KERN_ERR "Failed to setup_irq(%d) for "
320 "UIC%d cascade\n", cascade_virq,
321 uic->index);
322
323 /* FIXME: setup critical cascade?? */
324 }
325
326 np = of_find_compatible_node(np, NULL, "ibm,uic");
327 }
328}
329
330/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
331unsigned int uic_get_irq(void)
332{
333 u32 msr;
334 int src;
335
336 BUG_ON(! primary_uic);
337
338 msr = mfdcr(primary_uic->dcrbase + UIC_MSR);
339 src = 32 - ffs(msr);
340
341 return irq_linear_revmap(primary_uic->irqhost, src);
342}