aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-12-05 12:01:28 -0500
committerDavid Howells <dhowells@warthog.cambridge.redhat.com>2006-12-05 12:01:28 -0500
commit9db73724453a9350e1c22dbe732d427e2939a5c9 (patch)
tree15e3ead6413ae97398a54292acc199bee0864d42 /arch/powerpc/sysdev
parent4c1ac1b49122b805adfa4efc620592f68dccf5db (diff)
parente62438630ca37539c8cc1553710bbfaa3cf960a7 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: drivers/ata/libata-scsi.c include/linux/libata.h Futher merge of Linus's head and compilation fixups. Signed-Off-By: David Howells <dhowells@redhat.com>
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r--arch/powerpc/sysdev/Makefile5
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c34
-rw-r--r--arch/powerpc/sysdev/dcr-low.S39
-rw-r--r--arch/powerpc/sysdev/dcr.c137
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c28
-rw-r--r--arch/powerpc/sysdev/mpic.c172
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe.c3
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc_fast.c4
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc_slow.c4
-rw-r--r--arch/powerpc/sysdev/rom.c31
-rw-r--r--arch/powerpc/sysdev/todc.c392
-rw-r--r--arch/powerpc/sysdev/tsi108_pci.c48
12 files changed, 404 insertions, 493 deletions
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 91f052d8cce0..6cc34597a620 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -5,14 +5,13 @@ endif
5obj-$(CONFIG_MPIC) += mpic.o 5obj-$(CONFIG_MPIC) += mpic.o
6obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o 6obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
7obj-$(CONFIG_PPC_MPC106) += grackle.o 7obj-$(CONFIG_PPC_MPC106) += grackle.o
8obj-$(CONFIG_BOOKE) += dcr.o 8obj-$(CONFIG_PPC_DCR) += dcr.o dcr-low.o
9obj-$(CONFIG_40x) += dcr.o
10obj-$(CONFIG_U3_DART) += dart_iommu.o 9obj-$(CONFIG_U3_DART) += dart_iommu.o
11obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o 10obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
12obj-$(CONFIG_FSL_SOC) += fsl_soc.o 11obj-$(CONFIG_FSL_SOC) += fsl_soc.o
13obj-$(CONFIG_PPC_TODC) += todc.o
14obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o 12obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
15obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ 13obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
14obj-$(CONFIG_MTD) += rom.o
16 15
17ifeq ($(CONFIG_PPC_MERGE),y) 16ifeq ($(CONFIG_PPC_MERGE),y)
18obj-$(CONFIG_PPC_I8259) += i8259.o 17obj-$(CONFIG_PPC_I8259) += i8259.o
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 572b7846cc77..1488535b0e13 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
51extern int iommu_is_off;
52extern 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 */
55unsigned long dart_tablebase; /* exported to htab_initialize */ 52unsigned long dart_tablebase; /* exported to htab_initialize */
56static unsigned long dart_tablesize; 53static 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
292static void iommu_dev_setup_dart(struct pci_dev *dev) 289static 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
309static void iommu_bus_setup_dart(struct pci_bus *bus) 297static 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
324static void iommu_dev_setup_null(struct pci_dev *dev) { }
325static void iommu_bus_setup_null(struct pci_bus *bus) { }
326
327void iommu_init_early_dart(void) 312void 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 000000000000..2078f39e2f17
--- /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
34dcr = 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 000000000000..dffeeaeca1d9
--- /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
26unsigned 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
37unsigned 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
50static 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
69u64 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
102dcr_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
126void 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 dbe92ae20333..ad31e56e892b 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";
177static const char *gfar_rx_intr = "rx"; 178static const char *gfar_rx_intr = "rx";
178static const char *gfar_err_intr = "error"; 179static const char *gfar_err_intr = "error";
179 180
181
180static int __init gfar_of_init(void) 182static 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 ba4833f57d47..411480d5c626 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
150static inline u32 _mpic_read(unsigned int be, volatile u32 __iomem *base, 150static 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
159static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base, 168static 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
168static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi) 186static 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
179static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value) 197static 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
187static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg) 205static 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
197static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 value) 214static 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
207static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigned int reg) 224static 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
258static 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
267static 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
276static 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
847struct mpic * __init mpic_alloc(struct device_node *node, 896struct 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
975void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, 1063void __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 e4223226a7a8..e3d71e083f35 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 75fa3104a43a..e657559bea93 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 a49da6b73ecf..47b56203f47e 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 000000000000..bf5b3f10e6c6
--- /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
13static 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
31arch_initcall(powerpc_flash_init);
diff --git a/arch/powerpc/sysdev/todc.c b/arch/powerpc/sysdev/todc.c
deleted file mode 100644
index 0a65980efb50..000000000000
--- 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) */
73u_char
74todc_direct_read_val(int addr)
75{
76 return readb((void __iomem *)(todc_info->nvram_data + addr));
77}
78
79void
80todc_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 */
87u_char
88todc_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
95void
96todc_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 */
105u_char
106todc_mc146818_read_val(int addr)
107{
108 outb_p(addr, todc_info->nvram_as0);
109 return inb_p(todc_info->nvram_data);
110}
111
112void
113todc_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 */
127static inline u_char
128todc_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
146static inline void
147todc_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 */
174long __init
175todc_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 */
260void
261todc_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
348int
349todc_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 322f86e93de5..ae249c6bbbcf 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
49u32 tsi108_pci_cfg_base; 51u32 tsi108_pci_cfg_base;
50u32 tsi108_csr_vir_base; 52u32 tsi108_csr_vir_base;
53static struct device_node *pci_irq_node;
54static struct irq_host *pci_irq_host;
51 55
52extern u32 get_vir_csrbase(void); 56extern u32 get_vir_csrbase(void);
53extern u32 tsi108_read_reg(u32 reg_offset); 57extern 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
385static 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
394static 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
406static int pci_irq_host_match(struct irq_host *h, struct device_node *node)
407{
408 return pci_irq_node == node;
409}
410
411static 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
394void __init tsi108_pci_int_init(void) 430void __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();