aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-23 12:02:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-23 12:02:42 -0400
commit6f73b3629f774c6cba589b15fd095112b25ca923 (patch)
tree50a60feae71cb5f40078f552b9b08468bc7b29c9 /arch/powerpc/kernel
parent3a8580f82024e30b31c662aa49346adf7a3bcdb5 (diff)
parent2074b1d9d53ae696dd3f49482bad43254f40f01d (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull powerpc updates from Benjamin Herrenschmidt: "Here are the powerpc goodies for 3.5. Main highlights are: - Support for the NX crypto engine in Power7+ - A bunch of Anton goodness, including some micro optimization of our syscall entry on Power7 - I converted a pile of our thermal control drivers to the new i2c APIs (essentially turning the old therm_pm72 into a proper set of windfarm drivers). That's one more step toward removing the deprecated i2c APIs, there's still a few drivers to fix, but we are getting close - kexec/kdump support for 47x embedded cores The big missing thing here is no updates from Freescale. Not sure what's up here, but with Kumar not working for them anymore things are a bit in a state of flux in that area." * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (71 commits) powerpc: Fix irq distribution Revert "powerpc/hw-breakpoint: Use generic hw-breakpoint interfaces for new PPC ptrace flags" powerpc: Fixing a cputhread code documentation powerpc/crypto: Enable the PFO-based encryption device powerpc/crypto: Build files for the nx device driver powerpc/crypto: debugfs routines and docs for the nx device driver powerpc/crypto: SHA512 hash routines for nx encryption powerpc/crypto: SHA256 hash routines for nx encryption powerpc/crypto: AES-XCBC mode routines for nx encryption powerpc/crypto: AES-GCM mode routines for nx encryption powerpc/crypto: AES-ECB mode routines for nx encryption powerpc/crypto: AES-CTR mode routines for nx encryption powerpc/crypto: AES-CCM mode routines for nx encryption powerpc/crypto: AES-CBC mode routines for nx encryption powerpc/crypto: nx driver code supporting nx encryption powerpc/pseries: Enable the PFO-based RNG accelerator powerpc/pseries/hwrng: PFO-based hwrng driver powerpc/pseries: Add PFO support to the VIO bus powerpc/pseries: Add pseries update notifier for OFDT prop changes powerpc/pseries: Add new hvcall constants to support PFO ...
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/asm-offsets.c4
-rw-r--r--arch/powerpc/kernel/entry_64.S30
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S4
-rw-r--r--arch/powerpc/kernel/head_44x.S8
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S8
-rw-r--r--arch/powerpc/kernel/irq.c2
-rw-r--r--arch/powerpc/kernel/misc_32.S203
-rw-r--r--arch/powerpc/kernel/paca.c3
-rw-r--r--arch/powerpc/kernel/process.c2
-rw-r--r--arch/powerpc/kernel/prom_init.c17
-rw-r--r--arch/powerpc/kernel/ptrace.c42
-rw-r--r--arch/powerpc/kernel/ptrace32.c32
-rw-r--r--arch/powerpc/kernel/vector.S10
-rw-r--r--arch/powerpc/kernel/vio.c273
14 files changed, 468 insertions, 170 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 34b8afe94a50..4554dc2fe857 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -188,10 +188,6 @@ int main(void)
188 DEFINE(SLBSHADOW_STACKESID, 188 DEFINE(SLBSHADOW_STACKESID,
189 offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].esid)); 189 offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].esid));
190 DEFINE(SLBSHADOW_SAVEAREA, offsetof(struct slb_shadow, save_area)); 190 DEFINE(SLBSHADOW_SAVEAREA, offsetof(struct slb_shadow, save_area));
191 DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
192 DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
193 DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
194 DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
195 DEFINE(LPPACA_PMCINUSE, offsetof(struct lppaca, pmcregs_in_use)); 191 DEFINE(LPPACA_PMCINUSE, offsetof(struct lppaca, pmcregs_in_use));
196 DEFINE(LPPACA_DTLIDX, offsetof(struct lppaca, dtl_idx)); 192 DEFINE(LPPACA_DTLIDX, offsetof(struct lppaca, dtl_idx));
197 DEFINE(LPPACA_YIELDCOUNT, offsetof(struct lppaca, yield_count)); 193 DEFINE(LPPACA_YIELDCOUNT, offsetof(struct lppaca, yield_count));
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index ef2074c3e906..ed1718feb9d9 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -63,15 +63,9 @@ system_call_common:
63 std r0,GPR0(r1) 63 std r0,GPR0(r1)
64 std r10,GPR1(r1) 64 std r10,GPR1(r1)
65 ACCOUNT_CPU_USER_ENTRY(r10, r11) 65 ACCOUNT_CPU_USER_ENTRY(r10, r11)
66 /*
67 * This "crclr so" clears CR0.SO, which is the error indication on
68 * return from this system call. There must be no cmp instruction
69 * between it and the "mfcr r9" below, otherwise if XER.SO is set,
70 * CR0.SO will get set, causing all system calls to appear to fail.
71 */
72 crclr so
73 std r2,GPR2(r1) 66 std r2,GPR2(r1)
74 std r3,GPR3(r1) 67 std r3,GPR3(r1)
68 mfcr r2
75 std r4,GPR4(r1) 69 std r4,GPR4(r1)
76 std r5,GPR5(r1) 70 std r5,GPR5(r1)
77 std r6,GPR6(r1) 71 std r6,GPR6(r1)
@@ -82,18 +76,20 @@ system_call_common:
82 std r11,GPR10(r1) 76 std r11,GPR10(r1)
83 std r11,GPR11(r1) 77 std r11,GPR11(r1)
84 std r11,GPR12(r1) 78 std r11,GPR12(r1)
79 std r11,_XER(r1)
80 std r11,_CTR(r1)
85 std r9,GPR13(r1) 81 std r9,GPR13(r1)
86 mfcr r9
87 mflr r10 82 mflr r10
83 /*
84 * This clears CR0.SO (bit 28), which is the error indication on
85 * return from this system call.
86 */
87 rldimi r2,r11,28,(63-28)
88 li r11,0xc01 88 li r11,0xc01
89 std r9,_CCR(r1)
90 std r10,_LINK(r1) 89 std r10,_LINK(r1)
91 std r11,_TRAP(r1) 90 std r11,_TRAP(r1)
92 mfxer r9
93 mfctr r10
94 std r9,_XER(r1)
95 std r10,_CTR(r1)
96 std r3,ORIG_GPR3(r1) 91 std r3,ORIG_GPR3(r1)
92 std r2,_CCR(r1)
97 ld r2,PACATOC(r13) 93 ld r2,PACATOC(r13)
98 addi r9,r1,STACK_FRAME_OVERHEAD 94 addi r9,r1,STACK_FRAME_OVERHEAD
99 ld r11,exception_marker@toc(r2) 95 ld r11,exception_marker@toc(r2)
@@ -154,7 +150,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
154 ld r10,TI_FLAGS(r11) 150 ld r10,TI_FLAGS(r11)
155 andi. r11,r10,_TIF_SYSCALL_T_OR_A 151 andi. r11,r10,_TIF_SYSCALL_T_OR_A
156 bne- syscall_dotrace 152 bne- syscall_dotrace
157syscall_dotrace_cont: 153.Lsyscall_dotrace_cont:
158 cmpldi 0,r0,NR_syscalls 154 cmpldi 0,r0,NR_syscalls
159 bge- syscall_enosys 155 bge- syscall_enosys
160 156
@@ -211,7 +207,7 @@ syscall_exit:
211 cmpld r3,r11 207 cmpld r3,r11
212 ld r5,_CCR(r1) 208 ld r5,_CCR(r1)
213 bge- syscall_error 209 bge- syscall_error
214syscall_error_cont: 210.Lsyscall_error_cont:
215 ld r7,_NIP(r1) 211 ld r7,_NIP(r1)
216BEGIN_FTR_SECTION 212BEGIN_FTR_SECTION
217 stdcx. r0,0,r1 /* to clear the reservation */ 213 stdcx. r0,0,r1 /* to clear the reservation */
@@ -246,7 +242,7 @@ syscall_error:
246 oris r5,r5,0x1000 /* Set SO bit in CR */ 242 oris r5,r5,0x1000 /* Set SO bit in CR */
247 neg r3,r3 243 neg r3,r3
248 std r5,_CCR(r1) 244 std r5,_CCR(r1)
249 b syscall_error_cont 245 b .Lsyscall_error_cont
250 246
251/* Traced system call support */ 247/* Traced system call support */
252syscall_dotrace: 248syscall_dotrace:
@@ -268,7 +264,7 @@ syscall_dotrace:
268 addi r9,r1,STACK_FRAME_OVERHEAD 264 addi r9,r1,STACK_FRAME_OVERHEAD
269 clrrdi r10,r1,THREAD_SHIFT 265 clrrdi r10,r1,THREAD_SHIFT
270 ld r10,TI_FLAGS(r10) 266 ld r10,TI_FLAGS(r10)
271 b syscall_dotrace_cont 267 b .Lsyscall_dotrace_cont
272 268
273syscall_enosys: 269syscall_enosys:
274 li r3,-ENOSYS 270 li r3,-ENOSYS
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 8f880bc77c56..f7bed44ee165 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -94,12 +94,10 @@ machine_check_pSeries_1:
94data_access_pSeries: 94data_access_pSeries:
95 HMT_MEDIUM 95 HMT_MEDIUM
96 SET_SCRATCH0(r13) 96 SET_SCRATCH0(r13)
97#ifndef CONFIG_POWER4_ONLY
98BEGIN_FTR_SECTION 97BEGIN_FTR_SECTION
99 b data_access_check_stab 98 b data_access_check_stab
100data_access_not_stab: 99data_access_not_stab:
101END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB) 100END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB)
102#endif
103 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common, EXC_STD, 101 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common, EXC_STD,
104 KVMTEST, 0x300) 102 KVMTEST, 0x300)
105 103
@@ -301,7 +299,6 @@ machine_check_fwnmi:
301 EXC_STD, KVMTEST, 0x200) 299 EXC_STD, KVMTEST, 0x200)
302 KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200) 300 KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200)
303 301
304#ifndef CONFIG_POWER4_ONLY
305 /* moved from 0x300 */ 302 /* moved from 0x300 */
306data_access_check_stab: 303data_access_check_stab:
307 GET_PACA(r13) 304 GET_PACA(r13)
@@ -328,7 +325,6 @@ do_stab_bolted_pSeries:
328 GET_SCRATCH0(r10) 325 GET_SCRATCH0(r10)
329 std r10,PACA_EXSLB+EX_R13(r13) 326 std r10,PACA_EXSLB+EX_R13(r13)
330 EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD) 327 EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD)
331#endif /* CONFIG_POWER4_ONLY */
332 328
333 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300) 329 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300)
334 KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380) 330 KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380)
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index 7dd2981bcc50..22d608e8bb7d 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -778,14 +778,6 @@ _GLOBAL(__fixup_440A_mcheck)
778 blr 778 blr
779 779
780/* 780/*
781 * extern void giveup_altivec(struct task_struct *prev)
782 *
783 * The 44x core does not have an AltiVec unit.
784 */
785_GLOBAL(giveup_altivec)
786 blr
787
788/*
789 * extern void giveup_fpu(struct task_struct *prev) 781 * extern void giveup_fpu(struct task_struct *prev)
790 * 782 *
791 * The 44x core does not have an FPU. 783 * The 44x core does not have an FPU.
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 28e62598d0e8..de80e0f9a2bd 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -874,14 +874,6 @@ _GLOBAL(__setup_e500mc_ivors)
874 sync 874 sync
875 blr 875 blr
876 876
877/*
878 * extern void giveup_altivec(struct task_struct *prev)
879 *
880 * The e500 core does not have an AltiVec unit.
881 */
882_GLOBAL(giveup_altivec)
883 blr
884
885#ifdef CONFIG_SPE 877#ifdef CONFIG_SPE
886/* 878/*
887 * extern void giveup_spe(struct task_struct *prev) 879 * extern void giveup_spe(struct task_struct *prev)
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 641da9e868ce..7835a5e1ea5f 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -587,7 +587,7 @@ int irq_choose_cpu(const struct cpumask *mask)
587{ 587{
588 int cpuid; 588 int cpuid;
589 589
590 if (cpumask_equal(mask, cpu_all_mask)) { 590 if (cpumask_equal(mask, cpu_online_mask)) {
591 static int irq_rover; 591 static int irq_rover;
592 static DEFINE_RAW_SPINLOCK(irq_rover_lock); 592 static DEFINE_RAW_SPINLOCK(irq_rover_lock);
593 unsigned long flags; 593 unsigned long flags;
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 7cd07b42ca1a..386d57f66f28 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -738,8 +738,23 @@ relocate_new_kernel:
738 mr r5, r31 738 mr r5, r31
739 739
740 li r0, 0 740 li r0, 0
741#elif defined(CONFIG_44x) && !defined(CONFIG_PPC_47x) 741#elif defined(CONFIG_44x)
742 742
743 /* Save our parameters */
744 mr r29, r3
745 mr r30, r4
746 mr r31, r5
747
748#ifdef CONFIG_PPC_47x
749 /* Check for 47x cores */
750 mfspr r3,SPRN_PVR
751 srwi r3,r3,16
752 cmplwi cr0,r3,PVR_476@h
753 beq setup_map_47x
754 cmplwi cr0,r3,PVR_476_ISS@h
755 beq setup_map_47x
756#endif /* CONFIG_PPC_47x */
757
743/* 758/*
744 * Code for setting up 1:1 mapping for PPC440x for KEXEC 759 * Code for setting up 1:1 mapping for PPC440x for KEXEC
745 * 760 *
@@ -753,16 +768,15 @@ relocate_new_kernel:
753 * 5) Invalidate the tmp mapping. 768 * 5) Invalidate the tmp mapping.
754 * 769 *
755 * - Based on the kexec support code for FSL BookE 770 * - Based on the kexec support code for FSL BookE
756 * - Doesn't support 47x yet.
757 * 771 *
758 */ 772 */
759 /* Save our parameters */
760 mr r29, r3
761 mr r30, r4
762 mr r31, r5
763 773
764 /* Load our MSR_IS and TID to MMUCR for TLB search */ 774 /*
765 mfspr r3,SPRN_PID 775 * Load the PID with kernel PID (0).
776 * Also load our MSR_IS and TID to MMUCR for TLB search.
777 */
778 li r3, 0
779 mtspr SPRN_PID, r3
766 mfmsr r4 780 mfmsr r4
767 andi. r4,r4,MSR_IS@l 781 andi. r4,r4,MSR_IS@l
768 beq wmmucr 782 beq wmmucr
@@ -900,6 +914,179 @@ next_tlb:
900 li r3, 0 914 li r3, 0
901 tlbwe r3, r24, PPC44x_TLB_PAGEID 915 tlbwe r3, r24, PPC44x_TLB_PAGEID
902 sync 916 sync
917 b ppc44x_map_done
918
919#ifdef CONFIG_PPC_47x
920
921 /* 1:1 mapping for 47x */
922
923setup_map_47x:
924
925 /*
926 * Load the kernel pid (0) to PID and also to MMUCR[TID].
927 * Also set the MSR IS->MMUCR STS
928 */
929 li r3, 0
930 mtspr SPRN_PID, r3 /* Set PID */
931 mfmsr r4 /* Get MSR */
932 andi. r4, r4, MSR_IS@l /* TS=1? */
933 beq 1f /* If not, leave STS=0 */
934 oris r3, r3, PPC47x_MMUCR_STS@h /* Set STS=1 */
9351: mtspr SPRN_MMUCR, r3 /* Put MMUCR */
936 sync
937
938 /* Find the entry we are running from */
939 bl 2f
9402: mflr r23
941 tlbsx r23, 0, r23
942 tlbre r24, r23, 0 /* TLB Word 0 */
943 tlbre r25, r23, 1 /* TLB Word 1 */
944 tlbre r26, r23, 2 /* TLB Word 2 */
945
946
947 /*
948 * Invalidates all the tlb entries by writing to 256 RPNs(r4)
949 * of 4k page size in all 4 ways (0-3 in r3).
950 * This would invalidate the entire UTLB including the one we are
951 * running from. However the shadow TLB entries would help us
952 * to continue the execution, until we flush them (rfi/isync).
953 */
954 addis r3, 0, 0x8000 /* specify the way */
955 addi r4, 0, 0 /* TLB Word0 = (EPN=0, VALID = 0) */
956 addi r5, 0, 0
957 b clear_utlb_entry
958
959 /* Align the loop to speed things up. from head_44x.S */
960 .align 6
961
962clear_utlb_entry:
963
964 tlbwe r4, r3, 0
965 tlbwe r5, r3, 1
966 tlbwe r5, r3, 2
967 addis r3, r3, 0x2000 /* Increment the way */
968 cmpwi r3, 0
969 bne clear_utlb_entry
970 addis r3, 0, 0x8000
971 addis r4, r4, 0x100 /* Increment the EPN */
972 cmpwi r4, 0
973 bne clear_utlb_entry
974
975 /* Create the entries in the other address space */
976 mfmsr r5
977 rlwinm r7, r5, 27, 31, 31 /* Get the TS (Bit 26) from MSR */
978 xori r7, r7, 1 /* r7 = !TS */
979
980 insrwi r24, r7, 1, 21 /* Change the TS in the saved TLB word 0 */
981
982 /*
983 * write out the TLB entries for the tmp mapping
984 * Use way '0' so that we could easily invalidate it later.
985 */
986 lis r3, 0x8000 /* Way '0' */
987
988 tlbwe r24, r3, 0
989 tlbwe r25, r3, 1
990 tlbwe r26, r3, 2
991
992 /* Update the msr to the new TS */
993 insrwi r5, r7, 1, 26
994
995 bl 1f
9961: mflr r6
997 addi r6, r6, (2f-1b)
998
999 mtspr SPRN_SRR0, r6
1000 mtspr SPRN_SRR1, r5
1001 rfi
1002
1003 /*
1004 * Now we are in the tmp address space.
1005 * Create a 1:1 mapping for 0-2GiB in the original TS.
1006 */
10072:
1008 li r3, 0
1009 li r4, 0 /* TLB Word 0 */
1010 li r5, 0 /* TLB Word 1 */
1011 li r6, 0
1012 ori r6, r6, PPC47x_TLB2_S_RWX /* TLB word 2 */
1013
1014 li r8, 0 /* PageIndex */
1015
1016 xori r7, r7, 1 /* revert back to original TS */
1017
1018write_utlb:
1019 rotlwi r5, r8, 28 /* RPN = PageIndex * 256M */
1020 /* ERPN = 0 as we don't use memory above 2G */
1021
1022 mr r4, r5 /* EPN = RPN */
1023 ori r4, r4, (PPC47x_TLB0_VALID | PPC47x_TLB0_256M)
1024 insrwi r4, r7, 1, 21 /* Insert the TS to Word 0 */
1025
1026 tlbwe r4, r3, 0 /* Write out the entries */
1027 tlbwe r5, r3, 1
1028 tlbwe r6, r3, 2
1029 addi r8, r8, 1
1030 cmpwi r8, 8 /* Have we completed ? */
1031 bne write_utlb
1032
1033 /* make sure we complete the TLB write up */
1034 isync
1035
1036 /*
1037 * Prepare to jump to the 1:1 mapping.
1038 * 1) Extract page size of the tmp mapping
1039 * DSIZ = TLB_Word0[22:27]
1040 * 2) Calculate the physical address of the address
1041 * to jump to.
1042 */
1043 rlwinm r10, r24, 0, 22, 27
1044
1045 cmpwi r10, PPC47x_TLB0_4K
1046 bne 0f
1047 li r10, 0x1000 /* r10 = 4k */
1048 bl 1f
1049
10500:
1051 /* Defaults to 256M */
1052 lis r10, 0x1000
1053
1054 bl 1f
10551: mflr r4
1056 addi r4, r4, (2f-1b) /* virtual address of 2f */
1057
1058 subi r11, r10, 1 /* offsetmask = Pagesize - 1 */
1059 not r10, r11 /* Pagemask = ~(offsetmask) */
1060
1061 and r5, r25, r10 /* Physical page */
1062 and r6, r4, r11 /* offset within the current page */
1063
1064 or r5, r5, r6 /* Physical address for 2f */
1065
1066 /* Switch the TS in MSR to the original one */
1067 mfmsr r8
1068 insrwi r8, r7, 1, 26
1069
1070 mtspr SPRN_SRR1, r8
1071 mtspr SPRN_SRR0, r5
1072 rfi
1073
10742:
1075 /* Invalidate the tmp mapping */
1076 lis r3, 0x8000 /* Way '0' */
1077
1078 clrrwi r24, r24, 12 /* Clear the valid bit */
1079 tlbwe r24, r3, 0
1080 tlbwe r25, r3, 1
1081 tlbwe r26, r3, 2
1082
1083 /* Make sure we complete the TLB write and flush the shadow TLB */
1084 isync
1085
1086#endif
1087
1088ppc44x_map_done:
1089
903 1090
904 /* Restore the parameters */ 1091 /* Restore the parameters */
905 mr r3, r29 1092 mr r3, r29
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 0bb1f98613ba..fbe1a12dc7f1 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -36,10 +36,7 @@ struct lppaca lppaca[] = {
36 [0 ... (NR_LPPACAS-1)] = { 36 [0 ... (NR_LPPACAS-1)] = {
37 .desc = 0xd397d781, /* "LpPa" */ 37 .desc = 0xd397d781, /* "LpPa" */
38 .size = sizeof(struct lppaca), 38 .size = sizeof(struct lppaca),
39 .dyn_proc_status = 2,
40 .decr_val = 0x00ff0000,
41 .fpregs_in_use = 1, 39 .fpregs_in_use = 1,
42 .end_of_quantum = 0xfffffffffffffffful,
43 .slb_count = 64, 40 .slb_count = 64,
44 .vmxregs_in_use = 0, 41 .vmxregs_in_use = 0,
45 .page_ins = 0, 42 .page_ins = 0,
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index aa05935b6947..7f8ec1de0ace 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -124,7 +124,7 @@ void enable_kernel_altivec(void)
124 if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) 124 if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
125 giveup_altivec(current); 125 giveup_altivec(current);
126 else 126 else
127 giveup_altivec(NULL); /* just enable AltiVec for kernel - force */ 127 giveup_altivec_notask();
128#else 128#else
129 giveup_altivec(last_task_used_altivec); 129 giveup_altivec(last_task_used_altivec);
130#endif /* CONFIG_SMP */ 130#endif /* CONFIG_SMP */
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 99860273211b..1b488e5305c5 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -680,6 +680,9 @@ static void __init early_cmdline_parse(void)
680#define OV3_VMX 0x40 /* VMX/Altivec */ 680#define OV3_VMX 0x40 /* VMX/Altivec */
681#define OV3_DFP 0x20 /* decimal FP */ 681#define OV3_DFP 0x20 /* decimal FP */
682 682
683/* Option vector 4: IBM PAPR implementation */
684#define OV4_MIN_ENT_CAP 0x01 /* minimum VP entitled capacity */
685
683/* Option vector 5: PAPR/OF options supported */ 686/* Option vector 5: PAPR/OF options supported */
684#define OV5_LPAR 0x80 /* logical partitioning supported */ 687#define OV5_LPAR 0x80 /* logical partitioning supported */
685#define OV5_SPLPAR 0x40 /* shared-processor LPAR supported */ 688#define OV5_SPLPAR 0x40 /* shared-processor LPAR supported */
@@ -701,6 +704,8 @@ static void __init early_cmdline_parse(void)
701#define OV5_XCMO 0x00 704#define OV5_XCMO 0x00
702#endif 705#endif
703#define OV5_TYPE1_AFFINITY 0x80 /* Type 1 NUMA affinity */ 706#define OV5_TYPE1_AFFINITY 0x80 /* Type 1 NUMA affinity */
707#define OV5_PFO_HW_RNG 0x80 /* PFO Random Number Generator */
708#define OV5_PFO_HW_ENCR 0x20 /* PFO Encryption Accelerator */
704 709
705/* Option Vector 6: IBM PAPR hints */ 710/* Option Vector 6: IBM PAPR hints */
706#define OV6_LINUX 0x02 /* Linux is our OS */ 711#define OV6_LINUX 0x02 /* Linux is our OS */
@@ -744,11 +749,12 @@ static unsigned char ibm_architecture_vec[] = {
744 OV3_FP | OV3_VMX | OV3_DFP, 749 OV3_FP | OV3_VMX | OV3_DFP,
745 750
746 /* option vector 4: IBM PAPR implementation */ 751 /* option vector 4: IBM PAPR implementation */
747 2 - 2, /* length */ 752 3 - 2, /* length */
748 0, /* don't halt */ 753 0, /* don't halt */
754 OV4_MIN_ENT_CAP, /* minimum VP entitled capacity */
749 755
750 /* option vector 5: PAPR/OF options */ 756 /* option vector 5: PAPR/OF options */
751 13 - 2, /* length */ 757 18 - 2, /* length */
752 0, /* don't ignore, don't halt */ 758 0, /* don't ignore, don't halt */
753 OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY | 759 OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY |
754 OV5_DONATE_DEDICATE_CPU | OV5_MSI, 760 OV5_DONATE_DEDICATE_CPU | OV5_MSI,
@@ -762,8 +768,13 @@ static unsigned char ibm_architecture_vec[] = {
762 * must match by the macro below. Update the definition if 768 * must match by the macro below. Update the definition if
763 * the structure layout changes. 769 * the structure layout changes.
764 */ 770 */
765#define IBM_ARCH_VEC_NRCORES_OFFSET 100 771#define IBM_ARCH_VEC_NRCORES_OFFSET 101
766 W(NR_CPUS), /* number of cores supported */ 772 W(NR_CPUS), /* number of cores supported */
773 0,
774 0,
775 0,
776 0,
777 OV5_PFO_HW_RNG | OV5_PFO_HW_ENCR,
767 778
768 /* option vector 6: IBM PAPR hints */ 779 /* option vector 6: IBM PAPR hints */
769 4 - 2, /* length */ 780 4 - 2, /* length */
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index dd5e214cdf21..c10fc28b9092 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1432,40 +1432,6 @@ static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
1432#endif 1432#endif
1433} 1433}
1434 1434
1435/*
1436 * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls,
1437 * we mark them as obsolete now, they will be removed in a future version
1438 */
1439static long arch_ptrace_old(struct task_struct *child, long request,
1440 unsigned long addr, unsigned long data)
1441{
1442 void __user *datavp = (void __user *) data;
1443
1444 switch (request) {
1445 case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
1446 return copy_regset_to_user(child, &user_ppc_native_view,
1447 REGSET_GPR, 0, 32 * sizeof(long),
1448 datavp);
1449
1450 case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
1451 return copy_regset_from_user(child, &user_ppc_native_view,
1452 REGSET_GPR, 0, 32 * sizeof(long),
1453 datavp);
1454
1455 case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */
1456 return copy_regset_to_user(child, &user_ppc_native_view,
1457 REGSET_FPR, 0, 32 * sizeof(double),
1458 datavp);
1459
1460 case PPC_PTRACE_SETFPREGS: /* Set FPRs 0 - 31. */
1461 return copy_regset_from_user(child, &user_ppc_native_view,
1462 REGSET_FPR, 0, 32 * sizeof(double),
1463 datavp);
1464 }
1465
1466 return -EPERM;
1467}
1468
1469long arch_ptrace(struct task_struct *child, long request, 1435long arch_ptrace(struct task_struct *child, long request,
1470 unsigned long addr, unsigned long data) 1436 unsigned long addr, unsigned long data)
1471{ 1437{
@@ -1687,14 +1653,6 @@ long arch_ptrace(struct task_struct *child, long request,
1687 datavp); 1653 datavp);
1688#endif 1654#endif
1689 1655
1690 /* Old reverse args ptrace callss */
1691 case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
1692 case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
1693 case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */
1694 case PPC_PTRACE_SETFPREGS: /* Get FPRs 0 - 31. */
1695 ret = arch_ptrace_old(child, request, addr, data);
1696 break;
1697
1698 default: 1656 default:
1699 ret = ptrace_request(child, request, addr, data); 1657 ret = ptrace_request(child, request, addr, data);
1700 break; 1658 break;
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index 469349d14a97..8c21658719d9 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -39,30 +39,6 @@
39 * in exit.c or in signal.c. 39 * in exit.c or in signal.c.
40 */ 40 */
41 41
42/*
43 * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls,
44 * we mark them as obsolete now, they will be removed in a future version
45 */
46static long compat_ptrace_old(struct task_struct *child, long request,
47 long addr, long data)
48{
49 switch (request) {
50 case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
51 return copy_regset_to_user(child,
52 task_user_regset_view(current), 0,
53 0, 32 * sizeof(compat_long_t),
54 compat_ptr(data));
55
56 case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
57 return copy_regset_from_user(child,
58 task_user_regset_view(current), 0,
59 0, 32 * sizeof(compat_long_t),
60 compat_ptr(data));
61 }
62
63 return -EPERM;
64}
65
66/* Macros to workout the correct index for the FPR in the thread struct */ 42/* Macros to workout the correct index for the FPR in the thread struct */
67#define FPRNUMBER(i) (((i) - PT_FPR0) >> 1) 43#define FPRNUMBER(i) (((i) - PT_FPR0) >> 1)
68#define FPRHALF(i) (((i) - PT_FPR0) & 1) 44#define FPRHALF(i) (((i) - PT_FPR0) & 1)
@@ -308,8 +284,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
308 case PTRACE_SETVSRREGS: 284 case PTRACE_SETVSRREGS:
309 case PTRACE_GETREGS64: 285 case PTRACE_GETREGS64:
310 case PTRACE_SETREGS64: 286 case PTRACE_SETREGS64:
311 case PPC_PTRACE_GETFPREGS:
312 case PPC_PTRACE_SETFPREGS:
313 case PTRACE_KILL: 287 case PTRACE_KILL:
314 case PTRACE_SINGLESTEP: 288 case PTRACE_SINGLESTEP:
315 case PTRACE_DETACH: 289 case PTRACE_DETACH:
@@ -322,12 +296,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
322 ret = arch_ptrace(child, request, addr, data); 296 ret = arch_ptrace(child, request, addr, data);
323 break; 297 break;
324 298
325 /* Old reverse args ptrace callss */
326 case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
327 case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
328 ret = compat_ptrace_old(child, request, addr, data);
329 break;
330
331 default: 299 default:
332 ret = compat_ptrace_request(child, request, addr, data); 300 ret = compat_ptrace_request(child, request, addr, data);
333 break; 301 break;
diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S
index 4d5a3edff49e..e830289d2e48 100644
--- a/arch/powerpc/kernel/vector.S
+++ b/arch/powerpc/kernel/vector.S
@@ -89,6 +89,16 @@ _GLOBAL(load_up_altivec)
89 /* restore registers and return */ 89 /* restore registers and return */
90 blr 90 blr
91 91
92_GLOBAL(giveup_altivec_notask)
93 mfmsr r3
94 andis. r4,r3,MSR_VEC@h
95 bnelr /* Already enabled? */
96 oris r3,r3,MSR_VEC@h
97 SYNC
98 MTMSRD(r3) /* enable use of VMX now */
99 isync
100 blr
101
92/* 102/*
93 * giveup_altivec(tsk) 103 * giveup_altivec(tsk)
94 * Disable VMX for the task given as the argument, 104 * Disable VMX for the task given as the argument,
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index a3a99901c8ec..cb87301ccd55 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -14,7 +14,9 @@
14 * 2 of the License, or (at your option) any later version. 14 * 2 of the License, or (at your option) any later version.
15 */ 15 */
16 16
17#include <linux/cpu.h>
17#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/delay.h>
18#include <linux/stat.h> 20#include <linux/stat.h>
19#include <linux/device.h> 21#include <linux/device.h>
20#include <linux/init.h> 22#include <linux/init.h>
@@ -709,13 +711,26 @@ static int vio_cmo_bus_probe(struct vio_dev *viodev)
709 struct vio_driver *viodrv = to_vio_driver(dev->driver); 711 struct vio_driver *viodrv = to_vio_driver(dev->driver);
710 unsigned long flags; 712 unsigned long flags;
711 size_t size; 713 size_t size;
714 bool dma_capable = false;
715
716 /* A device requires entitlement if it has a DMA window property */
717 switch (viodev->family) {
718 case VDEVICE:
719 if (of_get_property(viodev->dev.of_node,
720 "ibm,my-dma-window", NULL))
721 dma_capable = true;
722 break;
723 case PFO:
724 dma_capable = false;
725 break;
726 default:
727 dev_warn(dev, "unknown device family: %d\n", viodev->family);
728 BUG();
729 break;
730 }
712 731
713 /* 732 /* Configure entitlement for the device. */
714 * Check to see that device has a DMA window and configure 733 if (dma_capable) {
715 * entitlement for the device.
716 */
717 if (of_get_property(viodev->dev.of_node,
718 "ibm,my-dma-window", NULL)) {
719 /* Check that the driver is CMO enabled and get desired DMA */ 734 /* Check that the driver is CMO enabled and get desired DMA */
720 if (!viodrv->get_desired_dma) { 735 if (!viodrv->get_desired_dma) {
721 dev_err(dev, "%s: device driver does not support CMO\n", 736 dev_err(dev, "%s: device driver does not support CMO\n",
@@ -1050,6 +1065,94 @@ static void vio_cmo_sysfs_init(void) { }
1050EXPORT_SYMBOL(vio_cmo_entitlement_update); 1065EXPORT_SYMBOL(vio_cmo_entitlement_update);
1051EXPORT_SYMBOL(vio_cmo_set_dev_desired); 1066EXPORT_SYMBOL(vio_cmo_set_dev_desired);
1052 1067
1068
1069/*
1070 * Platform Facilities Option (PFO) support
1071 */
1072
1073/**
1074 * vio_h_cop_sync - Perform a synchronous PFO co-processor operation
1075 *
1076 * @vdev - Pointer to a struct vio_dev for device
1077 * @op - Pointer to a struct vio_pfo_op for the operation parameters
1078 *
1079 * Calls the hypervisor to synchronously perform the PFO operation
1080 * described in @op. In the case of a busy response from the hypervisor,
1081 * the operation will be re-submitted indefinitely unless a non-zero timeout
1082 * is specified or an error occurs. The timeout places a limit on when to
1083 * stop re-submitting a operation, the total time can be exceeded if an
1084 * operation is in progress.
1085 *
1086 * If op->hcall_ret is not NULL, this will be set to the return from the
1087 * last h_cop_op call or it will be 0 if an error not involving the h_call
1088 * was encountered.
1089 *
1090 * Returns:
1091 * 0 on success,
1092 * -EINVAL if the h_call fails due to an invalid parameter,
1093 * -E2BIG if the h_call can not be performed synchronously,
1094 * -EBUSY if a timeout is specified and has elapsed,
1095 * -EACCES if the memory area for data/status has been rescinded, or
1096 * -EPERM if a hardware fault has been indicated
1097 */
1098int vio_h_cop_sync(struct vio_dev *vdev, struct vio_pfo_op *op)
1099{
1100 struct device *dev = &vdev->dev;
1101 unsigned long deadline = 0;
1102 long hret = 0;
1103 int ret = 0;
1104
1105 if (op->timeout)
1106 deadline = jiffies + msecs_to_jiffies(op->timeout);
1107
1108 while (true) {
1109 hret = plpar_hcall_norets(H_COP, op->flags,
1110 vdev->resource_id,
1111 op->in, op->inlen, op->out,
1112 op->outlen, op->csbcpb);
1113
1114 if (hret == H_SUCCESS ||
1115 (hret != H_NOT_ENOUGH_RESOURCES &&
1116 hret != H_BUSY && hret != H_RESOURCE) ||
1117 (op->timeout && time_after(deadline, jiffies)))
1118 break;
1119
1120 dev_dbg(dev, "%s: hcall ret(%ld), retrying.\n", __func__, hret);
1121 }
1122
1123 switch (hret) {
1124 case H_SUCCESS:
1125 ret = 0;
1126 break;
1127 case H_OP_MODE:
1128 case H_TOO_BIG:
1129 ret = -E2BIG;
1130 break;
1131 case H_RESCINDED:
1132 ret = -EACCES;
1133 break;
1134 case H_HARDWARE:
1135 ret = -EPERM;
1136 break;
1137 case H_NOT_ENOUGH_RESOURCES:
1138 case H_RESOURCE:
1139 case H_BUSY:
1140 ret = -EBUSY;
1141 break;
1142 default:
1143 ret = -EINVAL;
1144 break;
1145 }
1146
1147 if (ret)
1148 dev_dbg(dev, "%s: Sync h_cop_op failure (ret:%d) (hret:%ld)\n",
1149 __func__, ret, hret);
1150
1151 op->hcall_err = hret;
1152 return ret;
1153}
1154EXPORT_SYMBOL(vio_h_cop_sync);
1155
1053static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) 1156static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
1054{ 1157{
1055 const unsigned char *dma_window; 1158 const unsigned char *dma_window;
@@ -1211,35 +1314,87 @@ static void __devinit vio_dev_release(struct device *dev)
1211struct vio_dev *vio_register_device_node(struct device_node *of_node) 1314struct vio_dev *vio_register_device_node(struct device_node *of_node)
1212{ 1315{
1213 struct vio_dev *viodev; 1316 struct vio_dev *viodev;
1317 struct device_node *parent_node;
1214 const unsigned int *unit_address; 1318 const unsigned int *unit_address;
1319 const unsigned int *pfo_resid = NULL;
1320 enum vio_dev_family family;
1321 const char *of_node_name = of_node->name ? of_node->name : "<unknown>";
1215 1322
1216 /* we need the 'device_type' property, in order to match with drivers */ 1323 /*
1217 if (of_node->type == NULL) { 1324 * Determine if this node is a under the /vdevice node or under the
1218 printk(KERN_WARNING "%s: node %s missing 'device_type'\n", 1325 * /ibm,platform-facilities node. This decides the device's family.
1219 __func__, 1326 */
1220 of_node->name ? of_node->name : "<unknown>"); 1327 parent_node = of_get_parent(of_node);
1328 if (parent_node) {
1329 if (!strcmp(parent_node->full_name, "/ibm,platform-facilities"))
1330 family = PFO;
1331 else if (!strcmp(parent_node->full_name, "/vdevice"))
1332 family = VDEVICE;
1333 else {
1334 pr_warn("%s: parent(%s) of %s not recognized.\n",
1335 __func__,
1336 parent_node->full_name,
1337 of_node_name);
1338 of_node_put(parent_node);
1339 return NULL;
1340 }
1341 of_node_put(parent_node);
1342 } else {
1343 pr_warn("%s: could not determine the parent of node %s.\n",
1344 __func__, of_node_name);
1221 return NULL; 1345 return NULL;
1222 } 1346 }
1223 1347
1224 unit_address = of_get_property(of_node, "reg", NULL); 1348 if (family == PFO) {
1225 if (unit_address == NULL) { 1349 if (of_get_property(of_node, "interrupt-controller", NULL)) {
1226 printk(KERN_WARNING "%s: node %s missing 'reg'\n", 1350 pr_debug("%s: Skipping the interrupt controller %s.\n",
1227 __func__, 1351 __func__, of_node_name);
1228 of_node->name ? of_node->name : "<unknown>"); 1352 return NULL;
1229 return NULL; 1353 }
1230 } 1354 }
1231 1355
1232 /* allocate a vio_dev for this node */ 1356 /* allocate a vio_dev for this node */
1233 viodev = kzalloc(sizeof(struct vio_dev), GFP_KERNEL); 1357 viodev = kzalloc(sizeof(struct vio_dev), GFP_KERNEL);
1234 if (viodev == NULL) 1358 if (viodev == NULL) {
1359 pr_warn("%s: allocation failure for VIO device.\n", __func__);
1235 return NULL; 1360 return NULL;
1361 }
1236 1362
1237 viodev->irq = irq_of_parse_and_map(of_node, 0); 1363 /* we need the 'device_type' property, in order to match with drivers */
1364 viodev->family = family;
1365 if (viodev->family == VDEVICE) {
1366 if (of_node->type != NULL)
1367 viodev->type = of_node->type;
1368 else {
1369 pr_warn("%s: node %s is missing the 'device_type' "
1370 "property.\n", __func__, of_node_name);
1371 goto out;
1372 }
1373
1374 unit_address = of_get_property(of_node, "reg", NULL);
1375 if (unit_address == NULL) {
1376 pr_warn("%s: node %s missing 'reg'\n",
1377 __func__, of_node_name);
1378 goto out;
1379 }
1380 dev_set_name(&viodev->dev, "%x", *unit_address);
1381 viodev->irq = irq_of_parse_and_map(of_node, 0);
1382 viodev->unit_address = *unit_address;
1383 } else {
1384 /* PFO devices need their resource_id for submitting COP_OPs
1385 * This is an optional field for devices, but is required when
1386 * performing synchronous ops */
1387 pfo_resid = of_get_property(of_node, "ibm,resource-id", NULL);
1388 if (pfo_resid != NULL)
1389 viodev->resource_id = *pfo_resid;
1390
1391 unit_address = NULL;
1392 dev_set_name(&viodev->dev, "%s", of_node_name);
1393 viodev->type = of_node_name;
1394 viodev->irq = 0;
1395 }
1238 1396
1239 dev_set_name(&viodev->dev, "%x", *unit_address);
1240 viodev->name = of_node->name; 1397 viodev->name = of_node->name;
1241 viodev->type = of_node->type;
1242 viodev->unit_address = *unit_address;
1243 viodev->dev.of_node = of_node_get(of_node); 1398 viodev->dev.of_node = of_node_get(of_node);
1244 1399
1245 if (firmware_has_feature(FW_FEATURE_CMO)) 1400 if (firmware_has_feature(FW_FEATURE_CMO))
@@ -1267,16 +1422,51 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
1267 } 1422 }
1268 1423
1269 return viodev; 1424 return viodev;
1425
1426out: /* Use this exit point for any return prior to device_register */
1427 kfree(viodev);
1428
1429 return NULL;
1270} 1430}
1271EXPORT_SYMBOL(vio_register_device_node); 1431EXPORT_SYMBOL(vio_register_device_node);
1272 1432
1433/*
1434 * vio_bus_scan_for_devices - Scan OF and register each child device
1435 * @root_name - OF node name for the root of the subtree to search.
1436 * This must be non-NULL
1437 *
1438 * Starting from the root node provide, register the device node for
1439 * each child beneath the root.
1440 */
1441static void vio_bus_scan_register_devices(char *root_name)
1442{
1443 struct device_node *node_root, *node_child;
1444
1445 if (!root_name)
1446 return;
1447
1448 node_root = of_find_node_by_name(NULL, root_name);
1449 if (node_root) {
1450
1451 /*
1452 * Create struct vio_devices for each virtual device in
1453 * the device tree. Drivers will associate with them later.
1454 */
1455 node_child = of_get_next_child(node_root, NULL);
1456 while (node_child) {
1457 vio_register_device_node(node_child);
1458 node_child = of_get_next_child(node_root, node_child);
1459 }
1460 of_node_put(node_root);
1461 }
1462}
1463
1273/** 1464/**
1274 * vio_bus_init: - Initialize the virtual IO bus 1465 * vio_bus_init: - Initialize the virtual IO bus
1275 */ 1466 */
1276static int __init vio_bus_init(void) 1467static int __init vio_bus_init(void)
1277{ 1468{
1278 int err; 1469 int err;
1279 struct device_node *node_vroot;
1280 1470
1281 if (firmware_has_feature(FW_FEATURE_CMO)) 1471 if (firmware_has_feature(FW_FEATURE_CMO))
1282 vio_cmo_sysfs_init(); 1472 vio_cmo_sysfs_init();
@@ -1301,19 +1491,8 @@ static int __init vio_bus_init(void)
1301 if (firmware_has_feature(FW_FEATURE_CMO)) 1491 if (firmware_has_feature(FW_FEATURE_CMO))
1302 vio_cmo_bus_init(); 1492 vio_cmo_bus_init();
1303 1493
1304 node_vroot = of_find_node_by_name(NULL, "vdevice"); 1494 vio_bus_scan_register_devices("vdevice");
1305 if (node_vroot) { 1495 vio_bus_scan_register_devices("ibm,platform-facilities");
1306 struct device_node *of_node;
1307
1308 /*
1309 * Create struct vio_devices for each virtual device in
1310 * the device tree. Drivers will associate with them later.
1311 */
1312 for (of_node = node_vroot->child; of_node != NULL;
1313 of_node = of_node->sibling)
1314 vio_register_device_node(of_node);
1315 of_node_put(node_vroot);
1316 }
1317 1496
1318 return 0; 1497 return 0;
1319} 1498}
@@ -1436,12 +1615,28 @@ struct vio_dev *vio_find_node(struct device_node *vnode)
1436{ 1615{
1437 const uint32_t *unit_address; 1616 const uint32_t *unit_address;
1438 char kobj_name[20]; 1617 char kobj_name[20];
1618 struct device_node *vnode_parent;
1619 const char *dev_type;
1620
1621 vnode_parent = of_get_parent(vnode);
1622 if (!vnode_parent)
1623 return NULL;
1624
1625 dev_type = of_get_property(vnode_parent, "device_type", NULL);
1626 of_node_put(vnode_parent);
1627 if (!dev_type)
1628 return NULL;
1439 1629
1440 /* construct the kobject name from the device node */ 1630 /* construct the kobject name from the device node */
1441 unit_address = of_get_property(vnode, "reg", NULL); 1631 if (!strcmp(dev_type, "vdevice")) {
1442 if (!unit_address) 1632 unit_address = of_get_property(vnode, "reg", NULL);
1633 if (!unit_address)
1634 return NULL;
1635 snprintf(kobj_name, sizeof(kobj_name), "%x", *unit_address);
1636 } else if (!strcmp(dev_type, "ibm,platform-facilities"))
1637 snprintf(kobj_name, sizeof(kobj_name), "%s", vnode->name);
1638 else
1443 return NULL; 1639 return NULL;
1444 snprintf(kobj_name, sizeof(kobj_name), "%x", *unit_address);
1445 1640
1446 return vio_find_name(kobj_name); 1641 return vio_find_name(kobj_name);
1447} 1642}