aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/Kconfig13
-rw-r--r--arch/powerpc/Kconfig.debug1
-rw-r--r--arch/powerpc/boot/dts/mpc8641_hpcn.dts12
-rw-r--r--arch/powerpc/configs/g5_defconfig1
-rw-r--r--arch/powerpc/kernel/Makefile1
-rw-r--r--arch/powerpc/kernel/asm-offsets.c1
-rw-r--r--arch/powerpc/kernel/entry_32.S5
-rw-r--r--arch/powerpc/kernel/head_64.S11
-rw-r--r--arch/powerpc/kernel/irq.c10
-rw-r--r--arch/powerpc/kernel/misc_32.S25
-rw-r--r--arch/powerpc/kernel/process.c2
-rw-r--r--arch/powerpc/kernel/rio.c52
-rw-r--r--arch/powerpc/kernel/setup_32.c21
-rw-r--r--arch/powerpc/mm/mem.c30
-rw-r--r--arch/powerpc/platforms/86xx/Kconfig1
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c1
-rw-r--r--arch/powerpc/platforms/powermac/Makefile5
-rw-r--r--arch/powerpc/platforms/powermac/setup.c3
-rw-r--r--arch/powerpc/platforms/pseries/Makefile1
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-memory.c141
-rw-r--r--arch/powerpc/sysdev/fsl_rio.c711
-rw-r--r--arch/powerpc/sysdev/fsl_rio.h20
-rw-r--r--drivers/macintosh/Kconfig8
-rw-r--r--drivers/macintosh/Makefile5
-rw-r--r--drivers/macintosh/windfarm_lm75_sensor.c6
-rw-r--r--drivers/macintosh/windfarm_max6690_sensor.c20
-rw-r--r--drivers/macintosh/windfarm_pm121.c1040
-rw-r--r--drivers/macintosh/windfarm_smu_controls.c4
-rw-r--r--drivers/net/rionet.c16
-rw-r--r--drivers/rapidio/Kconfig8
-rw-r--r--drivers/rapidio/rio-access.c10
-rw-r--r--drivers/rapidio/rio-scan.c55
-rw-r--r--drivers/rapidio/rio-sysfs.c3
-rw-r--r--drivers/rapidio/rio.c2
-rw-r--r--drivers/rapidio/rio.h9
-rw-r--r--include/asm-powerpc/processor.h6
-rw-r--r--include/asm-powerpc/rio.h (renamed from include/asm-ppc/rio.h)0
-rw-r--r--include/asm-powerpc/system.h24
-rw-r--r--include/linux/lmb.h4
-rw-r--r--include/linux/rio.h38
-rw-r--r--lib/lmb.c99
41 files changed, 2037 insertions, 388 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 4e40c122bf26..3934e2659407 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -608,6 +608,19 @@ source "drivers/pcmcia/Kconfig"
608 608
609source "drivers/pci/hotplug/Kconfig" 609source "drivers/pci/hotplug/Kconfig"
610 610
611config HAS_RAPIDIO
612 bool
613 default n
614
615config RAPIDIO
616 bool "RapidIO support"
617 depends on HAS_RAPIDIO
618 help
619 If you say Y here, the kernel will include drivers and
620 infrastructure code to support RapidIO interconnect devices.
621
622source "drivers/rapidio/Kconfig"
623
611endmenu 624endmenu
612 625
613menu "Advanced setup" 626menu "Advanced setup"
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 807a2dce6263..a7d24e692bab 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -118,7 +118,6 @@ config XMON_DISASSEMBLY
118 118
119config IRQSTACKS 119config IRQSTACKS
120 bool "Use separate kernel stacks when processing interrupts" 120 bool "Use separate kernel stacks when processing interrupts"
121 depends on PPC64
122 help 121 help
123 If you say Y here the kernel will use separate kernel stacks 122 If you say Y here the kernel will use separate kernel stacks
124 for handling hard and soft interrupts. This can help avoid 123 for handling hard and soft interrupts. This can help avoid
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index 7f9b999843ce..1e4bfe9cadb9 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -26,6 +26,7 @@
26 serial1 = &serial1; 26 serial1 = &serial1;
27 pci0 = &pci0; 27 pci0 = &pci0;
28 pci1 = &pci1; 28 pci1 = &pci1;
29 rapidio0 = &rapidio0;
29 }; 30 };
30 31
31 cpus { 32 cpus {
@@ -500,4 +501,15 @@
500 0x0 0x00100000>; 501 0x0 0x00100000>;
501 }; 502 };
502 }; 503 };
504 rapidio0: rapidio@f80c0000 {
505 #address-cells = <2>;
506 #size-cells = <2>;
507 compatible = "fsl,rapidio-delta";
508 reg = <0xf80c0000 0x20000>;
509 ranges = <0 0 0xc0000000 0 0x20000000>;
510 interrupt-parent = <&mpic>;
511 /* err_irq bell_outb_irq bell_inb_irq
512 msg1_tx_irq msg1_rx_irq msg2_tx_irq msg2_rx_irq */
513 interrupts = <48 2 49 2 50 2 53 2 54 2 55 2 56 2>;
514 };
503}; 515};
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig
index a20501f89474..88338a9f5e95 100644
--- a/arch/powerpc/configs/g5_defconfig
+++ b/arch/powerpc/configs/g5_defconfig
@@ -696,6 +696,7 @@ CONFIG_WINDFARM=y
696CONFIG_WINDFARM_PM81=y 696CONFIG_WINDFARM_PM81=y
697CONFIG_WINDFARM_PM91=y 697CONFIG_WINDFARM_PM91=y
698CONFIG_WINDFARM_PM112=y 698CONFIG_WINDFARM_PM112=y
699CONFIG_WINDFARM_PM121=y
699# CONFIG_PMAC_RACKMETER is not set 700# CONFIG_PMAC_RACKMETER is not set
700CONFIG_NETDEVICES=y 701CONFIG_NETDEVICES=y
701# CONFIG_NETDEVICES_MULTIQUEUE is not set 702# CONFIG_NETDEVICES_MULTIQUEUE is not set
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 9177b21b1a95..d14cebf62bb0 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -73,7 +73,6 @@ pci64-$(CONFIG_PPC64) += pci_dn.o isa-bridge.o
73obj-$(CONFIG_PCI) += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \ 73obj-$(CONFIG_PCI) += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
74 pci-common.o 74 pci-common.o
75obj-$(CONFIG_PCI_MSI) += msi.o 75obj-$(CONFIG_PCI_MSI) += msi.o
76obj-$(CONFIG_RAPIDIO) += rio.o
77obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o \ 76obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o \
78 machine_kexec_$(CONFIG_WORD_SIZE).o 77 machine_kexec_$(CONFIG_WORD_SIZE).o
79obj-$(CONFIG_AUDIT) += audit.o 78obj-$(CONFIG_AUDIT) += audit.o
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 59044e7ed6f4..ec9228d687b0 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -63,6 +63,7 @@ int main(void)
63#endif /* CONFIG_PPC64 */ 63#endif /* CONFIG_PPC64 */
64 64
65 DEFINE(KSP, offsetof(struct thread_struct, ksp)); 65 DEFINE(KSP, offsetof(struct thread_struct, ksp));
66 DEFINE(KSP_LIMIT, offsetof(struct thread_struct, ksp_limit));
66 DEFINE(PT_REGS, offsetof(struct thread_struct, regs)); 67 DEFINE(PT_REGS, offsetof(struct thread_struct, regs));
67 DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode)); 68 DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode));
68 DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0])); 69 DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 84c868633068..0c8614d9875c 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -137,11 +137,12 @@ transfer_to_handler:
1372: /* if from kernel, check interrupted DOZE/NAP mode and 1372: /* if from kernel, check interrupted DOZE/NAP mode and
138 * check for stack overflow 138 * check for stack overflow
139 */ 139 */
140 lwz r9,THREAD_INFO-THREAD(r12) 140 lwz r9,KSP_LIMIT(r12)
141 cmplw r1,r9 /* if r1 <= current->thread_info */ 141 cmplw r1,r9 /* if r1 <= ksp_limit */
142 ble- stack_ovf /* then the kernel stack overflowed */ 142 ble- stack_ovf /* then the kernel stack overflowed */
1435: 1435:
144#ifdef CONFIG_6xx 144#ifdef CONFIG_6xx
145 rlwinm r9,r1,0,0,31-THREAD_SHIFT
145 tophys(r9,r9) /* check local flags */ 146 tophys(r9,r9) /* check local flags */
146 lwz r12,TI_LOCAL_FLAGS(r9) 147 lwz r12,TI_LOCAL_FLAGS(r9)
147 mtcrf 0x01,r12 148 mtcrf 0x01,r12
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 215973a2c8d5..024805e1747d 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -239,6 +239,10 @@ instruction_access_slb_pSeries:
239 .globl system_call_pSeries 239 .globl system_call_pSeries
240system_call_pSeries: 240system_call_pSeries:
241 HMT_MEDIUM 241 HMT_MEDIUM
242BEGIN_FTR_SECTION
243 cmpdi r0,0x1ebe
244 beq- 1f
245END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
242 mr r9,r13 246 mr r9,r13
243 mfmsr r10 247 mfmsr r10
244 mfspr r13,SPRN_SPRG3 248 mfspr r13,SPRN_SPRG3
@@ -253,6 +257,13 @@ system_call_pSeries:
253 rfid 257 rfid
254 b . /* prevent speculative execution */ 258 b . /* prevent speculative execution */
255 259
260/* Fast LE/BE switch system call */
2611: mfspr r12,SPRN_SRR1
262 xori r12,r12,MSR_LE
263 mtspr SPRN_SRR1,r12
264 rfid /* return to userspace */
265 b .
266
256 STD_EXCEPTION_PSERIES(0xd00, single_step) 267 STD_EXCEPTION_PSERIES(0xd00, single_step)
257 STD_EXCEPTION_PSERIES(0xe00, trap_0e) 268 STD_EXCEPTION_PSERIES(0xe00, trap_0e)
258 269
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 425616f92d18..2f73f705d564 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -307,6 +307,7 @@ void do_IRQ(struct pt_regs *regs)
307 if (curtp != irqtp) { 307 if (curtp != irqtp) {
308 struct irq_desc *desc = irq_desc + irq; 308 struct irq_desc *desc = irq_desc + irq;
309 void *handler = desc->handle_irq; 309 void *handler = desc->handle_irq;
310 unsigned long saved_sp_limit = current->thread.ksp_limit;
310 if (handler == NULL) 311 if (handler == NULL)
311 handler = &__do_IRQ; 312 handler = &__do_IRQ;
312 irqtp->task = curtp->task; 313 irqtp->task = curtp->task;
@@ -319,7 +320,10 @@ void do_IRQ(struct pt_regs *regs)
319 (irqtp->preempt_count & ~SOFTIRQ_MASK) | 320 (irqtp->preempt_count & ~SOFTIRQ_MASK) |
320 (curtp->preempt_count & SOFTIRQ_MASK); 321 (curtp->preempt_count & SOFTIRQ_MASK);
321 322
323 current->thread.ksp_limit = (unsigned long)irqtp +
324 _ALIGN_UP(sizeof(struct thread_info), 16);
322 call_handle_irq(irq, desc, irqtp, handler); 325 call_handle_irq(irq, desc, irqtp, handler);
326 current->thread.ksp_limit = saved_sp_limit;
323 irqtp->task = NULL; 327 irqtp->task = NULL;
324 328
325 329
@@ -352,9 +356,7 @@ void __init init_IRQ(void)
352{ 356{
353 if (ppc_md.init_IRQ) 357 if (ppc_md.init_IRQ)
354 ppc_md.init_IRQ(); 358 ppc_md.init_IRQ();
355#ifdef CONFIG_PPC64
356 irq_ctx_init(); 359 irq_ctx_init();
357#endif
358} 360}
359 361
360 362
@@ -383,11 +385,15 @@ void irq_ctx_init(void)
383static inline void do_softirq_onstack(void) 385static inline void do_softirq_onstack(void)
384{ 386{
385 struct thread_info *curtp, *irqtp; 387 struct thread_info *curtp, *irqtp;
388 unsigned long saved_sp_limit = current->thread.ksp_limit;
386 389
387 curtp = current_thread_info(); 390 curtp = current_thread_info();
388 irqtp = softirq_ctx[smp_processor_id()]; 391 irqtp = softirq_ctx[smp_processor_id()];
389 irqtp->task = curtp->task; 392 irqtp->task = curtp->task;
393 current->thread.ksp_limit = (unsigned long)irqtp +
394 _ALIGN_UP(sizeof(struct thread_info), 16);
390 call_do_softirq(irqtp); 395 call_do_softirq(irqtp);
396 current->thread.ksp_limit = saved_sp_limit;
391 irqtp->task = NULL; 397 irqtp->task = NULL;
392} 398}
393 399
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 92ccc6fcc5b0..89aaaa6f3561 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -32,6 +32,31 @@
32 32
33 .text 33 .text
34 34
35#ifdef CONFIG_IRQSTACKS
36_GLOBAL(call_do_softirq)
37 mflr r0
38 stw r0,4(r1)
39 stwu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r3)
40 mr r1,r3
41 bl __do_softirq
42 lwz r1,0(r1)
43 lwz r0,4(r1)
44 mtlr r0
45 blr
46
47_GLOBAL(call_handle_irq)
48 mflr r0
49 stw r0,4(r1)
50 mtctr r6
51 stwu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r5)
52 mr r1,r5
53 bctrl
54 lwz r1,0(r1)
55 lwz r0,4(r1)
56 mtlr r0
57 blr
58#endif /* CONFIG_IRQSTACKS */
59
35/* 60/*
36 * This returns the high 64 bits of the product of two 64-bit numbers. 61 * This returns the high 64 bits of the product of two 64-bit numbers.
37 */ 62 */
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 6caad17ea72e..7de41c3948ec 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -589,6 +589,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
589 kregs = (struct pt_regs *) sp; 589 kregs = (struct pt_regs *) sp;
590 sp -= STACK_FRAME_OVERHEAD; 590 sp -= STACK_FRAME_OVERHEAD;
591 p->thread.ksp = sp; 591 p->thread.ksp = sp;
592 p->thread.ksp_limit = (unsigned long)task_stack_page(p) +
593 _ALIGN_UP(sizeof(struct thread_info), 16);
592 594
593#ifdef CONFIG_PPC64 595#ifdef CONFIG_PPC64
594 if (cpu_has_feature(CPU_FTR_SLB)) { 596 if (cpu_has_feature(CPU_FTR_SLB)) {
diff --git a/arch/powerpc/kernel/rio.c b/arch/powerpc/kernel/rio.c
deleted file mode 100644
index 29487fedfc76..000000000000
--- a/arch/powerpc/kernel/rio.c
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 * RapidIO PPC32 support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/rio.h>
16
17#include <asm/rio.h>
18
19/**
20 * platform_rio_init - Do platform specific RIO init
21 *
22 * Any platform specific initialization of RapdIO
23 * hardware is done here as well as registration
24 * of any active master ports in the system.
25 */
26void __attribute__ ((weak))
27 platform_rio_init(void)
28{
29 printk(KERN_WARNING "RIO: No platform_rio_init() present\n");
30}
31
32/**
33 * ppc_rio_init - Do PPC32 RIO init
34 *
35 * Calls platform-specific RIO init code and then calls
36 * rio_init_mports() to initialize any master ports that
37 * have been registered with the RIO subsystem.
38 */
39static int __init ppc_rio_init(void)
40{
41 printk(KERN_INFO "RIO: RapidIO init\n");
42
43 /* Platform specific initialization */
44 platform_rio_init();
45
46 /* Enumerate all registered ports */
47 rio_init_mports();
48
49 return 0;
50}
51
52subsys_initcall(ppc_rio_init);
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 36f6779c88d4..5112a4aa801d 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -16,6 +16,7 @@
16#include <linux/root_dev.h> 16#include <linux/root_dev.h>
17#include <linux/cpu.h> 17#include <linux/cpu.h>
18#include <linux/console.h> 18#include <linux/console.h>
19#include <linux/lmb.h>
19 20
20#include <asm/io.h> 21#include <asm/io.h>
21#include <asm/prom.h> 22#include <asm/prom.h>
@@ -229,6 +230,24 @@ int __init ppc_init(void)
229 230
230arch_initcall(ppc_init); 231arch_initcall(ppc_init);
231 232
233#ifdef CONFIG_IRQSTACKS
234static void __init irqstack_early_init(void)
235{
236 unsigned int i;
237
238 /* interrupt stacks must be in lowmem, we get that for free on ppc32
239 * as the lmb is limited to lowmem by LMB_REAL_LIMIT */
240 for_each_possible_cpu(i) {
241 softirq_ctx[i] = (struct thread_info *)
242 __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
243 hardirq_ctx[i] = (struct thread_info *)
244 __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
245 }
246}
247#else
248#define irqstack_early_init()
249#endif
250
232/* Warning, IO base is not yet inited */ 251/* Warning, IO base is not yet inited */
233void __init setup_arch(char **cmdline_p) 252void __init setup_arch(char **cmdline_p)
234{ 253{
@@ -286,6 +305,8 @@ void __init setup_arch(char **cmdline_p)
286 init_mm.end_data = (unsigned long) _edata; 305 init_mm.end_data = (unsigned long) _edata;
287 init_mm.brk = klimit; 306 init_mm.brk = klimit;
288 307
308 irqstack_early_init();
309
289 /* set up the bootmem stuff with available memory */ 310 /* set up the bootmem stuff with available memory */
290 do_init_bootmem(); 311 do_init_bootmem();
291 if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); 312 if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index d9e37f365b54..f67e118116fa 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -154,19 +154,35 @@ out:
154 154
155/* 155/*
156 * walk_memory_resource() needs to make sure there is no holes in a given 156 * walk_memory_resource() needs to make sure there is no holes in a given
157 * memory range. On PPC64, since this range comes from /sysfs, the range 157 * memory range. PPC64 does not maintain the memory layout in /proc/iomem.
158 * is guaranteed to be valid, non-overlapping and can not contain any 158 * Instead it maintains it in lmb.memory structures. Walk through the
159 * holes. By the time we get here (memory add or remove), /proc/device-tree 159 * memory regions, find holes and callback for contiguous regions.
160 * is updated and correct. Only reason we need to check against device-tree
161 * would be if we allow user-land to specify a memory range through a
162 * system call/ioctl etc. instead of doing offline/online through /sysfs.
163 */ 160 */
164int 161int
165walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg, 162walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg,
166 int (*func)(unsigned long, unsigned long, void *)) 163 int (*func)(unsigned long, unsigned long, void *))
167{ 164{
168 return (*func)(start_pfn, nr_pages, arg); 165 struct lmb_property res;
166 unsigned long pfn, len;
167 u64 end;
168 int ret = -1;
169
170 res.base = (u64) start_pfn << PAGE_SHIFT;
171 res.size = (u64) nr_pages << PAGE_SHIFT;
172
173 end = res.base + res.size - 1;
174 while ((res.base < end) && (lmb_find(&res) >= 0)) {
175 pfn = (unsigned long)(res.base >> PAGE_SHIFT);
176 len = (unsigned long)(res.size >> PAGE_SHIFT);
177 ret = (*func)(pfn, len, arg);
178 if (ret)
179 break;
180 res.base += (res.size + 1);
181 res.size = (end - res.base + 1);
182 }
183 return ret;
169} 184}
185EXPORT_SYMBOL_GPL(walk_memory_resource);
170 186
171#endif /* CONFIG_MEMORY_HOTPLUG */ 187#endif /* CONFIG_MEMORY_HOTPLUG */
172 188
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index 7442c58d44f5..053f49a1dcae 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -8,6 +8,7 @@ config MPC8641_HPCN
8 select PPC_I8259 8 select PPC_I8259
9 select DEFAULT_UIMAGE 9 select DEFAULT_UIMAGE
10 select FSL_ULI1575 10 select FSL_ULI1575
11 select HAS_RAPIDIO
11 help 12 help
12 This option enables support for the MPC8641 HPCN board. 13 This option enables support for the MPC8641 HPCN board.
13 14
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index f947f555fd46..f13704aabbea 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -221,6 +221,7 @@ mpc86xx_time_init(void)
221 221
222static __initdata struct of_device_id of_bus_ids[] = { 222static __initdata struct of_device_id of_bus_ids[] = {
223 { .compatible = "simple-bus", }, 223 { .compatible = "simple-bus", },
224 { .compatible = "fsl,rapidio-delta", },
224 {}, 225 {},
225}; 226};
226 227
diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
index 78093d7f97af..4d72c8f72159 100644
--- a/arch/powerpc/platforms/powermac/Makefile
+++ b/arch/powerpc/platforms/powermac/Makefile
@@ -6,7 +6,10 @@ obj-y += pic.o setup.o time.o feature.o pci.o \
6obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o 6obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o
7obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o 7obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o
8obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o 8obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o
9obj-$(CONFIG_NVRAM) += nvram.o 9# CONFIG_NVRAM is an arch. independant tristate symbol, for pmac32 we really
10# need this to be a bool. Cheat here and pretend CONFIG_NVRAM=m is really
11# CONFIG_NVRAM=y
12obj-$(CONFIG_NVRAM:m=y) += nvram.o
10# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff 13# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff
11obj-$(CONFIG_PPC64) += nvram.o 14obj-$(CONFIG_PPC64) += nvram.o
12obj-$(CONFIG_PPC32) += bootx_init.o 15obj-$(CONFIG_PPC32) += bootx_init.o
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index bf44c5441a36..00bd0166d07f 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -337,7 +337,8 @@ static void __init pmac_setup_arch(void)
337 find_via_pmu(); 337 find_via_pmu();
338 smu_init(); 338 smu_init();
339 339
340#if defined(CONFIG_NVRAM) || defined(CONFIG_PPC64) 340#if defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE) || \
341 defined(CONFIG_PPC64)
341 pmac_nvram_init(); 342 pmac_nvram_init();
342#endif 343#endif
343 344
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index bd2593ed28dd..554c6e42ef2a 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_PCI) += pci.o pci_dlpar.o
18obj-$(CONFIG_PCI_MSI) += msi.o 18obj-$(CONFIG_PCI_MSI) += msi.o
19 19
20obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o 20obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o
21obj-$(CONFIG_MEMORY_HOTPLUG) += hotplug-memory.o
21 22
22obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o 23obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
23obj-$(CONFIG_HVCS) += hvcserver.o 24obj-$(CONFIG_HVCS) += hvcserver.o
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
new file mode 100644
index 000000000000..3c5727dd5aa5
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -0,0 +1,141 @@
1/*
2 * pseries Memory Hotplug infrastructure.
3 *
4 * Copyright (C) 2008 Badari Pulavarty, IBM Corporation
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/of.h>
13#include <linux/lmb.h>
14#include <asm/firmware.h>
15#include <asm/machdep.h>
16#include <asm/pSeries_reconfig.h>
17
18static int pseries_remove_memory(struct device_node *np)
19{
20 const char *type;
21 const unsigned int *my_index;
22 const unsigned int *regs;
23 u64 start_pfn, start;
24 struct zone *zone;
25 int ret = -EINVAL;
26
27 /*
28 * Check to see if we are actually removing memory
29 */
30 type = of_get_property(np, "device_type", NULL);
31 if (type == NULL || strcmp(type, "memory") != 0)
32 return 0;
33
34 /*
35 * Find the memory index and size of the removing section
36 */
37 my_index = of_get_property(np, "ibm,my-drc-index", NULL);
38 if (!my_index)
39 return ret;
40
41 regs = of_get_property(np, "reg", NULL);
42 if (!regs)
43 return ret;
44
45 start_pfn = section_nr_to_pfn(*my_index & 0xffff);
46 zone = page_zone(pfn_to_page(start_pfn));
47
48 /*
49 * Remove section mappings and sysfs entries for the
50 * section of the memory we are removing.
51 *
52 * NOTE: Ideally, this should be done in generic code like
53 * remove_memory(). But remove_memory() gets called by writing
54 * to sysfs "state" file and we can't remove sysfs entries
55 * while writing to it. So we have to defer it to here.
56 */
57 ret = __remove_pages(zone, start_pfn, regs[3] >> PAGE_SHIFT);
58 if (ret)
59 return ret;
60
61 /*
62 * Update memory regions for memory remove
63 */
64 lmb_remove(start_pfn << PAGE_SHIFT, regs[3]);
65
66 /*
67 * Remove htab bolted mappings for this section of memory
68 */
69 start = (unsigned long)__va(start_pfn << PAGE_SHIFT);
70 ret = remove_section_mapping(start, start + regs[3]);
71 return ret;
72}
73
74static int pseries_add_memory(struct device_node *np)
75{
76 const char *type;
77 const unsigned int *my_index;
78 const unsigned int *regs;
79 u64 start_pfn;
80 int ret = -EINVAL;
81
82 /*
83 * Check to see if we are actually adding memory
84 */
85 type = of_get_property(np, "device_type", NULL);
86 if (type == NULL || strcmp(type, "memory") != 0)
87 return 0;
88
89 /*
90 * Find the memory index and size of the added section
91 */
92 my_index = of_get_property(np, "ibm,my-drc-index", NULL);
93 if (!my_index)
94 return ret;
95
96 regs = of_get_property(np, "reg", NULL);
97 if (!regs)
98 return ret;
99
100 start_pfn = section_nr_to_pfn(*my_index & 0xffff);
101
102 /*
103 * Update memory region to represent the memory add
104 */
105 lmb_add(start_pfn << PAGE_SHIFT, regs[3]);
106 return 0;
107}
108
109static int pseries_memory_notifier(struct notifier_block *nb,
110 unsigned long action, void *node)
111{
112 int err = NOTIFY_OK;
113
114 switch (action) {
115 case PSERIES_RECONFIG_ADD:
116 if (pseries_add_memory(node))
117 err = NOTIFY_BAD;
118 break;
119 case PSERIES_RECONFIG_REMOVE:
120 if (pseries_remove_memory(node))
121 err = NOTIFY_BAD;
122 break;
123 default:
124 err = NOTIFY_DONE;
125 break;
126 }
127 return err;
128}
129
130static struct notifier_block pseries_mem_nb = {
131 .notifier_call = pseries_memory_notifier,
132};
133
134static int __init pseries_memory_hotplug_init(void)
135{
136 if (firmware_has_feature(FW_FEATURE_LPAR))
137 pSeries_reconfig_notifier_register(&pseries_mem_nb);
138
139 return 0;
140}
141machine_device_initcall(pseries, pseries_memory_hotplug_init);
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index af2425e4655f..3d920376f58e 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1,5 +1,8 @@
1/* 1/*
2 * MPC85xx RapidIO support 2 * Freescale MPC85xx/MPC86xx RapidIO support
3 *
4 * Copyright (C) 2007, 2008 Freescale Semiconductor, Inc.
5 * Zhang Wei <wei.zhang@freescale.com>
3 * 6 *
4 * Copyright 2005 MontaVista Software, Inc. 7 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org> 8 * Matt Porter <mporter@kernel.crashing.org>
@@ -17,12 +20,23 @@
17#include <linux/interrupt.h> 20#include <linux/interrupt.h>
18#include <linux/rio.h> 21#include <linux/rio.h>
19#include <linux/rio_drv.h> 22#include <linux/rio_drv.h>
23#include <linux/of_platform.h>
24#include <linux/delay.h>
20 25
21#include <asm/io.h> 26#include <asm/io.h>
22 27
23#define RIO_REGS_BASE (CCSRBAR + 0xc0000) 28/* RapidIO definition irq, which read from OF-tree */
29#define IRQ_RIO_BELL(m) (((struct rio_priv *)(m->priv))->bellirq)
30#define IRQ_RIO_TX(m) (((struct rio_priv *)(m->priv))->txirq)
31#define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq)
32
24#define RIO_ATMU_REGS_OFFSET 0x10c00 33#define RIO_ATMU_REGS_OFFSET 0x10c00
25#define RIO_MSG_REGS_OFFSET 0x11000 34#define RIO_P_MSG_REGS_OFFSET 0x11000
35#define RIO_S_MSG_REGS_OFFSET 0x13000
36#define RIO_ESCSR 0x158
37#define RIO_CCSR 0x15c
38#define RIO_ISR_AACR 0x10120
39#define RIO_ISR_AACR_AA 0x1 /* Accept All ID */
26#define RIO_MAINT_WIN_SIZE 0x400000 40#define RIO_MAINT_WIN_SIZE 0x400000
27#define RIO_DBELL_WIN_SIZE 0x1000 41#define RIO_DBELL_WIN_SIZE 0x1000
28 42
@@ -50,18 +64,18 @@
50#define DOORBELL_DSR_TE 0x00000080 64#define DOORBELL_DSR_TE 0x00000080
51#define DOORBELL_DSR_QFI 0x00000010 65#define DOORBELL_DSR_QFI 0x00000010
52#define DOORBELL_DSR_DIQI 0x00000001 66#define DOORBELL_DSR_DIQI 0x00000001
53#define DOORBELL_TID_OFFSET 0x03 67#define DOORBELL_TID_OFFSET 0x02
54#define DOORBELL_SID_OFFSET 0x05 68#define DOORBELL_SID_OFFSET 0x04
55#define DOORBELL_INFO_OFFSET 0x06 69#define DOORBELL_INFO_OFFSET 0x06
56 70
57#define DOORBELL_MESSAGE_SIZE 0x08 71#define DOORBELL_MESSAGE_SIZE 0x08
58#define DBELL_SID(x) (*(u8 *)(x + DOORBELL_SID_OFFSET)) 72#define DBELL_SID(x) (*(u16 *)(x + DOORBELL_SID_OFFSET))
59#define DBELL_TID(x) (*(u8 *)(x + DOORBELL_TID_OFFSET)) 73#define DBELL_TID(x) (*(u16 *)(x + DOORBELL_TID_OFFSET))
60#define DBELL_INF(x) (*(u16 *)(x + DOORBELL_INFO_OFFSET)) 74#define DBELL_INF(x) (*(u16 *)(x + DOORBELL_INFO_OFFSET))
61 75
62struct rio_atmu_regs { 76struct rio_atmu_regs {
63 u32 rowtar; 77 u32 rowtar;
64 u32 pad1; 78 u32 rowtear;
65 u32 rowbar; 79 u32 rowbar;
66 u32 pad2; 80 u32 pad2;
67 u32 rowar; 81 u32 rowar;
@@ -87,7 +101,15 @@ struct rio_msg_regs {
87 u32 ifqdpar; 101 u32 ifqdpar;
88 u32 pad6; 102 u32 pad6;
89 u32 ifqepar; 103 u32 ifqepar;
90 u32 pad7[250]; 104 u32 pad7[226];
105 u32 odmr;
106 u32 odsr;
107 u32 res0[4];
108 u32 oddpr;
109 u32 oddatr;
110 u32 res1[3];
111 u32 odretcr;
112 u32 res2[12];
91 u32 dmr; 113 u32 dmr;
92 u32 dsr; 114 u32 dsr;
93 u32 pad8; 115 u32 pad8;
@@ -112,20 +134,12 @@ struct rio_tx_desc {
112 u32 res4; 134 u32 res4;
113}; 135};
114 136
115static u32 regs_win; 137struct rio_dbell_ring {
116static struct rio_atmu_regs *atmu_regs;
117static struct rio_atmu_regs *maint_atmu_regs;
118static struct rio_atmu_regs *dbell_atmu_regs;
119static u32 dbell_win;
120static u32 maint_win;
121static struct rio_msg_regs *msg_regs;
122
123static struct rio_dbell_ring {
124 void *virt; 138 void *virt;
125 dma_addr_t phys; 139 dma_addr_t phys;
126} dbell_ring; 140};
127 141
128static struct rio_msg_tx_ring { 142struct rio_msg_tx_ring {
129 void *virt; 143 void *virt;
130 dma_addr_t phys; 144 dma_addr_t phys;
131 void *virt_buffer[RIO_MAX_TX_RING_SIZE]; 145 void *virt_buffer[RIO_MAX_TX_RING_SIZE];
@@ -133,19 +147,35 @@ static struct rio_msg_tx_ring {
133 int tx_slot; 147 int tx_slot;
134 int size; 148 int size;
135 void *dev_id; 149 void *dev_id;
136} msg_tx_ring; 150};
137 151
138static struct rio_msg_rx_ring { 152struct rio_msg_rx_ring {
139 void *virt; 153 void *virt;
140 dma_addr_t phys; 154 dma_addr_t phys;
141 void *virt_buffer[RIO_MAX_RX_RING_SIZE]; 155 void *virt_buffer[RIO_MAX_RX_RING_SIZE];
142 int rx_slot; 156 int rx_slot;
143 int size; 157 int size;
144 void *dev_id; 158 void *dev_id;
145} msg_rx_ring; 159};
160
161struct rio_priv {
162 void __iomem *regs_win;
163 struct rio_atmu_regs __iomem *atmu_regs;
164 struct rio_atmu_regs __iomem *maint_atmu_regs;
165 struct rio_atmu_regs __iomem *dbell_atmu_regs;
166 void __iomem *dbell_win;
167 void __iomem *maint_win;
168 struct rio_msg_regs __iomem *msg_regs;
169 struct rio_dbell_ring dbell_ring;
170 struct rio_msg_tx_ring msg_tx_ring;
171 struct rio_msg_rx_ring msg_rx_ring;
172 int bellirq;
173 int txirq;
174 int rxirq;
175};
146 176
147/** 177/**
148 * mpc85xx_rio_doorbell_send - Send a MPC85xx doorbell message 178 * fsl_rio_doorbell_send - Send a MPC85xx doorbell message
149 * @index: ID of RapidIO interface 179 * @index: ID of RapidIO interface
150 * @destid: Destination ID of target device 180 * @destid: Destination ID of target device
151 * @data: 16-bit info field of RapidIO doorbell message 181 * @data: 16-bit info field of RapidIO doorbell message
@@ -153,18 +183,34 @@ static struct rio_msg_rx_ring {
153 * Sends a MPC85xx doorbell message. Returns %0 on success or 183 * Sends a MPC85xx doorbell message. Returns %0 on success or
154 * %-EINVAL on failure. 184 * %-EINVAL on failure.
155 */ 185 */
156static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data) 186static int fsl_rio_doorbell_send(struct rio_mport *mport,
187 int index, u16 destid, u16 data)
157{ 188{
158 pr_debug("mpc85xx_doorbell_send: index %d destid %4.4x data %4.4x\n", 189 struct rio_priv *priv = mport->priv;
190 pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n",
159 index, destid, data); 191 index, destid, data);
160 out_be32((void *)&dbell_atmu_regs->rowtar, destid << 22); 192 switch (mport->phy_type) {
161 out_be16((void *)(dbell_win), data); 193 case RIO_PHY_PARALLEL:
194 out_be32(&priv->dbell_atmu_regs->rowtar, destid << 22);
195 out_be16(priv->dbell_win, data);
196 break;
197 case RIO_PHY_SERIAL:
198 /* In the serial version silicons, such as MPC8548, MPC8641,
199 * below operations is must be.
200 */
201 out_be32(&priv->msg_regs->odmr, 0x00000000);
202 out_be32(&priv->msg_regs->odretcr, 0x00000004);
203 out_be32(&priv->msg_regs->oddpr, destid << 16);
204 out_be32(&priv->msg_regs->oddatr, data);
205 out_be32(&priv->msg_regs->odmr, 0x00000001);
206 break;
207 }
162 208
163 return 0; 209 return 0;
164} 210}
165 211
166/** 212/**
167 * mpc85xx_local_config_read - Generate a MPC85xx local config space read 213 * fsl_local_config_read - Generate a MPC85xx local config space read
168 * @index: ID of RapdiIO interface 214 * @index: ID of RapdiIO interface
169 * @offset: Offset into configuration space 215 * @offset: Offset into configuration space
170 * @len: Length (in bytes) of the maintenance transaction 216 * @len: Length (in bytes) of the maintenance transaction
@@ -173,17 +219,19 @@ static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data)
173 * Generates a MPC85xx local configuration space read. Returns %0 on 219 * Generates a MPC85xx local configuration space read. Returns %0 on
174 * success or %-EINVAL on failure. 220 * success or %-EINVAL on failure.
175 */ 221 */
176static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data) 222static int fsl_local_config_read(struct rio_mport *mport,
223 int index, u32 offset, int len, u32 *data)
177{ 224{
178 pr_debug("mpc85xx_local_config_read: index %d offset %8.8x\n", index, 225 struct rio_priv *priv = mport->priv;
226 pr_debug("fsl_local_config_read: index %d offset %8.8x\n", index,
179 offset); 227 offset);
180 *data = in_be32((void *)(regs_win + offset)); 228 *data = in_be32(priv->regs_win + offset);
181 229
182 return 0; 230 return 0;
183} 231}
184 232
185/** 233/**
186 * mpc85xx_local_config_write - Generate a MPC85xx local config space write 234 * fsl_local_config_write - Generate a MPC85xx local config space write
187 * @index: ID of RapdiIO interface 235 * @index: ID of RapdiIO interface
188 * @offset: Offset into configuration space 236 * @offset: Offset into configuration space
189 * @len: Length (in bytes) of the maintenance transaction 237 * @len: Length (in bytes) of the maintenance transaction
@@ -192,18 +240,20 @@ static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data)
192 * Generates a MPC85xx local configuration space write. Returns %0 on 240 * Generates a MPC85xx local configuration space write. Returns %0 on
193 * success or %-EINVAL on failure. 241 * success or %-EINVAL on failure.
194 */ 242 */
195static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data) 243static int fsl_local_config_write(struct rio_mport *mport,
244 int index, u32 offset, int len, u32 data)
196{ 245{
246 struct rio_priv *priv = mport->priv;
197 pr_debug 247 pr_debug
198 ("mpc85xx_local_config_write: index %d offset %8.8x data %8.8x\n", 248 ("fsl_local_config_write: index %d offset %8.8x data %8.8x\n",
199 index, offset, data); 249 index, offset, data);
200 out_be32((void *)(regs_win + offset), data); 250 out_be32(priv->regs_win + offset, data);
201 251
202 return 0; 252 return 0;
203} 253}
204 254
205/** 255/**
206 * mpc85xx_rio_config_read - Generate a MPC85xx read maintenance transaction 256 * fsl_rio_config_read - Generate a MPC85xx read maintenance transaction
207 * @index: ID of RapdiIO interface 257 * @index: ID of RapdiIO interface
208 * @destid: Destination ID of transaction 258 * @destid: Destination ID of transaction
209 * @hopcount: Number of hops to target device 259 * @hopcount: Number of hops to target device
@@ -215,18 +265,19 @@ static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data)
215 * success or %-EINVAL on failure. 265 * success or %-EINVAL on failure.
216 */ 266 */
217static int 267static int
218mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len, 268fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid,
219 u32 * val) 269 u8 hopcount, u32 offset, int len, u32 *val)
220{ 270{
271 struct rio_priv *priv = mport->priv;
221 u8 *data; 272 u8 *data;
222 273
223 pr_debug 274 pr_debug
224 ("mpc85xx_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n", 275 ("fsl_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
225 index, destid, hopcount, offset, len); 276 index, destid, hopcount, offset, len);
226 out_be32((void *)&maint_atmu_regs->rowtar, 277 out_be32(&priv->maint_atmu_regs->rowtar,
227 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); 278 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
228 279
229 data = (u8 *) maint_win + offset; 280 data = (u8 *) priv->maint_win + offset;
230 switch (len) { 281 switch (len) {
231 case 1: 282 case 1:
232 *val = in_8((u8 *) data); 283 *val = in_8((u8 *) data);
@@ -243,7 +294,7 @@ mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
243} 294}
244 295
245/** 296/**
246 * mpc85xx_rio_config_write - Generate a MPC85xx write maintenance transaction 297 * fsl_rio_config_write - Generate a MPC85xx write maintenance transaction
247 * @index: ID of RapdiIO interface 298 * @index: ID of RapdiIO interface
248 * @destid: Destination ID of transaction 299 * @destid: Destination ID of transaction
249 * @hopcount: Number of hops to target device 300 * @hopcount: Number of hops to target device
@@ -255,17 +306,18 @@ mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
255 * success or %-EINVAL on failure. 306 * success or %-EINVAL on failure.
256 */ 307 */
257static int 308static int
258mpc85xx_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset, 309fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,
259 int len, u32 val) 310 u8 hopcount, u32 offset, int len, u32 val)
260{ 311{
312 struct rio_priv *priv = mport->priv;
261 u8 *data; 313 u8 *data;
262 pr_debug 314 pr_debug
263 ("mpc85xx_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", 315 ("fsl_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
264 index, destid, hopcount, offset, len, val); 316 index, destid, hopcount, offset, len, val);
265 out_be32((void *)&maint_atmu_regs->rowtar, 317 out_be32(&priv->maint_atmu_regs->rowtar,
266 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); 318 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
267 319
268 data = (u8 *) maint_win + offset; 320 data = (u8 *) priv->maint_win + offset;
269 switch (len) { 321 switch (len) {
270 case 1: 322 case 1:
271 out_8((u8 *) data, val); 323 out_8((u8 *) data, val);
@@ -296,9 +348,10 @@ int
296rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox, 348rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
297 void *buffer, size_t len) 349 void *buffer, size_t len)
298{ 350{
351 struct rio_priv *priv = mport->priv;
299 u32 omr; 352 u32 omr;
300 struct rio_tx_desc *desc = 353 struct rio_tx_desc *desc = (struct rio_tx_desc *)priv->msg_tx_ring.virt
301 (struct rio_tx_desc *)msg_tx_ring.virt + msg_tx_ring.tx_slot; 354 + priv->msg_tx_ring.tx_slot;
302 int ret = 0; 355 int ret = 0;
303 356
304 pr_debug 357 pr_debug
@@ -311,31 +364,43 @@ rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
311 } 364 }
312 365
313 /* Copy and clear rest of buffer */ 366 /* Copy and clear rest of buffer */
314 memcpy(msg_tx_ring.virt_buffer[msg_tx_ring.tx_slot], buffer, len); 367 memcpy(priv->msg_tx_ring.virt_buffer[priv->msg_tx_ring.tx_slot], buffer,
368 len);
315 if (len < (RIO_MAX_MSG_SIZE - 4)) 369 if (len < (RIO_MAX_MSG_SIZE - 4))
316 memset((void *)((u32) msg_tx_ring. 370 memset(priv->msg_tx_ring.virt_buffer[priv->msg_tx_ring.tx_slot]
317 virt_buffer[msg_tx_ring.tx_slot] + len), 0, 371 + len, 0, RIO_MAX_MSG_SIZE - len);
318 RIO_MAX_MSG_SIZE - len);
319 372
320 /* Set mbox field for message */ 373 switch (mport->phy_type) {
321 desc->dport = mbox & 0x3; 374 case RIO_PHY_PARALLEL:
375 /* Set mbox field for message */
376 desc->dport = mbox & 0x3;
322 377
323 /* Enable EOMI interrupt, set priority, and set destid */ 378 /* Enable EOMI interrupt, set priority, and set destid */
324 desc->dattr = 0x28000000 | (rdev->destid << 2); 379 desc->dattr = 0x28000000 | (rdev->destid << 2);
380 break;
381 case RIO_PHY_SERIAL:
382 /* Set mbox field for message, and set destid */
383 desc->dport = (rdev->destid << 16) | (mbox & 0x3);
384
385 /* Enable EOMI interrupt and priority */
386 desc->dattr = 0x28000000;
387 break;
388 }
325 389
326 /* Set transfer size aligned to next power of 2 (in double words) */ 390 /* Set transfer size aligned to next power of 2 (in double words) */
327 desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len); 391 desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len);
328 392
329 /* Set snooping and source buffer address */ 393 /* Set snooping and source buffer address */
330 desc->saddr = 0x00000004 | msg_tx_ring.phys_buffer[msg_tx_ring.tx_slot]; 394 desc->saddr = 0x00000004
395 | priv->msg_tx_ring.phys_buffer[priv->msg_tx_ring.tx_slot];
331 396
332 /* Increment enqueue pointer */ 397 /* Increment enqueue pointer */
333 omr = in_be32((void *)&msg_regs->omr); 398 omr = in_be32(&priv->msg_regs->omr);
334 out_be32((void *)&msg_regs->omr, omr | RIO_MSG_OMR_MUI); 399 out_be32(&priv->msg_regs->omr, omr | RIO_MSG_OMR_MUI);
335 400
336 /* Go to next descriptor */ 401 /* Go to next descriptor */
337 if (++msg_tx_ring.tx_slot == msg_tx_ring.size) 402 if (++priv->msg_tx_ring.tx_slot == priv->msg_tx_ring.size)
338 msg_tx_ring.tx_slot = 0; 403 priv->msg_tx_ring.tx_slot = 0;
339 404
340 out: 405 out:
341 return ret; 406 return ret;
@@ -344,7 +409,7 @@ rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
344EXPORT_SYMBOL_GPL(rio_hw_add_outb_message); 409EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);
345 410
346/** 411/**
347 * mpc85xx_rio_tx_handler - MPC85xx outbound message interrupt handler 412 * fsl_rio_tx_handler - MPC85xx outbound message interrupt handler
348 * @irq: Linux interrupt number 413 * @irq: Linux interrupt number
349 * @dev_instance: Pointer to interrupt-specific data 414 * @dev_instance: Pointer to interrupt-specific data
350 * 415 *
@@ -352,32 +417,34 @@ EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);
352 * mailbox event handler and acks the interrupt occurrence. 417 * mailbox event handler and acks the interrupt occurrence.
353 */ 418 */
354static irqreturn_t 419static irqreturn_t
355mpc85xx_rio_tx_handler(int irq, void *dev_instance) 420fsl_rio_tx_handler(int irq, void *dev_instance)
356{ 421{
357 int osr; 422 int osr;
358 struct rio_mport *port = (struct rio_mport *)dev_instance; 423 struct rio_mport *port = (struct rio_mport *)dev_instance;
424 struct rio_priv *priv = port->priv;
359 425
360 osr = in_be32((void *)&msg_regs->osr); 426 osr = in_be32(&priv->msg_regs->osr);
361 427
362 if (osr & RIO_MSG_OSR_TE) { 428 if (osr & RIO_MSG_OSR_TE) {
363 pr_info("RIO: outbound message transmission error\n"); 429 pr_info("RIO: outbound message transmission error\n");
364 out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_TE); 430 out_be32(&priv->msg_regs->osr, RIO_MSG_OSR_TE);
365 goto out; 431 goto out;
366 } 432 }
367 433
368 if (osr & RIO_MSG_OSR_QOI) { 434 if (osr & RIO_MSG_OSR_QOI) {
369 pr_info("RIO: outbound message queue overflow\n"); 435 pr_info("RIO: outbound message queue overflow\n");
370 out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_QOI); 436 out_be32(&priv->msg_regs->osr, RIO_MSG_OSR_QOI);
371 goto out; 437 goto out;
372 } 438 }
373 439
374 if (osr & RIO_MSG_OSR_EOMI) { 440 if (osr & RIO_MSG_OSR_EOMI) {
375 u32 dqp = in_be32((void *)&msg_regs->odqdpar); 441 u32 dqp = in_be32(&priv->msg_regs->odqdpar);
376 int slot = (dqp - msg_tx_ring.phys) >> 5; 442 int slot = (dqp - priv->msg_tx_ring.phys) >> 5;
377 port->outb_msg[0].mcback(port, msg_tx_ring.dev_id, -1, slot); 443 port->outb_msg[0].mcback(port, priv->msg_tx_ring.dev_id, -1,
444 slot);
378 445
379 /* Ack the end-of-message interrupt */ 446 /* Ack the end-of-message interrupt */
380 out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_EOMI); 447 out_be32(&priv->msg_regs->osr, RIO_MSG_OSR_EOMI);
381 } 448 }
382 449
383 out: 450 out:
@@ -398,6 +465,7 @@ mpc85xx_rio_tx_handler(int irq, void *dev_instance)
398int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries) 465int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
399{ 466{
400 int i, j, rc = 0; 467 int i, j, rc = 0;
468 struct rio_priv *priv = mport->priv;
401 469
402 if ((entries < RIO_MIN_TX_RING_SIZE) || 470 if ((entries < RIO_MIN_TX_RING_SIZE) ||
403 (entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) { 471 (entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) {
@@ -406,54 +474,53 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr
406 } 474 }
407 475
408 /* Initialize shadow copy ring */ 476 /* Initialize shadow copy ring */
409 msg_tx_ring.dev_id = dev_id; 477 priv->msg_tx_ring.dev_id = dev_id;
410 msg_tx_ring.size = entries; 478 priv->msg_tx_ring.size = entries;
411 479
412 for (i = 0; i < msg_tx_ring.size; i++) { 480 for (i = 0; i < priv->msg_tx_ring.size; i++) {
413 if (! 481 priv->msg_tx_ring.virt_buffer[i] =
414 (msg_tx_ring.virt_buffer[i] = 482 dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE,
415 dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE, 483 &priv->msg_tx_ring.phys_buffer[i], GFP_KERNEL);
416 &msg_tx_ring.phys_buffer[i], 484 if (!priv->msg_tx_ring.virt_buffer[i]) {
417 GFP_KERNEL))) {
418 rc = -ENOMEM; 485 rc = -ENOMEM;
419 for (j = 0; j < msg_tx_ring.size; j++) 486 for (j = 0; j < priv->msg_tx_ring.size; j++)
420 if (msg_tx_ring.virt_buffer[j]) 487 if (priv->msg_tx_ring.virt_buffer[j])
421 dma_free_coherent(NULL, 488 dma_free_coherent(NULL,
422 RIO_MSG_BUFFER_SIZE, 489 RIO_MSG_BUFFER_SIZE,
423 msg_tx_ring. 490 priv->msg_tx_ring.
424 virt_buffer[j], 491 virt_buffer[j],
425 msg_tx_ring. 492 priv->msg_tx_ring.
426 phys_buffer[j]); 493 phys_buffer[j]);
427 goto out; 494 goto out;
428 } 495 }
429 } 496 }
430 497
431 /* Initialize outbound message descriptor ring */ 498 /* Initialize outbound message descriptor ring */
432 if (!(msg_tx_ring.virt = dma_alloc_coherent(NULL, 499 priv->msg_tx_ring.virt = dma_alloc_coherent(NULL,
433 msg_tx_ring.size * 500 priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE,
434 RIO_MSG_DESC_SIZE, 501 &priv->msg_tx_ring.phys, GFP_KERNEL);
435 &msg_tx_ring.phys, 502 if (!priv->msg_tx_ring.virt) {
436 GFP_KERNEL))) {
437 rc = -ENOMEM; 503 rc = -ENOMEM;
438 goto out_dma; 504 goto out_dma;
439 } 505 }
440 memset(msg_tx_ring.virt, 0, msg_tx_ring.size * RIO_MSG_DESC_SIZE); 506 memset(priv->msg_tx_ring.virt, 0,
441 msg_tx_ring.tx_slot = 0; 507 priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE);
508 priv->msg_tx_ring.tx_slot = 0;
442 509
443 /* Point dequeue/enqueue pointers at first entry in ring */ 510 /* Point dequeue/enqueue pointers at first entry in ring */
444 out_be32((void *)&msg_regs->odqdpar, msg_tx_ring.phys); 511 out_be32(&priv->msg_regs->odqdpar, priv->msg_tx_ring.phys);
445 out_be32((void *)&msg_regs->odqepar, msg_tx_ring.phys); 512 out_be32(&priv->msg_regs->odqepar, priv->msg_tx_ring.phys);
446 513
447 /* Configure for snooping */ 514 /* Configure for snooping */
448 out_be32((void *)&msg_regs->osar, 0x00000004); 515 out_be32(&priv->msg_regs->osar, 0x00000004);
449 516
450 /* Clear interrupt status */ 517 /* Clear interrupt status */
451 out_be32((void *)&msg_regs->osr, 0x000000b3); 518 out_be32(&priv->msg_regs->osr, 0x000000b3);
452 519
453 /* Hook up outbound message handler */ 520 /* Hook up outbound message handler */
454 if ((rc = 521 rc = request_irq(IRQ_RIO_TX(mport), fsl_rio_tx_handler, 0,
455 request_irq(MPC85xx_IRQ_RIO_TX, mpc85xx_rio_tx_handler, 0, 522 "msg_tx", (void *)mport);
456 "msg_tx", (void *)mport)) < 0) 523 if (rc < 0)
457 goto out_irq; 524 goto out_irq;
458 525
459 /* 526 /*
@@ -463,28 +530,28 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr
463 * Chaining mode 530 * Chaining mode
464 * Disable 531 * Disable
465 */ 532 */
466 out_be32((void *)&msg_regs->omr, 0x00100220); 533 out_be32(&priv->msg_regs->omr, 0x00100220);
467 534
468 /* Set number of entries */ 535 /* Set number of entries */
469 out_be32((void *)&msg_regs->omr, 536 out_be32(&priv->msg_regs->omr,
470 in_be32((void *)&msg_regs->omr) | 537 in_be32(&priv->msg_regs->omr) |
471 ((get_bitmask_order(entries) - 2) << 12)); 538 ((get_bitmask_order(entries) - 2) << 12));
472 539
473 /* Now enable the unit */ 540 /* Now enable the unit */
474 out_be32((void *)&msg_regs->omr, in_be32((void *)&msg_regs->omr) | 0x1); 541 out_be32(&priv->msg_regs->omr, in_be32(&priv->msg_regs->omr) | 0x1);
475 542
476 out: 543 out:
477 return rc; 544 return rc;
478 545
479 out_irq: 546 out_irq:
480 dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE, 547 dma_free_coherent(NULL, priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE,
481 msg_tx_ring.virt, msg_tx_ring.phys); 548 priv->msg_tx_ring.virt, priv->msg_tx_ring.phys);
482 549
483 out_dma: 550 out_dma:
484 for (i = 0; i < msg_tx_ring.size; i++) 551 for (i = 0; i < priv->msg_tx_ring.size; i++)
485 dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE, 552 dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
486 msg_tx_ring.virt_buffer[i], 553 priv->msg_tx_ring.virt_buffer[i],
487 msg_tx_ring.phys_buffer[i]); 554 priv->msg_tx_ring.phys_buffer[i]);
488 555
489 return rc; 556 return rc;
490} 557}
@@ -499,19 +566,20 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr
499 */ 566 */
500void rio_close_outb_mbox(struct rio_mport *mport, int mbox) 567void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
501{ 568{
569 struct rio_priv *priv = mport->priv;
502 /* Disable inbound message unit */ 570 /* Disable inbound message unit */
503 out_be32((void *)&msg_regs->omr, 0); 571 out_be32(&priv->msg_regs->omr, 0);
504 572
505 /* Free ring */ 573 /* Free ring */
506 dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE, 574 dma_free_coherent(NULL, priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE,
507 msg_tx_ring.virt, msg_tx_ring.phys); 575 priv->msg_tx_ring.virt, priv->msg_tx_ring.phys);
508 576
509 /* Free interrupt */ 577 /* Free interrupt */
510 free_irq(MPC85xx_IRQ_RIO_TX, (void *)mport); 578 free_irq(IRQ_RIO_TX(mport), (void *)mport);
511} 579}
512 580
513/** 581/**
514 * mpc85xx_rio_rx_handler - MPC85xx inbound message interrupt handler 582 * fsl_rio_rx_handler - MPC85xx inbound message interrupt handler
515 * @irq: Linux interrupt number 583 * @irq: Linux interrupt number
516 * @dev_instance: Pointer to interrupt-specific data 584 * @dev_instance: Pointer to interrupt-specific data
517 * 585 *
@@ -519,16 +587,17 @@ void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
519 * mailbox event handler and acks the interrupt occurrence. 587 * mailbox event handler and acks the interrupt occurrence.
520 */ 588 */
521static irqreturn_t 589static irqreturn_t
522mpc85xx_rio_rx_handler(int irq, void *dev_instance) 590fsl_rio_rx_handler(int irq, void *dev_instance)
523{ 591{
524 int isr; 592 int isr;
525 struct rio_mport *port = (struct rio_mport *)dev_instance; 593 struct rio_mport *port = (struct rio_mport *)dev_instance;
594 struct rio_priv *priv = port->priv;
526 595
527 isr = in_be32((void *)&msg_regs->isr); 596 isr = in_be32(&priv->msg_regs->isr);
528 597
529 if (isr & RIO_MSG_ISR_TE) { 598 if (isr & RIO_MSG_ISR_TE) {
530 pr_info("RIO: inbound message reception error\n"); 599 pr_info("RIO: inbound message reception error\n");
531 out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_TE); 600 out_be32((void *)&priv->msg_regs->isr, RIO_MSG_ISR_TE);
532 goto out; 601 goto out;
533 } 602 }
534 603
@@ -540,10 +609,10 @@ mpc85xx_rio_rx_handler(int irq, void *dev_instance)
540 * make the callback with an unknown/invalid mailbox number 609 * make the callback with an unknown/invalid mailbox number
541 * argument. 610 * argument.
542 */ 611 */
543 port->inb_msg[0].mcback(port, msg_rx_ring.dev_id, -1, -1); 612 port->inb_msg[0].mcback(port, priv->msg_rx_ring.dev_id, -1, -1);
544 613
545 /* Ack the queueing interrupt */ 614 /* Ack the queueing interrupt */
546 out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_DIQI); 615 out_be32(&priv->msg_regs->isr, RIO_MSG_ISR_DIQI);
547 } 616 }
548 617
549 out: 618 out:
@@ -564,6 +633,7 @@ mpc85xx_rio_rx_handler(int irq, void *dev_instance)
564int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries) 633int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
565{ 634{
566 int i, rc = 0; 635 int i, rc = 0;
636 struct rio_priv *priv = mport->priv;
567 637
568 if ((entries < RIO_MIN_RX_RING_SIZE) || 638 if ((entries < RIO_MIN_RX_RING_SIZE) ||
569 (entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) { 639 (entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) {
@@ -572,36 +642,35 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri
572 } 642 }
573 643
574 /* Initialize client buffer ring */ 644 /* Initialize client buffer ring */
575 msg_rx_ring.dev_id = dev_id; 645 priv->msg_rx_ring.dev_id = dev_id;
576 msg_rx_ring.size = entries; 646 priv->msg_rx_ring.size = entries;
577 msg_rx_ring.rx_slot = 0; 647 priv->msg_rx_ring.rx_slot = 0;
578 for (i = 0; i < msg_rx_ring.size; i++) 648 for (i = 0; i < priv->msg_rx_ring.size; i++)
579 msg_rx_ring.virt_buffer[i] = NULL; 649 priv->msg_rx_ring.virt_buffer[i] = NULL;
580 650
581 /* Initialize inbound message ring */ 651 /* Initialize inbound message ring */
582 if (!(msg_rx_ring.virt = dma_alloc_coherent(NULL, 652 priv->msg_rx_ring.virt = dma_alloc_coherent(NULL,
583 msg_rx_ring.size * 653 priv->msg_rx_ring.size * RIO_MAX_MSG_SIZE,
584 RIO_MAX_MSG_SIZE, 654 &priv->msg_rx_ring.phys, GFP_KERNEL);
585 &msg_rx_ring.phys, 655 if (!priv->msg_rx_ring.virt) {
586 GFP_KERNEL))) {
587 rc = -ENOMEM; 656 rc = -ENOMEM;
588 goto out; 657 goto out;
589 } 658 }
590 659
591 /* Point dequeue/enqueue pointers at first entry in ring */ 660 /* Point dequeue/enqueue pointers at first entry in ring */
592 out_be32((void *)&msg_regs->ifqdpar, (u32) msg_rx_ring.phys); 661 out_be32(&priv->msg_regs->ifqdpar, (u32) priv->msg_rx_ring.phys);
593 out_be32((void *)&msg_regs->ifqepar, (u32) msg_rx_ring.phys); 662 out_be32(&priv->msg_regs->ifqepar, (u32) priv->msg_rx_ring.phys);
594 663
595 /* Clear interrupt status */ 664 /* Clear interrupt status */
596 out_be32((void *)&msg_regs->isr, 0x00000091); 665 out_be32(&priv->msg_regs->isr, 0x00000091);
597 666
598 /* Hook up inbound message handler */ 667 /* Hook up inbound message handler */
599 if ((rc = 668 rc = request_irq(IRQ_RIO_RX(mport), fsl_rio_rx_handler, 0,
600 request_irq(MPC85xx_IRQ_RIO_RX, mpc85xx_rio_rx_handler, 0, 669 "msg_rx", (void *)mport);
601 "msg_rx", (void *)mport)) < 0) { 670 if (rc < 0) {
602 dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE, 671 dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
603 msg_tx_ring.virt_buffer[i], 672 priv->msg_tx_ring.virt_buffer[i],
604 msg_tx_ring.phys_buffer[i]); 673 priv->msg_tx_ring.phys_buffer[i]);
605 goto out; 674 goto out;
606 } 675 }
607 676
@@ -612,15 +681,13 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri
612 * Unmask all interrupt sources 681 * Unmask all interrupt sources
613 * Disable 682 * Disable
614 */ 683 */
615 out_be32((void *)&msg_regs->imr, 0x001b0060); 684 out_be32(&priv->msg_regs->imr, 0x001b0060);
616 685
617 /* Set number of queue entries */ 686 /* Set number of queue entries */
618 out_be32((void *)&msg_regs->imr, 687 setbits32(&priv->msg_regs->imr, (get_bitmask_order(entries) - 2) << 12);
619 in_be32((void *)&msg_regs->imr) |
620 ((get_bitmask_order(entries) - 2) << 12));
621 688
622 /* Now enable the unit */ 689 /* Now enable the unit */
623 out_be32((void *)&msg_regs->imr, in_be32((void *)&msg_regs->imr) | 0x1); 690 setbits32(&priv->msg_regs->imr, 0x1);
624 691
625 out: 692 out:
626 return rc; 693 return rc;
@@ -636,15 +703,16 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri
636 */ 703 */
637void rio_close_inb_mbox(struct rio_mport *mport, int mbox) 704void rio_close_inb_mbox(struct rio_mport *mport, int mbox)
638{ 705{
706 struct rio_priv *priv = mport->priv;
639 /* Disable inbound message unit */ 707 /* Disable inbound message unit */
640 out_be32((void *)&msg_regs->imr, 0); 708 out_be32(&priv->msg_regs->imr, 0);
641 709
642 /* Free ring */ 710 /* Free ring */
643 dma_free_coherent(NULL, msg_rx_ring.size * RIO_MAX_MSG_SIZE, 711 dma_free_coherent(NULL, priv->msg_rx_ring.size * RIO_MAX_MSG_SIZE,
644 msg_rx_ring.virt, msg_rx_ring.phys); 712 priv->msg_rx_ring.virt, priv->msg_rx_ring.phys);
645 713
646 /* Free interrupt */ 714 /* Free interrupt */
647 free_irq(MPC85xx_IRQ_RIO_RX, (void *)mport); 715 free_irq(IRQ_RIO_RX(mport), (void *)mport);
648} 716}
649 717
650/** 718/**
@@ -659,21 +727,22 @@ void rio_close_inb_mbox(struct rio_mport *mport, int mbox)
659int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf) 727int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf)
660{ 728{
661 int rc = 0; 729 int rc = 0;
730 struct rio_priv *priv = mport->priv;
662 731
663 pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n", 732 pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n",
664 msg_rx_ring.rx_slot); 733 priv->msg_rx_ring.rx_slot);
665 734
666 if (msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot]) { 735 if (priv->msg_rx_ring.virt_buffer[priv->msg_rx_ring.rx_slot]) {
667 printk(KERN_ERR 736 printk(KERN_ERR
668 "RIO: error adding inbound buffer %d, buffer exists\n", 737 "RIO: error adding inbound buffer %d, buffer exists\n",
669 msg_rx_ring.rx_slot); 738 priv->msg_rx_ring.rx_slot);
670 rc = -EINVAL; 739 rc = -EINVAL;
671 goto out; 740 goto out;
672 } 741 }
673 742
674 msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot] = buf; 743 priv->msg_rx_ring.virt_buffer[priv->msg_rx_ring.rx_slot] = buf;
675 if (++msg_rx_ring.rx_slot == msg_rx_ring.size) 744 if (++priv->msg_rx_ring.rx_slot == priv->msg_rx_ring.size)
676 msg_rx_ring.rx_slot = 0; 745 priv->msg_rx_ring.rx_slot = 0;
677 746
678 out: 747 out:
679 return rc; 748 return rc;
@@ -691,20 +760,21 @@ EXPORT_SYMBOL_GPL(rio_hw_add_inb_buffer);
691 */ 760 */
692void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox) 761void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
693{ 762{
694 u32 imr; 763 struct rio_priv *priv = mport->priv;
695 u32 phys_buf, virt_buf; 764 u32 phys_buf, virt_buf;
696 void *buf = NULL; 765 void *buf = NULL;
697 int buf_idx; 766 int buf_idx;
698 767
699 phys_buf = in_be32((void *)&msg_regs->ifqdpar); 768 phys_buf = in_be32(&priv->msg_regs->ifqdpar);
700 769
701 /* If no more messages, then bail out */ 770 /* If no more messages, then bail out */
702 if (phys_buf == in_be32((void *)&msg_regs->ifqepar)) 771 if (phys_buf == in_be32(&priv->msg_regs->ifqepar))
703 goto out2; 772 goto out2;
704 773
705 virt_buf = (u32) msg_rx_ring.virt + (phys_buf - msg_rx_ring.phys); 774 virt_buf = (u32) priv->msg_rx_ring.virt + (phys_buf
706 buf_idx = (phys_buf - msg_rx_ring.phys) / RIO_MAX_MSG_SIZE; 775 - priv->msg_rx_ring.phys);
707 buf = msg_rx_ring.virt_buffer[buf_idx]; 776 buf_idx = (phys_buf - priv->msg_rx_ring.phys) / RIO_MAX_MSG_SIZE;
777 buf = priv->msg_rx_ring.virt_buffer[buf_idx];
708 778
709 if (!buf) { 779 if (!buf) {
710 printk(KERN_ERR 780 printk(KERN_ERR
@@ -716,11 +786,10 @@ void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
716 memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE); 786 memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE);
717 787
718 /* Clear the available buffer */ 788 /* Clear the available buffer */
719 msg_rx_ring.virt_buffer[buf_idx] = NULL; 789 priv->msg_rx_ring.virt_buffer[buf_idx] = NULL;
720 790
721 out1: 791 out1:
722 imr = in_be32((void *)&msg_regs->imr); 792 setbits32(&priv->msg_regs->imr, RIO_MSG_IMR_MI);
723 out_be32((void *)&msg_regs->imr, imr | RIO_MSG_IMR_MI);
724 793
725 out2: 794 out2:
726 return buf; 795 return buf;
@@ -729,7 +798,7 @@ void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
729EXPORT_SYMBOL_GPL(rio_hw_get_inb_message); 798EXPORT_SYMBOL_GPL(rio_hw_get_inb_message);
730 799
731/** 800/**
732 * mpc85xx_rio_dbell_handler - MPC85xx doorbell interrupt handler 801 * fsl_rio_dbell_handler - MPC85xx doorbell interrupt handler
733 * @irq: Linux interrupt number 802 * @irq: Linux interrupt number
734 * @dev_instance: Pointer to interrupt-specific data 803 * @dev_instance: Pointer to interrupt-specific data
735 * 804 *
@@ -737,31 +806,31 @@ EXPORT_SYMBOL_GPL(rio_hw_get_inb_message);
737 * doorbell event handlers and executes a matching event handler. 806 * doorbell event handlers and executes a matching event handler.
738 */ 807 */
739static irqreturn_t 808static irqreturn_t
740mpc85xx_rio_dbell_handler(int irq, void *dev_instance) 809fsl_rio_dbell_handler(int irq, void *dev_instance)
741{ 810{
742 int dsr; 811 int dsr;
743 struct rio_mport *port = (struct rio_mport *)dev_instance; 812 struct rio_mport *port = (struct rio_mport *)dev_instance;
813 struct rio_priv *priv = port->priv;
744 814
745 dsr = in_be32((void *)&msg_regs->dsr); 815 dsr = in_be32(&priv->msg_regs->dsr);
746 816
747 if (dsr & DOORBELL_DSR_TE) { 817 if (dsr & DOORBELL_DSR_TE) {
748 pr_info("RIO: doorbell reception error\n"); 818 pr_info("RIO: doorbell reception error\n");
749 out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_TE); 819 out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_TE);
750 goto out; 820 goto out;
751 } 821 }
752 822
753 if (dsr & DOORBELL_DSR_QFI) { 823 if (dsr & DOORBELL_DSR_QFI) {
754 pr_info("RIO: doorbell queue full\n"); 824 pr_info("RIO: doorbell queue full\n");
755 out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_QFI); 825 out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_QFI);
756 goto out; 826 goto out;
757 } 827 }
758 828
759 /* XXX Need to check/dispatch until queue empty */ 829 /* XXX Need to check/dispatch until queue empty */
760 if (dsr & DOORBELL_DSR_DIQI) { 830 if (dsr & DOORBELL_DSR_DIQI) {
761 u32 dmsg = 831 u32 dmsg =
762 (u32) dbell_ring.virt + 832 (u32) priv->dbell_ring.virt +
763 (in_be32((void *)&msg_regs->dqdpar) & 0xfff); 833 (in_be32(&priv->msg_regs->dqdpar) & 0xfff);
764 u32 dmr;
765 struct rio_dbell *dbell; 834 struct rio_dbell *dbell;
766 int found = 0; 835 int found = 0;
767 836
@@ -784,9 +853,8 @@ mpc85xx_rio_dbell_handler(int irq, void *dev_instance)
784 ("RIO: spurious doorbell, sid %2.2x tid %2.2x info %4.4x\n", 853 ("RIO: spurious doorbell, sid %2.2x tid %2.2x info %4.4x\n",
785 DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg)); 854 DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
786 } 855 }
787 dmr = in_be32((void *)&msg_regs->dmr); 856 setbits32(&priv->msg_regs->dmr, DOORBELL_DMR_DI);
788 out_be32((void *)&msg_regs->dmr, dmr | DOORBELL_DMR_DI); 857 out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_DIQI);
789 out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_DIQI);
790 } 858 }
791 859
792 out: 860 out:
@@ -794,21 +862,22 @@ mpc85xx_rio_dbell_handler(int irq, void *dev_instance)
794} 862}
795 863
796/** 864/**
797 * mpc85xx_rio_doorbell_init - MPC85xx doorbell interface init 865 * fsl_rio_doorbell_init - MPC85xx doorbell interface init
798 * @mport: Master port implementing the inbound doorbell unit 866 * @mport: Master port implementing the inbound doorbell unit
799 * 867 *
800 * Initializes doorbell unit hardware and inbound DMA buffer 868 * Initializes doorbell unit hardware and inbound DMA buffer
801 * ring. Called from mpc85xx_rio_setup(). Returns %0 on success 869 * ring. Called from fsl_rio_setup(). Returns %0 on success
802 * or %-ENOMEM on failure. 870 * or %-ENOMEM on failure.
803 */ 871 */
804static int mpc85xx_rio_doorbell_init(struct rio_mport *mport) 872static int fsl_rio_doorbell_init(struct rio_mport *mport)
805{ 873{
874 struct rio_priv *priv = mport->priv;
806 int rc = 0; 875 int rc = 0;
807 876
808 /* Map outbound doorbell window immediately after maintenance window */ 877 /* Map outbound doorbell window immediately after maintenance window */
809 if (!(dbell_win = 878 priv->dbell_win = ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE,
810 (u32) ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE, 879 RIO_DBELL_WIN_SIZE);
811 RIO_DBELL_WIN_SIZE))) { 880 if (!priv->dbell_win) {
812 printk(KERN_ERR 881 printk(KERN_ERR
813 "RIO: unable to map outbound doorbell window\n"); 882 "RIO: unable to map outbound doorbell window\n");
814 rc = -ENOMEM; 883 rc = -ENOMEM;
@@ -816,37 +885,36 @@ static int mpc85xx_rio_doorbell_init(struct rio_mport *mport)
816 } 885 }
817 886
818 /* Initialize inbound doorbells */ 887 /* Initialize inbound doorbells */
819 if (!(dbell_ring.virt = dma_alloc_coherent(NULL, 888 priv->dbell_ring.virt = dma_alloc_coherent(NULL, 512 *
820 512 * DOORBELL_MESSAGE_SIZE, 889 DOORBELL_MESSAGE_SIZE, &priv->dbell_ring.phys, GFP_KERNEL);
821 &dbell_ring.phys, 890 if (!priv->dbell_ring.virt) {
822 GFP_KERNEL))) {
823 printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n"); 891 printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n");
824 rc = -ENOMEM; 892 rc = -ENOMEM;
825 iounmap((void *)dbell_win); 893 iounmap(priv->dbell_win);
826 goto out; 894 goto out;
827 } 895 }
828 896
829 /* Point dequeue/enqueue pointers at first entry in ring */ 897 /* Point dequeue/enqueue pointers at first entry in ring */
830 out_be32((void *)&msg_regs->dqdpar, (u32) dbell_ring.phys); 898 out_be32(&priv->msg_regs->dqdpar, (u32) priv->dbell_ring.phys);
831 out_be32((void *)&msg_regs->dqepar, (u32) dbell_ring.phys); 899 out_be32(&priv->msg_regs->dqepar, (u32) priv->dbell_ring.phys);
832 900
833 /* Clear interrupt status */ 901 /* Clear interrupt status */
834 out_be32((void *)&msg_regs->dsr, 0x00000091); 902 out_be32(&priv->msg_regs->dsr, 0x00000091);
835 903
836 /* Hook up doorbell handler */ 904 /* Hook up doorbell handler */
837 if ((rc = 905 rc = request_irq(IRQ_RIO_BELL(mport), fsl_rio_dbell_handler, 0,
838 request_irq(MPC85xx_IRQ_RIO_BELL, mpc85xx_rio_dbell_handler, 0, 906 "dbell_rx", (void *)mport);
839 "dbell_rx", (void *)mport) < 0)) { 907 if (rc < 0) {
840 iounmap((void *)dbell_win); 908 iounmap(priv->dbell_win);
841 dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE, 909 dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE,
842 dbell_ring.virt, dbell_ring.phys); 910 priv->dbell_ring.virt, priv->dbell_ring.phys);
843 printk(KERN_ERR 911 printk(KERN_ERR
844 "MPC85xx RIO: unable to request inbound doorbell irq"); 912 "MPC85xx RIO: unable to request inbound doorbell irq");
845 goto out; 913 goto out;
846 } 914 }
847 915
848 /* Configure doorbells for snooping, 512 entries, and enable */ 916 /* Configure doorbells for snooping, 512 entries, and enable */
849 out_be32((void *)&msg_regs->dmr, 0x00108161); 917 out_be32(&priv->msg_regs->dmr, 0x00108161);
850 918
851 out: 919 out:
852 return rc; 920 return rc;
@@ -854,7 +922,7 @@ static int mpc85xx_rio_doorbell_init(struct rio_mport *mport)
854 922
855static char *cmdline = NULL; 923static char *cmdline = NULL;
856 924
857static int mpc85xx_rio_get_hdid(int index) 925static int fsl_rio_get_hdid(int index)
858{ 926{
859 /* XXX Need to parse multiple entries in some format */ 927 /* XXX Need to parse multiple entries in some format */
860 if (!cmdline) 928 if (!cmdline)
@@ -863,7 +931,7 @@ static int mpc85xx_rio_get_hdid(int index)
863 return simple_strtol(cmdline, NULL, 0); 931 return simple_strtol(cmdline, NULL, 0);
864} 932}
865 933
866static int mpc85xx_rio_get_cmdline(char *s) 934static int fsl_rio_get_cmdline(char *s)
867{ 935{
868 if (!s) 936 if (!s)
869 return 0; 937 return 0;
@@ -872,61 +940,266 @@ static int mpc85xx_rio_get_cmdline(char *s)
872 return 1; 940 return 1;
873} 941}
874 942
875__setup("riohdid=", mpc85xx_rio_get_cmdline); 943__setup("riohdid=", fsl_rio_get_cmdline);
944
945static inline void fsl_rio_info(struct device *dev, u32 ccsr)
946{
947 const char *str;
948 if (ccsr & 1) {
949 /* Serial phy */
950 switch (ccsr >> 30) {
951 case 0:
952 str = "1";
953 break;
954 case 1:
955 str = "4";
956 break;
957 default:
958 str = "Unknown";
959 break;;
960 }
961 dev_info(dev, "Hardware port width: %s\n", str);
962
963 switch ((ccsr >> 27) & 7) {
964 case 0:
965 str = "Single-lane 0";
966 break;
967 case 1:
968 str = "Single-lane 2";
969 break;
970 case 2:
971 str = "Four-lane";
972 break;
973 default:
974 str = "Unknown";
975 break;
976 }
977 dev_info(dev, "Training connection status: %s\n", str);
978 } else {
979 /* Parallel phy */
980 if (!(ccsr & 0x80000000))
981 dev_info(dev, "Output port operating in 8-bit mode\n");
982 if (!(ccsr & 0x08000000))
983 dev_info(dev, "Input port operating in 8-bit mode\n");
984 }
985}
876 986
877/** 987/**
878 * mpc85xx_rio_setup - Setup MPC85xx RapidIO interface 988 * fsl_rio_setup - Setup MPC85xx RapidIO interface
879 * @law_start: Starting physical address of RapidIO LAW 989 * @fsl_rio_setup - Setup Freescale PowerPC RapidIO interface
880 * @law_size: Size of RapidIO LAW
881 * 990 *
882 * Initializes MPC85xx RapidIO hardware interface, configures 991 * Initializes MPC85xx RapidIO hardware interface, configures
883 * master port with system-specific info, and registers the 992 * master port with system-specific info, and registers the
884 * master port with the RapidIO subsystem. 993 * master port with the RapidIO subsystem.
885 */ 994 */
886void mpc85xx_rio_setup(int law_start, int law_size) 995int fsl_rio_setup(struct of_device *dev)
887{ 996{
888 struct rio_ops *ops; 997 struct rio_ops *ops;
889 struct rio_mport *port; 998 struct rio_mport *port;
999 struct rio_priv *priv;
1000 int rc = 0;
1001 const u32 *dt_range, *cell;
1002 struct resource regs;
1003 int rlen;
1004 u32 ccsr;
1005 u64 law_start, law_size;
1006 int paw, aw, sw;
1007
1008 if (!dev->node) {
1009 dev_err(&dev->dev, "Device OF-Node is NULL");
1010 return -EFAULT;
1011 }
1012
1013 rc = of_address_to_resource(dev->node, 0, &regs);
1014 if (rc) {
1015 dev_err(&dev->dev, "Can't get %s property 'reg'\n",
1016 dev->node->full_name);
1017 return -EFAULT;
1018 }
1019 dev_info(&dev->dev, "Of-device full name %s\n", dev->node->full_name);
1020 dev_info(&dev->dev, "Regs start 0x%08x size 0x%08x\n", regs.start,
1021 regs.end - regs.start + 1);
1022
1023 dt_range = of_get_property(dev->node, "ranges", &rlen);
1024 if (!dt_range) {
1025 dev_err(&dev->dev, "Can't get %s property 'ranges'\n",
1026 dev->node->full_name);
1027 return -EFAULT;
1028 }
1029
1030 /* Get node address wide */
1031 cell = of_get_property(dev->node, "#address-cells", NULL);
1032 if (cell)
1033 aw = *cell;
1034 else
1035 aw = of_n_addr_cells(dev->node);
1036 /* Get node size wide */
1037 cell = of_get_property(dev->node, "#size-cells", NULL);
1038 if (cell)
1039 sw = *cell;
1040 else
1041 sw = of_n_size_cells(dev->node);
1042 /* Get parent address wide wide */
1043 paw = of_n_addr_cells(dev->node);
1044
1045 law_start = of_read_number(dt_range + aw, paw);
1046 law_size = of_read_number(dt_range + aw + paw, sw);
1047
1048 dev_info(&dev->dev, "LAW start 0x%016llx, size 0x%016llx.\n",
1049 law_start, law_size);
890 1050
891 ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL); 1051 ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
892 ops->lcread = mpc85xx_local_config_read; 1052 ops->lcread = fsl_local_config_read;
893 ops->lcwrite = mpc85xx_local_config_write; 1053 ops->lcwrite = fsl_local_config_write;
894 ops->cread = mpc85xx_rio_config_read; 1054 ops->cread = fsl_rio_config_read;
895 ops->cwrite = mpc85xx_rio_config_write; 1055 ops->cwrite = fsl_rio_config_write;
896 ops->dsend = mpc85xx_rio_doorbell_send; 1056 ops->dsend = fsl_rio_doorbell_send;
897 1057
898 port = kmalloc(sizeof(struct rio_mport), GFP_KERNEL); 1058 port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL);
899 port->id = 0; 1059 port->id = 0;
900 port->index = 0; 1060 port->index = 0;
1061
1062 priv = kzalloc(sizeof(struct rio_priv), GFP_KERNEL);
1063 if (!priv) {
1064 printk(KERN_ERR "Can't alloc memory for 'priv'\n");
1065 rc = -ENOMEM;
1066 goto err;
1067 }
1068
901 INIT_LIST_HEAD(&port->dbells); 1069 INIT_LIST_HEAD(&port->dbells);
902 port->iores.start = law_start; 1070 port->iores.start = law_start;
903 port->iores.end = law_start + law_size; 1071 port->iores.end = law_start + law_size;
904 port->iores.flags = IORESOURCE_MEM; 1072 port->iores.flags = IORESOURCE_MEM;
905 1073
1074 priv->bellirq = irq_of_parse_and_map(dev->node, 2);
1075 priv->txirq = irq_of_parse_and_map(dev->node, 3);
1076 priv->rxirq = irq_of_parse_and_map(dev->node, 4);
1077 dev_info(&dev->dev, "bellirq: %d, txirq: %d, rxirq %d\n", priv->bellirq,
1078 priv->txirq, priv->rxirq);
1079
906 rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); 1080 rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
907 rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0); 1081 rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
908 rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0); 1082 rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
909 strcpy(port->name, "RIO0 mport"); 1083 strcpy(port->name, "RIO0 mport");
910 1084
911 port->ops = ops; 1085 port->ops = ops;
912 port->host_deviceid = mpc85xx_rio_get_hdid(port->id); 1086 port->host_deviceid = fsl_rio_get_hdid(port->id);
913 1087
1088 port->priv = priv;
914 rio_register_mport(port); 1089 rio_register_mport(port);
915 1090
916 regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000); 1091 priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1);
917 atmu_regs = (struct rio_atmu_regs *)(regs_win + RIO_ATMU_REGS_OFFSET); 1092
918 maint_atmu_regs = atmu_regs + 1; 1093 /* Probe the master port phy type */
919 dbell_atmu_regs = atmu_regs + 2; 1094 ccsr = in_be32(priv->regs_win + RIO_CCSR);
920 msg_regs = (struct rio_msg_regs *)(regs_win + RIO_MSG_REGS_OFFSET); 1095 port->phy_type = (ccsr & 1) ? RIO_PHY_SERIAL : RIO_PHY_PARALLEL;
1096 dev_info(&dev->dev, "RapidIO PHY type: %s\n",
1097 (port->phy_type == RIO_PHY_PARALLEL) ? "parallel" :
1098 ((port->phy_type == RIO_PHY_SERIAL) ? "serial" :
1099 "unknown"));
1100 /* Checking the port training status */
1101 if (in_be32((priv->regs_win + RIO_ESCSR)) & 1) {
1102 dev_err(&dev->dev, "Port is not ready. "
1103 "Try to restart connection...\n");
1104 switch (port->phy_type) {
1105 case RIO_PHY_SERIAL:
1106 /* Disable ports */
1107 out_be32(priv->regs_win + RIO_CCSR, 0);
1108 /* Set 1x lane */
1109 setbits32(priv->regs_win + RIO_CCSR, 0x02000000);
1110 /* Enable ports */
1111 setbits32(priv->regs_win + RIO_CCSR, 0x00600000);
1112 break;
1113 case RIO_PHY_PARALLEL:
1114 /* Disable ports */
1115 out_be32(priv->regs_win + RIO_CCSR, 0x22000000);
1116 /* Enable ports */
1117 out_be32(priv->regs_win + RIO_CCSR, 0x44000000);
1118 break;
1119 }
1120 msleep(100);
1121 if (in_be32((priv->regs_win + RIO_ESCSR)) & 1) {
1122 dev_err(&dev->dev, "Port restart failed.\n");
1123 rc = -ENOLINK;
1124 goto err;
1125 }
1126 dev_info(&dev->dev, "Port restart success!\n");
1127 }
1128 fsl_rio_info(&dev->dev, ccsr);
1129
1130 port->sys_size = (in_be32((priv->regs_win + RIO_PEF_CAR))
1131 & RIO_PEF_CTLS) >> 4;
1132 dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n",
1133 port->sys_size ? 65536 : 256);
1134
1135 priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win
1136 + RIO_ATMU_REGS_OFFSET);
1137 priv->maint_atmu_regs = priv->atmu_regs + 1;
1138 priv->dbell_atmu_regs = priv->atmu_regs + 2;
1139 priv->msg_regs = (struct rio_msg_regs *)(priv->regs_win +
1140 ((port->phy_type == RIO_PHY_SERIAL) ?
1141 RIO_S_MSG_REGS_OFFSET : RIO_P_MSG_REGS_OFFSET));
1142
1143 /* Set to receive any dist ID for serial RapidIO controller. */
1144 if (port->phy_type == RIO_PHY_SERIAL)
1145 out_be32((priv->regs_win + RIO_ISR_AACR), RIO_ISR_AACR_AA);
921 1146
922 /* Configure maintenance transaction window */ 1147 /* Configure maintenance transaction window */
923 out_be32((void *)&maint_atmu_regs->rowbar, 0x000c0000); 1148 out_be32(&priv->maint_atmu_regs->rowbar, 0x000c0000);
924 out_be32((void *)&maint_atmu_regs->rowar, 0x80077015); 1149 out_be32(&priv->maint_atmu_regs->rowar, 0x80077015);
925 1150
926 maint_win = (u32) ioremap(law_start, RIO_MAINT_WIN_SIZE); 1151 priv->maint_win = ioremap(law_start, RIO_MAINT_WIN_SIZE);
927 1152
928 /* Configure outbound doorbell window */ 1153 /* Configure outbound doorbell window */
929 out_be32((void *)&dbell_atmu_regs->rowbar, 0x000c0400); 1154 out_be32(&priv->dbell_atmu_regs->rowbar, 0x000c0400);
930 out_be32((void *)&dbell_atmu_regs->rowar, 0x8004200b); 1155 out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b);
931 mpc85xx_rio_doorbell_init(port); 1156 fsl_rio_doorbell_init(port);
1157
1158 return 0;
1159err:
1160 if (priv)
1161 iounmap(priv->regs_win);
1162 kfree(ops);
1163 kfree(priv);
1164 kfree(port);
1165 return rc;
1166}
1167
1168/* The probe function for RapidIO peer-to-peer network.
1169 */
1170static int __devinit fsl_of_rio_rpn_probe(struct of_device *dev,
1171 const struct of_device_id *match)
1172{
1173 int rc;
1174 printk(KERN_INFO "Setting up RapidIO peer-to-peer network %s\n",
1175 dev->node->full_name);
1176
1177 rc = fsl_rio_setup(dev);
1178 if (rc)
1179 goto out;
1180
1181 /* Enumerate all registered ports */
1182 rc = rio_init_mports();
1183out:
1184 return rc;
1185};
1186
1187static const struct of_device_id fsl_of_rio_rpn_ids[] = {
1188 {
1189 .compatible = "fsl,rapidio-delta",
1190 },
1191 {},
1192};
1193
1194static struct of_platform_driver fsl_of_rio_rpn_driver = {
1195 .name = "fsl-of-rio",
1196 .match_table = fsl_of_rio_rpn_ids,
1197 .probe = fsl_of_rio_rpn_probe,
1198};
1199
1200static __init int fsl_of_rio_rpn_init(void)
1201{
1202 return of_register_platform_driver(&fsl_of_rio_rpn_driver);
932} 1203}
1204
1205subsys_initcall(fsl_of_rio_rpn_init);
diff --git a/arch/powerpc/sysdev/fsl_rio.h b/arch/powerpc/sysdev/fsl_rio.h
deleted file mode 100644
index 6d3ff30b1579..000000000000
--- a/arch/powerpc/sysdev/fsl_rio.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/*
2 * MPC85xx RapidIO definitions
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef __PPC_SYSLIB_PPC85XX_RIO_H
14#define __PPC_SYSLIB_PPC85XX_RIO_H
15
16#include <linux/init.h>
17
18extern void mpc85xx_rio_setup(int law_start, int law_size);
19
20#endif /* __PPC_SYSLIB_PPC85XX_RIO_H */
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 77f50b63a970..b52659620d50 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -234,6 +234,14 @@ config WINDFARM_PM112
234 which are the recent dual and quad G5 machines using the 234 which are the recent dual and quad G5 machines using the
235 970MP dual-core processor. 235 970MP dual-core processor.
236 236
237config WINDFARM_PM121
238 tristate "Support for thermal management on PowerMac12,1"
239 depends on WINDFARM && I2C && PMAC_SMU
240 select I2C_POWERMAC
241 help
242 This driver provides thermal control for the PowerMac12,1
243 which is the iMac G5 (iSight).
244
237config ANSLCD 245config ANSLCD
238 tristate "Support for ANS LCD display" 246 tristate "Support for ANS LCD display"
239 depends on ADB_CUDA && PPC_PMAC 247 depends on ADB_CUDA && PPC_PMAC
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
index 2dfc3f4eaf42..e3132efa17c0 100644
--- a/drivers/macintosh/Makefile
+++ b/drivers/macintosh/Makefile
@@ -42,4 +42,9 @@ obj-$(CONFIG_WINDFARM_PM112) += windfarm_pm112.o windfarm_smu_sat.o \
42 windfarm_smu_sensors.o \ 42 windfarm_smu_sensors.o \
43 windfarm_max6690_sensor.o \ 43 windfarm_max6690_sensor.o \
44 windfarm_lm75_sensor.o windfarm_pid.o 44 windfarm_lm75_sensor.o windfarm_pid.o
45obj-$(CONFIG_WINDFARM_PM121) += windfarm_pm121.o windfarm_smu_sat.o \
46 windfarm_smu_controls.o \
47 windfarm_smu_sensors.o \
48 windfarm_max6690_sensor.o \
49 windfarm_lm75_sensor.o windfarm_pid.o
45obj-$(CONFIG_PMAC_RACKMETER) += rack-meter.o 50obj-$(CONFIG_PMAC_RACKMETER) += rack-meter.o
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
index 7e10c3ab4d50..b92b959fe16e 100644
--- a/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -127,6 +127,12 @@ static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter,
127 */ 127 */
128 if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY")) 128 if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY"))
129 lm->sens.name = "hd-temp"; 129 lm->sens.name = "hd-temp";
130 else if (!strcmp(loc, "Incoming Air Temp"))
131 lm->sens.name = "incoming-air-temp";
132 else if (!strcmp(loc, "ODD Temp"))
133 lm->sens.name = "optical-drive-temp";
134 else if (!strcmp(loc, "HD Temp"))
135 lm->sens.name = "hard-drive-temp";
130 else 136 else
131 goto fail; 137 goto fail;
132 138
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
index 5f03aab9fb5d..e207a90d6b27 100644
--- a/drivers/macintosh/windfarm_max6690_sensor.c
+++ b/drivers/macintosh/windfarm_max6690_sensor.c
@@ -77,18 +77,28 @@ static struct wf_sensor_ops wf_max6690_ops = {
77 .owner = THIS_MODULE, 77 .owner = THIS_MODULE,
78}; 78};
79 79
80static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr) 80static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr,
81 const char *loc)
81{ 82{
82 struct wf_6690_sensor *max; 83 struct wf_6690_sensor *max;
83 char *name = "backside-temp"; 84 char *name;
84 85
85 max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); 86 max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
86 if (max == NULL) { 87 if (max == NULL) {
87 printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: " 88 printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: "
88 "no memory\n", name); 89 "no memory\n", loc);
89 return; 90 return;
90 } 91 }
91 92
93 if (!strcmp(loc, "BACKSIDE"))
94 name = "backside-temp";
95 else if (!strcmp(loc, "NB Ambient"))
96 name = "north-bridge-temp";
97 else if (!strcmp(loc, "GPU Ambient"))
98 name = "gpu-temp";
99 else
100 goto fail;
101
92 max->sens.ops = &wf_max6690_ops; 102 max->sens.ops = &wf_max6690_ops;
93 max->sens.name = name; 103 max->sens.name = name;
94 max->i2c.addr = addr >> 1; 104 max->i2c.addr = addr >> 1;
@@ -138,9 +148,7 @@ static int wf_max6690_attach(struct i2c_adapter *adapter)
138 if (loc == NULL || addr == 0) 148 if (loc == NULL || addr == 0)
139 continue; 149 continue;
140 printk("found max6690, loc=%s addr=0x%02x\n", loc, addr); 150 printk("found max6690, loc=%s addr=0x%02x\n", loc, addr);
141 if (strcmp(loc, "BACKSIDE")) 151 wf_max6690_create(adapter, addr, loc);
142 continue;
143 wf_max6690_create(adapter, addr);
144 } 152 }
145 153
146 return 0; 154 return 0;
diff --git a/drivers/macintosh/windfarm_pm121.c b/drivers/macintosh/windfarm_pm121.c
new file mode 100644
index 000000000000..66ec4fb115bb
--- /dev/null
+++ b/drivers/macintosh/windfarm_pm121.c
@@ -0,0 +1,1040 @@
1/*
2 * Windfarm PowerMac thermal control. iMac G5 iSight
3 *
4 * (c) Copyright 2007 Étienne Bersac <bersace@gmail.com>
5 *
6 * Bits & pieces from windfarm_pm81.c by (c) Copyright 2005 Benjamin
7 * Herrenschmidt, IBM Corp. <benh@kernel.crashing.org>
8 *
9 * Released under the term of the GNU GPL v2.
10 *
11 *
12 *
13 * PowerMac12,1
14 * ============
15 *
16 *
17 * The algorithm used is the PID control algorithm, used the same way
18 * the published Darwin code does, using the same values that are
19 * present in the Darwin 8.10 snapshot property lists (note however
20 * that none of the code has been re-used, it's a complete
21 * re-implementation
22 *
23 * There is two models using PowerMac12,1. Model 2 is iMac G5 iSight
24 * 17" while Model 3 is iMac G5 20". They do have both the same
25 * controls with a tiny difference. The control-ids of hard-drive-fan
26 * and cpu-fan is swapped.
27 *
28 *
29 * Target Correction :
30 *
31 * controls have a target correction calculated as :
32 *
33 * new_min = ((((average_power * slope) >> 16) + offset) >> 16) + min_value
34 * new_value = max(new_value, max(new_min, 0))
35 *
36 * OD Fan control correction.
37 *
38 * # model_id: 2
39 * offset : -19563152
40 * slope : 1956315
41 *
42 * # model_id: 3
43 * offset : -15650652
44 * slope : 1565065
45 *
46 * HD Fan control correction.
47 *
48 * # model_id: 2
49 * offset : -15650652
50 * slope : 1565065
51 *
52 * # model_id: 3
53 * offset : -19563152
54 * slope : 1956315
55 *
56 * CPU Fan control correction.
57 *
58 * # model_id: 2
59 * offset : -25431900
60 * slope : 2543190
61 *
62 * # model_id: 3
63 * offset : -15650652
64 * slope : 1565065
65 *
66 *
67 * Target rubber-banding :
68 *
69 * Some controls have a target correction which depends on another
70 * control value. The correction is computed in the following way :
71 *
72 * new_min = ref_value * slope + offset
73 *
74 * ref_value is the value of the reference control. If new_min is
75 * greater than 0, then we correct the target value using :
76 *
77 * new_target = max (new_target, new_min >> 16)
78 *
79 *
80 * # model_id : 2
81 * control : cpu-fan
82 * ref : optical-drive-fan
83 * offset : -15650652
84 * slope : 1565065
85 *
86 * # model_id : 3
87 * control : optical-drive-fan
88 * ref : hard-drive-fan
89 * offset : -32768000
90 * slope : 65536
91 *
92 *
93 * In order to have the moste efficient correction with those
94 * dependencies, we must trigger HD loop before OD loop before CPU
95 * loop.
96 *
97 *
98 * The various control loops found in Darwin config file are:
99 *
100 * HD Fan control loop.
101 *
102 * # model_id: 2
103 * control : hard-drive-fan
104 * sensor : hard-drive-temp
105 * PID params : G_d = 0x00000000
106 * G_p = 0x002D70A3
107 * G_r = 0x00019999
108 * History = 2 entries
109 * Input target = 0x370000
110 * Interval = 5s
111 *
112 * # model_id: 3
113 * control : hard-drive-fan
114 * sensor : hard-drive-temp
115 * PID params : G_d = 0x00000000
116 * G_p = 0x002170A3
117 * G_r = 0x00019999
118 * History = 2 entries
119 * Input target = 0x370000
120 * Interval = 5s
121 *
122 * OD Fan control loop.
123 *
124 * # model_id: 2
125 * control : optical-drive-fan
126 * sensor : optical-drive-temp
127 * PID params : G_d = 0x00000000
128 * G_p = 0x001FAE14
129 * G_r = 0x00019999
130 * History = 2 entries
131 * Input target = 0x320000
132 * Interval = 5s
133 *
134 * # model_id: 3
135 * control : optical-drive-fan
136 * sensor : optical-drive-temp
137 * PID params : G_d = 0x00000000
138 * G_p = 0x001FAE14
139 * G_r = 0x00019999
140 * History = 2 entries
141 * Input target = 0x320000
142 * Interval = 5s
143 *
144 * GPU Fan control loop.
145 *
146 * # model_id: 2
147 * control : hard-drive-fan
148 * sensor : gpu-temp
149 * PID params : G_d = 0x00000000
150 * G_p = 0x002A6666
151 * G_r = 0x00019999
152 * History = 2 entries
153 * Input target = 0x5A0000
154 * Interval = 5s
155 *
156 * # model_id: 3
157 * control : cpu-fan
158 * sensor : gpu-temp
159 * PID params : G_d = 0x00000000
160 * G_p = 0x0010CCCC
161 * G_r = 0x00019999
162 * History = 2 entries
163 * Input target = 0x500000
164 * Interval = 5s
165 *
166 * KODIAK (aka northbridge) Fan control loop.
167 *
168 * # model_id: 2
169 * control : optical-drive-fan
170 * sensor : north-bridge-temp
171 * PID params : G_d = 0x00000000
172 * G_p = 0x003BD70A
173 * G_r = 0x00019999
174 * History = 2 entries
175 * Input target = 0x550000
176 * Interval = 5s
177 *
178 * # model_id: 3
179 * control : hard-drive-fan
180 * sensor : north-bridge-temp
181 * PID params : G_d = 0x00000000
182 * G_p = 0x0030F5C2
183 * G_r = 0x00019999
184 * History = 2 entries
185 * Input target = 0x550000
186 * Interval = 5s
187 *
188 * CPU Fan control loop.
189 *
190 * control : cpu-fan
191 * sensors : cpu-temp, cpu-power
192 * PID params : from SDB partition
193 *
194 *
195 * CPU Slew control loop.
196 *
197 * control : cpufreq-clamp
198 * sensor : cpu-temp
199 *
200 */
201
202#undef DEBUG
203
204#include <linux/types.h>
205#include <linux/errno.h>
206#include <linux/kernel.h>
207#include <linux/delay.h>
208#include <linux/slab.h>
209#include <linux/init.h>
210#include <linux/spinlock.h>
211#include <linux/wait.h>
212#include <linux/kmod.h>
213#include <linux/device.h>
214#include <linux/platform_device.h>
215#include <asm/prom.h>
216#include <asm/machdep.h>
217#include <asm/io.h>
218#include <asm/system.h>
219#include <asm/sections.h>
220#include <asm/smu.h>
221
222#include "windfarm.h"
223#include "windfarm_pid.h"
224
225#define VERSION "0.3"
226
227static int pm121_mach_model; /* machine model id */
228
229/* Controls & sensors */
230static struct wf_sensor *sensor_cpu_power;
231static struct wf_sensor *sensor_cpu_temp;
232static struct wf_sensor *sensor_cpu_voltage;
233static struct wf_sensor *sensor_cpu_current;
234static struct wf_sensor *sensor_gpu_temp;
235static struct wf_sensor *sensor_north_bridge_temp;
236static struct wf_sensor *sensor_hard_drive_temp;
237static struct wf_sensor *sensor_optical_drive_temp;
238static struct wf_sensor *sensor_incoming_air_temp; /* unused ! */
239
240enum {
241 FAN_CPU,
242 FAN_HD,
243 FAN_OD,
244 CPUFREQ,
245 N_CONTROLS
246};
247static struct wf_control *controls[N_CONTROLS] = {};
248
249/* Set to kick the control loop into life */
250static int pm121_all_controls_ok, pm121_all_sensors_ok, pm121_started;
251
252enum {
253 FAILURE_FAN = 1 << 0,
254 FAILURE_SENSOR = 1 << 1,
255 FAILURE_OVERTEMP = 1 << 2
256};
257
258/* All sys loops. Note the HD before the OD loop in order to have it
259 run before. */
260enum {
261 LOOP_GPU, /* control = hd or cpu, but luckily,
262 it doesn't matter */
263 LOOP_HD, /* control = hd */
264 LOOP_KODIAK, /* control = hd or od */
265 LOOP_OD, /* control = od */
266 N_LOOPS
267};
268
269static const char *loop_names[N_LOOPS] = {
270 "GPU",
271 "HD",
272 "KODIAK",
273 "OD",
274};
275
276#define PM121_NUM_CONFIGS 2
277
278static unsigned int pm121_failure_state;
279static int pm121_readjust, pm121_skipping;
280static s32 average_power;
281
282struct pm121_correction {
283 int offset;
284 int slope;
285};
286
287static struct pm121_correction corrections[N_CONTROLS][PM121_NUM_CONFIGS] = {
288 /* FAN_OD */
289 {
290 /* MODEL 2 */
291 { .offset = -19563152,
292 .slope = 1956315
293 },
294 /* MODEL 3 */
295 { .offset = -15650652,
296 .slope = 1565065
297 },
298 },
299 /* FAN_HD */
300 {
301 /* MODEL 2 */
302 { .offset = -15650652,
303 .slope = 1565065
304 },
305 /* MODEL 3 */
306 { .offset = -19563152,
307 .slope = 1956315
308 },
309 },
310 /* FAN_CPU */
311 {
312 /* MODEL 2 */
313 { .offset = -25431900,
314 .slope = 2543190
315 },
316 /* MODEL 3 */
317 { .offset = -15650652,
318 .slope = 1565065
319 },
320 },
321 /* CPUFREQ has no correction (and is not implemented at all) */
322};
323
324struct pm121_connection {
325 unsigned int control_id;
326 unsigned int ref_id;
327 struct pm121_correction correction;
328};
329
330static struct pm121_connection pm121_connections[] = {
331 /* MODEL 2 */
332 { .control_id = FAN_CPU,
333 .ref_id = FAN_OD,
334 { .offset = -32768000,
335 .slope = 65536
336 }
337 },
338 /* MODEL 3 */
339 { .control_id = FAN_OD,
340 .ref_id = FAN_HD,
341 { .offset = -32768000,
342 .slope = 65536
343 }
344 },
345};
346
347/* pointer to the current model connection */
348static struct pm121_connection *pm121_connection;
349
350/*
351 * ****** System Fans Control Loop ******
352 *
353 */
354
355/* Since each loop handles only one control and we want to avoid
356 * writing virtual control, we store the control correction with the
357 * loop params. Some data are not set, there are common to all loop
358 * and thus, hardcoded.
359 */
360struct pm121_sys_param {
361 /* purely informative since we use mach_model-2 as index */
362 int model_id;
363 struct wf_sensor **sensor; /* use sensor_id instead ? */
364 s32 gp, itarget;
365 unsigned int control_id;
366};
367
368static struct pm121_sys_param
369pm121_sys_all_params[N_LOOPS][PM121_NUM_CONFIGS] = {
370 /* GPU Fan control loop */
371 {
372 { .model_id = 2,
373 .sensor = &sensor_gpu_temp,
374 .gp = 0x002A6666,
375 .itarget = 0x5A0000,
376 .control_id = FAN_HD,
377 },
378 { .model_id = 3,
379 .sensor = &sensor_gpu_temp,
380 .gp = 0x0010CCCC,
381 .itarget = 0x500000,
382 .control_id = FAN_CPU,
383 },
384 },
385 /* HD Fan control loop */
386 {
387 { .model_id = 2,
388 .sensor = &sensor_hard_drive_temp,
389 .gp = 0x002D70A3,
390 .itarget = 0x370000,
391 .control_id = FAN_HD,
392 },
393 { .model_id = 3,
394 .sensor = &sensor_hard_drive_temp,
395 .gp = 0x002170A3,
396 .itarget = 0x370000,
397 .control_id = FAN_HD,
398 },
399 },
400 /* KODIAK Fan control loop */
401 {
402 { .model_id = 2,
403 .sensor = &sensor_north_bridge_temp,
404 .gp = 0x003BD70A,
405 .itarget = 0x550000,
406 .control_id = FAN_OD,
407 },
408 { .model_id = 3,
409 .sensor = &sensor_north_bridge_temp,
410 .gp = 0x0030F5C2,
411 .itarget = 0x550000,
412 .control_id = FAN_HD,
413 },
414 },
415 /* OD Fan control loop */
416 {
417 { .model_id = 2,
418 .sensor = &sensor_optical_drive_temp,
419 .gp = 0x001FAE14,
420 .itarget = 0x320000,
421 .control_id = FAN_OD,
422 },
423 { .model_id = 3,
424 .sensor = &sensor_optical_drive_temp,
425 .gp = 0x001FAE14,
426 .itarget = 0x320000,
427 .control_id = FAN_OD,
428 },
429 },
430};
431
432/* the hardcoded values */
433#define PM121_SYS_GD 0x00000000
434#define PM121_SYS_GR 0x00019999
435#define PM121_SYS_HISTORY_SIZE 2
436#define PM121_SYS_INTERVAL 5
437
438/* State data used by the system fans control loop
439 */
440struct pm121_sys_state {
441 int ticks;
442 s32 setpoint;
443 struct wf_pid_state pid;
444};
445
446struct pm121_sys_state *pm121_sys_state[N_LOOPS] = {};
447
448/*
449 * ****** CPU Fans Control Loop ******
450 *
451 */
452
453#define PM121_CPU_INTERVAL 1
454
455/* State data used by the cpu fans control loop
456 */
457struct pm121_cpu_state {
458 int ticks;
459 s32 setpoint;
460 struct wf_cpu_pid_state pid;
461};
462
463static struct pm121_cpu_state *pm121_cpu_state;
464
465
466
467/*
468 * ***** Implementation *****
469 *
470 */
471
472/* correction the value using the output-low-bound correction algo */
473static s32 pm121_correct(s32 new_setpoint,
474 unsigned int control_id,
475 s32 min)
476{
477 s32 new_min;
478 struct pm121_correction *correction;
479 correction = &corrections[control_id][pm121_mach_model - 2];
480
481 new_min = (average_power * correction->slope) >> 16;
482 new_min += correction->offset;
483 new_min = (new_min >> 16) + min;
484
485 return max(new_setpoint, max(new_min, 0));
486}
487
488static s32 pm121_connect(unsigned int control_id, s32 setpoint)
489{
490 s32 new_min, value, new_setpoint;
491
492 if (pm121_connection->control_id == control_id) {
493 controls[control_id]->ops->get_value(controls[control_id],
494 &value);
495 new_min = value * pm121_connection->correction.slope;
496 new_min += pm121_connection->correction.offset;
497 if (new_min > 0) {
498 new_setpoint = max(setpoint, (new_min >> 16));
499 if (new_setpoint != setpoint) {
500 pr_debug("pm121: %s depending on %s, "
501 "corrected from %d to %d RPM\n",
502 controls[control_id]->name,
503 controls[pm121_connection->ref_id]->name,
504 (int) setpoint, (int) new_setpoint);
505 }
506 } else
507 new_setpoint = setpoint;
508 }
509 /* no connection */
510 else
511 new_setpoint = setpoint;
512
513 return new_setpoint;
514}
515
516/* FAN LOOPS */
517static void pm121_create_sys_fans(int loop_id)
518{
519 struct pm121_sys_param *param = NULL;
520 struct wf_pid_param pid_param;
521 struct wf_control *control = NULL;
522 int i;
523
524 /* First, locate the params for this model */
525 for (i = 0; i < PM121_NUM_CONFIGS; i++) {
526 if (pm121_sys_all_params[loop_id][i].model_id == pm121_mach_model) {
527 param = &(pm121_sys_all_params[loop_id][i]);
528 break;
529 }
530 }
531
532 /* No params found, put fans to max */
533 if (param == NULL) {
534 printk(KERN_WARNING "pm121: %s fan config not found "
535 " for this machine model\n",
536 loop_names[loop_id]);
537 goto fail;
538 }
539
540 control = controls[param->control_id];
541
542 /* Alloc & initialize state */
543 pm121_sys_state[loop_id] = kmalloc(sizeof(struct pm121_sys_state),
544 GFP_KERNEL);
545 if (pm121_sys_state[loop_id] == NULL) {
546 printk(KERN_WARNING "pm121: Memory allocation error\n");
547 goto fail;
548 }
549 pm121_sys_state[loop_id]->ticks = 1;
550
551 /* Fill PID params */
552 pid_param.gd = PM121_SYS_GD;
553 pid_param.gp = param->gp;
554 pid_param.gr = PM121_SYS_GR;
555 pid_param.interval = PM121_SYS_INTERVAL;
556 pid_param.history_len = PM121_SYS_HISTORY_SIZE;
557 pid_param.itarget = param->itarget;
558 pid_param.min = control->ops->get_min(control);
559 pid_param.max = control->ops->get_max(control);
560
561 wf_pid_init(&pm121_sys_state[loop_id]->pid, &pid_param);
562
563 pr_debug("pm121: %s Fan control loop initialized.\n"
564 " itarged=%d.%03d, min=%d RPM, max=%d RPM\n",
565 loop_names[loop_id], FIX32TOPRINT(pid_param.itarget),
566 pid_param.min, pid_param.max);
567 return;
568
569 fail:
570 /* note that this is not optimal since another loop may still
571 control the same control */
572 printk(KERN_WARNING "pm121: failed to set up %s loop "
573 "setting \"%s\" to max speed.\n",
574 loop_names[loop_id], control->name);
575
576 if (control)
577 wf_control_set_max(control);
578}
579
580static void pm121_sys_fans_tick(int loop_id)
581{
582 struct pm121_sys_param *param;
583 struct pm121_sys_state *st;
584 struct wf_sensor *sensor;
585 struct wf_control *control;
586 s32 temp, new_setpoint;
587 int rc;
588
589 param = &(pm121_sys_all_params[loop_id][pm121_mach_model-2]);
590 st = pm121_sys_state[loop_id];
591 sensor = *(param->sensor);
592 control = controls[param->control_id];
593
594 if (--st->ticks != 0) {
595 if (pm121_readjust)
596 goto readjust;
597 return;
598 }
599 st->ticks = PM121_SYS_INTERVAL;
600
601 rc = sensor->ops->get_value(sensor, &temp);
602 if (rc) {
603 printk(KERN_WARNING "windfarm: %s sensor error %d\n",
604 sensor->name, rc);
605 pm121_failure_state |= FAILURE_SENSOR;
606 return;
607 }
608
609 pr_debug("pm121: %s Fan tick ! %s: %d.%03d\n",
610 loop_names[loop_id], sensor->name,
611 FIX32TOPRINT(temp));
612
613 new_setpoint = wf_pid_run(&st->pid, temp);
614
615 /* correction */
616 new_setpoint = pm121_correct(new_setpoint,
617 param->control_id,
618 st->pid.param.min);
619 /* linked corretion */
620 new_setpoint = pm121_connect(param->control_id, new_setpoint);
621
622 if (new_setpoint == st->setpoint)
623 return;
624 st->setpoint = new_setpoint;
625 pr_debug("pm121: %s corrected setpoint: %d RPM\n",
626 control->name, (int)new_setpoint);
627 readjust:
628 if (control && pm121_failure_state == 0) {
629 rc = control->ops->set_value(control, st->setpoint);
630 if (rc) {
631 printk(KERN_WARNING "windfarm: %s fan error %d\n",
632 control->name, rc);
633 pm121_failure_state |= FAILURE_FAN;
634 }
635 }
636}
637
638
639/* CPU LOOP */
640static void pm121_create_cpu_fans(void)
641{
642 struct wf_cpu_pid_param pid_param;
643 const struct smu_sdbp_header *hdr;
644 struct smu_sdbp_cpupiddata *piddata;
645 struct smu_sdbp_fvt *fvt;
646 struct wf_control *fan_cpu;
647 s32 tmax, tdelta, maxpow, powadj;
648
649 fan_cpu = controls[FAN_CPU];
650
651 /* First, locate the PID params in SMU SBD */
652 hdr = smu_get_sdb_partition(SMU_SDB_CPUPIDDATA_ID, NULL);
653 if (hdr == 0) {
654 printk(KERN_WARNING "pm121: CPU PID fan config not found.\n");
655 goto fail;
656 }
657 piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
658
659 /* Get the FVT params for operating point 0 (the only supported one
660 * for now) in order to get tmax
661 */
662 hdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL);
663 if (hdr) {
664 fvt = (struct smu_sdbp_fvt *)&hdr[1];
665 tmax = ((s32)fvt->maxtemp) << 16;
666 } else
667 tmax = 0x5e0000; /* 94 degree default */
668
669 /* Alloc & initialize state */
670 pm121_cpu_state = kmalloc(sizeof(struct pm121_cpu_state),
671 GFP_KERNEL);
672 if (pm121_cpu_state == NULL)
673 goto fail;
674 pm121_cpu_state->ticks = 1;
675
676 /* Fill PID params */
677 pid_param.interval = PM121_CPU_INTERVAL;
678 pid_param.history_len = piddata->history_len;
679 if (pid_param.history_len > WF_CPU_PID_MAX_HISTORY) {
680 printk(KERN_WARNING "pm121: History size overflow on "
681 "CPU control loop (%d)\n", piddata->history_len);
682 pid_param.history_len = WF_CPU_PID_MAX_HISTORY;
683 }
684 pid_param.gd = piddata->gd;
685 pid_param.gp = piddata->gp;
686 pid_param.gr = piddata->gr / pid_param.history_len;
687
688 tdelta = ((s32)piddata->target_temp_delta) << 16;
689 maxpow = ((s32)piddata->max_power) << 16;
690 powadj = ((s32)piddata->power_adj) << 16;
691
692 pid_param.tmax = tmax;
693 pid_param.ttarget = tmax - tdelta;
694 pid_param.pmaxadj = maxpow - powadj;
695
696 pid_param.min = fan_cpu->ops->get_min(fan_cpu);
697 pid_param.max = fan_cpu->ops->get_max(fan_cpu);
698
699 wf_cpu_pid_init(&pm121_cpu_state->pid, &pid_param);
700
701 pr_debug("pm121: CPU Fan control initialized.\n");
702 pr_debug(" ttarged=%d.%03d, tmax=%d.%03d, min=%d RPM, max=%d RPM,\n",
703 FIX32TOPRINT(pid_param.ttarget), FIX32TOPRINT(pid_param.tmax),
704 pid_param.min, pid_param.max);
705
706 return;
707
708 fail:
709 printk(KERN_WARNING "pm121: CPU fan config not found, max fan speed\n");
710
711 if (controls[CPUFREQ])
712 wf_control_set_max(controls[CPUFREQ]);
713 if (fan_cpu)
714 wf_control_set_max(fan_cpu);
715}
716
717
718static void pm121_cpu_fans_tick(struct pm121_cpu_state *st)
719{
720 s32 new_setpoint, temp, power;
721 struct wf_control *fan_cpu = NULL;
722 int rc;
723
724 if (--st->ticks != 0) {
725 if (pm121_readjust)
726 goto readjust;
727 return;
728 }
729 st->ticks = PM121_CPU_INTERVAL;
730
731 fan_cpu = controls[FAN_CPU];
732
733 rc = sensor_cpu_temp->ops->get_value(sensor_cpu_temp, &temp);
734 if (rc) {
735 printk(KERN_WARNING "pm121: CPU temp sensor error %d\n",
736 rc);
737 pm121_failure_state |= FAILURE_SENSOR;
738 return;
739 }
740
741 rc = sensor_cpu_power->ops->get_value(sensor_cpu_power, &power);
742 if (rc) {
743 printk(KERN_WARNING "pm121: CPU power sensor error %d\n",
744 rc);
745 pm121_failure_state |= FAILURE_SENSOR;
746 return;
747 }
748
749 pr_debug("pm121: CPU Fans tick ! CPU temp: %d.%03d°C, power: %d.%03d\n",
750 FIX32TOPRINT(temp), FIX32TOPRINT(power));
751
752 if (temp > st->pid.param.tmax)
753 pm121_failure_state |= FAILURE_OVERTEMP;
754
755 new_setpoint = wf_cpu_pid_run(&st->pid, power, temp);
756
757 /* correction */
758 new_setpoint = pm121_correct(new_setpoint,
759 FAN_CPU,
760 st->pid.param.min);
761
762 /* connected correction */
763 new_setpoint = pm121_connect(FAN_CPU, new_setpoint);
764
765 if (st->setpoint == new_setpoint)
766 return;
767 st->setpoint = new_setpoint;
768 pr_debug("pm121: CPU corrected setpoint: %d RPM\n", (int)new_setpoint);
769
770 readjust:
771 if (fan_cpu && pm121_failure_state == 0) {
772 rc = fan_cpu->ops->set_value(fan_cpu, st->setpoint);
773 if (rc) {
774 printk(KERN_WARNING "pm121: %s fan error %d\n",
775 fan_cpu->name, rc);
776 pm121_failure_state |= FAILURE_FAN;
777 }
778 }
779}
780
781/*
782 * ****** Common ******
783 *
784 */
785
786static void pm121_tick(void)
787{
788 unsigned int last_failure = pm121_failure_state;
789 unsigned int new_failure;
790 s32 total_power;
791 int i;
792
793 if (!pm121_started) {
794 pr_debug("pm121: creating control loops !\n");
795 for (i = 0; i < N_LOOPS; i++)
796 pm121_create_sys_fans(i);
797
798 pm121_create_cpu_fans();
799 pm121_started = 1;
800 }
801
802 /* skipping ticks */
803 if (pm121_skipping && --pm121_skipping)
804 return;
805
806 /* compute average power */
807 total_power = 0;
808 for (i = 0; i < pm121_cpu_state->pid.param.history_len; i++)
809 total_power += pm121_cpu_state->pid.powers[i];
810
811 average_power = total_power / pm121_cpu_state->pid.param.history_len;
812
813
814 pm121_failure_state = 0;
815 for (i = 0 ; i < N_LOOPS; i++) {
816 if (pm121_sys_state[i])
817 pm121_sys_fans_tick(i);
818 }
819
820 if (pm121_cpu_state)
821 pm121_cpu_fans_tick(pm121_cpu_state);
822
823 pm121_readjust = 0;
824 new_failure = pm121_failure_state & ~last_failure;
825
826 /* If entering failure mode, clamp cpufreq and ramp all
827 * fans to full speed.
828 */
829 if (pm121_failure_state && !last_failure) {
830 for (i = 0; i < N_CONTROLS; i++) {
831 if (controls[i])
832 wf_control_set_max(controls[i]);
833 }
834 }
835
836 /* If leaving failure mode, unclamp cpufreq and readjust
837 * all fans on next iteration
838 */
839 if (!pm121_failure_state && last_failure) {
840 if (controls[CPUFREQ])
841 wf_control_set_min(controls[CPUFREQ]);
842 pm121_readjust = 1;
843 }
844
845 /* Overtemp condition detected, notify and start skipping a couple
846 * ticks to let the temperature go down
847 */
848 if (new_failure & FAILURE_OVERTEMP) {
849 wf_set_overtemp();
850 pm121_skipping = 2;
851 }
852
853 /* We only clear the overtemp condition if overtemp is cleared
854 * _and_ no other failure is present. Since a sensor error will
855 * clear the overtemp condition (can't measure temperature) at
856 * the control loop levels, but we don't want to keep it clear
857 * here in this case
858 */
859 if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
860 wf_clear_overtemp();
861}
862
863
864static struct wf_control* pm121_register_control(struct wf_control *ct,
865 const char *match,
866 unsigned int id)
867{
868 if (controls[id] == NULL && !strcmp(ct->name, match)) {
869 if (wf_get_control(ct) == 0)
870 controls[id] = ct;
871 }
872 return controls[id];
873}
874
875static void pm121_new_control(struct wf_control *ct)
876{
877 int all = 1;
878
879 if (pm121_all_controls_ok)
880 return;
881
882 all = pm121_register_control(ct, "optical-drive-fan", FAN_OD) && all;
883 all = pm121_register_control(ct, "hard-drive-fan", FAN_HD) && all;
884 all = pm121_register_control(ct, "cpu-fan", FAN_CPU) && all;
885 all = pm121_register_control(ct, "cpufreq-clamp", CPUFREQ) && all;
886
887 if (all)
888 pm121_all_controls_ok = 1;
889}
890
891
892
893
894static struct wf_sensor* pm121_register_sensor(struct wf_sensor *sensor,
895 const char *match,
896 struct wf_sensor **var)
897{
898 if (*var == NULL && !strcmp(sensor->name, match)) {
899 if (wf_get_sensor(sensor) == 0)
900 *var = sensor;
901 }
902 return *var;
903}
904
905static void pm121_new_sensor(struct wf_sensor *sr)
906{
907 int all = 1;
908
909 if (pm121_all_sensors_ok)
910 return;
911
912 all = pm121_register_sensor(sr, "cpu-temp",
913 &sensor_cpu_temp) && all;
914 all = pm121_register_sensor(sr, "cpu-current",
915 &sensor_cpu_current) && all;
916 all = pm121_register_sensor(sr, "cpu-voltage",
917 &sensor_cpu_voltage) && all;
918 all = pm121_register_sensor(sr, "cpu-power",
919 &sensor_cpu_power) && all;
920 all = pm121_register_sensor(sr, "hard-drive-temp",
921 &sensor_hard_drive_temp) && all;
922 all = pm121_register_sensor(sr, "optical-drive-temp",
923 &sensor_optical_drive_temp) && all;
924 all = pm121_register_sensor(sr, "incoming-air-temp",
925 &sensor_incoming_air_temp) && all;
926 all = pm121_register_sensor(sr, "north-bridge-temp",
927 &sensor_north_bridge_temp) && all;
928 all = pm121_register_sensor(sr, "gpu-temp",
929 &sensor_gpu_temp) && all;
930
931 if (all)
932 pm121_all_sensors_ok = 1;
933}
934
935
936
937static int pm121_notify(struct notifier_block *self,
938 unsigned long event, void *data)
939{
940 switch (event) {
941 case WF_EVENT_NEW_CONTROL:
942 pr_debug("pm121: new control %s detected\n",
943 ((struct wf_control *)data)->name);
944 pm121_new_control(data);
945 break;
946 case WF_EVENT_NEW_SENSOR:
947 pr_debug("pm121: new sensor %s detected\n",
948 ((struct wf_sensor *)data)->name);
949 pm121_new_sensor(data);
950 break;
951 case WF_EVENT_TICK:
952 if (pm121_all_controls_ok && pm121_all_sensors_ok)
953 pm121_tick();
954 break;
955 }
956
957 return 0;
958}
959
960static struct notifier_block pm121_events = {
961 .notifier_call = pm121_notify,
962};
963
964static int pm121_init_pm(void)
965{
966 const struct smu_sdbp_header *hdr;
967
968 hdr = smu_get_sdb_partition(SMU_SDB_SENSORTREE_ID, NULL);
969 if (hdr != 0) {
970 struct smu_sdbp_sensortree *st =
971 (struct smu_sdbp_sensortree *)&hdr[1];
972 pm121_mach_model = st->model_id;
973 }
974
975 pm121_connection = &pm121_connections[pm121_mach_model - 2];
976
977 printk(KERN_INFO "pm121: Initializing for iMac G5 iSight model ID %d\n",
978 pm121_mach_model);
979
980 return 0;
981}
982
983
984static int pm121_probe(struct platform_device *ddev)
985{
986 wf_register_client(&pm121_events);
987
988 return 0;
989}
990
991static int __devexit pm121_remove(struct platform_device *ddev)
992{
993 wf_unregister_client(&pm121_events);
994 return 0;
995}
996
997static struct platform_driver pm121_driver = {
998 .probe = pm121_probe,
999 .remove = __devexit_p(pm121_remove),
1000 .driver = {
1001 .name = "windfarm",
1002 .bus = &platform_bus_type,
1003 },
1004};
1005
1006
1007static int __init pm121_init(void)
1008{
1009 int rc = -ENODEV;
1010
1011 if (machine_is_compatible("PowerMac12,1"))
1012 rc = pm121_init_pm();
1013
1014 if (rc == 0) {
1015 request_module("windfarm_smu_controls");
1016 request_module("windfarm_smu_sensors");
1017 request_module("windfarm_smu_sat");
1018 request_module("windfarm_lm75_sensor");
1019 request_module("windfarm_max6690_sensor");
1020 request_module("windfarm_cpufreq_clamp");
1021 platform_driver_register(&pm121_driver);
1022 }
1023
1024 return rc;
1025}
1026
1027static void __exit pm121_exit(void)
1028{
1029
1030 platform_driver_unregister(&pm121_driver);
1031}
1032
1033
1034module_init(pm121_init);
1035module_exit(pm121_exit);
1036
1037MODULE_AUTHOR("Étienne Bersac <bersace@gmail.com>");
1038MODULE_DESCRIPTION("Thermal control logic for iMac G5 (iSight)");
1039MODULE_LICENSE("GPL");
1040
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c
index 58c2590f05ec..961fa0e7c2cf 100644
--- a/drivers/macintosh/windfarm_smu_controls.c
+++ b/drivers/macintosh/windfarm_smu_controls.c
@@ -218,6 +218,10 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node,
218 fct->ctrl.name = "cpu-fan"; 218 fct->ctrl.name = "cpu-fan";
219 else if (!strcmp(l, "Hard Drive") || !strcmp(l, "Hard drive")) 219 else if (!strcmp(l, "Hard Drive") || !strcmp(l, "Hard drive"))
220 fct->ctrl.name = "drive-bay-fan"; 220 fct->ctrl.name = "drive-bay-fan";
221 else if (!strcmp(l, "HDD Fan")) /* seen on iMac G5 iSight */
222 fct->ctrl.name = "hard-drive-fan";
223 else if (!strcmp(l, "ODD Fan")) /* same */
224 fct->ctrl.name = "optical-drive-fan";
221 225
222 /* Unrecognized fan, bail out */ 226 /* Unrecognized fan, bail out */
223 if (fct->ctrl.name == NULL) 227 if (fct->ctrl.name == NULL)
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index e7fd08adbbac..2b8fd68bc516 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -77,7 +77,7 @@ static int rionet_capable = 1;
77 * could be made into a hash table to save memory depending 77 * could be made into a hash table to save memory depending
78 * on system trade-offs. 78 * on system trade-offs.
79 */ 79 */
80static struct rio_dev *rionet_active[RIO_MAX_ROUTE_ENTRIES]; 80static struct rio_dev **rionet_active;
81 81
82#define is_rionet_capable(pef, src_ops, dst_ops) \ 82#define is_rionet_capable(pef, src_ops, dst_ops) \
83 ((pef & RIO_PEF_INB_MBOX) && \ 83 ((pef & RIO_PEF_INB_MBOX) && \
@@ -195,7 +195,8 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
195 } 195 }
196 196
197 if (eth->h_dest[0] & 0x01) { 197 if (eth->h_dest[0] & 0x01) {
198 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) 198 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size);
199 i++)
199 if (rionet_active[i]) 200 if (rionet_active[i])
200 rionet_queue_tx_msg(skb, ndev, 201 rionet_queue_tx_msg(skb, ndev,
201 rionet_active[i]); 202 rionet_active[i]);
@@ -385,6 +386,8 @@ static void rionet_remove(struct rio_dev *rdev)
385 struct net_device *ndev = NULL; 386 struct net_device *ndev = NULL;
386 struct rionet_peer *peer, *tmp; 387 struct rionet_peer *peer, *tmp;
387 388
389 free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ?
390 __ilog2(sizeof(void *)) + 4 : 0);
388 unregister_netdev(ndev); 391 unregister_netdev(ndev);
389 kfree(ndev); 392 kfree(ndev);
390 393
@@ -443,6 +446,15 @@ static int rionet_setup_netdev(struct rio_mport *mport)
443 goto out; 446 goto out;
444 } 447 }
445 448
449 rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
450 mport->sys_size ? __ilog2(sizeof(void *)) + 4 : 0);
451 if (!rionet_active) {
452 rc = -ENOMEM;
453 goto out;
454 }
455 memset((void *)rionet_active, 0, sizeof(void *) *
456 RIO_MAX_ROUTE_ENTRIES(mport->sys_size));
457
446 /* Set up private area */ 458 /* Set up private area */
447 rnet = (struct rionet_private *)ndev->priv; 459 rnet = (struct rionet_private *)ndev->priv;
448 rnet->mport = mport; 460 rnet->mport = mport;
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index 4142115d298e..c32822ad84a4 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -1,14 +1,6 @@
1# 1#
2# RapidIO configuration 2# RapidIO configuration
3# 3#
4config RAPIDIO_8_BIT_TRANSPORT
5 bool "8-bit transport addressing"
6 depends on RAPIDIO
7 ---help---
8 By default, the kernel assumes a 16-bit addressed RapidIO
9 network. By selecting this option, the kernel will support
10 an 8-bit addressed network.
11
12config RAPIDIO_DISC_TIMEOUT 4config RAPIDIO_DISC_TIMEOUT
13 int "Discovery timeout duration (seconds)" 5 int "Discovery timeout duration (seconds)"
14 depends on RAPIDIO 6 depends on RAPIDIO
diff --git a/drivers/rapidio/rio-access.c b/drivers/rapidio/rio-access.c
index 8b56bbdd011e..a3824baca2e5 100644
--- a/drivers/rapidio/rio-access.c
+++ b/drivers/rapidio/rio-access.c
@@ -48,7 +48,7 @@ int __rio_local_read_config_##size \
48 u32 data = 0; \ 48 u32 data = 0; \
49 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ 49 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
50 spin_lock_irqsave(&rio_config_lock, flags); \ 50 spin_lock_irqsave(&rio_config_lock, flags); \
51 res = mport->ops->lcread(mport->id, offset, len, &data); \ 51 res = mport->ops->lcread(mport, mport->id, offset, len, &data); \
52 *value = (type)data; \ 52 *value = (type)data; \
53 spin_unlock_irqrestore(&rio_config_lock, flags); \ 53 spin_unlock_irqrestore(&rio_config_lock, flags); \
54 return res; \ 54 return res; \
@@ -71,7 +71,7 @@ int __rio_local_write_config_##size \
71 unsigned long flags; \ 71 unsigned long flags; \
72 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ 72 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
73 spin_lock_irqsave(&rio_config_lock, flags); \ 73 spin_lock_irqsave(&rio_config_lock, flags); \
74 res = mport->ops->lcwrite(mport->id, offset, len, value); \ 74 res = mport->ops->lcwrite(mport, mport->id, offset, len, value);\
75 spin_unlock_irqrestore(&rio_config_lock, flags); \ 75 spin_unlock_irqrestore(&rio_config_lock, flags); \
76 return res; \ 76 return res; \
77} 77}
@@ -108,7 +108,7 @@ int rio_mport_read_config_##size \
108 u32 data = 0; \ 108 u32 data = 0; \
109 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ 109 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
110 spin_lock_irqsave(&rio_config_lock, flags); \ 110 spin_lock_irqsave(&rio_config_lock, flags); \
111 res = mport->ops->cread(mport->id, destid, hopcount, offset, len, &data); \ 111 res = mport->ops->cread(mport, mport->id, destid, hopcount, offset, len, &data); \
112 *value = (type)data; \ 112 *value = (type)data; \
113 spin_unlock_irqrestore(&rio_config_lock, flags); \ 113 spin_unlock_irqrestore(&rio_config_lock, flags); \
114 return res; \ 114 return res; \
@@ -131,7 +131,7 @@ int rio_mport_write_config_##size \
131 unsigned long flags; \ 131 unsigned long flags; \
132 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ 132 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
133 spin_lock_irqsave(&rio_config_lock, flags); \ 133 spin_lock_irqsave(&rio_config_lock, flags); \
134 res = mport->ops->cwrite(mport->id, destid, hopcount, offset, len, value); \ 134 res = mport->ops->cwrite(mport, mport->id, destid, hopcount, offset, len, value); \
135 spin_unlock_irqrestore(&rio_config_lock, flags); \ 135 spin_unlock_irqrestore(&rio_config_lock, flags); \
136 return res; \ 136 return res; \
137} 137}
@@ -166,7 +166,7 @@ int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data)
166 unsigned long flags; 166 unsigned long flags;
167 167
168 spin_lock_irqsave(&rio_doorbell_lock, flags); 168 spin_lock_irqsave(&rio_doorbell_lock, flags);
169 res = mport->ops->dsend(mport->id, destid, data); 169 res = mport->ops->dsend(mport, mport->id, destid, data);
170 spin_unlock_irqrestore(&rio_doorbell_lock, flags); 170 spin_unlock_irqrestore(&rio_doorbell_lock, flags);
171 171
172 return res; 172 return res;
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 44420723a359..a926c896475e 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -73,7 +73,7 @@ static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
73 73
74 rio_mport_read_config_32(port, destid, hopcount, RIO_DID_CSR, &result); 74 rio_mport_read_config_32(port, destid, hopcount, RIO_DID_CSR, &result);
75 75
76 return RIO_GET_DID(result); 76 return RIO_GET_DID(port->sys_size, result);
77} 77}
78 78
79/** 79/**
@@ -88,7 +88,7 @@ static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
88static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did) 88static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did)
89{ 89{
90 rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR, 90 rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR,
91 RIO_SET_DID(did)); 91 RIO_SET_DID(port->sys_size, did));
92} 92}
93 93
94/** 94/**
@@ -100,7 +100,8 @@ static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u
100 */ 100 */
101static void rio_local_set_device_id(struct rio_mport *port, u16 did) 101static void rio_local_set_device_id(struct rio_mport *port, u16 did)
102{ 102{
103 rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(did)); 103 rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(port->sys_size,
104 did));
104} 105}
105 106
106/** 107/**
@@ -350,8 +351,18 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
350 rswitch->switchid = next_switchid; 351 rswitch->switchid = next_switchid;
351 rswitch->hopcount = hopcount; 352 rswitch->hopcount = hopcount;
352 rswitch->destid = destid; 353 rswitch->destid = destid;
354 rswitch->route_table = kzalloc(sizeof(u8)*
355 RIO_MAX_ROUTE_ENTRIES(port->sys_size),
356 GFP_KERNEL);
357 if (!rswitch->route_table) {
358 kfree(rdev);
359 rdev = NULL;
360 kfree(rswitch);
361 goto out;
362 }
353 /* Initialize switch route table */ 363 /* Initialize switch route table */
354 for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES; rdid++) 364 for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES(port->sys_size);
365 rdid++)
355 rswitch->route_table[rdid] = RIO_INVALID_ROUTE; 366 rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
356 rdev->rswitch = rswitch; 367 rdev->rswitch = rswitch;
357 sprintf(rio_name(rdev), "%02x:s:%04x", rdev->net->id, 368 sprintf(rio_name(rdev), "%02x:s:%04x", rdev->net->id,
@@ -480,7 +491,7 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
480{ 491{
481 u32 result; 492 u32 result;
482 493
483 rio_mport_read_config_32(port, RIO_ANY_DESTID, hopcount, 494 rio_mport_read_config_32(port, RIO_ANY_DESTID(port->sys_size), hopcount,
484 RIO_HOST_DID_LOCK_CSR, &result); 495 RIO_HOST_DID_LOCK_CSR, &result);
485 496
486 return (u16) (result & 0xffff); 497 return (u16) (result & 0xffff);
@@ -571,14 +582,16 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
571 } 582 }
572 583
573 /* Attempt to acquire device lock */ 584 /* Attempt to acquire device lock */
574 rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount, 585 rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size),
586 hopcount,
575 RIO_HOST_DID_LOCK_CSR, port->host_deviceid); 587 RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
576 while ((tmp = rio_get_host_deviceid_lock(port, hopcount)) 588 while ((tmp = rio_get_host_deviceid_lock(port, hopcount))
577 < port->host_deviceid) { 589 < port->host_deviceid) {
578 /* Delay a bit */ 590 /* Delay a bit */
579 mdelay(1); 591 mdelay(1);
580 /* Attempt to acquire device lock again */ 592 /* Attempt to acquire device lock again */
581 rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount, 593 rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size),
594 hopcount,
582 RIO_HOST_DID_LOCK_CSR, 595 RIO_HOST_DID_LOCK_CSR,
583 port->host_deviceid); 596 port->host_deviceid);
584 } 597 }
@@ -590,7 +603,9 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
590 } 603 }
591 604
592 /* Setup new RIO device */ 605 /* Setup new RIO device */
593 if ((rdev = rio_setup_device(net, port, RIO_ANY_DESTID, hopcount, 1))) { 606 rdev = rio_setup_device(net, port, RIO_ANY_DESTID(port->sys_size),
607 hopcount, 1);
608 if (rdev) {
594 /* Add device to the global and bus/net specific list. */ 609 /* Add device to the global and bus/net specific list. */
595 list_add_tail(&rdev->net_list, &net->devices); 610 list_add_tail(&rdev->net_list, &net->devices);
596 } else 611 } else
@@ -598,7 +613,8 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
598 613
599 if (rio_is_switch(rdev)) { 614 if (rio_is_switch(rdev)) {
600 next_switchid++; 615 next_switchid++;
601 sw_inport = rio_get_swpinfo_inport(port, RIO_ANY_DESTID, hopcount); 616 sw_inport = rio_get_swpinfo_inport(port,
617 RIO_ANY_DESTID(port->sys_size), hopcount);
602 rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, 618 rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE,
603 port->host_deviceid, sw_inport); 619 port->host_deviceid, sw_inport);
604 rdev->rswitch->route_table[port->host_deviceid] = sw_inport; 620 rdev->rswitch->route_table[port->host_deviceid] = sw_inport;
@@ -612,7 +628,8 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
612 } 628 }
613 629
614 num_ports = 630 num_ports =
615 rio_get_swpinfo_tports(port, RIO_ANY_DESTID, hopcount); 631 rio_get_swpinfo_tports(port, RIO_ANY_DESTID(port->sys_size),
632 hopcount);
616 pr_debug( 633 pr_debug(
617 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", 634 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
618 rio_name(rdev), rdev->vid, rdev->did, num_ports); 635 rio_name(rdev), rdev->vid, rdev->did, num_ports);
@@ -624,13 +641,15 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
624 cur_destid = next_destid; 641 cur_destid = next_destid;
625 642
626 if (rio_sport_is_active 643 if (rio_sport_is_active
627 (port, RIO_ANY_DESTID, hopcount, port_num)) { 644 (port, RIO_ANY_DESTID(port->sys_size), hopcount,
645 port_num)) {
628 pr_debug( 646 pr_debug(
629 "RIO: scanning device on port %d\n", 647 "RIO: scanning device on port %d\n",
630 port_num); 648 port_num);
631 rio_route_add_entry(port, rdev->rswitch, 649 rio_route_add_entry(port, rdev->rswitch,
632 RIO_GLOBAL_TABLE, 650 RIO_GLOBAL_TABLE,
633 RIO_ANY_DESTID, port_num); 651 RIO_ANY_DESTID(port->sys_size),
652 port_num);
634 653
635 if (rio_enum_peer(net, port, hopcount + 1) < 0) 654 if (rio_enum_peer(net, port, hopcount + 1) < 0)
636 return -1; 655 return -1;
@@ -735,7 +754,8 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
735 pr_debug( 754 pr_debug(
736 "RIO: scanning device on port %d\n", 755 "RIO: scanning device on port %d\n",
737 port_num); 756 port_num);
738 for (ndestid = 0; ndestid < RIO_ANY_DESTID; 757 for (ndestid = 0;
758 ndestid < RIO_ANY_DESTID(port->sys_size);
739 ndestid++) { 759 ndestid++) {
740 rio_route_get_entry(port, rdev->rswitch, 760 rio_route_get_entry(port, rdev->rswitch,
741 RIO_GLOBAL_TABLE, 761 RIO_GLOBAL_TABLE,
@@ -917,7 +937,9 @@ static void rio_build_route_tables(void)
917 937
918 list_for_each_entry(rdev, &rio_devices, global_list) 938 list_for_each_entry(rdev, &rio_devices, global_list)
919 if (rio_is_switch(rdev)) 939 if (rio_is_switch(rdev))
920 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) { 940 for (i = 0;
941 i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
942 i++) {
921 if (rio_route_get_entry 943 if (rio_route_get_entry
922 (rdev->net->hport, rdev->rswitch, RIO_GLOBAL_TABLE, 944 (rdev->net->hport, rdev->rswitch, RIO_GLOBAL_TABLE,
923 i, &sport) < 0) 945 i, &sport) < 0)
@@ -981,7 +1003,8 @@ int rio_disc_mport(struct rio_mport *mport)
981 del_timer_sync(&rio_enum_timer); 1003 del_timer_sync(&rio_enum_timer);
982 1004
983 pr_debug("done\n"); 1005 pr_debug("done\n");
984 if (rio_disc_peer(net, mport, RIO_ANY_DESTID, 0) < 0) { 1006 if (rio_disc_peer(net, mport, RIO_ANY_DESTID(mport->sys_size),
1007 0) < 0) {
985 printk(KERN_INFO 1008 printk(KERN_INFO
986 "RIO: master port %d device has failed discovery\n", 1009 "RIO: master port %d device has failed discovery\n",
987 mport->id); 1010 mport->id);
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 659e31164cf0..97a147f050d6 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -43,7 +43,8 @@ static ssize_t routes_show(struct device *dev, struct device_attribute *attr, ch
43 if (!rdev->rswitch) 43 if (!rdev->rswitch)
44 goto out; 44 goto out;
45 45
46 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) { 46 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
47 i++) {
47 if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE) 48 if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE)
48 continue; 49 continue;
49 str += 50 str +=
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 80c5f1ba2e49..680661abbc4b 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -43,7 +43,7 @@ u16 rio_local_get_device_id(struct rio_mport *port)
43 43
44 rio_local_read_config_32(port, RIO_DID_CSR, &result); 44 rio_local_read_config_32(port, RIO_DID_CSR, &result);
45 45
46 return (RIO_GET_DID(result)); 46 return (RIO_GET_DID(port->sys_size, result));
47} 47}
48 48
49/** 49/**
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
index 80e3f03b5041..7786d02581f2 100644
--- a/drivers/rapidio/rio.h
+++ b/drivers/rapidio/rio.h
@@ -51,10 +51,5 @@ extern struct rio_route_ops __end_rio_route_ops[];
51 DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, \ 51 DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, \
52 vid, did, add_hook, get_hook) 52 vid, did, add_hook, get_hook)
53 53
54#ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT 54#define RIO_GET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x00ff0000) >> 16))
55#define RIO_GET_DID(x) ((x & 0x00ff0000) >> 16) 55#define RIO_SET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x000000ff) << 16))
56#define RIO_SET_DID(x) ((x & 0x000000ff) << 16)
57#else
58#define RIO_GET_DID(x) (x & 0xffff)
59#define RIO_SET_DID(x) (x & 0xffff)
60#endif
diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h
index fd98ca998b4f..cf83f2d7e2a5 100644
--- a/include/asm-powerpc/processor.h
+++ b/include/asm-powerpc/processor.h
@@ -138,6 +138,8 @@ typedef struct {
138 138
139struct thread_struct { 139struct thread_struct {
140 unsigned long ksp; /* Kernel stack pointer */ 140 unsigned long ksp; /* Kernel stack pointer */
141 unsigned long ksp_limit; /* if ksp <= ksp_limit stack overflow */
142
141#ifdef CONFIG_PPC64 143#ifdef CONFIG_PPC64
142 unsigned long ksp_vsid; 144 unsigned long ksp_vsid;
143#endif 145#endif
@@ -182,11 +184,14 @@ struct thread_struct {
182#define ARCH_MIN_TASKALIGN 16 184#define ARCH_MIN_TASKALIGN 16
183 185
184#define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack) 186#define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack)
187#define INIT_SP_LIMIT \
188 (_ALIGN_UP(sizeof(init_thread_info), 16) + (unsigned long) &init_stack)
185 189
186 190
187#ifdef CONFIG_PPC32 191#ifdef CONFIG_PPC32
188#define INIT_THREAD { \ 192#define INIT_THREAD { \
189 .ksp = INIT_SP, \ 193 .ksp = INIT_SP, \
194 .ksp_limit = INIT_SP_LIMIT, \
190 .fs = KERNEL_DS, \ 195 .fs = KERNEL_DS, \
191 .pgdir = swapper_pg_dir, \ 196 .pgdir = swapper_pg_dir, \
192 .fpexc_mode = MSR_FE0 | MSR_FE1, \ 197 .fpexc_mode = MSR_FE0 | MSR_FE1, \
@@ -194,6 +199,7 @@ struct thread_struct {
194#else 199#else
195#define INIT_THREAD { \ 200#define INIT_THREAD { \
196 .ksp = INIT_SP, \ 201 .ksp = INIT_SP, \
202 .ksp_limit = INIT_SP_LIMIT, \
197 .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \ 203 .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \
198 .fs = KERNEL_DS, \ 204 .fs = KERNEL_DS, \
199 .fpr = {0}, \ 205 .fpr = {0}, \
diff --git a/include/asm-ppc/rio.h b/include/asm-powerpc/rio.h
index 0018bf80cb25..0018bf80cb25 100644
--- a/include/asm-ppc/rio.h
+++ b/include/asm-powerpc/rio.h
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index fab1674b31b6..2b6559a6d113 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -204,7 +204,7 @@ extern int powersave_nap; /* set if nap mode can be used in idle loop */
204 * Changes the memory location '*ptr' to be val and returns 204 * Changes the memory location '*ptr' to be val and returns
205 * the previous value stored there. 205 * the previous value stored there.
206 */ 206 */
207static __inline__ unsigned long 207static __always_inline unsigned long
208__xchg_u32(volatile void *p, unsigned long val) 208__xchg_u32(volatile void *p, unsigned long val)
209{ 209{
210 unsigned long prev; 210 unsigned long prev;
@@ -229,7 +229,7 @@ __xchg_u32(volatile void *p, unsigned long val)
229 * Changes the memory location '*ptr' to be val and returns 229 * Changes the memory location '*ptr' to be val and returns
230 * the previous value stored there. 230 * the previous value stored there.
231 */ 231 */
232static __inline__ unsigned long 232static __always_inline unsigned long
233__xchg_u32_local(volatile void *p, unsigned long val) 233__xchg_u32_local(volatile void *p, unsigned long val)
234{ 234{
235 unsigned long prev; 235 unsigned long prev;
@@ -247,7 +247,7 @@ __xchg_u32_local(volatile void *p, unsigned long val)
247} 247}
248 248
249#ifdef CONFIG_PPC64 249#ifdef CONFIG_PPC64
250static __inline__ unsigned long 250static __always_inline unsigned long
251__xchg_u64(volatile void *p, unsigned long val) 251__xchg_u64(volatile void *p, unsigned long val)
252{ 252{
253 unsigned long prev; 253 unsigned long prev;
@@ -266,7 +266,7 @@ __xchg_u64(volatile void *p, unsigned long val)
266 return prev; 266 return prev;
267} 267}
268 268
269static __inline__ unsigned long 269static __always_inline unsigned long
270__xchg_u64_local(volatile void *p, unsigned long val) 270__xchg_u64_local(volatile void *p, unsigned long val)
271{ 271{
272 unsigned long prev; 272 unsigned long prev;
@@ -290,7 +290,7 @@ __xchg_u64_local(volatile void *p, unsigned long val)
290 */ 290 */
291extern void __xchg_called_with_bad_pointer(void); 291extern void __xchg_called_with_bad_pointer(void);
292 292
293static __inline__ unsigned long 293static __always_inline unsigned long
294__xchg(volatile void *ptr, unsigned long x, unsigned int size) 294__xchg(volatile void *ptr, unsigned long x, unsigned int size)
295{ 295{
296 switch (size) { 296 switch (size) {
@@ -305,7 +305,7 @@ __xchg(volatile void *ptr, unsigned long x, unsigned int size)
305 return x; 305 return x;
306} 306}
307 307
308static __inline__ unsigned long 308static __always_inline unsigned long
309__xchg_local(volatile void *ptr, unsigned long x, unsigned int size) 309__xchg_local(volatile void *ptr, unsigned long x, unsigned int size)
310{ 310{
311 switch (size) { 311 switch (size) {
@@ -338,7 +338,7 @@ __xchg_local(volatile void *ptr, unsigned long x, unsigned int size)
338 */ 338 */
339#define __HAVE_ARCH_CMPXCHG 1 339#define __HAVE_ARCH_CMPXCHG 1
340 340
341static __inline__ unsigned long 341static __always_inline unsigned long
342__cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new) 342__cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
343{ 343{
344 unsigned int prev; 344 unsigned int prev;
@@ -361,7 +361,7 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
361 return prev; 361 return prev;
362} 362}
363 363
364static __inline__ unsigned long 364static __always_inline unsigned long
365__cmpxchg_u32_local(volatile unsigned int *p, unsigned long old, 365__cmpxchg_u32_local(volatile unsigned int *p, unsigned long old,
366 unsigned long new) 366 unsigned long new)
367{ 367{
@@ -384,7 +384,7 @@ __cmpxchg_u32_local(volatile unsigned int *p, unsigned long old,
384} 384}
385 385
386#ifdef CONFIG_PPC64 386#ifdef CONFIG_PPC64
387static __inline__ unsigned long 387static __always_inline unsigned long
388__cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new) 388__cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
389{ 389{
390 unsigned long prev; 390 unsigned long prev;
@@ -406,7 +406,7 @@ __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
406 return prev; 406 return prev;
407} 407}
408 408
409static __inline__ unsigned long 409static __always_inline unsigned long
410__cmpxchg_u64_local(volatile unsigned long *p, unsigned long old, 410__cmpxchg_u64_local(volatile unsigned long *p, unsigned long old,
411 unsigned long new) 411 unsigned long new)
412{ 412{
@@ -432,7 +432,7 @@ __cmpxchg_u64_local(volatile unsigned long *p, unsigned long old,
432 if something tries to do an invalid cmpxchg(). */ 432 if something tries to do an invalid cmpxchg(). */
433extern void __cmpxchg_called_with_bad_pointer(void); 433extern void __cmpxchg_called_with_bad_pointer(void);
434 434
435static __inline__ unsigned long 435static __always_inline unsigned long
436__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, 436__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
437 unsigned int size) 437 unsigned int size)
438{ 438{
@@ -448,7 +448,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
448 return old; 448 return old;
449} 449}
450 450
451static __inline__ unsigned long 451static __always_inline unsigned long
452__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new, 452__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
453 unsigned int size) 453 unsigned int size)
454{ 454{
diff --git a/include/linux/lmb.h b/include/linux/lmb.h
index 271153d27fba..c46c89505dac 100644
--- a/include/linux/lmb.h
+++ b/include/linux/lmb.h
@@ -40,7 +40,8 @@ extern struct lmb lmb;
40 40
41extern void __init lmb_init(void); 41extern void __init lmb_init(void);
42extern void __init lmb_analyze(void); 42extern void __init lmb_analyze(void);
43extern long __init lmb_add(u64 base, u64 size); 43extern long lmb_add(u64 base, u64 size);
44extern long lmb_remove(u64 base, u64 size);
44extern long __init lmb_reserve(u64 base, u64 size); 45extern long __init lmb_reserve(u64 base, u64 size);
45extern u64 __init lmb_alloc_nid(u64 size, u64 align, int nid, 46extern u64 __init lmb_alloc_nid(u64 size, u64 align, int nid,
46 u64 (*nid_range)(u64, u64, int *)); 47 u64 (*nid_range)(u64, u64, int *));
@@ -53,6 +54,7 @@ extern u64 __init lmb_phys_mem_size(void);
53extern u64 __init lmb_end_of_DRAM(void); 54extern u64 __init lmb_end_of_DRAM(void);
54extern void __init lmb_enforce_memory_limit(u64 memory_limit); 55extern void __init lmb_enforce_memory_limit(u64 memory_limit);
55extern int __init lmb_is_reserved(u64 addr); 56extern int __init lmb_is_reserved(u64 addr);
57extern int lmb_find(struct lmb_property *res);
56 58
57extern void lmb_dump_all(void); 59extern void lmb_dump_all(void);
58 60
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 68e3f6853fa6..cfb66bbc0f27 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -23,7 +23,6 @@
23#include <linux/device.h> 23#include <linux/device.h>
24#include <linux/rio_regs.h> 24#include <linux/rio_regs.h>
25 25
26#define RIO_ANY_DESTID 0xff
27#define RIO_NO_HOPCOUNT -1 26#define RIO_NO_HOPCOUNT -1
28#define RIO_INVALID_DESTID 0xffff 27#define RIO_INVALID_DESTID 0xffff
29 28
@@ -39,11 +38,8 @@
39 entry is invalid (no route 38 entry is invalid (no route
40 exists for the device ID) */ 39 exists for the device ID) */
41 40
42#ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT 41#define RIO_MAX_ROUTE_ENTRIES(size) (size ? (1 << 16) : (1 << 8))
43#define RIO_MAX_ROUTE_ENTRIES (1 << 8) 42#define RIO_ANY_DESTID(size) (size ? 0xffff : 0xff)
44#else
45#define RIO_MAX_ROUTE_ENTRIES (1 << 16)
46#endif
47 43
48#define RIO_MAX_MBOX 4 44#define RIO_MAX_MBOX 4
49#define RIO_MAX_MSG_SIZE 0x1000 45#define RIO_MAX_MSG_SIZE 0x1000
@@ -149,6 +145,11 @@ struct rio_dbell {
149 void *dev_id; 145 void *dev_id;
150}; 146};
151 147
148enum rio_phy_type {
149 RIO_PHY_PARALLEL,
150 RIO_PHY_SERIAL,
151};
152
152/** 153/**
153 * struct rio_mport - RIO master port info 154 * struct rio_mport - RIO master port info
154 * @dbells: List of doorbell events 155 * @dbells: List of doorbell events
@@ -163,6 +164,7 @@ struct rio_dbell {
163 * @id: Port ID, unique among all ports 164 * @id: Port ID, unique among all ports
164 * @index: Port index, unique among all port interfaces of the same type 165 * @index: Port index, unique among all port interfaces of the same type
165 * @name: Port name string 166 * @name: Port name string
167 * @priv: Master port private data
166 */ 168 */
167struct rio_mport { 169struct rio_mport {
168 struct list_head dbells; /* list of doorbell events */ 170 struct list_head dbells; /* list of doorbell events */
@@ -177,7 +179,13 @@ struct rio_mport {
177 unsigned char id; /* port ID, unique among all ports */ 179 unsigned char id; /* port ID, unique among all ports */
178 unsigned char index; /* port index, unique among all port 180 unsigned char index; /* port index, unique among all port
179 interfaces of the same type */ 181 interfaces of the same type */
182 unsigned int sys_size; /* RapidIO common transport system size.
183 * 0 - Small size. 256 devices.
184 * 1 - Large size, 65536 devices.
185 */
186 enum rio_phy_type phy_type; /* RapidIO phy type */
180 unsigned char name[40]; 187 unsigned char name[40];
188 void *priv; /* Master port private data */
181}; 189};
182 190
183/** 191/**
@@ -211,7 +219,7 @@ struct rio_switch {
211 u16 switchid; 219 u16 switchid;
212 u16 hopcount; 220 u16 hopcount;
213 u16 destid; 221 u16 destid;
214 u8 route_table[RIO_MAX_ROUTE_ENTRIES]; 222 u8 *route_table;
215 int (*add_entry) (struct rio_mport * mport, u16 destid, u8 hopcount, 223 int (*add_entry) (struct rio_mport * mport, u16 destid, u8 hopcount,
216 u16 table, u16 route_destid, u8 route_port); 224 u16 table, u16 route_destid, u8 route_port);
217 int (*get_entry) (struct rio_mport * mport, u16 destid, u8 hopcount, 225 int (*get_entry) (struct rio_mport * mport, u16 destid, u8 hopcount,
@@ -229,13 +237,15 @@ struct rio_switch {
229 * @dsend: Callback to send a doorbell message. 237 * @dsend: Callback to send a doorbell message.
230 */ 238 */
231struct rio_ops { 239struct rio_ops {
232 int (*lcread) (int index, u32 offset, int len, u32 * data); 240 int (*lcread) (struct rio_mport *mport, int index, u32 offset, int len,
233 int (*lcwrite) (int index, u32 offset, int len, u32 data); 241 u32 *data);
234 int (*cread) (int index, u16 destid, u8 hopcount, u32 offset, int len, 242 int (*lcwrite) (struct rio_mport *mport, int index, u32 offset, int len,
235 u32 * data); 243 u32 data);
236 int (*cwrite) (int index, u16 destid, u8 hopcount, u32 offset, int len, 244 int (*cread) (struct rio_mport *mport, int index, u16 destid,
237 u32 data); 245 u8 hopcount, u32 offset, int len, u32 *data);
238 int (*dsend) (int index, u16 destid, u16 data); 246 int (*cwrite) (struct rio_mport *mport, int index, u16 destid,
247 u8 hopcount, u32 offset, int len, u32 data);
248 int (*dsend) (struct rio_mport *mport, int index, u16 destid, u16 data);
239}; 249};
240 250
241#define RIO_RESOURCE_MEM 0x00000100 251#define RIO_RESOURCE_MEM 0x00000100
diff --git a/lib/lmb.c b/lib/lmb.c
index 207147ab25e4..83287d3869a3 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -46,14 +46,13 @@ void lmb_dump_all(void)
46#endif /* DEBUG */ 46#endif /* DEBUG */
47} 47}
48 48
49static unsigned long __init lmb_addrs_overlap(u64 base1, u64 size1, 49static unsigned long lmb_addrs_overlap(u64 base1, u64 size1, u64 base2,
50 u64 base2, u64 size2) 50 u64 size2)
51{ 51{
52 return ((base1 < (base2 + size2)) && (base2 < (base1 + size1))); 52 return ((base1 < (base2 + size2)) && (base2 < (base1 + size1)));
53} 53}
54 54
55static long __init lmb_addrs_adjacent(u64 base1, u64 size1, 55static long lmb_addrs_adjacent(u64 base1, u64 size1, u64 base2, u64 size2)
56 u64 base2, u64 size2)
57{ 56{
58 if (base2 == base1 + size1) 57 if (base2 == base1 + size1)
59 return 1; 58 return 1;
@@ -63,7 +62,7 @@ static long __init lmb_addrs_adjacent(u64 base1, u64 size1,
63 return 0; 62 return 0;
64} 63}
65 64
66static long __init lmb_regions_adjacent(struct lmb_region *rgn, 65static long lmb_regions_adjacent(struct lmb_region *rgn,
67 unsigned long r1, unsigned long r2) 66 unsigned long r1, unsigned long r2)
68{ 67{
69 u64 base1 = rgn->region[r1].base; 68 u64 base1 = rgn->region[r1].base;
@@ -74,7 +73,7 @@ static long __init lmb_regions_adjacent(struct lmb_region *rgn,
74 return lmb_addrs_adjacent(base1, size1, base2, size2); 73 return lmb_addrs_adjacent(base1, size1, base2, size2);
75} 74}
76 75
77static void __init lmb_remove_region(struct lmb_region *rgn, unsigned long r) 76static void lmb_remove_region(struct lmb_region *rgn, unsigned long r)
78{ 77{
79 unsigned long i; 78 unsigned long i;
80 79
@@ -86,7 +85,7 @@ static void __init lmb_remove_region(struct lmb_region *rgn, unsigned long r)
86} 85}
87 86
88/* Assumption: base addr of region 1 < base addr of region 2 */ 87/* Assumption: base addr of region 1 < base addr of region 2 */
89static void __init lmb_coalesce_regions(struct lmb_region *rgn, 88static void lmb_coalesce_regions(struct lmb_region *rgn,
90 unsigned long r1, unsigned long r2) 89 unsigned long r1, unsigned long r2)
91{ 90{
92 rgn->region[r1].size += rgn->region[r2].size; 91 rgn->region[r1].size += rgn->region[r2].size;
@@ -118,7 +117,7 @@ void __init lmb_analyze(void)
118 lmb.memory.size += lmb.memory.region[i].size; 117 lmb.memory.size += lmb.memory.region[i].size;
119} 118}
120 119
121static long __init lmb_add_region(struct lmb_region *rgn, u64 base, u64 size) 120static long lmb_add_region(struct lmb_region *rgn, u64 base, u64 size)
122{ 121{
123 unsigned long coalesced = 0; 122 unsigned long coalesced = 0;
124 long adjacent, i; 123 long adjacent, i;
@@ -182,7 +181,7 @@ static long __init lmb_add_region(struct lmb_region *rgn, u64 base, u64 size)
182 return 0; 181 return 0;
183} 182}
184 183
185long __init lmb_add(u64 base, u64 size) 184long lmb_add(u64 base, u64 size)
186{ 185{
187 struct lmb_region *_rgn = &lmb.memory; 186 struct lmb_region *_rgn = &lmb.memory;
188 187
@@ -194,6 +193,55 @@ long __init lmb_add(u64 base, u64 size)
194 193
195} 194}
196 195
196long lmb_remove(u64 base, u64 size)
197{
198 struct lmb_region *rgn = &(lmb.memory);
199 u64 rgnbegin, rgnend;
200 u64 end = base + size;
201 int i;
202
203 rgnbegin = rgnend = 0; /* supress gcc warnings */
204
205 /* Find the region where (base, size) belongs to */
206 for (i=0; i < rgn->cnt; i++) {
207 rgnbegin = rgn->region[i].base;
208 rgnend = rgnbegin + rgn->region[i].size;
209
210 if ((rgnbegin <= base) && (end <= rgnend))
211 break;
212 }
213
214 /* Didn't find the region */
215 if (i == rgn->cnt)
216 return -1;
217
218 /* Check to see if we are removing entire region */
219 if ((rgnbegin == base) && (rgnend == end)) {
220 lmb_remove_region(rgn, i);
221 return 0;
222 }
223
224 /* Check to see if region is matching at the front */
225 if (rgnbegin == base) {
226 rgn->region[i].base = end;
227 rgn->region[i].size -= size;
228 return 0;
229 }
230
231 /* Check to see if the region is matching at the end */
232 if (rgnend == end) {
233 rgn->region[i].size -= size;
234 return 0;
235 }
236
237 /*
238 * We need to split the entry - adjust the current one to the
239 * beginging of the hole and add the region after hole.
240 */
241 rgn->region[i].size = base - rgn->region[i].base;
242 return lmb_add_region(rgn, end, rgnend - end);
243}
244
197long __init lmb_reserve(u64 base, u64 size) 245long __init lmb_reserve(u64 base, u64 size)
198{ 246{
199 struct lmb_region *_rgn = &lmb.reserved; 247 struct lmb_region *_rgn = &lmb.reserved;
@@ -426,3 +474,36 @@ int __init lmb_is_reserved(u64 addr)
426 } 474 }
427 return 0; 475 return 0;
428} 476}
477
478/*
479 * Given a <base, len>, find which memory regions belong to this range.
480 * Adjust the request and return a contiguous chunk.
481 */
482int lmb_find(struct lmb_property *res)
483{
484 int i;
485 u64 rstart, rend;
486
487 rstart = res->base;
488 rend = rstart + res->size - 1;
489
490 for (i = 0; i < lmb.memory.cnt; i++) {
491 u64 start = lmb.memory.region[i].base;
492 u64 end = start + lmb.memory.region[i].size - 1;
493
494 if (start > rend)
495 return -1;
496
497 if ((end >= rstart) && (start < rend)) {
498 /* adjust the request */
499 if (rstart < start)
500 rstart = start;
501 if (rend > end)
502 rend = end;
503 res->base = rstart;
504 res->size = rend - rstart + 1;
505 return 0;
506 }
507 }
508 return -1;
509}