aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-23 12:49:55 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-23 12:49:55 -0400
commit24665cd00dd06c741ef6268515ca9e6d3cda5c57 (patch)
treed55e925db2b78bc6529965fa6b1df07a76b56610
parentfed2fc18a4567d613cd35115322257c6c6c710e9 (diff)
parentd7152fe14cad075d6dd4ee4194acd131aed0244e (diff)
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/paulus/ppc64-2.6
-rw-r--r--MAINTAINERS7
-rw-r--r--arch/ppc64/Kconfig21
-rw-r--r--arch/ppc64/Makefile2
-rw-r--r--arch/ppc64/kernel/Makefile11
-rw-r--r--arch/ppc64/kernel/bpa_iic.c270
-rw-r--r--arch/ppc64/kernel/bpa_iic.h62
-rw-r--r--arch/ppc64/kernel/bpa_iommu.c377
-rw-r--r--arch/ppc64/kernel/bpa_iommu.h65
-rw-r--r--arch/ppc64/kernel/bpa_nvram.c118
-rw-r--r--arch/ppc64/kernel/bpa_setup.c140
-rw-r--r--arch/ppc64/kernel/cpu_setup_power4.S16
-rw-r--r--arch/ppc64/kernel/cputable.c11
-rw-r--r--arch/ppc64/kernel/iSeries_setup.c5
-rw-r--r--arch/ppc64/kernel/irq.c3
-rw-r--r--arch/ppc64/kernel/maple_setup.c64
-rw-r--r--arch/ppc64/kernel/maple_time.c51
-rw-r--r--arch/ppc64/kernel/mpic.h3
-rw-r--r--arch/ppc64/kernel/pSeries_pci.c497
-rw-r--r--arch/ppc64/kernel/pSeries_setup.c184
-rw-r--r--arch/ppc64/kernel/pSeries_smp.c69
-rw-r--r--arch/ppc64/kernel/pci.c3
-rw-r--r--arch/ppc64/kernel/pci.h6
-rw-r--r--arch/ppc64/kernel/pmac_time.c8
-rw-r--r--arch/ppc64/kernel/proc_ppc64.c2
-rw-r--r--arch/ppc64/kernel/prom_init.c4
-rw-r--r--arch/ppc64/kernel/rtas-proc.c4
-rw-r--r--arch/ppc64/kernel/rtas.c121
-rw-r--r--arch/ppc64/kernel/rtas_pci.c495
-rw-r--r--arch/ppc64/kernel/rtc.c6
-rw-r--r--arch/ppc64/kernel/setup.c33
-rw-r--r--arch/ppc64/kernel/smp.c4
-rw-r--r--arch/ppc64/kernel/spider-pic.c191
-rw-r--r--arch/ppc64/kernel/time.c63
-rw-r--r--arch/ppc64/kernel/traps.c4
-rw-r--r--drivers/char/watchdog/Kconfig10
-rw-r--r--drivers/char/watchdog/Makefile1
-rw-r--r--drivers/char/watchdog/wdrtas.c696
-rw-r--r--include/asm-ppc64/machdep.h1
-rw-r--r--include/asm-ppc64/mmu.h5
-rw-r--r--include/asm-ppc64/nvram.h1
-rw-r--r--include/asm-ppc64/processor.h15
-rw-r--r--include/asm-ppc64/rtas.h6
-rw-r--r--include/asm-ppc64/smp.h8
-rw-r--r--include/asm-ppc64/time.h9
44 files changed, 2918 insertions, 754 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index fc4b0e8bca6b..651af5012c98 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -504,6 +504,13 @@ L: bonding-devel@lists.sourceforge.net
504W: http://sourceforge.net/projects/bonding/ 504W: http://sourceforge.net/projects/bonding/
505S: Supported 505S: Supported
506 506
507BROADBAND PROCESSOR ARCHITECTURE
508P: Arnd Bergmann
509M: arnd@arndb.de
510L: linuxppc64-dev@ozlabs.org
511W: http://linuxppc64.org
512S: Supported
513
507BTTV VIDEO4LINUX DRIVER 514BTTV VIDEO4LINUX DRIVER
508P: Gerd Knorr 515P: Gerd Knorr
509M: kraxel@bytesex.org 516M: kraxel@bytesex.org
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
index 6448231cb106..cb27068bfcd4 100644
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -77,6 +77,10 @@ config PPC_PSERIES
77 bool " IBM pSeries & new iSeries" 77 bool " IBM pSeries & new iSeries"
78 default y 78 default y
79 79
80config PPC_BPA
81 bool " Broadband Processor Architecture"
82 depends on PPC_MULTIPLATFORM
83
80config PPC_PMAC 84config PPC_PMAC
81 depends on PPC_MULTIPLATFORM 85 depends on PPC_MULTIPLATFORM
82 bool " Apple G5 based machines" 86 bool " Apple G5 based machines"
@@ -106,6 +110,21 @@ config PPC_OF
106 bool 110 bool
107 default y 111 default y
108 112
113config XICS
114 depends on PPC_PSERIES
115 bool
116 default y
117
118config MPIC
119 depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE
120 bool
121 default y
122
123config BPA_IIC
124 depends on PPC_BPA
125 bool
126 default y
127
109# VMX is pSeries only for now until somebody writes the iSeries 128# VMX is pSeries only for now until somebody writes the iSeries
110# exception vectors for it 129# exception vectors for it
111config ALTIVEC 130config ALTIVEC
@@ -292,7 +311,7 @@ config MSCHUNKS
292 311
293config PPC_RTAS 312config PPC_RTAS
294 bool 313 bool
295 depends on PPC_PSERIES 314 depends on PPC_PSERIES || PPC_BPA
296 default y 315 default y
297 316
298config RTAS_PROC 317config RTAS_PROC
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile
index 33c752ceca4b..731b84758331 100644
--- a/arch/ppc64/Makefile
+++ b/arch/ppc64/Makefile
@@ -90,12 +90,14 @@ boot := arch/ppc64/boot
90boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd 90boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd
91boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd 91boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd
92boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd vmlinux.sm 92boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd vmlinux.sm
93boottarget-$(CONFIG_PPC_BPA) := zImage zImage.initrd
93$(boottarget-y): vmlinux 94$(boottarget-y): vmlinux
94 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ 95 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
95 96
96bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage 97bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage
97bootimage-$(CONFIG_PPC_PMAC) := vmlinux 98bootimage-$(CONFIG_PPC_PMAC) := vmlinux
98bootimage-$(CONFIG_PPC_MAPLE) := $(boot)/zImage 99bootimage-$(CONFIG_PPC_MAPLE) := $(boot)/zImage
100bootimage-$(CONFIG_PPC_BPA) := zImage
99bootimage-$(CONFIG_PPC_ISERIES) := vmlinux 101bootimage-$(CONFIG_PPC_ISERIES) := vmlinux
100BOOTIMAGE := $(bootimage-y) 102BOOTIMAGE := $(bootimage-y)
101install: vmlinux 103install: vmlinux
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
index b5e167cf1a05..dffbfb7ac8d5 100644
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -27,17 +27,21 @@ obj-$(CONFIG_PPC_ISERIES) += HvCall.o HvLpConfig.o LparData.o \
27 mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \ 27 mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \
28 iSeries_iommu.o 28 iSeries_iommu.o
29 29
30obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o mpic.o 30obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o
31 31
32obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \ 32obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
33 pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \ 33 pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \
34 xics.o rtas.o pSeries_setup.o pSeries_iommu.o 34 pSeries_setup.o pSeries_iommu.o
35
36obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \
37 bpa_iic.o spider-pic.o
35 38
36obj-$(CONFIG_EEH) += eeh.o 39obj-$(CONFIG_EEH) += eeh.o
37obj-$(CONFIG_PROC_FS) += proc_ppc64.o 40obj-$(CONFIG_PROC_FS) += proc_ppc64.o
38obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o 41obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
39obj-$(CONFIG_SMP) += smp.o 42obj-$(CONFIG_SMP) += smp.o
40obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o 43obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
44obj-$(CONFIG_PPC_RTAS) += rtas.o rtas_pci.o
41obj-$(CONFIG_RTAS_PROC) += rtas-proc.o 45obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
42obj-$(CONFIG_SCANLOG) += scanlog.o 46obj-$(CONFIG_SCANLOG) += scanlog.o
43obj-$(CONFIG_VIOPATH) += viopath.o 47obj-$(CONFIG_VIOPATH) += viopath.o
@@ -46,6 +50,8 @@ obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
46obj-$(CONFIG_BOOTX_TEXT) += btext.o 50obj-$(CONFIG_BOOTX_TEXT) += btext.o
47obj-$(CONFIG_HVCS) += hvcserver.o 51obj-$(CONFIG_HVCS) += hvcserver.o
48obj-$(CONFIG_IBMVIO) += vio.o 52obj-$(CONFIG_IBMVIO) += vio.o
53obj-$(CONFIG_XICS) += xics.o
54obj-$(CONFIG_MPIC) += mpic.o
49 55
50obj-$(CONFIG_PPC_PMAC) += pmac_setup.o pmac_feature.o pmac_pci.o \ 56obj-$(CONFIG_PPC_PMAC) += pmac_setup.o pmac_feature.o pmac_pci.o \
51 pmac_time.o pmac_nvram.o pmac_low_i2c.o 57 pmac_time.o pmac_nvram.o pmac_low_i2c.o
@@ -58,6 +64,7 @@ ifdef CONFIG_SMP
58obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o 64obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o
59obj-$(CONFIG_PPC_ISERIES) += iSeries_smp.o 65obj-$(CONFIG_PPC_ISERIES) += iSeries_smp.o
60obj-$(CONFIG_PPC_PSERIES) += pSeries_smp.o 66obj-$(CONFIG_PPC_PSERIES) += pSeries_smp.o
67obj-$(CONFIG_PPC_BPA) += pSeries_smp.o
61obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o 68obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o
62endif 69endif
63 70
diff --git a/arch/ppc64/kernel/bpa_iic.c b/arch/ppc64/kernel/bpa_iic.c
new file mode 100644
index 000000000000..c8f3dc3fad70
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_iic.c
@@ -0,0 +1,270 @@
1/*
2 * BPA Internal Interrupt Controller
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5 *
6 * Author: Arnd Bergmann <arndb@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/config.h>
24#include <linux/interrupt.h>
25#include <linux/irq.h>
26#include <linux/percpu.h>
27#include <linux/types.h>
28
29#include <asm/io.h>
30#include <asm/pgtable.h>
31#include <asm/prom.h>
32#include <asm/ptrace.h>
33
34#include "bpa_iic.h"
35
36struct iic_pending_bits {
37 u32 data;
38 u8 flags;
39 u8 class;
40 u8 source;
41 u8 prio;
42};
43
44enum iic_pending_flags {
45 IIC_VALID = 0x80,
46 IIC_IPI = 0x40,
47};
48
49struct iic_regs {
50 struct iic_pending_bits pending;
51 struct iic_pending_bits pending_destr;
52 u64 generate;
53 u64 prio;
54};
55
56struct iic {
57 struct iic_regs __iomem *regs;
58};
59
60static DEFINE_PER_CPU(struct iic, iic);
61
62void iic_local_enable(void)
63{
64 out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
65}
66
67void iic_local_disable(void)
68{
69 out_be64(&__get_cpu_var(iic).regs->prio, 0x0);
70}
71
72static unsigned int iic_startup(unsigned int irq)
73{
74 return 0;
75}
76
77static void iic_enable(unsigned int irq)
78{
79 iic_local_enable();
80}
81
82static void iic_disable(unsigned int irq)
83{
84}
85
86static void iic_end(unsigned int irq)
87{
88 iic_local_enable();
89}
90
91static struct hw_interrupt_type iic_pic = {
92 .typename = " BPA-IIC ",
93 .startup = iic_startup,
94 .enable = iic_enable,
95 .disable = iic_disable,
96 .end = iic_end,
97};
98
99static int iic_external_get_irq(struct iic_pending_bits pending)
100{
101 int irq;
102 unsigned char node, unit;
103
104 node = pending.source >> 4;
105 unit = pending.source & 0xf;
106 irq = -1;
107
108 /*
109 * This mapping is specific to the Broadband
110 * Engine. We might need to get the numbers
111 * from the device tree to support future CPUs.
112 */
113 switch (unit) {
114 case 0x00:
115 case 0x0b:
116 /*
117 * One of these units can be connected
118 * to an external interrupt controller.
119 */
120 if (pending.prio > 0x3f ||
121 pending.class != 2)
122 break;
123 irq = IIC_EXT_OFFSET
124 + spider_get_irq(pending.prio + node * IIC_NODE_STRIDE)
125 + node * IIC_NODE_STRIDE;
126 break;
127 case 0x01 ... 0x04:
128 case 0x07 ... 0x0a:
129 /*
130 * These units are connected to the SPEs
131 */
132 if (pending.class > 2)
133 break;
134 irq = IIC_SPE_OFFSET
135 + pending.class * IIC_CLASS_STRIDE
136 + node * IIC_NODE_STRIDE
137 + unit;
138 break;
139 }
140 if (irq == -1)
141 printk(KERN_WARNING "Unexpected interrupt class %02x, "
142 "source %02x, prio %02x, cpu %02x\n", pending.class,
143 pending.source, pending.prio, smp_processor_id());
144 return irq;
145}
146
147/* Get an IRQ number from the pending state register of the IIC */
148int iic_get_irq(struct pt_regs *regs)
149{
150 struct iic *iic;
151 int irq;
152 struct iic_pending_bits pending;
153
154 iic = &__get_cpu_var(iic);
155 *(unsigned long *) &pending =
156 in_be64((unsigned long __iomem *) &iic->regs->pending_destr);
157
158 irq = -1;
159 if (pending.flags & IIC_VALID) {
160 if (pending.flags & IIC_IPI) {
161 irq = IIC_IPI_OFFSET + (pending.prio >> 4);
162/*
163 if (irq > 0x80)
164 printk(KERN_WARNING "Unexpected IPI prio %02x"
165 "on CPU %02x\n", pending.prio,
166 smp_processor_id());
167*/
168 } else {
169 irq = iic_external_get_irq(pending);
170 }
171 }
172 return irq;
173}
174
175static struct iic_regs __iomem *find_iic(int cpu)
176{
177 struct device_node *np;
178 int nodeid = cpu / 2;
179 unsigned long regs;
180 struct iic_regs __iomem *iic_regs;
181
182 for (np = of_find_node_by_type(NULL, "cpu");
183 np;
184 np = of_find_node_by_type(np, "cpu")) {
185 if (nodeid == *(int *)get_property(np, "node-id", NULL))
186 break;
187 }
188
189 if (!np) {
190 printk(KERN_WARNING "IIC: CPU %d not found\n", cpu);
191 iic_regs = NULL;
192 } else {
193 regs = *(long *)get_property(np, "iic", NULL);
194
195 /* hack until we have decided on the devtree info */
196 regs += 0x400;
197 if (cpu & 1)
198 regs += 0x20;
199
200 printk(KERN_DEBUG "IIC for CPU %d at %lx\n", cpu, regs);
201 iic_regs = __ioremap(regs, sizeof(struct iic_regs),
202 _PAGE_NO_CACHE);
203 }
204 return iic_regs;
205}
206
207#ifdef CONFIG_SMP
208void iic_setup_cpu(void)
209{
210 out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
211}
212
213void iic_cause_IPI(int cpu, int mesg)
214{
215 out_be64(&per_cpu(iic, cpu).regs->generate, mesg);
216}
217
218static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
219{
220
221 smp_message_recv(irq - IIC_IPI_OFFSET, regs);
222 return IRQ_HANDLED;
223}
224
225static void iic_request_ipi(int irq, const char *name)
226{
227 /* IPIs are marked SA_INTERRUPT as they must run with irqs
228 * disabled */
229 get_irq_desc(irq)->handler = &iic_pic;
230 get_irq_desc(irq)->status |= IRQ_PER_CPU;
231 request_irq(irq, iic_ipi_action, SA_INTERRUPT, name, NULL);
232}
233
234void iic_request_IPIs(void)
235{
236 iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_CALL_FUNCTION, "IPI-call");
237 iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_RESCHEDULE, "IPI-resched");
238#ifdef CONFIG_DEBUGGER
239 iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
240#endif /* CONFIG_DEBUGGER */
241}
242#endif /* CONFIG_SMP */
243
244static void iic_setup_spe_handlers(void)
245{
246 int be, isrc;
247
248 /* Assume two threads per BE are present */
249 for (be=0; be < num_present_cpus() / 2; be++) {
250 for (isrc = 0; isrc < IIC_CLASS_STRIDE * 3; isrc++) {
251 int irq = IIC_NODE_STRIDE * be + IIC_SPE_OFFSET + isrc;
252 get_irq_desc(irq)->handler = &iic_pic;
253 }
254 }
255}
256
257void iic_init_IRQ(void)
258{
259 int cpu, irq_offset;
260 struct iic *iic;
261
262 irq_offset = 0;
263 for_each_cpu(cpu) {
264 iic = &per_cpu(iic, cpu);
265 iic->regs = find_iic(cpu);
266 if (iic->regs)
267 out_be64(&iic->regs->prio, 0xff);
268 }
269 iic_setup_spe_handlers();
270}
diff --git a/arch/ppc64/kernel/bpa_iic.h b/arch/ppc64/kernel/bpa_iic.h
new file mode 100644
index 000000000000..6833c3022166
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_iic.h
@@ -0,0 +1,62 @@
1#ifndef ASM_BPA_IIC_H
2#define ASM_BPA_IIC_H
3#ifdef __KERNEL__
4/*
5 * Mapping of IIC pending bits into per-node
6 * interrupt numbers.
7 *
8 * IRQ FF CC SS PP FF CC SS PP Description
9 *
10 * 00-3f 80 02 +0 00 - 80 02 +0 3f South Bridge
11 * 00-3f 80 02 +b 00 - 80 02 +b 3f South Bridge
12 * 41-4a 80 00 +1 ** - 80 00 +a ** SPU Class 0
13 * 51-5a 80 01 +1 ** - 80 01 +a ** SPU Class 1
14 * 61-6a 80 02 +1 ** - 80 02 +a ** SPU Class 2
15 * 70-7f C0 ** ** 00 - C0 ** ** 0f IPI
16 *
17 * F flags
18 * C class
19 * S source
20 * P Priority
21 * + node number
22 * * don't care
23 *
24 * A node consists of a Broadband Engine and an optional
25 * south bridge device providing a maximum of 64 IRQs.
26 * The south bridge may be connected to either IOIF0
27 * or IOIF1.
28 * Each SPE is represented as three IRQ lines, one per
29 * interrupt class.
30 * 16 IRQ numbers are reserved for inter processor
31 * interruptions, although these are only used in the
32 * range of the first node.
33 *
34 * This scheme needs 128 IRQ numbers per BIF node ID,
35 * which means that with the total of 512 lines
36 * available, we can have a maximum of four nodes.
37 */
38
39enum {
40 IIC_EXT_OFFSET = 0x00, /* Start of south bridge IRQs */
41 IIC_NUM_EXT = 0x40, /* Number of south bridge IRQs */
42 IIC_SPE_OFFSET = 0x40, /* Start of SPE interrupts */
43 IIC_CLASS_STRIDE = 0x10, /* SPE IRQs per class */
44 IIC_IPI_OFFSET = 0x70, /* Start of IPI IRQs */
45 IIC_NUM_IPIS = 0x10, /* IRQs reserved for IPI */
46 IIC_NODE_STRIDE = 0x80, /* Total IRQs per node */
47};
48
49extern void iic_init_IRQ(void);
50extern int iic_get_irq(struct pt_regs *regs);
51extern void iic_cause_IPI(int cpu, int mesg);
52extern void iic_request_IPIs(void);
53extern void iic_setup_cpu(void);
54extern void iic_local_enable(void);
55extern void iic_local_disable(void);
56
57
58extern void spider_init_IRQ(void);
59extern int spider_get_irq(unsigned long int_pending);
60
61#endif
62#endif /* ASM_BPA_IIC_H */
diff --git a/arch/ppc64/kernel/bpa_iommu.c b/arch/ppc64/kernel/bpa_iommu.c
new file mode 100644
index 000000000000..f33a7bccb0d7
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_iommu.c
@@ -0,0 +1,377 @@
1/*
2 * IOMMU implementation for Broadband Processor Architecture
3 * We just establish a linear mapping at boot by setting all the
4 * IOPT cache entries in the CPU.
5 * The mapping functions should be identical to pci_direct_iommu,
6 * except for the handling of the high order bit that is required
7 * by the Spider bridge. These should be split into a separate
8 * file at the point where we get a different bridge chip.
9 *
10 * Copyright (C) 2005 IBM Deutschland Entwicklung GmbH,
11 * Arnd Bergmann <arndb@de.ibm.com>
12 *
13 * Based on linear mapping
14 * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version
19 * 2 of the License, or (at your option) any later version.
20 */
21
22#undef DEBUG
23
24#include <linux/kernel.h>
25#include <linux/pci.h>
26#include <linux/delay.h>
27#include <linux/string.h>
28#include <linux/init.h>
29#include <linux/bootmem.h>
30#include <linux/mm.h>
31#include <linux/dma-mapping.h>
32
33#include <asm/sections.h>
34#include <asm/iommu.h>
35#include <asm/io.h>
36#include <asm/prom.h>
37#include <asm/pci-bridge.h>
38#include <asm/machdep.h>
39#include <asm/pmac_feature.h>
40#include <asm/abs_addr.h>
41#include <asm/system.h>
42
43#include "pci.h"
44#include "bpa_iommu.h"
45
46static inline unsigned long
47get_iopt_entry(unsigned long real_address, unsigned long ioid,
48 unsigned long prot)
49{
50 return (prot & IOPT_PROT_MASK)
51 | (IOPT_COHERENT)
52 | (IOPT_ORDER_VC)
53 | (real_address & IOPT_RPN_MASK)
54 | (ioid & IOPT_IOID_MASK);
55}
56
57typedef struct {
58 unsigned long val;
59} ioste;
60
61static inline ioste
62mk_ioste(unsigned long val)
63{
64 ioste ioste = { .val = val, };
65 return ioste;
66}
67
68static inline ioste
69get_iost_entry(unsigned long iopt_base, unsigned long io_address, unsigned page_size)
70{
71 unsigned long ps;
72 unsigned long iostep;
73 unsigned long nnpt;
74 unsigned long shift;
75
76 switch (page_size) {
77 case 0x1000000:
78 ps = IOST_PS_16M;
79 nnpt = 0; /* one page per segment */
80 shift = 5; /* segment has 16 iopt entries */
81 break;
82
83 case 0x100000:
84 ps = IOST_PS_1M;
85 nnpt = 0; /* one page per segment */
86 shift = 1; /* segment has 256 iopt entries */
87 break;
88
89 case 0x10000:
90 ps = IOST_PS_64K;
91 nnpt = 0x07; /* 8 pages per io page table */
92 shift = 0; /* all entries are used */
93 break;
94
95 case 0x1000:
96 ps = IOST_PS_4K;
97 nnpt = 0x7f; /* 128 pages per io page table */
98 shift = 0; /* all entries are used */
99 break;
100
101 default: /* not a known compile time constant */
102 BUILD_BUG_ON(1);
103 break;
104 }
105
106 iostep = iopt_base +
107 /* need 8 bytes per iopte */
108 (((io_address / page_size * 8)
109 /* align io page tables on 4k page boundaries */
110 << shift)
111 /* nnpt+1 pages go into each iopt */
112 & ~(nnpt << 12));
113
114 nnpt++; /* this seems to work, but the documentation is not clear
115 about wether we put nnpt or nnpt-1 into the ioste bits.
116 In theory, this can't work for 4k pages. */
117 return mk_ioste(IOST_VALID_MASK
118 | (iostep & IOST_PT_BASE_MASK)
119 | ((nnpt << 5) & IOST_NNPT_MASK)
120 | (ps & IOST_PS_MASK));
121}
122
123/* compute the address of an io pte */
124static inline unsigned long
125get_ioptep(ioste iost_entry, unsigned long io_address)
126{
127 unsigned long iopt_base;
128 unsigned long page_size;
129 unsigned long page_number;
130 unsigned long iopt_offset;
131
132 iopt_base = iost_entry.val & IOST_PT_BASE_MASK;
133 page_size = iost_entry.val & IOST_PS_MASK;
134
135 /* decode page size to compute page number */
136 page_number = (io_address & 0x0fffffff) >> (10 + 2 * page_size);
137 /* page number is an offset into the io page table */
138 iopt_offset = (page_number << 3) & 0x7fff8ul;
139 return iopt_base + iopt_offset;
140}
141
142/* compute the tag field of the iopt cache entry */
143static inline unsigned long
144get_ioc_tag(ioste iost_entry, unsigned long io_address)
145{
146 unsigned long iopte = get_ioptep(iost_entry, io_address);
147
148 return IOPT_VALID_MASK
149 | ((iopte & 0x00000000000000ff8ul) >> 3)
150 | ((iopte & 0x0000003fffffc0000ul) >> 9);
151}
152
153/* compute the hashed 6 bit index for the 4-way associative pte cache */
154static inline unsigned long
155get_ioc_hash(ioste iost_entry, unsigned long io_address)
156{
157 unsigned long iopte = get_ioptep(iost_entry, io_address);
158
159 return ((iopte & 0x000000000000001f8ul) >> 3)
160 ^ ((iopte & 0x00000000000020000ul) >> 17)
161 ^ ((iopte & 0x00000000000010000ul) >> 15)
162 ^ ((iopte & 0x00000000000008000ul) >> 13)
163 ^ ((iopte & 0x00000000000004000ul) >> 11)
164 ^ ((iopte & 0x00000000000002000ul) >> 9)
165 ^ ((iopte & 0x00000000000001000ul) >> 7);
166}
167
168/* same as above, but pretend that we have a simpler 1-way associative
169 pte cache with an 8 bit index */
170static inline unsigned long
171get_ioc_hash_1way(ioste iost_entry, unsigned long io_address)
172{
173 unsigned long iopte = get_ioptep(iost_entry, io_address);
174
175 return ((iopte & 0x000000000000001f8ul) >> 3)
176 ^ ((iopte & 0x00000000000020000ul) >> 17)
177 ^ ((iopte & 0x00000000000010000ul) >> 15)
178 ^ ((iopte & 0x00000000000008000ul) >> 13)
179 ^ ((iopte & 0x00000000000004000ul) >> 11)
180 ^ ((iopte & 0x00000000000002000ul) >> 9)
181 ^ ((iopte & 0x00000000000001000ul) >> 7)
182 ^ ((iopte & 0x0000000000000c000ul) >> 8);
183}
184
185static inline ioste
186get_iost_cache(void __iomem *base, unsigned long index)
187{
188 unsigned long __iomem *p = (base + IOC_ST_CACHE_DIR);
189 return mk_ioste(in_be64(&p[index]));
190}
191
192static inline void
193set_iost_cache(void __iomem *base, unsigned long index, ioste ste)
194{
195 unsigned long __iomem *p = (base + IOC_ST_CACHE_DIR);
196 pr_debug("ioste %02lx was %016lx, store %016lx", index,
197 get_iost_cache(base, index).val, ste.val);
198 out_be64(&p[index], ste.val);
199 pr_debug(" now %016lx\n", get_iost_cache(base, index).val);
200}
201
202static inline unsigned long
203get_iopt_cache(void __iomem *base, unsigned long index, unsigned long *tag)
204{
205 unsigned long __iomem *tags = (void *)(base + IOC_PT_CACHE_DIR);
206 unsigned long __iomem *p = (void *)(base + IOC_PT_CACHE_REG);
207
208 *tag = tags[index];
209 rmb();
210 return *p;
211}
212
213static inline void
214set_iopt_cache(void __iomem *base, unsigned long index,
215 unsigned long tag, unsigned long val)
216{
217 unsigned long __iomem *tags = base + IOC_PT_CACHE_DIR;
218 unsigned long __iomem *p = base + IOC_PT_CACHE_REG;
219 pr_debug("iopt %02lx was v%016lx/t%016lx, store v%016lx/t%016lx\n",
220 index, get_iopt_cache(base, index, &oldtag), oldtag, val, tag);
221
222 out_be64(p, val);
223 out_be64(&tags[index], tag);
224}
225
226static inline void
227set_iost_origin(void __iomem *base)
228{
229 unsigned long __iomem *p = base + IOC_ST_ORIGIN;
230 unsigned long origin = IOSTO_ENABLE | IOSTO_SW;
231
232 pr_debug("iost_origin %016lx, now %016lx\n", in_be64(p), origin);
233 out_be64(p, origin);
234}
235
236static inline void
237set_iocmd_config(void __iomem *base)
238{
239 unsigned long __iomem *p = base + 0xc00;
240 unsigned long conf;
241
242 conf = in_be64(p);
243 pr_debug("iost_conf %016lx, now %016lx\n", conf, conf | IOCMD_CONF_TE);
244 out_be64(p, conf | IOCMD_CONF_TE);
245}
246
247/* FIXME: get these from the device tree */
248#define ioc_base 0x20000511000ull
249#define ioc_mmio_base 0x20000510000ull
250#define ioid 0x48a
251#define iopt_phys_offset (- 0x20000000) /* We have a 512MB offset from the SB */
252#define io_page_size 0x1000000
253
254static unsigned long map_iopt_entry(unsigned long address)
255{
256 switch (address >> 20) {
257 case 0x600:
258 address = 0x24020000000ull; /* spider i/o */
259 break;
260 default:
261 address += iopt_phys_offset;
262 break;
263 }
264
265 return get_iopt_entry(address, ioid, IOPT_PROT_RW);
266}
267
268static void iommu_bus_setup_null(struct pci_bus *b) { }
269static void iommu_dev_setup_null(struct pci_dev *d) { }
270
271/* initialize the iommu to support a simple linear mapping
272 * for each DMA window used by any device. For now, we
273 * happen to know that there is only one DMA window in use,
274 * starting at iopt_phys_offset. */
275static void bpa_map_iommu(void)
276{
277 unsigned long address;
278 void __iomem *base;
279 ioste ioste;
280 unsigned long index;
281
282 base = __ioremap(ioc_base, 0x1000, _PAGE_NO_CACHE);
283 pr_debug("%lx mapped to %p\n", ioc_base, base);
284 set_iocmd_config(base);
285 iounmap(base);
286
287 base = __ioremap(ioc_mmio_base, 0x1000, _PAGE_NO_CACHE);
288 pr_debug("%lx mapped to %p\n", ioc_mmio_base, base);
289
290 set_iost_origin(base);
291
292 for (address = 0; address < 0x100000000ul; address += io_page_size) {
293 ioste = get_iost_entry(0x10000000000ul, address, io_page_size);
294 if ((address & 0xfffffff) == 0) /* segment start */
295 set_iost_cache(base, address >> 28, ioste);
296 index = get_ioc_hash_1way(ioste, address);
297 pr_debug("addr %08lx, index %02lx, ioste %016lx\n",
298 address, index, ioste.val);
299 set_iopt_cache(base,
300 get_ioc_hash_1way(ioste, address),
301 get_ioc_tag(ioste, address),
302 map_iopt_entry(address));
303 }
304 iounmap(base);
305}
306
307
308static void *bpa_alloc_coherent(struct device *hwdev, size_t size,
309 dma_addr_t *dma_handle, unsigned int __nocast flag)
310{
311 void *ret;
312
313 ret = (void *)__get_free_pages(flag, get_order(size));
314 if (ret != NULL) {
315 memset(ret, 0, size);
316 *dma_handle = virt_to_abs(ret) | BPA_DMA_VALID;
317 }
318 return ret;
319}
320
321static void bpa_free_coherent(struct device *hwdev, size_t size,
322 void *vaddr, dma_addr_t dma_handle)
323{
324 free_pages((unsigned long)vaddr, get_order(size));
325}
326
327static dma_addr_t bpa_map_single(struct device *hwdev, void *ptr,
328 size_t size, enum dma_data_direction direction)
329{
330 return virt_to_abs(ptr) | BPA_DMA_VALID;
331}
332
333static void bpa_unmap_single(struct device *hwdev, dma_addr_t dma_addr,
334 size_t size, enum dma_data_direction direction)
335{
336}
337
338static int bpa_map_sg(struct device *hwdev, struct scatterlist *sg,
339 int nents, enum dma_data_direction direction)
340{
341 int i;
342
343 for (i = 0; i < nents; i++, sg++) {
344 sg->dma_address = (page_to_phys(sg->page) + sg->offset)
345 | BPA_DMA_VALID;
346 sg->dma_length = sg->length;
347 }
348
349 return nents;
350}
351
352static void bpa_unmap_sg(struct device *hwdev, struct scatterlist *sg,
353 int nents, enum dma_data_direction direction)
354{
355}
356
357static int bpa_dma_supported(struct device *dev, u64 mask)
358{
359 return mask < 0x100000000ull;
360}
361
362void bpa_init_iommu(void)
363{
364 bpa_map_iommu();
365
366 /* Direct I/O, IOMMU off */
367 ppc_md.iommu_dev_setup = iommu_dev_setup_null;
368 ppc_md.iommu_bus_setup = iommu_bus_setup_null;
369
370 pci_dma_ops.alloc_coherent = bpa_alloc_coherent;
371 pci_dma_ops.free_coherent = bpa_free_coherent;
372 pci_dma_ops.map_single = bpa_map_single;
373 pci_dma_ops.unmap_single = bpa_unmap_single;
374 pci_dma_ops.map_sg = bpa_map_sg;
375 pci_dma_ops.unmap_sg = bpa_unmap_sg;
376 pci_dma_ops.dma_supported = bpa_dma_supported;
377}
diff --git a/arch/ppc64/kernel/bpa_iommu.h b/arch/ppc64/kernel/bpa_iommu.h
new file mode 100644
index 000000000000..e547d77dfa04
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_iommu.h
@@ -0,0 +1,65 @@
1#ifndef BPA_IOMMU_H
2#define BPA_IOMMU_H
3
4/* some constants */
5enum {
6 /* segment table entries */
7 IOST_VALID_MASK = 0x8000000000000000ul,
8 IOST_TAG_MASK = 0x3000000000000000ul,
9 IOST_PT_BASE_MASK = 0x000003fffffff000ul,
10 IOST_NNPT_MASK = 0x0000000000000fe0ul,
11 IOST_PS_MASK = 0x000000000000000ful,
12
13 IOST_PS_4K = 0x1,
14 IOST_PS_64K = 0x3,
15 IOST_PS_1M = 0x5,
16 IOST_PS_16M = 0x7,
17
18 /* iopt tag register */
19 IOPT_VALID_MASK = 0x0000000200000000ul,
20 IOPT_TAG_MASK = 0x00000001fffffffful,
21
22 /* iopt cache register */
23 IOPT_PROT_MASK = 0xc000000000000000ul,
24 IOPT_PROT_NONE = 0x0000000000000000ul,
25 IOPT_PROT_READ = 0x4000000000000000ul,
26 IOPT_PROT_WRITE = 0x8000000000000000ul,
27 IOPT_PROT_RW = 0xc000000000000000ul,
28 IOPT_COHERENT = 0x2000000000000000ul,
29
30 IOPT_ORDER_MASK = 0x1800000000000000ul,
31 /* order access to same IOID/VC on same address */
32 IOPT_ORDER_ADDR = 0x0800000000000000ul,
33 /* similar, but only after a write access */
34 IOPT_ORDER_WRITES = 0x1000000000000000ul,
35 /* Order all accesses to same IOID/VC */
36 IOPT_ORDER_VC = 0x1800000000000000ul,
37
38 IOPT_RPN_MASK = 0x000003fffffff000ul,
39 IOPT_HINT_MASK = 0x0000000000000800ul,
40 IOPT_IOID_MASK = 0x00000000000007fful,
41
42 IOSTO_ENABLE = 0x8000000000000000ul,
43 IOSTO_ORIGIN = 0x000003fffffff000ul,
44 IOSTO_HW = 0x0000000000000800ul,
45 IOSTO_SW = 0x0000000000000400ul,
46
47 IOCMD_CONF_TE = 0x0000800000000000ul,
48
49 /* memory mapped registers */
50 IOC_PT_CACHE_DIR = 0x000,
51 IOC_ST_CACHE_DIR = 0x800,
52 IOC_PT_CACHE_REG = 0x910,
53 IOC_ST_ORIGIN = 0x918,
54 IOC_CONF = 0x930,
55
56 /* The high bit needs to be set on every DMA address,
57 only 2GB are addressable */
58 BPA_DMA_VALID = 0x80000000,
59 BPA_DMA_MASK = 0x7fffffff,
60};
61
62
63void bpa_init_iommu(void);
64
65#endif
diff --git a/arch/ppc64/kernel/bpa_nvram.c b/arch/ppc64/kernel/bpa_nvram.c
new file mode 100644
index 000000000000..06a119cfceb5
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_nvram.c
@@ -0,0 +1,118 @@
1/*
2 * NVRAM for CPBW
3 *
4 * (C) Copyright IBM Corp. 2005
5 *
6 * Authors : Utz Bacher <utz.bacher@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/fs.h>
24#include <linux/init.h>
25#include <linux/kernel.h>
26#include <linux/spinlock.h>
27#include <linux/types.h>
28
29#include <asm/machdep.h>
30#include <asm/nvram.h>
31#include <asm/prom.h>
32
33static void __iomem *bpa_nvram_start;
34static long bpa_nvram_len;
35static spinlock_t bpa_nvram_lock = SPIN_LOCK_UNLOCKED;
36
37static ssize_t bpa_nvram_read(char *buf, size_t count, loff_t *index)
38{
39 unsigned long flags;
40
41 if (*index >= bpa_nvram_len)
42 return 0;
43 if (*index + count > bpa_nvram_len)
44 count = bpa_nvram_len - *index;
45
46 spin_lock_irqsave(&bpa_nvram_lock, flags);
47
48 memcpy_fromio(buf, bpa_nvram_start + *index, count);
49
50 spin_unlock_irqrestore(&bpa_nvram_lock, flags);
51
52 *index += count;
53 return count;
54}
55
56static ssize_t bpa_nvram_write(char *buf, size_t count, loff_t *index)
57{
58 unsigned long flags;
59
60 if (*index >= bpa_nvram_len)
61 return 0;
62 if (*index + count > bpa_nvram_len)
63 count = bpa_nvram_len - *index;
64
65 spin_lock_irqsave(&bpa_nvram_lock, flags);
66
67 memcpy_toio(bpa_nvram_start + *index, buf, count);
68
69 spin_unlock_irqrestore(&bpa_nvram_lock, flags);
70
71 *index += count;
72 return count;
73}
74
75static ssize_t bpa_nvram_get_size(void)
76{
77 return bpa_nvram_len;
78}
79
80int __init bpa_nvram_init(void)
81{
82 struct device_node *nvram_node;
83 unsigned long *buffer;
84 int proplen;
85 unsigned long nvram_addr;
86 int ret;
87
88 ret = -ENODEV;
89 nvram_node = of_find_node_by_type(NULL, "nvram");
90 if (!nvram_node)
91 goto out;
92
93 ret = -EIO;
94 buffer = (unsigned long *)get_property(nvram_node, "reg", &proplen);
95 if (proplen != 2*sizeof(unsigned long))
96 goto out;
97
98 ret = -ENODEV;
99 nvram_addr = buffer[0];
100 bpa_nvram_len = buffer[1];
101 if ( (!bpa_nvram_len) || (!nvram_addr) )
102 goto out;
103
104 bpa_nvram_start = ioremap(nvram_addr, bpa_nvram_len);
105 if (!bpa_nvram_start)
106 goto out;
107
108 printk(KERN_INFO "BPA NVRAM, %luk mapped to %p\n",
109 bpa_nvram_len >> 10, bpa_nvram_start);
110
111 ppc_md.nvram_read = bpa_nvram_read;
112 ppc_md.nvram_write = bpa_nvram_write;
113 ppc_md.nvram_size = bpa_nvram_get_size;
114
115out:
116 of_node_put(nvram_node);
117 return ret;
118}
diff --git a/arch/ppc64/kernel/bpa_setup.c b/arch/ppc64/kernel/bpa_setup.c
new file mode 100644
index 000000000000..57b3db66f458
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_setup.c
@@ -0,0 +1,140 @@
1/*
2 * linux/arch/ppc/kernel/bpa_setup.c
3 *
4 * Copyright (C) 1995 Linus Torvalds
5 * Adapted from 'alpha' version by Gary Thomas
6 * Modified by Cort Dougan (cort@cs.nmt.edu)
7 * Modified by PPC64 Team, IBM Corp
8 * Modified by BPA Team, IBM Deutschland Entwicklung GmbH
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15#undef DEBUG
16
17#include <linux/config.h>
18#include <linux/sched.h>
19#include <linux/kernel.h>
20#include <linux/mm.h>
21#include <linux/stddef.h>
22#include <linux/unistd.h>
23#include <linux/slab.h>
24#include <linux/user.h>
25#include <linux/reboot.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/irq.h>
29#include <linux/seq_file.h>
30#include <linux/root_dev.h>
31#include <linux/console.h>
32
33#include <asm/mmu.h>
34#include <asm/processor.h>
35#include <asm/io.h>
36#include <asm/pgtable.h>
37#include <asm/prom.h>
38#include <asm/rtas.h>
39#include <asm/pci-bridge.h>
40#include <asm/iommu.h>
41#include <asm/dma.h>
42#include <asm/machdep.h>
43#include <asm/time.h>
44#include <asm/nvram.h>
45#include <asm/cputable.h>
46
47#include "pci.h"
48#include "bpa_iic.h"
49#include "bpa_iommu.h"
50
51#ifdef DEBUG
52#define DBG(fmt...) udbg_printf(fmt)
53#else
54#define DBG(fmt...)
55#endif
56
57void bpa_get_cpuinfo(struct seq_file *m)
58{
59 struct device_node *root;
60 const char *model = "";
61
62 root = of_find_node_by_path("/");
63 if (root)
64 model = get_property(root, "model", NULL);
65 seq_printf(m, "machine\t\t: BPA %s\n", model);
66 of_node_put(root);
67}
68
69static void bpa_progress(char *s, unsigned short hex)
70{
71 printk("*** %04x : %s\n", hex, s ? s : "");
72}
73
74static void __init bpa_setup_arch(void)
75{
76 ppc_md.init_IRQ = iic_init_IRQ;
77 ppc_md.get_irq = iic_get_irq;
78
79#ifdef CONFIG_SMP
80 smp_init_pSeries();
81#endif
82
83 /* init to some ~sane value until calibrate_delay() runs */
84 loops_per_jiffy = 50000000;
85
86 if (ROOT_DEV == 0) {
87 printk("No ramdisk, default root is /dev/hda2\n");
88 ROOT_DEV = Root_HDA2;
89 }
90
91 /* Find and initialize PCI host bridges */
92 init_pci_config_tokens();
93 find_and_init_phbs();
94 spider_init_IRQ();
95#ifdef CONFIG_DUMMY_CONSOLE
96 conswitchp = &dummy_con;
97#endif
98
99 bpa_nvram_init();
100}
101
102/*
103 * Early initialization. Relocation is on but do not reference unbolted pages
104 */
105static void __init bpa_init_early(void)
106{
107 DBG(" -> bpa_init_early()\n");
108
109 hpte_init_native();
110
111 bpa_init_iommu();
112
113 ppc64_interrupt_controller = IC_BPA_IIC;
114
115 DBG(" <- bpa_init_early()\n");
116}
117
118
119static int __init bpa_probe(int platform)
120{
121 if (platform != PLATFORM_BPA)
122 return 0;
123
124 return 1;
125}
126
127struct machdep_calls __initdata bpa_md = {
128 .probe = bpa_probe,
129 .setup_arch = bpa_setup_arch,
130 .init_early = bpa_init_early,
131 .get_cpuinfo = bpa_get_cpuinfo,
132 .restart = rtas_restart,
133 .power_off = rtas_power_off,
134 .halt = rtas_halt,
135 .get_boot_time = rtas_get_boot_time,
136 .get_rtc_time = rtas_get_rtc_time,
137 .set_rtc_time = rtas_set_rtc_time,
138 .calibrate_decr = generic_calibrate_decr,
139 .progress = bpa_progress,
140};
diff --git a/arch/ppc64/kernel/cpu_setup_power4.S b/arch/ppc64/kernel/cpu_setup_power4.S
index 3bd951820850..42fc08cf87a0 100644
--- a/arch/ppc64/kernel/cpu_setup_power4.S
+++ b/arch/ppc64/kernel/cpu_setup_power4.S
@@ -73,7 +73,21 @@ _GLOBAL(__970_cpu_preinit)
73 73
74_GLOBAL(__setup_cpu_power4) 74_GLOBAL(__setup_cpu_power4)
75 blr 75 blr
76 76
77_GLOBAL(__setup_cpu_be)
78 /* Set large page sizes LP=0: 16MB, LP=1: 64KB */
79 addi r3, 0, 0
80 ori r3, r3, HID6_LB
81 sldi r3, r3, 32
82 nor r3, r3, r3
83 mfspr r4, SPRN_HID6
84 and r4, r4, r3
85 addi r3, 0, 0x02000
86 sldi r3, r3, 32
87 or r4, r4, r3
88 mtspr SPRN_HID6, r4
89 blr
90
77_GLOBAL(__setup_cpu_ppc970) 91_GLOBAL(__setup_cpu_ppc970)
78 mfspr r0,SPRN_HID0 92 mfspr r0,SPRN_HID0
79 li r11,5 /* clear DOZE and SLEEP */ 93 li r11,5 /* clear DOZE and SLEEP */
diff --git a/arch/ppc64/kernel/cputable.c b/arch/ppc64/kernel/cputable.c
index 8644a8648058..1d162c7c59df 100644
--- a/arch/ppc64/kernel/cputable.c
+++ b/arch/ppc64/kernel/cputable.c
@@ -34,6 +34,7 @@ EXPORT_SYMBOL(cur_cpu_spec);
34extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec); 34extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec);
35extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec); 35extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec);
36extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); 36extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
37extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec);
37 38
38 39
39/* We only set the altivec features if the kernel was compiled with altivec 40/* We only set the altivec features if the kernel was compiled with altivec
@@ -162,6 +163,16 @@ struct cpu_spec cpu_specs[] = {
162 __setup_cpu_power4, 163 __setup_cpu_power4,
163 COMMON_PPC64_FW 164 COMMON_PPC64_FW
164 }, 165 },
166 { /* BE DD1.x */
167 0xffff0000, 0x00700000, "Broadband Engine",
168 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
169 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
170 CPU_FTR_SMT,
171 COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP,
172 128, 128,
173 __setup_cpu_be,
174 COMMON_PPC64_FW
175 },
165 { /* default match */ 176 { /* default match */
166 0x00000000, 0x00000000, "POWER4 (compatible)", 177 0x00000000, 0x00000000, "POWER4 (compatible)",
167 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 178 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
index b31962436fe3..86966ce76b58 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -671,9 +671,6 @@ static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr)
671 } 671 }
672} 672}
673 673
674extern unsigned long ppc_proc_freq;
675extern unsigned long ppc_tb_freq;
676
677/* 674/*
678 * Document me. 675 * Document me.
679 */ 676 */
@@ -772,8 +769,6 @@ static void iSeries_halt(void)
772 mf_power_off(); 769 mf_power_off();
773} 770}
774 771
775extern void setup_default_decr(void);
776
777/* 772/*
778 * void __init iSeries_calibrate_decr() 773 * void __init iSeries_calibrate_decr()
779 * 774 *
diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c
index d860467b8f09..3defc8c33adf 100644
--- a/arch/ppc64/kernel/irq.c
+++ b/arch/ppc64/kernel/irq.c
@@ -395,6 +395,9 @@ int virt_irq_create_mapping(unsigned int real_irq)
395 if (ppc64_interrupt_controller == IC_OPEN_PIC) 395 if (ppc64_interrupt_controller == IC_OPEN_PIC)
396 return real_irq; /* no mapping for openpic (for now) */ 396 return real_irq; /* no mapping for openpic (for now) */
397 397
398 if (ppc64_interrupt_controller == IC_BPA_IIC)
399 return real_irq; /* no mapping for iic either */
400
398 /* don't map interrupts < MIN_VIRT_IRQ */ 401 /* don't map interrupts < MIN_VIRT_IRQ */
399 if (real_irq < MIN_VIRT_IRQ) { 402 if (real_irq < MIN_VIRT_IRQ) {
400 virt_irq_to_real_map[real_irq] = real_irq; 403 virt_irq_to_real_map[real_irq] = real_irq;
diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/ppc64/kernel/maple_setup.c
index 8cf95a27178e..da8900b51f40 100644
--- a/arch/ppc64/kernel/maple_setup.c
+++ b/arch/ppc64/kernel/maple_setup.c
@@ -78,17 +78,77 @@ extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel);
78extern void generic_find_legacy_serial_ports(u64 *physport, 78extern void generic_find_legacy_serial_ports(u64 *physport,
79 unsigned int *default_speed); 79 unsigned int *default_speed);
80 80
81
82static void maple_restart(char *cmd) 81static void maple_restart(char *cmd)
83{ 82{
83 unsigned int maple_nvram_base;
84 unsigned int maple_nvram_offset;
85 unsigned int maple_nvram_command;
86 struct device_node *rtcs;
87
88 /* find NVRAM device */
89 rtcs = find_compatible_devices("nvram", "AMD8111");
90 if (rtcs && rtcs->addrs) {
91 maple_nvram_base = rtcs->addrs[0].address;
92 } else {
93 printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
94 printk(KERN_EMERG "Maple: Manual Restart Required\n");
95 return;
96 }
97
98 /* find service processor device */
99 rtcs = find_devices("service-processor");
100 if (!rtcs) {
101 printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
102 printk(KERN_EMERG "Maple: Manual Restart Required\n");
103 return;
104 }
105 maple_nvram_offset = *(unsigned int*) get_property(rtcs,
106 "restart-addr", NULL);
107 maple_nvram_command = *(unsigned int*) get_property(rtcs,
108 "restart-value", NULL);
109
110 /* send command */
111 outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
112 for (;;) ;
84} 113}
85 114
86static void maple_power_off(void) 115static void maple_power_off(void)
87{ 116{
117 unsigned int maple_nvram_base;
118 unsigned int maple_nvram_offset;
119 unsigned int maple_nvram_command;
120 struct device_node *rtcs;
121
122 /* find NVRAM device */
123 rtcs = find_compatible_devices("nvram", "AMD8111");
124 if (rtcs && rtcs->addrs) {
125 maple_nvram_base = rtcs->addrs[0].address;
126 } else {
127 printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
128 printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
129 return;
130 }
131
132 /* find service processor device */
133 rtcs = find_devices("service-processor");
134 if (!rtcs) {
135 printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
136 printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
137 return;
138 }
139 maple_nvram_offset = *(unsigned int*) get_property(rtcs,
140 "power-off-addr", NULL);
141 maple_nvram_command = *(unsigned int*) get_property(rtcs,
142 "power-off-value", NULL);
143
144 /* send command */
145 outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
146 for (;;) ;
88} 147}
89 148
90static void maple_halt(void) 149static void maple_halt(void)
91{ 150{
151 maple_power_off();
92} 152}
93 153
94#ifdef CONFIG_SMP 154#ifdef CONFIG_SMP
@@ -235,6 +295,6 @@ struct machdep_calls __initdata maple_md = {
235 .get_boot_time = maple_get_boot_time, 295 .get_boot_time = maple_get_boot_time,
236 .set_rtc_time = maple_set_rtc_time, 296 .set_rtc_time = maple_set_rtc_time,
237 .get_rtc_time = maple_get_rtc_time, 297 .get_rtc_time = maple_get_rtc_time,
238 .calibrate_decr = maple_calibrate_decr, 298 .calibrate_decr = generic_calibrate_decr,
239 .progress = maple_progress, 299 .progress = maple_progress,
240}; 300};
diff --git a/arch/ppc64/kernel/maple_time.c b/arch/ppc64/kernel/maple_time.c
index 07ce7895b43d..d65210abcd03 100644
--- a/arch/ppc64/kernel/maple_time.c
+++ b/arch/ppc64/kernel/maple_time.c
@@ -42,11 +42,8 @@
42#define DBG(x...) 42#define DBG(x...)
43#endif 43#endif
44 44
45extern void setup_default_decr(void);
46extern void GregorianDay(struct rtc_time * tm); 45extern void GregorianDay(struct rtc_time * tm);
47 46
48extern unsigned long ppc_tb_freq;
49extern unsigned long ppc_proc_freq;
50static int maple_rtc_addr; 47static int maple_rtc_addr;
51 48
52static int maple_clock_read(int addr) 49static int maple_clock_read(int addr)
@@ -176,51 +173,3 @@ void __init maple_get_boot_time(struct rtc_time *tm)
176 maple_get_rtc_time(tm); 173 maple_get_rtc_time(tm);
177} 174}
178 175
179/* XXX FIXME: Some sane defaults: 125 MHz timebase, 1GHz processor */
180#define DEFAULT_TB_FREQ 125000000UL
181#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8)
182
183void __init maple_calibrate_decr(void)
184{
185 struct device_node *cpu;
186 struct div_result divres;
187 unsigned int *fp = NULL;
188
189 /*
190 * The cpu node should have a timebase-frequency property
191 * to tell us the rate at which the decrementer counts.
192 */
193 cpu = of_find_node_by_type(NULL, "cpu");
194
195 ppc_tb_freq = DEFAULT_TB_FREQ;
196 if (cpu != 0)
197 fp = (unsigned int *)get_property(cpu, "timebase-frequency", NULL);
198 if (fp != NULL)
199 ppc_tb_freq = *fp;
200 else
201 printk(KERN_ERR "WARNING: Estimating decrementer frequency (not found)\n");
202 fp = NULL;
203 ppc_proc_freq = DEFAULT_PROC_FREQ;
204 if (cpu != 0)
205 fp = (unsigned int *)get_property(cpu, "clock-frequency", NULL);
206 if (fp != NULL)
207 ppc_proc_freq = *fp;
208 else
209 printk(KERN_ERR "WARNING: Estimating processor frequency (not found)\n");
210
211 of_node_put(cpu);
212
213 printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
214 ppc_tb_freq/1000000, ppc_tb_freq%1000000);
215 printk(KERN_INFO "time_init: processor frequency = %lu.%.6lu MHz\n",
216 ppc_proc_freq/1000000, ppc_proc_freq%1000000);
217
218 tb_ticks_per_jiffy = ppc_tb_freq / HZ;
219 tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
220 tb_ticks_per_usec = ppc_tb_freq / 1000000;
221 tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
222 div128_by_32(1024*1024, 0, tb_ticks_per_sec, &divres);
223 tb_to_xs = divres.result_low;
224
225 setup_default_decr();
226}
diff --git a/arch/ppc64/kernel/mpic.h b/arch/ppc64/kernel/mpic.h
index 571b3c99e062..63e177143eac 100644
--- a/arch/ppc64/kernel/mpic.h
+++ b/arch/ppc64/kernel/mpic.h
@@ -265,3 +265,6 @@ extern void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask);
265extern int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs); 265extern int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs);
266/* This one gets to the primary mpic */ 266/* This one gets to the primary mpic */
267extern int mpic_get_irq(struct pt_regs *regs); 267extern int mpic_get_irq(struct pt_regs *regs);
268
269/* global mpic for pSeries */
270extern struct mpic *pSeries_mpic;
diff --git a/arch/ppc64/kernel/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c
index 0b1cca281408..1f5f141fb7a1 100644
--- a/arch/ppc64/kernel/pSeries_pci.c
+++ b/arch/ppc64/kernel/pSeries_pci.c
@@ -1,13 +1,11 @@
1/* 1/*
2 * pSeries_pci.c 2 * arch/ppc64/kernel/pSeries_pci.c
3 * 3 *
4 * Copyright (C) 2001 Dave Engebretsen, IBM Corporation 4 * Copyright (C) 2001 Dave Engebretsen, IBM Corporation
5 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM 5 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
6 * 6 *
7 * pSeries specific routines for PCI. 7 * pSeries specific routines for PCI.
8 * 8 *
9 * Based on code from pci.c and chrp_pci.c
10 *
11 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 11 * the Free Software Foundation; either version 2 of the License, or
@@ -23,430 +21,18 @@
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */ 22 */
25 23
24#include <linux/init.h>
25#include <linux/ioport.h>
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/threads.h>
28#include <linux/pci.h> 27#include <linux/pci.h>
29#include <linux/string.h> 28#include <linux/string.h>
30#include <linux/init.h>
31#include <linux/bootmem.h>
32 29
33#include <asm/io.h>
34#include <asm/pgtable.h>
35#include <asm/irq.h>
36#include <asm/prom.h>
37#include <asm/machdep.h>
38#include <asm/pci-bridge.h> 30#include <asm/pci-bridge.h>
39#include <asm/iommu.h> 31#include <asm/prom.h>
40#include <asm/rtas.h>
41 32
42#include "mpic.h"
43#include "pci.h" 33#include "pci.h"
44 34
45/* RTAS tokens */ 35static int __initdata s7a_workaround = -1;
46static int read_pci_config;
47static int write_pci_config;
48static int ibm_read_pci_config;
49static int ibm_write_pci_config;
50
51static int s7a_workaround;
52
53extern struct mpic *pSeries_mpic;
54
55static int config_access_valid(struct device_node *dn, int where)
56{
57 if (where < 256)
58 return 1;
59 if (where < 4096 && dn->pci_ext_config_space)
60 return 1;
61
62 return 0;
63}
64
65static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val)
66{
67 int returnval = -1;
68 unsigned long buid, addr;
69 int ret;
70
71 if (!dn)
72 return PCIBIOS_DEVICE_NOT_FOUND;
73 if (!config_access_valid(dn, where))
74 return PCIBIOS_BAD_REGISTER_NUMBER;
75
76 addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
77 (dn->devfn << 8) | (where & 0xff);
78 buid = dn->phb->buid;
79 if (buid) {
80 ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
81 addr, buid >> 32, buid & 0xffffffff, size);
82 } else {
83 ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
84 }
85 *val = returnval;
86
87 if (ret)
88 return PCIBIOS_DEVICE_NOT_FOUND;
89
90 if (returnval == EEH_IO_ERROR_VALUE(size)
91 && eeh_dn_check_failure (dn, NULL))
92 return PCIBIOS_DEVICE_NOT_FOUND;
93
94 return PCIBIOS_SUCCESSFUL;
95}
96
97static int rtas_pci_read_config(struct pci_bus *bus,
98 unsigned int devfn,
99 int where, int size, u32 *val)
100{
101 struct device_node *busdn, *dn;
102
103 if (bus->self)
104 busdn = pci_device_to_OF_node(bus->self);
105 else
106 busdn = bus->sysdata; /* must be a phb */
107
108 /* Search only direct children of the bus */
109 for (dn = busdn->child; dn; dn = dn->sibling)
110 if (dn->devfn == devfn)
111 return rtas_read_config(dn, where, size, val);
112 return PCIBIOS_DEVICE_NOT_FOUND;
113}
114
115static int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
116{
117 unsigned long buid, addr;
118 int ret;
119
120 if (!dn)
121 return PCIBIOS_DEVICE_NOT_FOUND;
122 if (!config_access_valid(dn, where))
123 return PCIBIOS_BAD_REGISTER_NUMBER;
124
125 addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
126 (dn->devfn << 8) | (where & 0xff);
127 buid = dn->phb->buid;
128 if (buid) {
129 ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val);
130 } else {
131 ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val);
132 }
133
134 if (ret)
135 return PCIBIOS_DEVICE_NOT_FOUND;
136
137 return PCIBIOS_SUCCESSFUL;
138}
139
140static int rtas_pci_write_config(struct pci_bus *bus,
141 unsigned int devfn,
142 int where, int size, u32 val)
143{
144 struct device_node *busdn, *dn;
145
146 if (bus->self)
147 busdn = pci_device_to_OF_node(bus->self);
148 else
149 busdn = bus->sysdata; /* must be a phb */
150
151 /* Search only direct children of the bus */
152 for (dn = busdn->child; dn; dn = dn->sibling)
153 if (dn->devfn == devfn)
154 return rtas_write_config(dn, where, size, val);
155 return PCIBIOS_DEVICE_NOT_FOUND;
156}
157
158struct pci_ops rtas_pci_ops = {
159 rtas_pci_read_config,
160 rtas_pci_write_config
161};
162
163int is_python(struct device_node *dev)
164{
165 char *model = (char *)get_property(dev, "model", NULL);
166
167 if (model && strstr(model, "Python"))
168 return 1;
169
170 return 0;
171}
172
173static int get_phb_reg_prop(struct device_node *dev,
174 unsigned int addr_size_words,
175 struct reg_property64 *reg)
176{
177 unsigned int *ui_ptr = NULL, len;
178
179 /* Found a PHB, now figure out where his registers are mapped. */
180 ui_ptr = (unsigned int *)get_property(dev, "reg", &len);
181 if (ui_ptr == NULL)
182 return 1;
183
184 if (addr_size_words == 1) {
185 reg->address = ((struct reg_property32 *)ui_ptr)->address;
186 reg->size = ((struct reg_property32 *)ui_ptr)->size;
187 } else {
188 *reg = *((struct reg_property64 *)ui_ptr);
189 }
190
191 return 0;
192}
193
194static void python_countermeasures(struct device_node *dev,
195 unsigned int addr_size_words)
196{
197 struct reg_property64 reg_struct;
198 void __iomem *chip_regs;
199 volatile u32 val;
200
201 if (get_phb_reg_prop(dev, addr_size_words, &reg_struct))
202 return;
203
204 /* Python's register file is 1 MB in size. */
205 chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000);
206
207 /*
208 * Firmware doesn't always clear this bit which is critical
209 * for good performance - Anton
210 */
211
212#define PRG_CL_RESET_VALID 0x00010000
213
214 val = in_be32(chip_regs + 0xf6030);
215 if (val & PRG_CL_RESET_VALID) {
216 printk(KERN_INFO "Python workaround: ");
217 val &= ~PRG_CL_RESET_VALID;
218 out_be32(chip_regs + 0xf6030, val);
219 /*
220 * We must read it back for changes to
221 * take effect
222 */
223 val = in_be32(chip_regs + 0xf6030);
224 printk("reg0: %x\n", val);
225 }
226
227 iounmap(chip_regs);
228}
229
230void __init init_pci_config_tokens (void)
231{
232 read_pci_config = rtas_token("read-pci-config");
233 write_pci_config = rtas_token("write-pci-config");
234 ibm_read_pci_config = rtas_token("ibm,read-pci-config");
235 ibm_write_pci_config = rtas_token("ibm,write-pci-config");
236}
237
238unsigned long __devinit get_phb_buid (struct device_node *phb)
239{
240 int addr_cells;
241 unsigned int *buid_vals;
242 unsigned int len;
243 unsigned long buid;
244
245 if (ibm_read_pci_config == -1) return 0;
246
247 /* PHB's will always be children of the root node,
248 * or so it is promised by the current firmware. */
249 if (phb->parent == NULL)
250 return 0;
251 if (phb->parent->parent)
252 return 0;
253
254 buid_vals = (unsigned int *) get_property(phb, "reg", &len);
255 if (buid_vals == NULL)
256 return 0;
257
258 addr_cells = prom_n_addr_cells(phb);
259 if (addr_cells == 1) {
260 buid = (unsigned long) buid_vals[0];
261 } else {
262 buid = (((unsigned long)buid_vals[0]) << 32UL) |
263 (((unsigned long)buid_vals[1]) & 0xffffffff);
264 }
265 return buid;
266}
267
268static int phb_set_bus_ranges(struct device_node *dev,
269 struct pci_controller *phb)
270{
271 int *bus_range;
272 unsigned int len;
273
274 bus_range = (int *) get_property(dev, "bus-range", &len);
275 if (bus_range == NULL || len < 2 * sizeof(int)) {
276 return 1;
277 }
278
279 phb->first_busno = bus_range[0];
280 phb->last_busno = bus_range[1];
281
282 return 0;
283}
284
285static int __devinit setup_phb(struct device_node *dev,
286 struct pci_controller *phb,
287 unsigned int addr_size_words)
288{
289 pci_setup_pci_controller(phb);
290
291 if (is_python(dev))
292 python_countermeasures(dev, addr_size_words);
293
294 if (phb_set_bus_ranges(dev, phb))
295 return 1;
296
297 phb->arch_data = dev;
298 phb->ops = &rtas_pci_ops;
299 phb->buid = get_phb_buid(dev);
300
301 return 0;
302}
303
304static void __devinit add_linux_pci_domain(struct device_node *dev,
305 struct pci_controller *phb,
306 struct property *of_prop)
307{
308 memset(of_prop, 0, sizeof(struct property));
309 of_prop->name = "linux,pci-domain";
310 of_prop->length = sizeof(phb->global_number);
311 of_prop->value = (unsigned char *)&of_prop[1];
312 memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number));
313 prom_add_property(dev, of_prop);
314}
315
316static struct pci_controller * __init alloc_phb(struct device_node *dev,
317 unsigned int addr_size_words)
318{
319 struct pci_controller *phb;
320 struct property *of_prop;
321
322 phb = alloc_bootmem(sizeof(struct pci_controller));
323 if (phb == NULL)
324 return NULL;
325
326 of_prop = alloc_bootmem(sizeof(struct property) +
327 sizeof(phb->global_number));
328 if (!of_prop)
329 return NULL;
330
331 if (setup_phb(dev, phb, addr_size_words))
332 return NULL;
333
334 add_linux_pci_domain(dev, phb, of_prop);
335
336 return phb;
337}
338
339static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words)
340{
341 struct pci_controller *phb;
342
343 phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
344 GFP_KERNEL);
345 if (phb == NULL)
346 return NULL;
347
348 if (setup_phb(dev, phb, addr_size_words))
349 return NULL;
350
351 phb->is_dynamic = 1;
352
353 /* TODO: linux,pci-domain? */
354
355 return phb;
356}
357
358unsigned long __init find_and_init_phbs(void)
359{
360 struct device_node *node;
361 struct pci_controller *phb;
362 unsigned int root_size_cells = 0;
363 unsigned int index;
364 unsigned int *opprop = NULL;
365 struct device_node *root = of_find_node_by_path("/");
366
367 if (ppc64_interrupt_controller == IC_OPEN_PIC) {
368 opprop = (unsigned int *)get_property(root,
369 "platform-open-pic", NULL);
370 }
371
372 root_size_cells = prom_n_size_cells(root);
373
374 index = 0;
375
376 for (node = of_get_next_child(root, NULL);
377 node != NULL;
378 node = of_get_next_child(root, node)) {
379 if (node->type == NULL || strcmp(node->type, "pci") != 0)
380 continue;
381
382 phb = alloc_phb(node, root_size_cells);
383 if (!phb)
384 continue;
385
386 pci_process_bridge_OF_ranges(phb, node);
387 pci_setup_phb_io(phb, index == 0);
388
389 if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
390 int addr = root_size_cells * (index + 2) - 1;
391 mpic_assign_isu(pSeries_mpic, index, opprop[addr]);
392 }
393
394 index++;
395 }
396
397 of_node_put(root);
398 pci_devs_phb_init();
399
400 /*
401 * pci_probe_only and pci_assign_all_buses can be set via properties
402 * in chosen.
403 */
404 if (of_chosen) {
405 int *prop;
406
407 prop = (int *)get_property(of_chosen, "linux,pci-probe-only",
408 NULL);
409 if (prop)
410 pci_probe_only = *prop;
411
412 prop = (int *)get_property(of_chosen,
413 "linux,pci-assign-all-buses", NULL);
414 if (prop)
415 pci_assign_all_buses = *prop;
416 }
417
418 return 0;
419}
420
421struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
422{
423 struct device_node *root = of_find_node_by_path("/");
424 unsigned int root_size_cells = 0;
425 struct pci_controller *phb;
426 struct pci_bus *bus;
427 int primary;
428
429 root_size_cells = prom_n_size_cells(root);
430
431 primary = list_empty(&hose_list);
432 phb = alloc_phb_dynamic(dn, root_size_cells);
433 if (!phb)
434 return NULL;
435
436 pci_process_bridge_OF_ranges(phb, dn);
437
438 pci_setup_phb_io_dynamic(phb, primary);
439 of_node_put(root);
440
441 pci_devs_phb_init_dynamic(phb);
442 phb->last_busno = 0xff;
443 bus = pci_scan_bus(phb->first_busno, phb->ops, phb->arch_data);
444 phb->bus = bus;
445 phb->last_busno = bus->subordinate;
446
447 return phb;
448}
449EXPORT_SYMBOL(init_phb_dynamic);
450 36
451#if 0 37#if 0
452void pcibios_name_device(struct pci_dev *dev) 38void pcibios_name_device(struct pci_dev *dev)
@@ -474,11 +60,12 @@ void pcibios_name_device(struct pci_dev *dev)
474DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device); 60DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
475#endif 61#endif
476 62
477static void check_s7a(void) 63static void __init check_s7a(void)
478{ 64{
479 struct device_node *root; 65 struct device_node *root;
480 char *model; 66 char *model;
481 67
68 s7a_workaround = 0;
482 root = of_find_node_by_path("/"); 69 root = of_find_node_by_path("/");
483 if (root) { 70 if (root) {
484 model = get_property(root, "model", NULL); 71 model = get_property(root, "model", NULL);
@@ -488,55 +75,23 @@ static void check_s7a(void)
488 } 75 }
489} 76}
490 77
491/* RPA-specific bits for removing PHBs */ 78void __devinit pSeries_irq_bus_setup(struct pci_bus *bus)
492int pcibios_remove_root_bus(struct pci_controller *phb)
493{ 79{
494 struct pci_bus *b = phb->bus; 80 struct pci_dev *dev;
495 struct resource *res;
496 int rc, i;
497
498 res = b->resource[0];
499 if (!res->flags) {
500 printk(KERN_ERR "%s: no IO resource for PHB %s\n", __FUNCTION__,
501 b->name);
502 return 1;
503 }
504
505 rc = unmap_bus_range(b);
506 if (rc) {
507 printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
508 __FUNCTION__, b->name);
509 return 1;
510 }
511 81
512 if (release_resource(res)) { 82 if (s7a_workaround < 0)
513 printk(KERN_ERR "%s: failed to release IO on bus %s\n", 83 check_s7a();
514 __FUNCTION__, b->name); 84 list_for_each_entry(dev, &bus->devices, bus_list) {
515 return 1; 85 pci_read_irq_line(dev);
516 } 86 if (s7a_workaround) {
517 87 if (dev->irq > 16) {
518 for (i = 1; i < 3; ++i) { 88 dev->irq -= 3;
519 res = b->resource[i]; 89 pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
520 if (!res->flags && i == 0) { 90 dev->irq);
521 printk(KERN_ERR "%s: no MEM resource for PHB %s\n", 91 }
522 __FUNCTION__, b->name);
523 return 1;
524 }
525 if (res->flags && release_resource(res)) {
526 printk(KERN_ERR
527 "%s: failed to release IO %d on bus %s\n",
528 __FUNCTION__, i, b->name);
529 return 1;
530 } 92 }
531 } 93 }
532
533 list_del(&phb->list_node);
534 if (phb->is_dynamic)
535 kfree(phb);
536
537 return 0;
538} 94}
539EXPORT_SYMBOL(pcibios_remove_root_bus);
540 95
541static void __init pSeries_request_regions(void) 96static void __init pSeries_request_regions(void)
542{ 97{
@@ -553,20 +108,6 @@ static void __init pSeries_request_regions(void)
553 108
554void __init pSeries_final_fixup(void) 109void __init pSeries_final_fixup(void)
555{ 110{
556 struct pci_dev *dev = NULL;
557
558 check_s7a();
559
560 for_each_pci_dev(dev) {
561 pci_read_irq_line(dev);
562 if (s7a_workaround) {
563 if (dev->irq > 16) {
564 dev->irq -= 3;
565 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
566 }
567 }
568 }
569
570 phbs_remap_io(); 111 phbs_remap_io();
571 pSeries_request_regions(); 112 pSeries_request_regions();
572 113
diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c
index 6c0d1d58a552..f2b41243342c 100644
--- a/arch/ppc64/kernel/pSeries_setup.c
+++ b/arch/ppc64/kernel/pSeries_setup.c
@@ -71,11 +71,6 @@
71#define DBG(fmt...) 71#define DBG(fmt...)
72#endif 72#endif
73 73
74extern void pSeries_final_fixup(void);
75
76extern void pSeries_get_boot_time(struct rtc_time *rtc_time);
77extern void pSeries_get_rtc_time(struct rtc_time *rtc_time);
78extern int pSeries_set_rtc_time(struct rtc_time *rtc_time);
79extern void find_udbg_vterm(void); 74extern void find_udbg_vterm(void);
80extern void system_reset_fwnmi(void); /* from head.S */ 75extern void system_reset_fwnmi(void); /* from head.S */
81extern void machine_check_fwnmi(void); /* from head.S */ 76extern void machine_check_fwnmi(void); /* from head.S */
@@ -84,9 +79,6 @@ extern void generic_find_legacy_serial_ports(u64 *physport,
84 79
85int fwnmi_active; /* TRUE if an FWNMI handler is present */ 80int fwnmi_active; /* TRUE if an FWNMI handler is present */
86 81
87extern unsigned long ppc_proc_freq;
88extern unsigned long ppc_tb_freq;
89
90extern void pSeries_system_reset_exception(struct pt_regs *regs); 82extern void pSeries_system_reset_exception(struct pt_regs *regs);
91extern int pSeries_machine_check_exception(struct pt_regs *regs); 83extern int pSeries_machine_check_exception(struct pt_regs *regs);
92 84
@@ -381,171 +373,6 @@ static void __init pSeries_init_early(void)
381} 373}
382 374
383 375
384static void pSeries_progress(char *s, unsigned short hex)
385{
386 struct device_node *root;
387 int width, *p;
388 char *os;
389 static int display_character, set_indicator;
390 static int max_width;
391 static DEFINE_SPINLOCK(progress_lock);
392 static int pending_newline = 0; /* did last write end with unprinted newline? */
393
394 if (!rtas.base)
395 return;
396
397 if (max_width == 0) {
398 if ((root = find_path_device("/rtas")) &&
399 (p = (unsigned int *)get_property(root,
400 "ibm,display-line-length",
401 NULL)))
402 max_width = *p;
403 else
404 max_width = 0x10;
405 display_character = rtas_token("display-character");
406 set_indicator = rtas_token("set-indicator");
407 }
408
409 if (display_character == RTAS_UNKNOWN_SERVICE) {
410 /* use hex display if available */
411 if (set_indicator != RTAS_UNKNOWN_SERVICE)
412 rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
413 return;
414 }
415
416 spin_lock(&progress_lock);
417
418 /*
419 * Last write ended with newline, but we didn't print it since
420 * it would just clear the bottom line of output. Print it now
421 * instead.
422 *
423 * If no newline is pending, print a CR to start output at the
424 * beginning of the line.
425 */
426 if (pending_newline) {
427 rtas_call(display_character, 1, 1, NULL, '\r');
428 rtas_call(display_character, 1, 1, NULL, '\n');
429 pending_newline = 0;
430 } else {
431 rtas_call(display_character, 1, 1, NULL, '\r');
432 }
433
434 width = max_width;
435 os = s;
436 while (*os) {
437 if (*os == '\n' || *os == '\r') {
438 /* Blank to end of line. */
439 while (width-- > 0)
440 rtas_call(display_character, 1, 1, NULL, ' ');
441
442 /* If newline is the last character, save it
443 * until next call to avoid bumping up the
444 * display output.
445 */
446 if (*os == '\n' && !os[1]) {
447 pending_newline = 1;
448 spin_unlock(&progress_lock);
449 return;
450 }
451
452 /* RTAS wants CR-LF, not just LF */
453
454 if (*os == '\n') {
455 rtas_call(display_character, 1, 1, NULL, '\r');
456 rtas_call(display_character, 1, 1, NULL, '\n');
457 } else {
458 /* CR might be used to re-draw a line, so we'll
459 * leave it alone and not add LF.
460 */
461 rtas_call(display_character, 1, 1, NULL, *os);
462 }
463
464 width = max_width;
465 } else {
466 width--;
467 rtas_call(display_character, 1, 1, NULL, *os);
468 }
469
470 os++;
471
472 /* if we overwrite the screen length */
473 if (width <= 0)
474 while ((*os != 0) && (*os != '\n') && (*os != '\r'))
475 os++;
476 }
477
478 /* Blank to end of line. */
479 while (width-- > 0)
480 rtas_call(display_character, 1, 1, NULL, ' ');
481
482 spin_unlock(&progress_lock);
483}
484
485extern void setup_default_decr(void);
486
487/* Some sane defaults: 125 MHz timebase, 1GHz processor */
488#define DEFAULT_TB_FREQ 125000000UL
489#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8)
490
491static void __init pSeries_calibrate_decr(void)
492{
493 struct device_node *cpu;
494 struct div_result divres;
495 unsigned int *fp;
496 int node_found;
497
498 /*
499 * The cpu node should have a timebase-frequency property
500 * to tell us the rate at which the decrementer counts.
501 */
502 cpu = of_find_node_by_type(NULL, "cpu");
503
504 ppc_tb_freq = DEFAULT_TB_FREQ; /* hardcoded default */
505 node_found = 0;
506 if (cpu != 0) {
507 fp = (unsigned int *)get_property(cpu, "timebase-frequency",
508 NULL);
509 if (fp != 0) {
510 node_found = 1;
511 ppc_tb_freq = *fp;
512 }
513 }
514 if (!node_found)
515 printk(KERN_ERR "WARNING: Estimating decrementer frequency "
516 "(not found)\n");
517
518 ppc_proc_freq = DEFAULT_PROC_FREQ;
519 node_found = 0;
520 if (cpu != 0) {
521 fp = (unsigned int *)get_property(cpu, "clock-frequency",
522 NULL);
523 if (fp != 0) {
524 node_found = 1;
525 ppc_proc_freq = *fp;
526 }
527 }
528 if (!node_found)
529 printk(KERN_ERR "WARNING: Estimating processor frequency "
530 "(not found)\n");
531
532 of_node_put(cpu);
533
534 printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
535 ppc_tb_freq/1000000, ppc_tb_freq%1000000);
536 printk(KERN_INFO "time_init: processor frequency = %lu.%.6lu MHz\n",
537 ppc_proc_freq/1000000, ppc_proc_freq%1000000);
538
539 tb_ticks_per_jiffy = ppc_tb_freq / HZ;
540 tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
541 tb_ticks_per_usec = ppc_tb_freq / 1000000;
542 tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
543 div128_by_32(1024*1024, 0, tb_ticks_per_sec, &divres);
544 tb_to_xs = divres.result_low;
545
546 setup_default_decr();
547}
548
549static int pSeries_check_legacy_ioport(unsigned int baseport) 376static int pSeries_check_legacy_ioport(unsigned int baseport)
550{ 377{
551 struct device_node *np; 378 struct device_node *np;
@@ -596,16 +423,17 @@ struct machdep_calls __initdata pSeries_md = {
596 .get_cpuinfo = pSeries_get_cpuinfo, 423 .get_cpuinfo = pSeries_get_cpuinfo,
597 .log_error = pSeries_log_error, 424 .log_error = pSeries_log_error,
598 .pcibios_fixup = pSeries_final_fixup, 425 .pcibios_fixup = pSeries_final_fixup,
426 .irq_bus_setup = pSeries_irq_bus_setup,
599 .restart = rtas_restart, 427 .restart = rtas_restart,
600 .power_off = rtas_power_off, 428 .power_off = rtas_power_off,
601 .halt = rtas_halt, 429 .halt = rtas_halt,
602 .panic = rtas_os_term, 430 .panic = rtas_os_term,
603 .cpu_die = pSeries_mach_cpu_die, 431 .cpu_die = pSeries_mach_cpu_die,
604 .get_boot_time = pSeries_get_boot_time, 432 .get_boot_time = rtas_get_boot_time,
605 .get_rtc_time = pSeries_get_rtc_time, 433 .get_rtc_time = rtas_get_rtc_time,
606 .set_rtc_time = pSeries_set_rtc_time, 434 .set_rtc_time = rtas_set_rtc_time,
607 .calibrate_decr = pSeries_calibrate_decr, 435 .calibrate_decr = generic_calibrate_decr,
608 .progress = pSeries_progress, 436 .progress = rtas_progress,
609 .check_legacy_ioport = pSeries_check_legacy_ioport, 437 .check_legacy_ioport = pSeries_check_legacy_ioport,
610 .system_reset_exception = pSeries_system_reset_exception, 438 .system_reset_exception = pSeries_system_reset_exception,
611 .machine_check_exception = pSeries_machine_check_exception, 439 .machine_check_exception = pSeries_machine_check_exception,
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c
index 4203bd020c82..30154140f7e2 100644
--- a/arch/ppc64/kernel/pSeries_smp.c
+++ b/arch/ppc64/kernel/pSeries_smp.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * SMP support for pSeries machines. 2 * SMP support for pSeries and BPA machines.
3 * 3 *
4 * Dave Engebretsen, Peter Bergner, and 4 * Dave Engebretsen, Peter Bergner, and
5 * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com 5 * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
@@ -47,6 +47,7 @@
47#include <asm/pSeries_reconfig.h> 47#include <asm/pSeries_reconfig.h>
48 48
49#include "mpic.h" 49#include "mpic.h"
50#include "bpa_iic.h"
50 51
51#ifdef DEBUG 52#ifdef DEBUG
52#define DBG(fmt...) udbg_printf(fmt) 53#define DBG(fmt...) udbg_printf(fmt)
@@ -286,6 +287,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
286 return 1; 287 return 1;
287} 288}
288 289
290#ifdef CONFIG_XICS
289static inline void smp_xics_do_message(int cpu, int msg) 291static inline void smp_xics_do_message(int cpu, int msg)
290{ 292{
291 set_bit(msg, &xics_ipi_message[cpu].value); 293 set_bit(msg, &xics_ipi_message[cpu].value);
@@ -327,6 +329,37 @@ static void __devinit smp_xics_setup_cpu(int cpu)
327 cpu_clear(cpu, of_spin_map); 329 cpu_clear(cpu, of_spin_map);
328 330
329} 331}
332#endif /* CONFIG_XICS */
333#ifdef CONFIG_BPA_IIC
334static void smp_iic_message_pass(int target, int msg)
335{
336 unsigned int i;
337
338 if (target < NR_CPUS) {
339 iic_cause_IPI(target, msg);
340 } else {
341 for_each_online_cpu(i) {
342 if (target == MSG_ALL_BUT_SELF
343 && i == smp_processor_id())
344 continue;
345 iic_cause_IPI(i, msg);
346 }
347 }
348}
349
350static int __init smp_iic_probe(void)
351{
352 iic_request_IPIs();
353
354 return cpus_weight(cpu_possible_map);
355}
356
357static void __devinit smp_iic_setup_cpu(int cpu)
358{
359 if (cpu != boot_cpuid)
360 iic_setup_cpu();
361}
362#endif /* CONFIG_BPA_IIC */
330 363
331static DEFINE_SPINLOCK(timebase_lock); 364static DEFINE_SPINLOCK(timebase_lock);
332static unsigned long timebase = 0; 365static unsigned long timebase = 0;
@@ -381,14 +414,15 @@ static int smp_pSeries_cpu_bootable(unsigned int nr)
381 414
382 return 1; 415 return 1;
383} 416}
384 417#ifdef CONFIG_MPIC
385static struct smp_ops_t pSeries_mpic_smp_ops = { 418static struct smp_ops_t pSeries_mpic_smp_ops = {
386 .message_pass = smp_mpic_message_pass, 419 .message_pass = smp_mpic_message_pass,
387 .probe = smp_mpic_probe, 420 .probe = smp_mpic_probe,
388 .kick_cpu = smp_pSeries_kick_cpu, 421 .kick_cpu = smp_pSeries_kick_cpu,
389 .setup_cpu = smp_mpic_setup_cpu, 422 .setup_cpu = smp_mpic_setup_cpu,
390}; 423};
391 424#endif
425#ifdef CONFIG_XICS
392static struct smp_ops_t pSeries_xics_smp_ops = { 426static struct smp_ops_t pSeries_xics_smp_ops = {
393 .message_pass = smp_xics_message_pass, 427 .message_pass = smp_xics_message_pass,
394 .probe = smp_xics_probe, 428 .probe = smp_xics_probe,
@@ -396,6 +430,16 @@ static struct smp_ops_t pSeries_xics_smp_ops = {
396 .setup_cpu = smp_xics_setup_cpu, 430 .setup_cpu = smp_xics_setup_cpu,
397 .cpu_bootable = smp_pSeries_cpu_bootable, 431 .cpu_bootable = smp_pSeries_cpu_bootable,
398}; 432};
433#endif
434#ifdef CONFIG_BPA_IIC
435static struct smp_ops_t bpa_iic_smp_ops = {
436 .message_pass = smp_iic_message_pass,
437 .probe = smp_iic_probe,
438 .kick_cpu = smp_pSeries_kick_cpu,
439 .setup_cpu = smp_iic_setup_cpu,
440 .cpu_bootable = smp_pSeries_cpu_bootable,
441};
442#endif
399 443
400/* This is called very early */ 444/* This is called very early */
401void __init smp_init_pSeries(void) 445void __init smp_init_pSeries(void)
@@ -404,10 +448,25 @@ void __init smp_init_pSeries(void)
404 448
405 DBG(" -> smp_init_pSeries()\n"); 449 DBG(" -> smp_init_pSeries()\n");
406 450
407 if (ppc64_interrupt_controller == IC_OPEN_PIC) 451 switch (ppc64_interrupt_controller) {
452#ifdef CONFIG_MPIC
453 case IC_OPEN_PIC:
408 smp_ops = &pSeries_mpic_smp_ops; 454 smp_ops = &pSeries_mpic_smp_ops;
409 else 455 break;
456#endif
457#ifdef CONFIG_XICS
458 case IC_PPC_XIC:
410 smp_ops = &pSeries_xics_smp_ops; 459 smp_ops = &pSeries_xics_smp_ops;
460 break;
461#endif
462#ifdef CONFIG_BPA_IIC
463 case IC_BPA_IIC:
464 smp_ops = &bpa_iic_smp_ops;
465 break;
466#endif
467 default:
468 panic("Invalid interrupt controller");
469 }
411 470
412#ifdef CONFIG_HOTPLUG_CPU 471#ifdef CONFIG_HOTPLUG_CPU
413 smp_ops->cpu_disable = pSeries_cpu_disable; 472 smp_ops->cpu_disable = pSeries_cpu_disable;
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index 2bf0513f3eca..580676f87d23 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -902,6 +902,9 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
902 list_for_each_entry(dev, &bus->devices, bus_list) 902 list_for_each_entry(dev, &bus->devices, bus_list)
903 ppc_md.iommu_dev_setup(dev); 903 ppc_md.iommu_dev_setup(dev);
904 904
905 if (ppc_md.irq_bus_setup)
906 ppc_md.irq_bus_setup(bus);
907
905 if (!pci_probe_only) 908 if (!pci_probe_only)
906 return; 909 return;
907 910
diff --git a/arch/ppc64/kernel/pci.h b/arch/ppc64/kernel/pci.h
index 0fd7d849aa77..26be78b13af1 100644
--- a/arch/ppc64/kernel/pci.h
+++ b/arch/ppc64/kernel/pci.h
@@ -40,10 +40,14 @@ struct device_node *fetch_dev_dn(struct pci_dev *dev);
40void pci_addr_cache_insert_device(struct pci_dev *dev); 40void pci_addr_cache_insert_device(struct pci_dev *dev);
41void pci_addr_cache_remove_device(struct pci_dev *dev); 41void pci_addr_cache_remove_device(struct pci_dev *dev);
42 42
43/* From pSeries_pci.h */ 43/* From rtas_pci.h */
44void init_pci_config_tokens (void); 44void init_pci_config_tokens (void);
45unsigned long get_phb_buid (struct device_node *); 45unsigned long get_phb_buid (struct device_node *);
46 46
47/* From pSeries_pci.h */
48extern void pSeries_final_fixup(void);
49extern void pSeries_irq_bus_setup(struct pci_bus *bus);
50
47extern unsigned long pci_probe_only; 51extern unsigned long pci_probe_only;
48extern unsigned long pci_assign_all_buses; 52extern unsigned long pci_assign_all_buses;
49extern int pci_read_irq_line(struct pci_dev *pci_dev); 53extern int pci_read_irq_line(struct pci_dev *pci_dev);
diff --git a/arch/ppc64/kernel/pmac_time.c b/arch/ppc64/kernel/pmac_time.c
index f24827581dd7..3059edb09cc8 100644
--- a/arch/ppc64/kernel/pmac_time.c
+++ b/arch/ppc64/kernel/pmac_time.c
@@ -40,11 +40,6 @@
40#define DBG(x...) 40#define DBG(x...)
41#endif 41#endif
42 42
43extern void setup_default_decr(void);
44
45extern unsigned long ppc_tb_freq;
46extern unsigned long ppc_proc_freq;
47
48/* Apparently the RTC stores seconds since 1 Jan 1904 */ 43/* Apparently the RTC stores seconds since 1 Jan 1904 */
49#define RTC_OFFSET 2082844800 44#define RTC_OFFSET 2082844800
50 45
@@ -161,8 +156,7 @@ void __init pmac_get_boot_time(struct rtc_time *tm)
161 156
162/* 157/*
163 * Query the OF and get the decr frequency. 158 * Query the OF and get the decr frequency.
164 * This was taken from the pmac time_init() when merging the prep/pmac 159 * FIXME: merge this with generic_calibrate_decr
165 * time functions.
166 */ 160 */
167void __init pmac_calibrate_decr(void) 161void __init pmac_calibrate_decr(void)
168{ 162{
diff --git a/arch/ppc64/kernel/proc_ppc64.c b/arch/ppc64/kernel/proc_ppc64.c
index 0914b0669b05..a87c66a9652a 100644
--- a/arch/ppc64/kernel/proc_ppc64.c
+++ b/arch/ppc64/kernel/proc_ppc64.c
@@ -53,7 +53,7 @@ static int __init proc_ppc64_create(void)
53 if (!root) 53 if (!root)
54 return 1; 54 return 1;
55 55
56 if (!(systemcfg->platform & PLATFORM_PSERIES)) 56 if (!(systemcfg->platform & (PLATFORM_PSERIES | PLATFORM_BPA)))
57 return 0; 57 return 0;
58 58
59 if (!proc_mkdir("rtas", root)) 59 if (!proc_mkdir("rtas", root))
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
index b7683abfbe6a..e248a7950aeb 100644
--- a/arch/ppc64/kernel/prom_init.c
+++ b/arch/ppc64/kernel/prom_init.c
@@ -1915,9 +1915,9 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
1915 prom_send_capabilities(); 1915 prom_send_capabilities();
1916 1916
1917 /* 1917 /*
1918 * On pSeries, copy the CPU hold code 1918 * On pSeries and BPA, copy the CPU hold code
1919 */ 1919 */
1920 if (RELOC(of_platform) & PLATFORM_PSERIES) 1920 if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_BPA))
1921 copy_and_flush(0, KERNELBASE - offset, 0x100, 0); 1921 copy_and_flush(0, KERNELBASE - offset, 0x100, 0);
1922 1922
1923 /* 1923 /*
diff --git a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c
index 28b1f1521f21..1f3ff860fdf0 100644
--- a/arch/ppc64/kernel/rtas-proc.c
+++ b/arch/ppc64/kernel/rtas-proc.c
@@ -371,11 +371,11 @@ static ssize_t ppc_rtas_progress_write(struct file *file,
371 /* Lets see if the user passed hexdigits */ 371 /* Lets see if the user passed hexdigits */
372 hex = simple_strtoul(progress_led, NULL, 10); 372 hex = simple_strtoul(progress_led, NULL, 10);
373 373
374 ppc_md.progress ((char *)progress_led, hex); 374 rtas_progress ((char *)progress_led, hex);
375 return count; 375 return count;
376 376
377 /* clear the line */ 377 /* clear the line */
378 /* ppc_md.progress(" ", 0xffff);*/ 378 /* rtas_progress(" ", 0xffff);*/
379} 379}
380/* ****************************************************************** */ 380/* ****************************************************************** */
381static int ppc_rtas_progress_show(struct seq_file *m, void *v) 381static int ppc_rtas_progress_show(struct seq_file *m, void *v)
diff --git a/arch/ppc64/kernel/rtas.c b/arch/ppc64/kernel/rtas.c
index 5575603def27..5e8eb33b8e54 100644
--- a/arch/ppc64/kernel/rtas.c
+++ b/arch/ppc64/kernel/rtas.c
@@ -91,6 +91,123 @@ call_rtas_display_status_delay(unsigned char c)
91 } 91 }
92} 92}
93 93
94void
95rtas_progress(char *s, unsigned short hex)
96{
97 struct device_node *root;
98 int width, *p;
99 char *os;
100 static int display_character, set_indicator;
101 static int display_width, display_lines, *row_width, form_feed;
102 static DEFINE_SPINLOCK(progress_lock);
103 static int current_line;
104 static int pending_newline = 0; /* did last write end with unprinted newline? */
105
106 if (!rtas.base)
107 return;
108
109 if (display_width == 0) {
110 display_width = 0x10;
111 if ((root = find_path_device("/rtas"))) {
112 if ((p = (unsigned int *)get_property(root,
113 "ibm,display-line-length", NULL)))
114 display_width = *p;
115 if ((p = (unsigned int *)get_property(root,
116 "ibm,form-feed", NULL)))
117 form_feed = *p;
118 if ((p = (unsigned int *)get_property(root,
119 "ibm,display-number-of-lines", NULL)))
120 display_lines = *p;
121 row_width = (unsigned int *)get_property(root,
122 "ibm,display-truncation-length", NULL);
123 }
124 display_character = rtas_token("display-character");
125 set_indicator = rtas_token("set-indicator");
126 }
127
128 if (display_character == RTAS_UNKNOWN_SERVICE) {
129 /* use hex display if available */
130 if (set_indicator != RTAS_UNKNOWN_SERVICE)
131 rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
132 return;
133 }
134
135 spin_lock(&progress_lock);
136
137 /*
138 * Last write ended with newline, but we didn't print it since
139 * it would just clear the bottom line of output. Print it now
140 * instead.
141 *
142 * If no newline is pending and form feed is supported, clear the
143 * display with a form feed; otherwise, print a CR to start output
144 * at the beginning of the line.
145 */
146 if (pending_newline) {
147 rtas_call(display_character, 1, 1, NULL, '\r');
148 rtas_call(display_character, 1, 1, NULL, '\n');
149 pending_newline = 0;
150 } else {
151 current_line = 0;
152 if (form_feed)
153 rtas_call(display_character, 1, 1, NULL,
154 (char)form_feed);
155 else
156 rtas_call(display_character, 1, 1, NULL, '\r');
157 }
158
159 if (row_width)
160 width = row_width[current_line];
161 else
162 width = display_width;
163 os = s;
164 while (*os) {
165 if (*os == '\n' || *os == '\r') {
166 /* If newline is the last character, save it
167 * until next call to avoid bumping up the
168 * display output.
169 */
170 if (*os == '\n' && !os[1]) {
171 pending_newline = 1;
172 current_line++;
173 if (current_line > display_lines-1)
174 current_line = display_lines-1;
175 spin_unlock(&progress_lock);
176 return;
177 }
178
179 /* RTAS wants CR-LF, not just LF */
180
181 if (*os == '\n') {
182 rtas_call(display_character, 1, 1, NULL, '\r');
183 rtas_call(display_character, 1, 1, NULL, '\n');
184 } else {
185 /* CR might be used to re-draw a line, so we'll
186 * leave it alone and not add LF.
187 */
188 rtas_call(display_character, 1, 1, NULL, *os);
189 }
190
191 if (row_width)
192 width = row_width[current_line];
193 else
194 width = display_width;
195 } else {
196 width--;
197 rtas_call(display_character, 1, 1, NULL, *os);
198 }
199
200 os++;
201
202 /* if we overwrite the screen length */
203 if (width <= 0)
204 while ((*os != 0) && (*os != '\n') && (*os != '\r'))
205 os++;
206 }
207
208 spin_unlock(&progress_lock);
209}
210
94int 211int
95rtas_token(const char *service) 212rtas_token(const char *service)
96{ 213{
@@ -425,8 +542,8 @@ rtas_flash_firmware(void)
425 542
426 printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size); 543 printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
427 printk(KERN_ALERT "FLASH: performing flash and reboot\n"); 544 printk(KERN_ALERT "FLASH: performing flash and reboot\n");
428 ppc_md.progress("Flashing \n", 0x0); 545 rtas_progress("Flashing \n", 0x0);
429 ppc_md.progress("Please Wait... ", 0x0); 546 rtas_progress("Please Wait... ", 0x0);
430 printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n"); 547 printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n");
431 status = rtas_call(update_token, 1, 1, NULL, rtas_block_list); 548 status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
432 switch (status) { /* should only get "bad" status */ 549 switch (status) { /* should only get "bad" status */
diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c
new file mode 100644
index 000000000000..1048817befb8
--- /dev/null
+++ b/arch/ppc64/kernel/rtas_pci.c
@@ -0,0 +1,495 @@
1/*
2 * arch/ppc64/kernel/rtas_pci.c
3 *
4 * Copyright (C) 2001 Dave Engebretsen, IBM Corporation
5 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
6 *
7 * RTAS specific routines for PCI.
8 *
9 * Based on code from pci.c, chrp_pci.c and pSeries_pci.c
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26#include <linux/kernel.h>
27#include <linux/threads.h>
28#include <linux/pci.h>
29#include <linux/string.h>
30#include <linux/init.h>
31#include <linux/bootmem.h>
32
33#include <asm/io.h>
34#include <asm/pgtable.h>
35#include <asm/irq.h>
36#include <asm/prom.h>
37#include <asm/machdep.h>
38#include <asm/pci-bridge.h>
39#include <asm/iommu.h>
40#include <asm/rtas.h>
41
42#include "mpic.h"
43#include "pci.h"
44
45/* RTAS tokens */
46static int read_pci_config;
47static int write_pci_config;
48static int ibm_read_pci_config;
49static int ibm_write_pci_config;
50
51static int config_access_valid(struct device_node *dn, int where)
52{
53 if (where < 256)
54 return 1;
55 if (where < 4096 && dn->pci_ext_config_space)
56 return 1;
57
58 return 0;
59}
60
61static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val)
62{
63 int returnval = -1;
64 unsigned long buid, addr;
65 int ret;
66
67 if (!dn)
68 return PCIBIOS_DEVICE_NOT_FOUND;
69 if (!config_access_valid(dn, where))
70 return PCIBIOS_BAD_REGISTER_NUMBER;
71
72 addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
73 (dn->devfn << 8) | (where & 0xff);
74 buid = dn->phb->buid;
75 if (buid) {
76 ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
77 addr, buid >> 32, buid & 0xffffffff, size);
78 } else {
79 ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
80 }
81 *val = returnval;
82
83 if (ret)
84 return PCIBIOS_DEVICE_NOT_FOUND;
85
86 if (returnval == EEH_IO_ERROR_VALUE(size)
87 && eeh_dn_check_failure (dn, NULL))
88 return PCIBIOS_DEVICE_NOT_FOUND;
89
90 return PCIBIOS_SUCCESSFUL;
91}
92
93static int rtas_pci_read_config(struct pci_bus *bus,
94 unsigned int devfn,
95 int where, int size, u32 *val)
96{
97 struct device_node *busdn, *dn;
98
99 if (bus->self)
100 busdn = pci_device_to_OF_node(bus->self);
101 else
102 busdn = bus->sysdata; /* must be a phb */
103
104 /* Search only direct children of the bus */
105 for (dn = busdn->child; dn; dn = dn->sibling)
106 if (dn->devfn == devfn)
107 return rtas_read_config(dn, where, size, val);
108 return PCIBIOS_DEVICE_NOT_FOUND;
109}
110
111static int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
112{
113 unsigned long buid, addr;
114 int ret;
115
116 if (!dn)
117 return PCIBIOS_DEVICE_NOT_FOUND;
118 if (!config_access_valid(dn, where))
119 return PCIBIOS_BAD_REGISTER_NUMBER;
120
121 addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
122 (dn->devfn << 8) | (where & 0xff);
123 buid = dn->phb->buid;
124 if (buid) {
125 ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val);
126 } else {
127 ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val);
128 }
129
130 if (ret)
131 return PCIBIOS_DEVICE_NOT_FOUND;
132
133 return PCIBIOS_SUCCESSFUL;
134}
135
136static int rtas_pci_write_config(struct pci_bus *bus,
137 unsigned int devfn,
138 int where, int size, u32 val)
139{
140 struct device_node *busdn, *dn;
141
142 if (bus->self)
143 busdn = pci_device_to_OF_node(bus->self);
144 else
145 busdn = bus->sysdata; /* must be a phb */
146
147 /* Search only direct children of the bus */
148 for (dn = busdn->child; dn; dn = dn->sibling)
149 if (dn->devfn == devfn)
150 return rtas_write_config(dn, where, size, val);
151 return PCIBIOS_DEVICE_NOT_FOUND;
152}
153
154struct pci_ops rtas_pci_ops = {
155 rtas_pci_read_config,
156 rtas_pci_write_config
157};
158
159int is_python(struct device_node *dev)
160{
161 char *model = (char *)get_property(dev, "model", NULL);
162
163 if (model && strstr(model, "Python"))
164 return 1;
165
166 return 0;
167}
168
169static int get_phb_reg_prop(struct device_node *dev,
170 unsigned int addr_size_words,
171 struct reg_property64 *reg)
172{
173 unsigned int *ui_ptr = NULL, len;
174
175 /* Found a PHB, now figure out where his registers are mapped. */
176 ui_ptr = (unsigned int *)get_property(dev, "reg", &len);
177 if (ui_ptr == NULL)
178 return 1;
179
180 if (addr_size_words == 1) {
181 reg->address = ((struct reg_property32 *)ui_ptr)->address;
182 reg->size = ((struct reg_property32 *)ui_ptr)->size;
183 } else {
184 *reg = *((struct reg_property64 *)ui_ptr);
185 }
186
187 return 0;
188}
189
190static void python_countermeasures(struct device_node *dev,
191 unsigned int addr_size_words)
192{
193 struct reg_property64 reg_struct;
194 void __iomem *chip_regs;
195 volatile u32 val;
196
197 if (get_phb_reg_prop(dev, addr_size_words, &reg_struct))
198 return;
199
200 /* Python's register file is 1 MB in size. */
201 chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000);
202
203 /*
204 * Firmware doesn't always clear this bit which is critical
205 * for good performance - Anton
206 */
207
208#define PRG_CL_RESET_VALID 0x00010000
209
210 val = in_be32(chip_regs + 0xf6030);
211 if (val & PRG_CL_RESET_VALID) {
212 printk(KERN_INFO "Python workaround: ");
213 val &= ~PRG_CL_RESET_VALID;
214 out_be32(chip_regs + 0xf6030, val);
215 /*
216 * We must read it back for changes to
217 * take effect
218 */
219 val = in_be32(chip_regs + 0xf6030);
220 printk("reg0: %x\n", val);
221 }
222
223 iounmap(chip_regs);
224}
225
226void __init init_pci_config_tokens (void)
227{
228 read_pci_config = rtas_token("read-pci-config");
229 write_pci_config = rtas_token("write-pci-config");
230 ibm_read_pci_config = rtas_token("ibm,read-pci-config");
231 ibm_write_pci_config = rtas_token("ibm,write-pci-config");
232}
233
234unsigned long __devinit get_phb_buid (struct device_node *phb)
235{
236 int addr_cells;
237 unsigned int *buid_vals;
238 unsigned int len;
239 unsigned long buid;
240
241 if (ibm_read_pci_config == -1) return 0;
242
243 /* PHB's will always be children of the root node,
244 * or so it is promised by the current firmware. */
245 if (phb->parent == NULL)
246 return 0;
247 if (phb->parent->parent)
248 return 0;
249
250 buid_vals = (unsigned int *) get_property(phb, "reg", &len);
251 if (buid_vals == NULL)
252 return 0;
253
254 addr_cells = prom_n_addr_cells(phb);
255 if (addr_cells == 1) {
256 buid = (unsigned long) buid_vals[0];
257 } else {
258 buid = (((unsigned long)buid_vals[0]) << 32UL) |
259 (((unsigned long)buid_vals[1]) & 0xffffffff);
260 }
261 return buid;
262}
263
264static int phb_set_bus_ranges(struct device_node *dev,
265 struct pci_controller *phb)
266{
267 int *bus_range;
268 unsigned int len;
269
270 bus_range = (int *) get_property(dev, "bus-range", &len);
271 if (bus_range == NULL || len < 2 * sizeof(int)) {
272 return 1;
273 }
274
275 phb->first_busno = bus_range[0];
276 phb->last_busno = bus_range[1];
277
278 return 0;
279}
280
281static int __devinit setup_phb(struct device_node *dev,
282 struct pci_controller *phb,
283 unsigned int addr_size_words)
284{
285 pci_setup_pci_controller(phb);
286
287 if (is_python(dev))
288 python_countermeasures(dev, addr_size_words);
289
290 if (phb_set_bus_ranges(dev, phb))
291 return 1;
292
293 phb->arch_data = dev;
294 phb->ops = &rtas_pci_ops;
295 phb->buid = get_phb_buid(dev);
296
297 return 0;
298}
299
300static void __devinit add_linux_pci_domain(struct device_node *dev,
301 struct pci_controller *phb,
302 struct property *of_prop)
303{
304 memset(of_prop, 0, sizeof(struct property));
305 of_prop->name = "linux,pci-domain";
306 of_prop->length = sizeof(phb->global_number);
307 of_prop->value = (unsigned char *)&of_prop[1];
308 memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number));
309 prom_add_property(dev, of_prop);
310}
311
312static struct pci_controller * __init alloc_phb(struct device_node *dev,
313 unsigned int addr_size_words)
314{
315 struct pci_controller *phb;
316 struct property *of_prop;
317
318 phb = alloc_bootmem(sizeof(struct pci_controller));
319 if (phb == NULL)
320 return NULL;
321
322 of_prop = alloc_bootmem(sizeof(struct property) +
323 sizeof(phb->global_number));
324 if (!of_prop)
325 return NULL;
326
327 if (setup_phb(dev, phb, addr_size_words))
328 return NULL;
329
330 add_linux_pci_domain(dev, phb, of_prop);
331
332 return phb;
333}
334
335static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words)
336{
337 struct pci_controller *phb;
338
339 phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
340 GFP_KERNEL);
341 if (phb == NULL)
342 return NULL;
343
344 if (setup_phb(dev, phb, addr_size_words))
345 return NULL;
346
347 phb->is_dynamic = 1;
348
349 /* TODO: linux,pci-domain? */
350
351 return phb;
352}
353
354unsigned long __init find_and_init_phbs(void)
355{
356 struct device_node *node;
357 struct pci_controller *phb;
358 unsigned int root_size_cells = 0;
359 unsigned int index;
360 unsigned int *opprop = NULL;
361 struct device_node *root = of_find_node_by_path("/");
362
363 if (ppc64_interrupt_controller == IC_OPEN_PIC) {
364 opprop = (unsigned int *)get_property(root,
365 "platform-open-pic", NULL);
366 }
367
368 root_size_cells = prom_n_size_cells(root);
369
370 index = 0;
371
372 for (node = of_get_next_child(root, NULL);
373 node != NULL;
374 node = of_get_next_child(root, node)) {
375 if (node->type == NULL || strcmp(node->type, "pci") != 0)
376 continue;
377
378 phb = alloc_phb(node, root_size_cells);
379 if (!phb)
380 continue;
381
382 pci_process_bridge_OF_ranges(phb, node);
383 pci_setup_phb_io(phb, index == 0);
384#ifdef CONFIG_PPC_PSERIES
385 if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
386 int addr = root_size_cells * (index + 2) - 1;
387 mpic_assign_isu(pSeries_mpic, index, opprop[addr]);
388 }
389#endif
390 index++;
391 }
392
393 of_node_put(root);
394 pci_devs_phb_init();
395
396 /*
397 * pci_probe_only and pci_assign_all_buses can be set via properties
398 * in chosen.
399 */
400 if (of_chosen) {
401 int *prop;
402
403 prop = (int *)get_property(of_chosen, "linux,pci-probe-only",
404 NULL);
405 if (prop)
406 pci_probe_only = *prop;
407
408 prop = (int *)get_property(of_chosen,
409 "linux,pci-assign-all-buses", NULL);
410 if (prop)
411 pci_assign_all_buses = *prop;
412 }
413
414 return 0;
415}
416
417struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
418{
419 struct device_node *root = of_find_node_by_path("/");
420 unsigned int root_size_cells = 0;
421 struct pci_controller *phb;
422 struct pci_bus *bus;
423 int primary;
424
425 root_size_cells = prom_n_size_cells(root);
426
427 primary = list_empty(&hose_list);
428 phb = alloc_phb_dynamic(dn, root_size_cells);
429 if (!phb)
430 return NULL;
431
432 pci_process_bridge_OF_ranges(phb, dn);
433
434 pci_setup_phb_io_dynamic(phb, primary);
435 of_node_put(root);
436
437 pci_devs_phb_init_dynamic(phb);
438 phb->last_busno = 0xff;
439 bus = pci_scan_bus(phb->first_busno, phb->ops, phb->arch_data);
440 phb->bus = bus;
441 phb->last_busno = bus->subordinate;
442
443 return phb;
444}
445EXPORT_SYMBOL(init_phb_dynamic);
446
447/* RPA-specific bits for removing PHBs */
448int pcibios_remove_root_bus(struct pci_controller *phb)
449{
450 struct pci_bus *b = phb->bus;
451 struct resource *res;
452 int rc, i;
453
454 res = b->resource[0];
455 if (!res->flags) {
456 printk(KERN_ERR "%s: no IO resource for PHB %s\n", __FUNCTION__,
457 b->name);
458 return 1;
459 }
460
461 rc = unmap_bus_range(b);
462 if (rc) {
463 printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
464 __FUNCTION__, b->name);
465 return 1;
466 }
467
468 if (release_resource(res)) {
469 printk(KERN_ERR "%s: failed to release IO on bus %s\n",
470 __FUNCTION__, b->name);
471 return 1;
472 }
473
474 for (i = 1; i < 3; ++i) {
475 res = b->resource[i];
476 if (!res->flags && i == 0) {
477 printk(KERN_ERR "%s: no MEM resource for PHB %s\n",
478 __FUNCTION__, b->name);
479 return 1;
480 }
481 if (res->flags && release_resource(res)) {
482 printk(KERN_ERR
483 "%s: failed to release IO %d on bus %s\n",
484 __FUNCTION__, i, b->name);
485 return 1;
486 }
487 }
488
489 list_del(&phb->list_node);
490 if (phb->is_dynamic)
491 kfree(phb);
492
493 return 0;
494}
495EXPORT_SYMBOL(pcibios_remove_root_bus);
diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c
index de02aedbe080..d729fefa0df5 100644
--- a/arch/ppc64/kernel/rtc.c
+++ b/arch/ppc64/kernel/rtc.c
@@ -301,7 +301,7 @@ void iSeries_get_boot_time(struct rtc_time *tm)
301#ifdef CONFIG_PPC_RTAS 301#ifdef CONFIG_PPC_RTAS
302#define MAX_RTC_WAIT 5000 /* 5 sec */ 302#define MAX_RTC_WAIT 5000 /* 5 sec */
303#define RTAS_CLOCK_BUSY (-2) 303#define RTAS_CLOCK_BUSY (-2)
304void pSeries_get_boot_time(struct rtc_time *rtc_tm) 304void rtas_get_boot_time(struct rtc_time *rtc_tm)
305{ 305{
306 int ret[8]; 306 int ret[8];
307 int error, wait_time; 307 int error, wait_time;
@@ -336,7 +336,7 @@ void pSeries_get_boot_time(struct rtc_time *rtc_tm)
336 * and if a delay is needed to read the clock. In this case we just 336 * and if a delay is needed to read the clock. In this case we just
337 * silently return without updating rtc_tm. 337 * silently return without updating rtc_tm.
338 */ 338 */
339void pSeries_get_rtc_time(struct rtc_time *rtc_tm) 339void rtas_get_rtc_time(struct rtc_time *rtc_tm)
340{ 340{
341 int ret[8]; 341 int ret[8];
342 int error, wait_time; 342 int error, wait_time;
@@ -371,7 +371,7 @@ void pSeries_get_rtc_time(struct rtc_time *rtc_tm)
371 rtc_tm->tm_year = ret[0] - 1900; 371 rtc_tm->tm_year = ret[0] - 1900;
372} 372}
373 373
374int pSeries_set_rtc_time(struct rtc_time *tm) 374int rtas_set_rtc_time(struct rtc_time *tm)
375{ 375{
376 int error, wait_time; 376 int error, wait_time;
377 unsigned long max_wait_tb; 377 unsigned long max_wait_tb;
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
index 9e70ac90dec1..0a47a5ef428d 100644
--- a/arch/ppc64/kernel/setup.c
+++ b/arch/ppc64/kernel/setup.c
@@ -344,6 +344,7 @@ static void __init setup_cpu_maps(void)
344extern struct machdep_calls pSeries_md; 344extern struct machdep_calls pSeries_md;
345extern struct machdep_calls pmac_md; 345extern struct machdep_calls pmac_md;
346extern struct machdep_calls maple_md; 346extern struct machdep_calls maple_md;
347extern struct machdep_calls bpa_md;
347 348
348/* Ultimately, stuff them in an elf section like initcalls... */ 349/* Ultimately, stuff them in an elf section like initcalls... */
349static struct machdep_calls __initdata *machines[] = { 350static struct machdep_calls __initdata *machines[] = {
@@ -356,6 +357,9 @@ static struct machdep_calls __initdata *machines[] = {
356#ifdef CONFIG_PPC_MAPLE 357#ifdef CONFIG_PPC_MAPLE
357 &maple_md, 358 &maple_md,
358#endif /* CONFIG_PPC_MAPLE */ 359#endif /* CONFIG_PPC_MAPLE */
360#ifdef CONFIG_PPC_BPA
361 &bpa_md,
362#endif
359 NULL 363 NULL
360}; 364};
361 365
@@ -679,6 +683,12 @@ void machine_restart(char *cmd)
679 if (ppc_md.nvram_sync) 683 if (ppc_md.nvram_sync)
680 ppc_md.nvram_sync(); 684 ppc_md.nvram_sync();
681 ppc_md.restart(cmd); 685 ppc_md.restart(cmd);
686#ifdef CONFIG_SMP
687 smp_send_stop();
688#endif
689 printk(KERN_EMERG "System Halted, OK to turn off power\n");
690 local_irq_disable();
691 while (1) ;
682} 692}
683 693
684EXPORT_SYMBOL(machine_restart); 694EXPORT_SYMBOL(machine_restart);
@@ -688,6 +698,12 @@ void machine_power_off(void)
688 if (ppc_md.nvram_sync) 698 if (ppc_md.nvram_sync)
689 ppc_md.nvram_sync(); 699 ppc_md.nvram_sync();
690 ppc_md.power_off(); 700 ppc_md.power_off();
701#ifdef CONFIG_SMP
702 smp_send_stop();
703#endif
704 printk(KERN_EMERG "System Halted, OK to turn off power\n");
705 local_irq_disable();
706 while (1) ;
691} 707}
692 708
693EXPORT_SYMBOL(machine_power_off); 709EXPORT_SYMBOL(machine_power_off);
@@ -697,13 +713,16 @@ void machine_halt(void)
697 if (ppc_md.nvram_sync) 713 if (ppc_md.nvram_sync)
698 ppc_md.nvram_sync(); 714 ppc_md.nvram_sync();
699 ppc_md.halt(); 715 ppc_md.halt();
716#ifdef CONFIG_SMP
717 smp_send_stop();
718#endif
719 printk(KERN_EMERG "System Halted, OK to turn off power\n");
720 local_irq_disable();
721 while (1) ;
700} 722}
701 723
702EXPORT_SYMBOL(machine_halt); 724EXPORT_SYMBOL(machine_halt);
703 725
704unsigned long ppc_proc_freq;
705unsigned long ppc_tb_freq;
706
707static int ppc64_panic_event(struct notifier_block *this, 726static int ppc64_panic_event(struct notifier_block *this,
708 unsigned long event, void *ptr) 727 unsigned long event, void *ptr)
709{ 728{
@@ -1080,11 +1099,11 @@ void __init setup_arch(char **cmdline_p)
1080static void ppc64_do_msg(unsigned int src, const char *msg) 1099static void ppc64_do_msg(unsigned int src, const char *msg)
1081{ 1100{
1082 if (ppc_md.progress) { 1101 if (ppc_md.progress) {
1083 char buf[32]; 1102 char buf[128];
1084 1103
1085 sprintf(buf, "%08x \n", src); 1104 sprintf(buf, "%08X\n", src);
1086 ppc_md.progress(buf, 0); 1105 ppc_md.progress(buf, 0);
1087 sprintf(buf, "%-16s", msg); 1106 snprintf(buf, 128, "%s", msg);
1088 ppc_md.progress(buf, 0); 1107 ppc_md.progress(buf, 0);
1089 } 1108 }
1090} 1109}
@@ -1118,7 +1137,7 @@ void ppc64_dump_msg(unsigned int src, const char *msg)
1118} 1137}
1119 1138
1120/* This should only be called on processor 0 during calibrate decr */ 1139/* This should only be called on processor 0 during calibrate decr */
1121void setup_default_decr(void) 1140void __init setup_default_decr(void)
1122{ 1141{
1123 struct paca_struct *lpaca = get_paca(); 1142 struct paca_struct *lpaca = get_paca();
1124 1143
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
index 9ef5d36d6b25..2fcddfcb594d 100644
--- a/arch/ppc64/kernel/smp.c
+++ b/arch/ppc64/kernel/smp.c
@@ -71,7 +71,7 @@ void smp_call_function_interrupt(void);
71 71
72int smt_enabled_at_boot = 1; 72int smt_enabled_at_boot = 1;
73 73
74#ifdef CONFIG_PPC_MULTIPLATFORM 74#ifdef CONFIG_MPIC
75void smp_mpic_message_pass(int target, int msg) 75void smp_mpic_message_pass(int target, int msg)
76{ 76{
77 /* make sure we're sending something that translates to an IPI */ 77 /* make sure we're sending something that translates to an IPI */
@@ -128,7 +128,7 @@ void __devinit smp_generic_kick_cpu(int nr)
128 smp_mb(); 128 smp_mb();
129} 129}
130 130
131#endif /* CONFIG_PPC_MULTIPLATFORM */ 131#endif /* CONFIG_MPIC */
132 132
133static void __init smp_space_timers(unsigned int max_cpus) 133static void __init smp_space_timers(unsigned int max_cpus)
134{ 134{
diff --git a/arch/ppc64/kernel/spider-pic.c b/arch/ppc64/kernel/spider-pic.c
new file mode 100644
index 000000000000..d5c9a02fb119
--- /dev/null
+++ b/arch/ppc64/kernel/spider-pic.c
@@ -0,0 +1,191 @@
1/*
2 * External Interrupt Controller on Spider South Bridge
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5 *
6 * Author: Arnd Bergmann <arndb@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/interrupt.h>
24#include <linux/irq.h>
25
26#include <asm/pgtable.h>
27#include <asm/prom.h>
28#include <asm/io.h>
29
30#include "bpa_iic.h"
31
32/* register layout taken from Spider spec, table 7.4-4 */
33enum {
34 TIR_DEN = 0x004, /* Detection Enable Register */
35 TIR_MSK = 0x084, /* Mask Level Register */
36 TIR_EDC = 0x0c0, /* Edge Detection Clear Register */
37 TIR_PNDA = 0x100, /* Pending Register A */
38 TIR_PNDB = 0x104, /* Pending Register B */
39 TIR_CS = 0x144, /* Current Status Register */
40 TIR_LCSA = 0x150, /* Level Current Status Register A */
41 TIR_LCSB = 0x154, /* Level Current Status Register B */
42 TIR_LCSC = 0x158, /* Level Current Status Register C */
43 TIR_LCSD = 0x15c, /* Level Current Status Register D */
44 TIR_CFGA = 0x200, /* Setting Register A0 */
45 TIR_CFGB = 0x204, /* Setting Register B0 */
46 /* 0x208 ... 0x3ff Setting Register An/Bn */
47 TIR_PPNDA = 0x400, /* Packet Pending Register A */
48 TIR_PPNDB = 0x404, /* Packet Pending Register B */
49 TIR_PIERA = 0x408, /* Packet Output Error Register A */
50 TIR_PIERB = 0x40c, /* Packet Output Error Register B */
51 TIR_PIEN = 0x444, /* Packet Output Enable Register */
52 TIR_PIPND = 0x454, /* Packet Output Pending Register */
53 TIRDID = 0x484, /* Spider Device ID Register */
54 REISTIM = 0x500, /* Reissue Command Timeout Time Setting */
55 REISTIMEN = 0x504, /* Reissue Command Timeout Setting */
56 REISWAITEN = 0x508, /* Reissue Wait Control*/
57};
58
59static void __iomem *spider_pics[4];
60
61static void __iomem *spider_get_pic(int irq)
62{
63 int node = irq / IIC_NODE_STRIDE;
64 irq %= IIC_NODE_STRIDE;
65
66 if (irq >= IIC_EXT_OFFSET &&
67 irq < IIC_EXT_OFFSET + IIC_NUM_EXT &&
68 spider_pics)
69 return spider_pics[node];
70 return NULL;
71}
72
73static int spider_get_nr(unsigned int irq)
74{
75 return (irq % IIC_NODE_STRIDE) - IIC_EXT_OFFSET;
76}
77
78static void __iomem *spider_get_irq_config(int irq)
79{
80 void __iomem *pic;
81 pic = spider_get_pic(irq);
82 return pic + TIR_CFGA + 8 * spider_get_nr(irq);
83}
84
85static void spider_enable_irq(unsigned int irq)
86{
87 void __iomem *cfg = spider_get_irq_config(irq);
88 irq = spider_get_nr(irq);
89
90 out_be32(cfg, in_be32(cfg) | 0x3107000eu);
91 out_be32(cfg + 4, in_be32(cfg + 4) | 0x00020000u | irq);
92}
93
94static void spider_disable_irq(unsigned int irq)
95{
96 void __iomem *cfg = spider_get_irq_config(irq);
97 irq = spider_get_nr(irq);
98
99 out_be32(cfg, in_be32(cfg) & ~0x30000000u);
100}
101
102static unsigned int spider_startup_irq(unsigned int irq)
103{
104 spider_enable_irq(irq);
105 return 0;
106}
107
108static void spider_shutdown_irq(unsigned int irq)
109{
110 spider_disable_irq(irq);
111}
112
113static void spider_end_irq(unsigned int irq)
114{
115 spider_enable_irq(irq);
116}
117
118static void spider_ack_irq(unsigned int irq)
119{
120 spider_disable_irq(irq);
121 iic_local_enable();
122}
123
124static struct hw_interrupt_type spider_pic = {
125 .typename = " SPIDER ",
126 .startup = spider_startup_irq,
127 .shutdown = spider_shutdown_irq,
128 .enable = spider_enable_irq,
129 .disable = spider_disable_irq,
130 .ack = spider_ack_irq,
131 .end = spider_end_irq,
132};
133
134
135int spider_get_irq(unsigned long int_pending)
136{
137 void __iomem *regs = spider_get_pic(int_pending);
138 unsigned long cs;
139 int irq;
140
141 cs = in_be32(regs + TIR_CS);
142
143 irq = cs >> 24;
144 if (irq != 63)
145 return irq;
146
147 return -1;
148}
149
150void spider_init_IRQ(void)
151{
152 int node;
153 struct device_node *dn;
154 unsigned int *property;
155 long spiderpic;
156 int n;
157
158/* FIXME: detect multiple PICs as soon as the device tree has them */
159 for (node = 0; node < 1; node++) {
160 dn = of_find_node_by_path("/");
161 n = prom_n_addr_cells(dn);
162 property = (unsigned int *) get_property(dn,
163 "platform-spider-pic", NULL);
164
165 if (!property)
166 continue;
167 for (spiderpic = 0; n > 0; --n)
168 spiderpic = (spiderpic << 32) + *property++;
169 printk(KERN_DEBUG "SPIDER addr: %lx\n", spiderpic);
170 spider_pics[node] = __ioremap(spiderpic, 0x800, _PAGE_NO_CACHE);
171 for (n = 0; n < IIC_NUM_EXT; n++) {
172 int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE;
173 get_irq_desc(irq)->handler = &spider_pic;
174
175 /* do not mask any interrupts because of level */
176 out_be32(spider_pics[node] + TIR_MSK, 0x0);
177
178 /* disable edge detection clear */
179 /* out_be32(spider_pics[node] + TIR_EDC, 0x0); */
180
181 /* enable interrupt packets to be output */
182 out_be32(spider_pics[node] + TIR_PIEN,
183 in_be32(spider_pics[node] + TIR_PIEN) | 0x1);
184
185 /* Enable the interrupt detection enable bit. Do this last! */
186 out_be32(spider_pics[node] + TIR_DEN,
187 in_be32(spider_pics[node] +TIR_DEN) | 0x1);
188
189 }
190 }
191}
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
index 33364a7d2cd2..2348a75e050d 100644
--- a/arch/ppc64/kernel/time.c
+++ b/arch/ppc64/kernel/time.c
@@ -107,6 +107,9 @@ void ppc_adjtimex(void);
107 107
108static unsigned adjusting_time = 0; 108static unsigned adjusting_time = 0;
109 109
110unsigned long ppc_proc_freq;
111unsigned long ppc_tb_freq;
112
110static __inline__ void timer_check_rtc(void) 113static __inline__ void timer_check_rtc(void)
111{ 114{
112 /* 115 /*
@@ -472,6 +475,66 @@ int do_settimeofday(struct timespec *tv)
472 475
473EXPORT_SYMBOL(do_settimeofday); 476EXPORT_SYMBOL(do_settimeofday);
474 477
478#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA)
479void __init generic_calibrate_decr(void)
480{
481 struct device_node *cpu;
482 struct div_result divres;
483 unsigned int *fp;
484 int node_found;
485
486 /*
487 * The cpu node should have a timebase-frequency property
488 * to tell us the rate at which the decrementer counts.
489 */
490 cpu = of_find_node_by_type(NULL, "cpu");
491
492 ppc_tb_freq = DEFAULT_TB_FREQ; /* hardcoded default */
493 node_found = 0;
494 if (cpu != 0) {
495 fp = (unsigned int *)get_property(cpu, "timebase-frequency",
496 NULL);
497 if (fp != 0) {
498 node_found = 1;
499 ppc_tb_freq = *fp;
500 }
501 }
502 if (!node_found)
503 printk(KERN_ERR "WARNING: Estimating decrementer frequency "
504 "(not found)\n");
505
506 ppc_proc_freq = DEFAULT_PROC_FREQ;
507 node_found = 0;
508 if (cpu != 0) {
509 fp = (unsigned int *)get_property(cpu, "clock-frequency",
510 NULL);
511 if (fp != 0) {
512 node_found = 1;
513 ppc_proc_freq = *fp;
514 }
515 }
516 if (!node_found)
517 printk(KERN_ERR "WARNING: Estimating processor frequency "
518 "(not found)\n");
519
520 of_node_put(cpu);
521
522 printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
523 ppc_tb_freq/1000000, ppc_tb_freq%1000000);
524 printk(KERN_INFO "time_init: processor frequency = %lu.%.6lu MHz\n",
525 ppc_proc_freq/1000000, ppc_proc_freq%1000000);
526
527 tb_ticks_per_jiffy = ppc_tb_freq / HZ;
528 tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
529 tb_ticks_per_usec = ppc_tb_freq / 1000000;
530 tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
531 div128_by_32(1024*1024, 0, tb_ticks_per_sec, &divres);
532 tb_to_xs = divres.result_low;
533
534 setup_default_decr();
535}
536#endif
537
475void __init time_init(void) 538void __init time_init(void)
476{ 539{
477 /* This function is only called on the boot processor */ 540 /* This function is only called on the boot processor */
diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
index 7e52cb2605e0..a8d5e83ee89f 100644
--- a/arch/ppc64/kernel/traps.c
+++ b/arch/ppc64/kernel/traps.c
@@ -126,6 +126,10 @@ int die(const char *str, struct pt_regs *regs, long err)
126 printk("POWERMAC "); 126 printk("POWERMAC ");
127 nl = 1; 127 nl = 1;
128 break; 128 break;
129 case PLATFORM_BPA:
130 printk("BPA ");
131 nl = 1;
132 break;
129 } 133 }
130 if (nl) 134 if (nl)
131 printk("\n"); 135 printk("\n");
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index 06a31da2381c..b53e2e2b5aee 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -414,6 +414,16 @@ config WATCHDOG_RIO
414 machines. The watchdog timeout period is normally one minute but 414 machines. The watchdog timeout period is normally one minute but
415 can be changed with a boot-time parameter. 415 can be changed with a boot-time parameter.
416 416
417# ppc64 RTAS watchdog
418config WATCHDOG_RTAS
419 tristate "RTAS watchdog"
420 depends on WATCHDOG && PPC_RTAS
421 help
422 This driver adds watchdog support for the RTAS watchdog.
423
424 To compile this driver as a module, choose M here. The module
425 will be called wdrtas.
426
417# 427#
418# ISA-based Watchdog Cards 428# ISA-based Watchdog Cards
419# 429#
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index 1cd27efa35c1..c1838834ea7f 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
33obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o 33obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
34obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o 34obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
35obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o 35obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
36obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
36 37
37# Only one watchdog can succeed. We probe the hardware watchdog 38# Only one watchdog can succeed. We probe the hardware watchdog
38# drivers first, then the softdog driver. This means if your hardware 39# drivers first, then the softdog driver. This means if your hardware
diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/char/watchdog/wdrtas.c
new file mode 100644
index 000000000000..619e2ffca33f
--- /dev/null
+++ b/drivers/char/watchdog/wdrtas.c
@@ -0,0 +1,696 @@
1/*
2 * FIXME: add wdrtas_get_status and wdrtas_get_boot_status as soon as
3 * RTAS calls are available
4 */
5
6/*
7 * RTAS watchdog driver
8 *
9 * (C) Copyright IBM Corp. 2005
10 * device driver to exploit watchdog RTAS functions
11 *
12 * Authors : Utz Bacher <utz.bacher@de.ibm.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/config.h>
30#include <linux/fs.h>
31#include <linux/init.h>
32#include <linux/kernel.h>
33#include <linux/miscdevice.h>
34#include <linux/module.h>
35#include <linux/notifier.h>
36#include <linux/reboot.h>
37#include <linux/types.h>
38#include <linux/watchdog.h>
39
40#include <asm/rtas.h>
41#include <asm/uaccess.h>
42
43#define WDRTAS_MAGIC_CHAR 42
44#define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \
45 WDIOF_MAGICCLOSE)
46
47MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
48MODULE_DESCRIPTION("RTAS watchdog driver");
49MODULE_LICENSE("GPL");
50MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
51MODULE_ALIAS_MISCDEV(TEMP_MINOR);
52
53#ifdef CONFIG_WATCHDOG_NOWAYOUT
54static int wdrtas_nowayout = 1;
55#else
56static int wdrtas_nowayout = 0;
57#endif
58
59static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0);
60static char wdrtas_expect_close = 0;
61
62static int wdrtas_interval;
63
64#define WDRTAS_THERMAL_SENSOR 3
65static int wdrtas_token_get_sensor_state;
66#define WDRTAS_SURVEILLANCE_IND 9000
67static int wdrtas_token_set_indicator;
68#define WDRTAS_SP_SPI 28
69static int wdrtas_token_get_sp;
70static int wdrtas_token_event_scan;
71
72#define WDRTAS_DEFAULT_INTERVAL 300
73
74#define WDRTAS_LOGBUFFER_LEN 128
75static char wdrtas_logbuffer[WDRTAS_LOGBUFFER_LEN];
76
77
78/*** watchdog access functions */
79
80/**
81 * wdrtas_set_interval - sets the watchdog interval
82 * @interval: new interval
83 *
84 * returns 0 on success, <0 on failures
85 *
86 * wdrtas_set_interval sets the watchdog keepalive interval by calling the
87 * RTAS function set-indicator (surveillance). The unit of interval is
88 * seconds.
89 */
90static int
91wdrtas_set_interval(int interval)
92{
93 long result;
94 static int print_msg = 10;
95
96 /* rtas uses minutes */
97 interval = (interval + 59) / 60;
98
99 result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL,
100 WDRTAS_SURVEILLANCE_IND, 0, interval);
101 if ( (result < 0) && (print_msg) ) {
102 printk(KERN_ERR "wdrtas: setting the watchdog to %i "
103 "timeout failed: %li\n", interval, result);
104 print_msg--;
105 }
106
107 return result;
108}
109
110/**
111 * wdrtas_get_interval - returns the current watchdog interval
112 * @fallback_value: value (in seconds) to use, if the RTAS call fails
113 *
114 * returns the interval
115 *
116 * wdrtas_get_interval returns the current watchdog keepalive interval
117 * as reported by the RTAS function ibm,get-system-parameter. The unit
118 * of the return value is seconds.
119 */
120static int
121wdrtas_get_interval(int fallback_value)
122{
123 long result;
124 char value[4];
125
126 result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL,
127 WDRTAS_SP_SPI, (void *)__pa(&value), 4);
128 if ( (value[0] != 0) || (value[1] != 2) || (value[3] != 0) ||
129 (result < 0) ) {
130 printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog "
131 "timeout (%li). Continuing\n", result);
132 return fallback_value;
133 }
134
135 /* rtas uses minutes */
136 return ((int)value[2]) * 60;
137}
138
139/**
140 * wdrtas_timer_start - starts watchdog
141 *
142 * wdrtas_timer_start starts the watchdog by calling the RTAS function
143 * set-interval (surveillance)
144 */
145static void
146wdrtas_timer_start(void)
147{
148 wdrtas_set_interval(wdrtas_interval);
149}
150
151/**
152 * wdrtas_timer_stop - stops watchdog
153 *
154 * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function
155 * set-interval (surveillance)
156 */
157static void
158wdrtas_timer_stop(void)
159{
160 wdrtas_set_interval(0);
161}
162
163/**
164 * wdrtas_log_scanned_event - logs an event we received during keepalive
165 *
166 * wdrtas_log_scanned_event prints a message to the log buffer dumping
167 * the results of the last event-scan call
168 */
169static void
170wdrtas_log_scanned_event(void)
171{
172 int i;
173
174 for (i = 0; i < WDRTAS_LOGBUFFER_LEN; i += 16)
175 printk(KERN_INFO "wdrtas: dumping event (line %i/%i), data = "
176 "%02x %02x %02x %02x %02x %02x %02x %02x "
177 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
178 (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16),
179 wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1],
180 wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3],
181 wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5],
182 wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7],
183 wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9],
184 wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11],
185 wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13],
186 wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]);
187}
188
189/**
190 * wdrtas_timer_keepalive - resets watchdog timer to keep system alive
191 *
192 * wdrtas_timer_keepalive restarts the watchdog timer by calling the
193 * RTAS function event-scan and repeats these calls as long as there are
194 * events available. All events will be dumped.
195 */
196static void
197wdrtas_timer_keepalive(void)
198{
199 long result;
200
201 do {
202 result = rtas_call(wdrtas_token_event_scan, 4, 1, NULL,
203 RTAS_EVENT_SCAN_ALL_EVENTS, 0,
204 (void *)__pa(wdrtas_logbuffer),
205 WDRTAS_LOGBUFFER_LEN);
206 if (result < 0)
207 printk(KERN_ERR "wdrtas: event-scan failed: %li\n",
208 result);
209 if (result == 0)
210 wdrtas_log_scanned_event();
211 } while (result == 0);
212}
213
214/**
215 * wdrtas_get_temperature - returns current temperature
216 *
217 * returns temperature or <0 on failures
218 *
219 * wdrtas_get_temperature returns the current temperature in Fahrenheit. It
220 * uses the RTAS call get-sensor-state, token 3 to do so
221 */
222static int
223wdrtas_get_temperature(void)
224{
225 long result;
226 int temperature = 0;
227
228 result = rtas_call(wdrtas_token_get_sensor_state, 2, 2,
229 (void *)__pa(&temperature),
230 WDRTAS_THERMAL_SENSOR, 0);
231
232 if (result < 0)
233 printk(KERN_WARNING "wdrtas: reading the thermal sensor "
234 "faild: %li\n", result);
235 else
236 temperature = ((temperature * 9) / 5) + 32; /* fahrenheit */
237
238 return temperature;
239}
240
241/**
242 * wdrtas_get_status - returns the status of the watchdog
243 *
244 * returns a bitmask of defines WDIOF_... as defined in
245 * include/linux/watchdog.h
246 */
247static int
248wdrtas_get_status(void)
249{
250 return 0; /* TODO */
251}
252
253/**
254 * wdrtas_get_boot_status - returns the reason for the last boot
255 *
256 * returns a bitmask of defines WDIOF_... as defined in
257 * include/linux/watchdog.h, indicating why the watchdog rebooted the system
258 */
259static int
260wdrtas_get_boot_status(void)
261{
262 return 0; /* TODO */
263}
264
265/*** watchdog API and operations stuff */
266
267/* wdrtas_write - called when watchdog device is written to
268 * @file: file structure
269 * @buf: user buffer with data
270 * @len: amount to data written
271 * @ppos: position in file
272 *
273 * returns the number of successfully processed characters, which is always
274 * the number of bytes passed to this function
275 *
276 * wdrtas_write processes all the data given to it and looks for the magic
277 * character 'V'. This character allows the watchdog device to be closed
278 * properly.
279 */
280static ssize_t
281wdrtas_write(struct file *file, const char __user *buf,
282 size_t len, loff_t *ppos)
283{
284 int i;
285 char c;
286
287 if (!len)
288 goto out;
289
290 if (!wdrtas_nowayout) {
291 wdrtas_expect_close = 0;
292 /* look for 'V' */
293 for (i = 0; i < len; i++) {
294 if (get_user(c, buf + i))
295 return -EFAULT;
296 /* allow to close device */
297 if (c == 'V')
298 wdrtas_expect_close = WDRTAS_MAGIC_CHAR;
299 }
300 }
301
302 wdrtas_timer_keepalive();
303
304out:
305 return len;
306}
307
308/**
309 * wdrtas_ioctl - ioctl function for the watchdog device
310 * @inode: inode structure
311 * @file: file structure
312 * @cmd: command for ioctl
313 * @arg: argument pointer
314 *
315 * returns 0 on success, <0 on failure
316 *
317 * wdrtas_ioctl implements the watchdog API ioctls
318 */
319static int
320wdrtas_ioctl(struct inode *inode, struct file *file,
321 unsigned int cmd, unsigned long arg)
322{
323 int __user *argp = (void *)arg;
324 int i;
325 static struct watchdog_info wdinfo = {
326 .options = WDRTAS_SUPPORTED_MASK,
327 .firmware_version = 0,
328 .identity = "wdrtas"
329 };
330
331 switch (cmd) {
332 case WDIOC_GETSUPPORT:
333 if (copy_to_user(argp, &wdinfo, sizeof(wdinfo)))
334 return -EFAULT;
335 return 0;
336
337 case WDIOC_GETSTATUS:
338 i = wdrtas_get_status();
339 return put_user(i, argp);
340
341 case WDIOC_GETBOOTSTATUS:
342 i = wdrtas_get_boot_status();
343 return put_user(i, argp);
344
345 case WDIOC_GETTEMP:
346 if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE)
347 return -EOPNOTSUPP;
348
349 i = wdrtas_get_temperature();
350 return put_user(i, argp);
351
352 case WDIOC_SETOPTIONS:
353 if (get_user(i, argp))
354 return -EFAULT;
355 if (i & WDIOS_DISABLECARD)
356 wdrtas_timer_stop();
357 if (i & WDIOS_ENABLECARD) {
358 wdrtas_timer_keepalive();
359 wdrtas_timer_start();
360 }
361 if (i & WDIOS_TEMPPANIC) {
362 /* not implemented. Done by H8 */
363 }
364 return 0;
365
366 case WDIOC_KEEPALIVE:
367 wdrtas_timer_keepalive();
368 return 0;
369
370 case WDIOC_SETTIMEOUT:
371 if (get_user(i, argp))
372 return -EFAULT;
373
374 if (wdrtas_set_interval(i))
375 return -EINVAL;
376
377 wdrtas_timer_keepalive();
378
379 if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE)
380 wdrtas_interval = i;
381 else
382 wdrtas_interval = wdrtas_get_interval(i);
383 /* fallthrough */
384
385 case WDIOC_GETTIMEOUT:
386 return put_user(wdrtas_interval, argp);
387
388 default:
389 return -ENOIOCTLCMD;
390 }
391}
392
393/**
394 * wdrtas_open - open function of watchdog device
395 * @inode: inode structure
396 * @file: file structure
397 *
398 * returns 0 on success, -EBUSY if the file has been opened already, <0 on
399 * other failures
400 *
401 * function called when watchdog device is opened
402 */
403static int
404wdrtas_open(struct inode *inode, struct file *file)
405{
406 /* only open once */
407 if (atomic_inc_return(&wdrtas_miscdev_open) > 1) {
408 atomic_dec(&wdrtas_miscdev_open);
409 return -EBUSY;
410 }
411
412 wdrtas_timer_start();
413 wdrtas_timer_keepalive();
414
415 return nonseekable_open(inode, file);
416}
417
418/**
419 * wdrtas_close - close function of watchdog device
420 * @inode: inode structure
421 * @file: file structure
422 *
423 * returns 0 on success
424 *
425 * close function. Always succeeds
426 */
427static int
428wdrtas_close(struct inode *inode, struct file *file)
429{
430 /* only stop watchdog, if this was announced using 'V' before */
431 if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR)
432 wdrtas_timer_stop();
433 else {
434 printk(KERN_WARNING "wdrtas: got unexpected close. Watchdog "
435 "not stopped.\n");
436 wdrtas_timer_keepalive();
437 }
438
439 wdrtas_expect_close = 0;
440 atomic_dec(&wdrtas_miscdev_open);
441 return 0;
442}
443
444/**
445 * wdrtas_temp_read - gives back the temperature in fahrenheit
446 * @file: file structure
447 * @buf: user buffer
448 * @count: number of bytes to be read
449 * @ppos: position in file
450 *
451 * returns always 1 or -EFAULT in case of user space copy failures, <0 on
452 * other failures
453 *
454 * wdrtas_temp_read gives the temperature to the users by copying this
455 * value as one byte into the user space buffer. The unit is Fahrenheit...
456 */
457static ssize_t
458wdrtas_temp_read(struct file *file, char __user *buf,
459 size_t count, loff_t *ppos)
460{
461 int temperature = 0;
462
463 temperature = wdrtas_get_temperature();
464 if (temperature < 0)
465 return temperature;
466
467 if (copy_to_user(buf, &temperature, 1))
468 return -EFAULT;
469
470 return 1;
471}
472
473/**
474 * wdrtas_temp_open - open function of temperature device
475 * @inode: inode structure
476 * @file: file structure
477 *
478 * returns 0 on success, <0 on failure
479 *
480 * function called when temperature device is opened
481 */
482static int
483wdrtas_temp_open(struct inode *inode, struct file *file)
484{
485 return nonseekable_open(inode, file);
486}
487
488/**
489 * wdrtas_temp_close - close function of temperature device
490 * @inode: inode structure
491 * @file: file structure
492 *
493 * returns 0 on success
494 *
495 * close function. Always succeeds
496 */
497static int
498wdrtas_temp_close(struct inode *inode, struct file *file)
499{
500 return 0;
501}
502
503/**
504 * wdrtas_reboot - reboot notifier function
505 * @nb: notifier block structure
506 * @code: reboot code
507 * @ptr: unused
508 *
509 * returns NOTIFY_DONE
510 *
511 * wdrtas_reboot stops the watchdog in case of a reboot
512 */
513static int
514wdrtas_reboot(struct notifier_block *this, unsigned long code, void *ptr)
515{
516 if ( (code==SYS_DOWN) || (code==SYS_HALT) )
517 wdrtas_timer_stop();
518
519 return NOTIFY_DONE;
520}
521
522/*** initialization stuff */
523
524static struct file_operations wdrtas_fops = {
525 .owner = THIS_MODULE,
526 .llseek = no_llseek,
527 .write = wdrtas_write,
528 .ioctl = wdrtas_ioctl,
529 .open = wdrtas_open,
530 .release = wdrtas_close,
531};
532
533static struct miscdevice wdrtas_miscdev = {
534 .minor = WATCHDOG_MINOR,
535 .name = "watchdog",
536 .fops = &wdrtas_fops,
537};
538
539static struct file_operations wdrtas_temp_fops = {
540 .owner = THIS_MODULE,
541 .llseek = no_llseek,
542 .read = wdrtas_temp_read,
543 .open = wdrtas_temp_open,
544 .release = wdrtas_temp_close,
545};
546
547static struct miscdevice wdrtas_tempdev = {
548 .minor = TEMP_MINOR,
549 .name = "temperature",
550 .fops = &wdrtas_temp_fops,
551};
552
553static struct notifier_block wdrtas_notifier = {
554 .notifier_call = wdrtas_reboot,
555};
556
557/**
558 * wdrtas_get_tokens - reads in RTAS tokens
559 *
560 * returns 0 on succes, <0 on failure
561 *
562 * wdrtas_get_tokens reads in the tokens for the RTAS calls used in
563 * this watchdog driver. It tolerates, if "get-sensor-state" and
564 * "ibm,get-system-parameter" are not available.
565 */
566static int
567wdrtas_get_tokens(void)
568{
569 wdrtas_token_get_sensor_state = rtas_token("get-sensor-state");
570 if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) {
571 printk(KERN_WARNING "wdrtas: couldn't get token for "
572 "get-sensor-state. Trying to continue without "
573 "temperature support.\n");
574 }
575
576 wdrtas_token_get_sp = rtas_token("ibm,get-system-parameter");
577 if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE) {
578 printk(KERN_WARNING "wdrtas: couldn't get token for "
579 "ibm,get-system-parameter. Trying to continue with "
580 "a default timeout value of %i seconds.\n",
581 WDRTAS_DEFAULT_INTERVAL);
582 }
583
584 wdrtas_token_set_indicator = rtas_token("set-indicator");
585 if (wdrtas_token_set_indicator == RTAS_UNKNOWN_SERVICE) {
586 printk(KERN_ERR "wdrtas: couldn't get token for "
587 "set-indicator. Terminating watchdog code.\n");
588 return -EIO;
589 }
590
591 wdrtas_token_event_scan = rtas_token("event-scan");
592 if (wdrtas_token_event_scan == RTAS_UNKNOWN_SERVICE) {
593 printk(KERN_ERR "wdrtas: couldn't get token for event-scan. "
594 "Terminating watchdog code.\n");
595 return -EIO;
596 }
597
598 return 0;
599}
600
601/**
602 * wdrtas_unregister_devs - unregisters the misc dev handlers
603 *
604 * wdrtas_register_devs unregisters the watchdog and temperature watchdog
605 * misc devs
606 */
607static void
608wdrtas_unregister_devs(void)
609{
610 misc_deregister(&wdrtas_miscdev);
611 if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE)
612 misc_deregister(&wdrtas_tempdev);
613}
614
615/**
616 * wdrtas_register_devs - registers the misc dev handlers
617 *
618 * returns 0 on succes, <0 on failure
619 *
620 * wdrtas_register_devs registers the watchdog and temperature watchdog
621 * misc devs
622 */
623static int
624wdrtas_register_devs(void)
625{
626 int result;
627
628 result = misc_register(&wdrtas_miscdev);
629 if (result) {
630 printk(KERN_ERR "wdrtas: couldn't register watchdog misc "
631 "device. Terminating watchdog code.\n");
632 return result;
633 }
634
635 if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) {
636 result = misc_register(&wdrtas_tempdev);
637 if (result) {
638 printk(KERN_WARNING "wdrtas: couldn't register "
639 "watchdog temperature misc device. Continuing "
640 "without temperature support.\n");
641 wdrtas_token_get_sensor_state = RTAS_UNKNOWN_SERVICE;
642 }
643 }
644
645 return 0;
646}
647
648/**
649 * wdrtas_init - init function of the watchdog driver
650 *
651 * returns 0 on succes, <0 on failure
652 *
653 * registers the file handlers and the reboot notifier
654 */
655static int __init
656wdrtas_init(void)
657{
658 if (wdrtas_get_tokens())
659 return -ENODEV;
660
661 if (wdrtas_register_devs())
662 return -ENODEV;
663
664 if (register_reboot_notifier(&wdrtas_notifier)) {
665 printk(KERN_ERR "wdrtas: could not register reboot notifier. "
666 "Terminating watchdog code.\n");
667 wdrtas_unregister_devs();
668 return -ENODEV;
669 }
670
671 if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE)
672 wdrtas_interval = WDRTAS_DEFAULT_INTERVAL;
673 else
674 wdrtas_interval = wdrtas_get_interval(WDRTAS_DEFAULT_INTERVAL);
675
676 return 0;
677}
678
679/**
680 * wdrtas_exit - exit function of the watchdog driver
681 *
682 * unregisters the file handlers and the reboot notifier
683 */
684static void __exit
685wdrtas_exit(void)
686{
687 if (!wdrtas_nowayout)
688 wdrtas_timer_stop();
689
690 wdrtas_unregister_devs();
691
692 unregister_reboot_notifier(&wdrtas_notifier);
693}
694
695module_init(wdrtas_init);
696module_exit(wdrtas_exit);
diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h
index 5d3cd9d042e2..553b2ea23bed 100644
--- a/include/asm-ppc64/machdep.h
+++ b/include/asm-ppc64/machdep.h
@@ -76,6 +76,7 @@ struct machdep_calls {
76 void (*tce_flush)(struct iommu_table *tbl); 76 void (*tce_flush)(struct iommu_table *tbl);
77 void (*iommu_dev_setup)(struct pci_dev *dev); 77 void (*iommu_dev_setup)(struct pci_dev *dev);
78 void (*iommu_bus_setup)(struct pci_bus *bus); 78 void (*iommu_bus_setup)(struct pci_bus *bus);
79 void (*irq_bus_setup)(struct pci_bus *bus);
79 80
80 int (*probe)(int platform); 81 int (*probe)(int platform);
81 void (*setup_arch)(void); 82 void (*setup_arch)(void);
diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h
index c78282a67d8e..9d03a98a4fa3 100644
--- a/include/asm-ppc64/mmu.h
+++ b/include/asm-ppc64/mmu.h
@@ -47,9 +47,10 @@
47#define SLB_VSID_KS ASM_CONST(0x0000000000000800) 47#define SLB_VSID_KS ASM_CONST(0x0000000000000800)
48#define SLB_VSID_KP ASM_CONST(0x0000000000000400) 48#define SLB_VSID_KP ASM_CONST(0x0000000000000400)
49#define SLB_VSID_N ASM_CONST(0x0000000000000200) /* no-execute */ 49#define SLB_VSID_N ASM_CONST(0x0000000000000200) /* no-execute */
50#define SLB_VSID_L ASM_CONST(0x0000000000000100) /* largepage 16M */ 50#define SLB_VSID_L ASM_CONST(0x0000000000000100) /* largepage */
51#define SLB_VSID_C ASM_CONST(0x0000000000000080) /* class */ 51#define SLB_VSID_C ASM_CONST(0x0000000000000080) /* class */
52 52#define SLB_VSID_LS ASM_CONST(0x0000000000000070) /* size of largepage */
53
53#define SLB_VSID_KERNEL (SLB_VSID_KP|SLB_VSID_C) 54#define SLB_VSID_KERNEL (SLB_VSID_KP|SLB_VSID_C)
54#define SLB_VSID_USER (SLB_VSID_KP|SLB_VSID_KS) 55#define SLB_VSID_USER (SLB_VSID_KP|SLB_VSID_KS)
55 56
diff --git a/include/asm-ppc64/nvram.h b/include/asm-ppc64/nvram.h
index 4e6dd370d936..dfaa21566c9a 100644
--- a/include/asm-ppc64/nvram.h
+++ b/include/asm-ppc64/nvram.h
@@ -70,6 +70,7 @@ extern struct nvram_partition *nvram_find_partition(int sig, const char *name);
70 70
71extern int pSeries_nvram_init(void); 71extern int pSeries_nvram_init(void);
72extern int pmac_nvram_init(void); 72extern int pmac_nvram_init(void);
73extern int bpa_nvram_init(void);
73 74
74/* PowerMac specific nvram stuffs */ 75/* PowerMac specific nvram stuffs */
75 76
diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
index 3084099086a8..af28aa55d8c1 100644
--- a/include/asm-ppc64/processor.h
+++ b/include/asm-ppc64/processor.h
@@ -138,8 +138,16 @@
138#define SPRN_NIADORM 0x3F3 /* Hardware Implementation Register 2 */ 138#define SPRN_NIADORM 0x3F3 /* Hardware Implementation Register 2 */
139#define SPRN_HID4 0x3F4 /* 970 HID4 */ 139#define SPRN_HID4 0x3F4 /* 970 HID4 */
140#define SPRN_HID5 0x3F6 /* 970 HID5 */ 140#define SPRN_HID5 0x3F6 /* 970 HID5 */
141#define SPRN_TSC 0x3FD /* Thread switch control */ 141#define SPRN_HID6 0x3F9 /* BE HID 6 */
142#define SPRN_TST 0x3FC /* Thread switch timeout */ 142#define HID6_LB (0x0F<<12) /* Concurrent Large Page Modes */
143#define HID6_DLP (1<<20) /* Disable all large page modes (4K only) */
144#define SPRN_TSCR 0x399 /* Thread switch control on BE */
145#define SPRN_TTR 0x39A /* Thread switch timeout on BE */
146#define TSCR_DEC_ENABLE 0x200000 /* Decrementer Interrupt */
147#define TSCR_EE_ENABLE 0x100000 /* External Interrupt */
148#define TSCR_EE_BOOST 0x080000 /* External Interrupt Boost */
149#define SPRN_TSC 0x3FD /* Thread switch control on others */
150#define SPRN_TST 0x3FC /* Thread switch timeout on others */
143#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ 151#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */
144#define SPRN_LR 0x008 /* Link Register */ 152#define SPRN_LR 0x008 /* Link Register */
145#define SPRN_PIR 0x3FF /* Processor Identification Register */ 153#define SPRN_PIR 0x3FF /* Processor Identification Register */
@@ -259,6 +267,7 @@
259#define PV_970FX 0x003C 267#define PV_970FX 0x003C
260#define PV_630 0x0040 268#define PV_630 0x0040
261#define PV_630p 0x0041 269#define PV_630p 0x0041
270#define PV_BE 0x0070
262 271
263/* Platforms supported by PPC64 */ 272/* Platforms supported by PPC64 */
264#define PLATFORM_PSERIES 0x0100 273#define PLATFORM_PSERIES 0x0100
@@ -267,6 +276,7 @@
267#define PLATFORM_LPAR 0x0001 276#define PLATFORM_LPAR 0x0001
268#define PLATFORM_POWERMAC 0x0400 277#define PLATFORM_POWERMAC 0x0400
269#define PLATFORM_MAPLE 0x0500 278#define PLATFORM_MAPLE 0x0500
279#define PLATFORM_BPA 0x1000
270 280
271/* Compatibility with drivers coming from PPC32 world */ 281/* Compatibility with drivers coming from PPC32 world */
272#define _machine (systemcfg->platform) 282#define _machine (systemcfg->platform)
@@ -278,6 +288,7 @@
278#define IC_INVALID 0 288#define IC_INVALID 0
279#define IC_OPEN_PIC 1 289#define IC_OPEN_PIC 1
280#define IC_PPC_XIC 2 290#define IC_PPC_XIC 2
291#define IC_BPA_IIC 3
281 292
282#define XGLUE(a,b) a##b 293#define XGLUE(a,b) a##b
283#define GLUE(a,b) XGLUE(a,b) 294#define GLUE(a,b) XGLUE(a,b)
diff --git a/include/asm-ppc64/rtas.h b/include/asm-ppc64/rtas.h
index a8ab0e9db84a..e7d1b5222802 100644
--- a/include/asm-ppc64/rtas.h
+++ b/include/asm-ppc64/rtas.h
@@ -186,8 +186,14 @@ extern int rtas_get_sensor(int sensor, int index, int *state);
186extern int rtas_get_power_level(int powerdomain, int *level); 186extern int rtas_get_power_level(int powerdomain, int *level);
187extern int rtas_set_power_level(int powerdomain, int level, int *setlevel); 187extern int rtas_set_power_level(int powerdomain, int level, int *setlevel);
188extern int rtas_set_indicator(int indicator, int index, int new_value); 188extern int rtas_set_indicator(int indicator, int index, int new_value);
189extern void rtas_progress(char *s, unsigned short hex);
189extern void rtas_initialize(void); 190extern void rtas_initialize(void);
190 191
192struct rtc_time;
193extern void rtas_get_boot_time(struct rtc_time *rtc_time);
194extern void rtas_get_rtc_time(struct rtc_time *rtc_time);
195extern int rtas_set_rtc_time(struct rtc_time *rtc_time);
196
191/* Given an RTAS status code of 9900..9905 compute the hinted delay */ 197/* Given an RTAS status code of 9900..9905 compute the hinted delay */
192unsigned int rtas_extended_busy_delay_time(int status); 198unsigned int rtas_extended_busy_delay_time(int status);
193static inline int rtas_is_extended_busy(int status) 199static inline int rtas_is_extended_busy(int status)
diff --git a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h
index 8115ecb8feee..d86f742e9a21 100644
--- a/include/asm-ppc64/smp.h
+++ b/include/asm-ppc64/smp.h
@@ -85,6 +85,14 @@ extern void smp_generic_take_timebase(void);
85 85
86extern struct smp_ops_t *smp_ops; 86extern struct smp_ops_t *smp_ops;
87 87
88#ifdef CONFIG_PPC_PSERIES
89void vpa_init(int cpu);
90#else
91static inline void vpa_init(int cpu)
92{
93}
94#endif /* CONFIG_PPC_PSERIES */
95
88#endif /* __ASSEMBLY__ */ 96#endif /* __ASSEMBLY__ */
89 97
90#endif /* !(_PPC64_SMP_H) */ 98#endif /* !(_PPC64_SMP_H) */
diff --git a/include/asm-ppc64/time.h b/include/asm-ppc64/time.h
index 8d6e3760ee10..c6c762cad8b0 100644
--- a/include/asm-ppc64/time.h
+++ b/include/asm-ppc64/time.h
@@ -34,6 +34,15 @@ struct rtc_time;
34extern void to_tm(int tim, struct rtc_time * tm); 34extern void to_tm(int tim, struct rtc_time * tm);
35extern time_t last_rtc_update; 35extern time_t last_rtc_update;
36 36
37void generic_calibrate_decr(void);
38void setup_default_decr(void);
39
40/* Some sane defaults: 125 MHz timebase, 1GHz processor */
41extern unsigned long ppc_proc_freq;
42#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8)
43extern unsigned long ppc_tb_freq;
44#define DEFAULT_TB_FREQ 125000000UL
45
37/* 46/*
38 * By putting all of this stuff into a single struct we 47 * By putting all of this stuff into a single struct we
39 * reduce the number of cache lines touched by do_gettimeofday. 48 * reduce the number of cache lines touched by do_gettimeofday.