diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-29 14:32:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-29 14:32:34 -0400 |
commit | 3aa590c6b7c89d844f81c2e96f295cf2c6967773 (patch) | |
tree | 6f18b295b1ff4cd7fd1880db6f56721599d64439 /arch/powerpc | |
parent | 4d3ce21fa9d2eaeda113aa2f9c2da80d972bef64 (diff) | |
parent | 339d76c54336443f5050b00172beb675f35e3be0 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (43 commits)
[POWERPC] Use little-endian bit from firmware ibm,pa-features property
[POWERPC] Make sure smp_processor_id works very early in boot
[POWERPC] U4 DART improvements
[POWERPC] todc: add support for Time-Of-Day-Clock
[POWERPC] Make lparcfg.c work when both iseries and pseries are selected
[POWERPC] Fix idr locking in init_new_context
[POWERPC] mpc7448hpc2 (taiga) board config file
[POWERPC] Add tsi108 pci and platform device data register function
[POWERPC] Add general support for mpc7448hpc2 (Taiga) platform
[POWERPC] Correct the MAX_CONTEXT definition
powerpc: minor cleanups for mpc86xx
[POWERPC] Make sure we select CONFIG_NEW_LEDS if ADB_PMU_LED is set
[POWERPC] Simplify the code defining the 64-bit CPU features
[POWERPC] powerpc: kconfig warning fix
[POWERPC] Consolidate some of kernel/misc*.S
[POWERPC] Remove unused function call_with_mmu_off
[POWERPC] update asm-powerpc/time.h
[POWERPC] Clean up it_lp_queue.h
[POWERPC] Skip the "copy down" of the kernel if it is already at zero.
[POWERPC] Add the use of the firmware soft-reset-nmi to kdump.
...
Diffstat (limited to 'arch/powerpc')
58 files changed, 3256 insertions, 921 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index d43e4521abf2..b9a40a35a9ed 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -340,7 +340,7 @@ config PPC_ISERIES | |||
340 | 340 | ||
341 | config EMBEDDED6xx | 341 | config EMBEDDED6xx |
342 | bool "Embedded 6xx/7xx/7xxx-based board" | 342 | bool "Embedded 6xx/7xx/7xxx-based board" |
343 | depends on PPC32 && BROKEN | 343 | depends on PPC32 && (BROKEN||BROKEN_ON_SMP) |
344 | 344 | ||
345 | config APUS | 345 | config APUS |
346 | bool "Amiga-APUS" | 346 | bool "Amiga-APUS" |
@@ -417,12 +417,17 @@ config PPC_CELL_NATIVE | |||
417 | default n | 417 | default n |
418 | 418 | ||
419 | config PPC_IBM_CELL_BLADE | 419 | config PPC_IBM_CELL_BLADE |
420 | bool " IBM Cell Blade" | 420 | bool "IBM Cell Blade" |
421 | depends on PPC_MULTIPLATFORM && PPC64 | 421 | depends on PPC_MULTIPLATFORM && PPC64 |
422 | select PPC_CELL_NATIVE | 422 | select PPC_CELL_NATIVE |
423 | select PPC_RTAS | 423 | select PPC_RTAS |
424 | select MMIO_NVRAM | 424 | select MMIO_NVRAM |
425 | select PPC_UDBG_16550 | 425 | select PPC_UDBG_16550 |
426 | select UDBG_RTAS_CONSOLE | ||
427 | |||
428 | config UDBG_RTAS_CONSOLE | ||
429 | bool | ||
430 | default n | ||
426 | 431 | ||
427 | config XICS | 432 | config XICS |
428 | depends on PPC_PSERIES | 433 | depends on PPC_PSERIES |
@@ -435,7 +440,8 @@ config U3_DART | |||
435 | default n | 440 | default n |
436 | 441 | ||
437 | config MPIC | 442 | config MPIC |
438 | depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP | 443 | depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP \ |
444 | || MPC7448HPC2 | ||
439 | bool | 445 | bool |
440 | default y | 446 | default y |
441 | 447 | ||
@@ -561,6 +567,13 @@ config TAU_AVERAGE | |||
561 | /proc/cpuinfo. | 567 | /proc/cpuinfo. |
562 | 568 | ||
563 | If in doubt, say N here. | 569 | If in doubt, say N here. |
570 | |||
571 | config PPC_TODC | ||
572 | depends on EMBEDDED6xx | ||
573 | bool "Generic Time-of-day Clock (TODC) support" | ||
574 | ---help--- | ||
575 | This adds support for many TODC/RTC chips. | ||
576 | |||
564 | endmenu | 577 | endmenu |
565 | 578 | ||
566 | source arch/powerpc/platforms/embedded6xx/Kconfig | 579 | source arch/powerpc/platforms/embedded6xx/Kconfig |
@@ -801,7 +814,6 @@ config GENERIC_ISA_DMA | |||
801 | 814 | ||
802 | config PPC_I8259 | 815 | config PPC_I8259 |
803 | bool | 816 | bool |
804 | default y if MPC8641_HPCN | ||
805 | default n | 817 | default n |
806 | 818 | ||
807 | config PPC_INDIRECT_PCI | 819 | config PPC_INDIRECT_PCI |
@@ -824,7 +836,8 @@ config MCA | |||
824 | bool | 836 | bool |
825 | 837 | ||
826 | config PCI | 838 | config PCI |
827 | bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) | 839 | bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) \ |
840 | || MPC7448HPC2 | ||
828 | default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx && !PPC_85xx && !PPC_86xx | 841 | default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx && !PPC_85xx && !PPC_86xx |
829 | default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS | 842 | default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS |
830 | default PCI_QSPAN if !4xx && !CPM2 && 8xx | 843 | default PCI_QSPAN if !4xx && !CPM2 && 8xx |
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index c69006ae8246..e29ef77d3b00 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug | |||
@@ -134,12 +134,19 @@ config PPC_EARLY_DEBUG_G5 | |||
134 | help | 134 | help |
135 | Select this to enable early debugging for Apple G5 machines. | 135 | Select this to enable early debugging for Apple G5 machines. |
136 | 136 | ||
137 | config PPC_EARLY_DEBUG_RTAS | 137 | config PPC_EARLY_DEBUG_RTAS_PANEL |
138 | bool "RTAS Panel" | 138 | bool "RTAS Panel" |
139 | depends on PPC_RTAS | 139 | depends on PPC_RTAS |
140 | help | 140 | help |
141 | Select this to enable early debugging via the RTAS panel. | 141 | Select this to enable early debugging via the RTAS panel. |
142 | 142 | ||
143 | config PPC_EARLY_DEBUG_RTAS_CONSOLE | ||
144 | bool "RTAS Console" | ||
145 | depends on PPC_RTAS | ||
146 | select UDBG_RTAS_CONSOLE | ||
147 | help | ||
148 | Select this to enable early debugging via the RTAS console. | ||
149 | |||
143 | config PPC_EARLY_DEBUG_MAPLE | 150 | config PPC_EARLY_DEBUG_MAPLE |
144 | bool "Maple real mode" | 151 | bool "Maple real mode" |
145 | depends on PPC_MAPLE | 152 | depends on PPC_MAPLE |
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index b8b8d4675dc0..e028a2ecb8a3 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.17 | 3 | # Linux kernel version: 2.6.17-rc6 |
4 | # Mon Jun 19 17:23:03 2006 | 4 | # Thu Jun 22 15:28:36 2006 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | 6 | CONFIG_PPC64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -1063,7 +1063,8 @@ CONFIG_DEBUG_FS=y | |||
1063 | # CONFIG_DEBUG_STACKOVERFLOW is not set | 1063 | # CONFIG_DEBUG_STACKOVERFLOW is not set |
1064 | # CONFIG_DEBUG_STACK_USAGE is not set | 1064 | # CONFIG_DEBUG_STACK_USAGE is not set |
1065 | CONFIG_DEBUGGER=y | 1065 | CONFIG_DEBUGGER=y |
1066 | # CONFIG_XMON is not set | 1066 | CONFIG_XMON=y |
1067 | CONFIG_XMON_DEFAULT=y | ||
1067 | CONFIG_IRQSTACKS=y | 1068 | CONFIG_IRQSTACKS=y |
1068 | # CONFIG_BOOTX_TEXT is not set | 1069 | # CONFIG_BOOTX_TEXT is not set |
1069 | # CONFIG_PPC_EARLY_DEBUG is not set | 1070 | # CONFIG_PPC_EARLY_DEBUG is not set |
diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig new file mode 100644 index 000000000000..15a50f4ceb1f --- /dev/null +++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig | |||
@@ -0,0 +1,923 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.17-rc4 | ||
4 | # Sat May 27 18:45:55 2006 | ||
5 | # | ||
6 | # CONFIG_PPC64 is not set | ||
7 | CONFIG_PPC32=y | ||
8 | CONFIG_PPC_MERGE=y | ||
9 | CONFIG_MMU=y | ||
10 | CONFIG_GENERIC_HARDIRQS=y | ||
11 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | ||
12 | CONFIG_GENERIC_HWEIGHT=y | ||
13 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
14 | CONFIG_PPC=y | ||
15 | CONFIG_EARLY_PRINTK=y | ||
16 | CONFIG_GENERIC_NVRAM=y | ||
17 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | ||
18 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y | ||
19 | CONFIG_PPC_OF=y | ||
20 | CONFIG_PPC_UDBG_16550=y | ||
21 | # CONFIG_GENERIC_TBSYNC is not set | ||
22 | CONFIG_DEFAULT_UIMAGE=y | ||
23 | |||
24 | # | ||
25 | # Processor support | ||
26 | # | ||
27 | CONFIG_CLASSIC32=y | ||
28 | # CONFIG_PPC_52xx is not set | ||
29 | # CONFIG_PPC_82xx is not set | ||
30 | # CONFIG_PPC_83xx is not set | ||
31 | # CONFIG_PPC_85xx is not set | ||
32 | # CONFIG_40x is not set | ||
33 | # CONFIG_44x is not set | ||
34 | # CONFIG_8xx is not set | ||
35 | # CONFIG_E200 is not set | ||
36 | CONFIG_6xx=y | ||
37 | CONFIG_PPC_FPU=y | ||
38 | # CONFIG_ALTIVEC is not set | ||
39 | CONFIG_PPC_STD_MMU=y | ||
40 | CONFIG_PPC_STD_MMU_32=y | ||
41 | # CONFIG_SMP is not set | ||
42 | |||
43 | # | ||
44 | # Code maturity level options | ||
45 | # | ||
46 | CONFIG_EXPERIMENTAL=y | ||
47 | CONFIG_BROKEN_ON_SMP=y | ||
48 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
49 | |||
50 | # | ||
51 | # General setup | ||
52 | # | ||
53 | CONFIG_LOCALVERSION="" | ||
54 | CONFIG_LOCALVERSION_AUTO=y | ||
55 | CONFIG_SWAP=y | ||
56 | CONFIG_SYSVIPC=y | ||
57 | # CONFIG_POSIX_MQUEUE is not set | ||
58 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
59 | CONFIG_SYSCTL=y | ||
60 | # CONFIG_AUDIT is not set | ||
61 | # CONFIG_IKCONFIG is not set | ||
62 | # CONFIG_RELAY is not set | ||
63 | CONFIG_INITRAMFS_SOURCE="" | ||
64 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
65 | CONFIG_EMBEDDED=y | ||
66 | CONFIG_KALLSYMS=y | ||
67 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
68 | CONFIG_HOTPLUG=y | ||
69 | CONFIG_PRINTK=y | ||
70 | CONFIG_BUG=y | ||
71 | CONFIG_ELF_CORE=y | ||
72 | CONFIG_BASE_FULL=y | ||
73 | CONFIG_FUTEX=y | ||
74 | CONFIG_EPOLL=y | ||
75 | CONFIG_SHMEM=y | ||
76 | CONFIG_SLAB=y | ||
77 | # CONFIG_TINY_SHMEM is not set | ||
78 | CONFIG_BASE_SMALL=0 | ||
79 | # CONFIG_SLOB is not set | ||
80 | |||
81 | # | ||
82 | # Loadable module support | ||
83 | # | ||
84 | # CONFIG_MODULES is not set | ||
85 | |||
86 | # | ||
87 | # Block layer | ||
88 | # | ||
89 | CONFIG_LBD=y | ||
90 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
91 | # CONFIG_LSF is not set | ||
92 | |||
93 | # | ||
94 | # IO Schedulers | ||
95 | # | ||
96 | CONFIG_IOSCHED_NOOP=y | ||
97 | CONFIG_IOSCHED_AS=y | ||
98 | CONFIG_IOSCHED_DEADLINE=y | ||
99 | CONFIG_IOSCHED_CFQ=y | ||
100 | CONFIG_DEFAULT_AS=y | ||
101 | # CONFIG_DEFAULT_DEADLINE is not set | ||
102 | # CONFIG_DEFAULT_CFQ is not set | ||
103 | # CONFIG_DEFAULT_NOOP is not set | ||
104 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
105 | |||
106 | # | ||
107 | # Platform support | ||
108 | # | ||
109 | # CONFIG_PPC_MULTIPLATFORM is not set | ||
110 | # CONFIG_PPC_ISERIES is not set | ||
111 | CONFIG_EMBEDDED6xx=y | ||
112 | # CONFIG_APUS is not set | ||
113 | CONFIG_MPIC=y | ||
114 | # CONFIG_PPC_RTAS is not set | ||
115 | # CONFIG_MMIO_NVRAM is not set | ||
116 | # CONFIG_PPC_MPC106 is not set | ||
117 | # CONFIG_PPC_970_NAP is not set | ||
118 | # CONFIG_CPU_FREQ is not set | ||
119 | # CONFIG_TAU is not set | ||
120 | # CONFIG_KATANA is not set | ||
121 | # CONFIG_WILLOW is not set | ||
122 | # CONFIG_CPCI690 is not set | ||
123 | # CONFIG_POWERPMC250 is not set | ||
124 | # CONFIG_CHESTNUT is not set | ||
125 | # CONFIG_SPRUCE is not set | ||
126 | # CONFIG_HDPU is not set | ||
127 | # CONFIG_EV64260 is not set | ||
128 | # CONFIG_LOPEC is not set | ||
129 | # CONFIG_MVME5100 is not set | ||
130 | # CONFIG_PPLUS is not set | ||
131 | # CONFIG_PRPMC750 is not set | ||
132 | # CONFIG_PRPMC800 is not set | ||
133 | # CONFIG_SANDPOINT is not set | ||
134 | CONFIG_MPC7448HPC2=y | ||
135 | # CONFIG_RADSTONE_PPC7D is not set | ||
136 | # CONFIG_PAL4 is not set | ||
137 | # CONFIG_GEMINI is not set | ||
138 | # CONFIG_EST8260 is not set | ||
139 | # CONFIG_SBC82xx is not set | ||
140 | # CONFIG_SBS8260 is not set | ||
141 | # CONFIG_RPX8260 is not set | ||
142 | # CONFIG_TQM8260 is not set | ||
143 | # CONFIG_ADS8272 is not set | ||
144 | # CONFIG_PQ2FADS is not set | ||
145 | # CONFIG_LITE5200 is not set | ||
146 | # CONFIG_EV64360 is not set | ||
147 | CONFIG_TSI108_BRIDGE=y | ||
148 | # CONFIG_WANT_EARLY_SERIAL is not set | ||
149 | |||
150 | # | ||
151 | # Kernel options | ||
152 | # | ||
153 | # CONFIG_HIGHMEM is not set | ||
154 | # CONFIG_HZ_100 is not set | ||
155 | CONFIG_HZ_250=y | ||
156 | # CONFIG_HZ_1000 is not set | ||
157 | CONFIG_HZ=250 | ||
158 | CONFIG_PREEMPT_NONE=y | ||
159 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
160 | # CONFIG_PREEMPT is not set | ||
161 | CONFIG_BINFMT_ELF=y | ||
162 | CONFIG_BINFMT_MISC=y | ||
163 | CONFIG_ARCH_FLATMEM_ENABLE=y | ||
164 | CONFIG_SELECT_MEMORY_MODEL=y | ||
165 | CONFIG_FLATMEM_MANUAL=y | ||
166 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
167 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
168 | CONFIG_FLATMEM=y | ||
169 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
170 | # CONFIG_SPARSEMEM_STATIC is not set | ||
171 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
172 | CONFIG_PROC_DEVICETREE=y | ||
173 | # CONFIG_CMDLINE_BOOL is not set | ||
174 | # CONFIG_PM is not set | ||
175 | # CONFIG_SOFTWARE_SUSPEND is not set | ||
176 | # CONFIG_SECCOMP is not set | ||
177 | CONFIG_ISA_DMA_API=y | ||
178 | |||
179 | # | ||
180 | # Bus options | ||
181 | # | ||
182 | CONFIG_GENERIC_ISA_DMA=y | ||
183 | # CONFIG_PPC_I8259 is not set | ||
184 | # CONFIG_PPC_INDIRECT_PCI is not set | ||
185 | CONFIG_PCI=y | ||
186 | CONFIG_PCI_DOMAINS=y | ||
187 | |||
188 | # | ||
189 | # PCCARD (PCMCIA/CardBus) support | ||
190 | # | ||
191 | # CONFIG_PCCARD is not set | ||
192 | |||
193 | # | ||
194 | # PCI Hotplug Support | ||
195 | # | ||
196 | # CONFIG_HOTPLUG_PCI is not set | ||
197 | |||
198 | # | ||
199 | # Advanced setup | ||
200 | # | ||
201 | # CONFIG_ADVANCED_OPTIONS is not set | ||
202 | |||
203 | # | ||
204 | # Default settings for advanced configuration options are used | ||
205 | # | ||
206 | CONFIG_HIGHMEM_START=0xfe000000 | ||
207 | CONFIG_LOWMEM_SIZE=0x30000000 | ||
208 | CONFIG_KERNEL_START=0xc0000000 | ||
209 | CONFIG_TASK_SIZE=0x80000000 | ||
210 | CONFIG_BOOT_LOAD=0x00800000 | ||
211 | |||
212 | # | ||
213 | # Networking | ||
214 | # | ||
215 | CONFIG_NET=y | ||
216 | |||
217 | # | ||
218 | # Networking options | ||
219 | # | ||
220 | # CONFIG_NETDEBUG is not set | ||
221 | CONFIG_PACKET=y | ||
222 | # CONFIG_PACKET_MMAP is not set | ||
223 | CONFIG_UNIX=y | ||
224 | # CONFIG_NET_KEY is not set | ||
225 | CONFIG_INET=y | ||
226 | CONFIG_IP_MULTICAST=y | ||
227 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
228 | CONFIG_IP_FIB_HASH=y | ||
229 | CONFIG_IP_PNP=y | ||
230 | CONFIG_IP_PNP_DHCP=y | ||
231 | CONFIG_IP_PNP_BOOTP=y | ||
232 | # CONFIG_IP_PNP_RARP is not set | ||
233 | # CONFIG_NET_IPIP is not set | ||
234 | # CONFIG_NET_IPGRE is not set | ||
235 | # CONFIG_IP_MROUTE is not set | ||
236 | # CONFIG_ARPD is not set | ||
237 | CONFIG_SYN_COOKIES=y | ||
238 | # CONFIG_INET_AH is not set | ||
239 | # CONFIG_INET_ESP is not set | ||
240 | # CONFIG_INET_IPCOMP is not set | ||
241 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
242 | # CONFIG_INET_TUNNEL is not set | ||
243 | CONFIG_INET_DIAG=y | ||
244 | CONFIG_INET_TCP_DIAG=y | ||
245 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
246 | CONFIG_TCP_CONG_BIC=y | ||
247 | # CONFIG_IPV6 is not set | ||
248 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
249 | # CONFIG_INET6_TUNNEL is not set | ||
250 | # CONFIG_NETFILTER is not set | ||
251 | |||
252 | # | ||
253 | # DCCP Configuration (EXPERIMENTAL) | ||
254 | # | ||
255 | # CONFIG_IP_DCCP is not set | ||
256 | |||
257 | # | ||
258 | # SCTP Configuration (EXPERIMENTAL) | ||
259 | # | ||
260 | # CONFIG_IP_SCTP is not set | ||
261 | |||
262 | # | ||
263 | # TIPC Configuration (EXPERIMENTAL) | ||
264 | # | ||
265 | # CONFIG_TIPC is not set | ||
266 | # CONFIG_ATM is not set | ||
267 | # CONFIG_BRIDGE is not set | ||
268 | # CONFIG_VLAN_8021Q is not set | ||
269 | # CONFIG_DECNET is not set | ||
270 | # CONFIG_LLC2 is not set | ||
271 | # CONFIG_IPX is not set | ||
272 | # CONFIG_ATALK is not set | ||
273 | # CONFIG_X25 is not set | ||
274 | # CONFIG_LAPB is not set | ||
275 | # CONFIG_NET_DIVERT is not set | ||
276 | # CONFIG_ECONET is not set | ||
277 | # CONFIG_WAN_ROUTER is not set | ||
278 | |||
279 | # | ||
280 | # QoS and/or fair queueing | ||
281 | # | ||
282 | # CONFIG_NET_SCHED is not set | ||
283 | |||
284 | # | ||
285 | # Network testing | ||
286 | # | ||
287 | # CONFIG_NET_PKTGEN is not set | ||
288 | # CONFIG_HAMRADIO is not set | ||
289 | # CONFIG_IRDA is not set | ||
290 | # CONFIG_BT is not set | ||
291 | # CONFIG_IEEE80211 is not set | ||
292 | |||
293 | # | ||
294 | # Device Drivers | ||
295 | # | ||
296 | |||
297 | # | ||
298 | # Generic Driver Options | ||
299 | # | ||
300 | CONFIG_STANDALONE=y | ||
301 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
302 | # CONFIG_FW_LOADER is not set | ||
303 | |||
304 | # | ||
305 | # Connector - unified userspace <-> kernelspace linker | ||
306 | # | ||
307 | # CONFIG_CONNECTOR is not set | ||
308 | |||
309 | # | ||
310 | # Memory Technology Devices (MTD) | ||
311 | # | ||
312 | # CONFIG_MTD is not set | ||
313 | |||
314 | # | ||
315 | # Parallel port support | ||
316 | # | ||
317 | # CONFIG_PARPORT is not set | ||
318 | |||
319 | # | ||
320 | # Plug and Play support | ||
321 | # | ||
322 | |||
323 | # | ||
324 | # Block devices | ||
325 | # | ||
326 | # CONFIG_BLK_DEV_FD is not set | ||
327 | # CONFIG_BLK_CPQ_DA is not set | ||
328 | # CONFIG_BLK_CPQ_CISS_DA is not set | ||
329 | # CONFIG_BLK_DEV_DAC960 is not set | ||
330 | # CONFIG_BLK_DEV_UMEM is not set | ||
331 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
332 | CONFIG_BLK_DEV_LOOP=y | ||
333 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
334 | # CONFIG_BLK_DEV_NBD is not set | ||
335 | # CONFIG_BLK_DEV_SX8 is not set | ||
336 | CONFIG_BLK_DEV_RAM=y | ||
337 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
338 | CONFIG_BLK_DEV_RAM_SIZE=131072 | ||
339 | CONFIG_BLK_DEV_INITRD=y | ||
340 | # CONFIG_CDROM_PKTCDVD is not set | ||
341 | # CONFIG_ATA_OVER_ETH is not set | ||
342 | |||
343 | # | ||
344 | # ATA/ATAPI/MFM/RLL support | ||
345 | # | ||
346 | # CONFIG_IDE is not set | ||
347 | |||
348 | # | ||
349 | # SCSI device support | ||
350 | # | ||
351 | # CONFIG_RAID_ATTRS is not set | ||
352 | CONFIG_SCSI=y | ||
353 | CONFIG_SCSI_PROC_FS=y | ||
354 | |||
355 | # | ||
356 | # SCSI support type (disk, tape, CD-ROM) | ||
357 | # | ||
358 | CONFIG_BLK_DEV_SD=y | ||
359 | # CONFIG_CHR_DEV_ST is not set | ||
360 | # CONFIG_CHR_DEV_OSST is not set | ||
361 | # CONFIG_BLK_DEV_SR is not set | ||
362 | # CONFIG_CHR_DEV_SG is not set | ||
363 | # CONFIG_CHR_DEV_SCH is not set | ||
364 | |||
365 | # | ||
366 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs | ||
367 | # | ||
368 | # CONFIG_SCSI_MULTI_LUN is not set | ||
369 | # CONFIG_SCSI_CONSTANTS is not set | ||
370 | # CONFIG_SCSI_LOGGING is not set | ||
371 | |||
372 | # | ||
373 | # SCSI Transport Attributes | ||
374 | # | ||
375 | # CONFIG_SCSI_SPI_ATTRS is not set | ||
376 | # CONFIG_SCSI_FC_ATTRS is not set | ||
377 | # CONFIG_SCSI_ISCSI_ATTRS is not set | ||
378 | # CONFIG_SCSI_SAS_ATTRS is not set | ||
379 | |||
380 | # | ||
381 | # SCSI low-level drivers | ||
382 | # | ||
383 | # CONFIG_ISCSI_TCP is not set | ||
384 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | ||
385 | # CONFIG_SCSI_3W_9XXX is not set | ||
386 | # CONFIG_SCSI_ACARD is not set | ||
387 | # CONFIG_SCSI_AACRAID is not set | ||
388 | # CONFIG_SCSI_AIC7XXX is not set | ||
389 | # CONFIG_SCSI_AIC7XXX_OLD is not set | ||
390 | # CONFIG_SCSI_AIC79XX is not set | ||
391 | # CONFIG_SCSI_DPT_I2O is not set | ||
392 | # CONFIG_MEGARAID_NEWGEN is not set | ||
393 | # CONFIG_MEGARAID_LEGACY is not set | ||
394 | # CONFIG_MEGARAID_SAS is not set | ||
395 | CONFIG_SCSI_SATA=y | ||
396 | # CONFIG_SCSI_SATA_AHCI is not set | ||
397 | # CONFIG_SCSI_SATA_SVW is not set | ||
398 | # CONFIG_SCSI_ATA_PIIX is not set | ||
399 | CONFIG_SCSI_SATA_MV=y | ||
400 | # CONFIG_SCSI_SATA_NV is not set | ||
401 | # CONFIG_SCSI_PDC_ADMA is not set | ||
402 | # CONFIG_SCSI_SATA_QSTOR is not set | ||
403 | # CONFIG_SCSI_SATA_PROMISE is not set | ||
404 | # CONFIG_SCSI_SATA_SX4 is not set | ||
405 | # CONFIG_SCSI_SATA_SIL is not set | ||
406 | # CONFIG_SCSI_SATA_SIL24 is not set | ||
407 | # CONFIG_SCSI_SATA_SIS is not set | ||
408 | # CONFIG_SCSI_SATA_ULI is not set | ||
409 | # CONFIG_SCSI_SATA_VIA is not set | ||
410 | # CONFIG_SCSI_SATA_VITESSE is not set | ||
411 | # CONFIG_SCSI_BUSLOGIC is not set | ||
412 | # CONFIG_SCSI_DMX3191D is not set | ||
413 | # CONFIG_SCSI_EATA is not set | ||
414 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | ||
415 | # CONFIG_SCSI_GDTH is not set | ||
416 | # CONFIG_SCSI_IPS is not set | ||
417 | # CONFIG_SCSI_INITIO is not set | ||
418 | # CONFIG_SCSI_INIA100 is not set | ||
419 | # CONFIG_SCSI_SYM53C8XX_2 is not set | ||
420 | # CONFIG_SCSI_IPR is not set | ||
421 | # CONFIG_SCSI_QLOGIC_1280 is not set | ||
422 | # CONFIG_SCSI_QLA_FC is not set | ||
423 | # CONFIG_SCSI_LPFC is not set | ||
424 | # CONFIG_SCSI_DC395x is not set | ||
425 | # CONFIG_SCSI_DC390T is not set | ||
426 | # CONFIG_SCSI_NSP32 is not set | ||
427 | # CONFIG_SCSI_DEBUG is not set | ||
428 | |||
429 | # | ||
430 | # Multi-device support (RAID and LVM) | ||
431 | # | ||
432 | # CONFIG_MD is not set | ||
433 | |||
434 | # | ||
435 | # Fusion MPT device support | ||
436 | # | ||
437 | # CONFIG_FUSION is not set | ||
438 | # CONFIG_FUSION_SPI is not set | ||
439 | # CONFIG_FUSION_FC is not set | ||
440 | # CONFIG_FUSION_SAS is not set | ||
441 | |||
442 | # | ||
443 | # IEEE 1394 (FireWire) support | ||
444 | # | ||
445 | # CONFIG_IEEE1394 is not set | ||
446 | |||
447 | # | ||
448 | # I2O device support | ||
449 | # | ||
450 | # CONFIG_I2O is not set | ||
451 | |||
452 | # | ||
453 | # Macintosh device drivers | ||
454 | # | ||
455 | # CONFIG_WINDFARM is not set | ||
456 | |||
457 | # | ||
458 | # Network device support | ||
459 | # | ||
460 | CONFIG_NETDEVICES=y | ||
461 | # CONFIG_DUMMY is not set | ||
462 | # CONFIG_BONDING is not set | ||
463 | # CONFIG_EQUALIZER is not set | ||
464 | # CONFIG_TUN is not set | ||
465 | |||
466 | # | ||
467 | # ARCnet devices | ||
468 | # | ||
469 | # CONFIG_ARCNET is not set | ||
470 | |||
471 | # | ||
472 | # PHY device support | ||
473 | # | ||
474 | CONFIG_PHYLIB=y | ||
475 | |||
476 | # | ||
477 | # MII PHY device drivers | ||
478 | # | ||
479 | # CONFIG_MARVELL_PHY is not set | ||
480 | # CONFIG_DAVICOM_PHY is not set | ||
481 | # CONFIG_QSEMI_PHY is not set | ||
482 | # CONFIG_LXT_PHY is not set | ||
483 | # CONFIG_CICADA_PHY is not set | ||
484 | |||
485 | # | ||
486 | # Ethernet (10 or 100Mbit) | ||
487 | # | ||
488 | CONFIG_NET_ETHERNET=y | ||
489 | CONFIG_MII=y | ||
490 | # CONFIG_HAPPYMEAL is not set | ||
491 | # CONFIG_SUNGEM is not set | ||
492 | # CONFIG_CASSINI is not set | ||
493 | # CONFIG_NET_VENDOR_3COM is not set | ||
494 | |||
495 | # | ||
496 | # Tulip family network device support | ||
497 | # | ||
498 | # CONFIG_NET_TULIP is not set | ||
499 | # CONFIG_HP100 is not set | ||
500 | CONFIG_NET_PCI=y | ||
501 | # CONFIG_PCNET32 is not set | ||
502 | # CONFIG_AMD8111_ETH is not set | ||
503 | # CONFIG_ADAPTEC_STARFIRE is not set | ||
504 | # CONFIG_B44 is not set | ||
505 | # CONFIG_FORCEDETH is not set | ||
506 | # CONFIG_DGRS is not set | ||
507 | # CONFIG_EEPRO100 is not set | ||
508 | CONFIG_E100=y | ||
509 | # CONFIG_FEALNX is not set | ||
510 | # CONFIG_NATSEMI is not set | ||
511 | # CONFIG_NE2K_PCI is not set | ||
512 | # CONFIG_8139CP is not set | ||
513 | CONFIG_8139TOO=y | ||
514 | # CONFIG_8139TOO_PIO is not set | ||
515 | # CONFIG_8139TOO_TUNE_TWISTER is not set | ||
516 | # CONFIG_8139TOO_8129 is not set | ||
517 | # CONFIG_8139_OLD_RX_RESET is not set | ||
518 | # CONFIG_SIS900 is not set | ||
519 | # CONFIG_EPIC100 is not set | ||
520 | # CONFIG_SUNDANCE is not set | ||
521 | # CONFIG_TLAN is not set | ||
522 | # CONFIG_VIA_RHINE is not set | ||
523 | |||
524 | # | ||
525 | # Ethernet (1000 Mbit) | ||
526 | # | ||
527 | # CONFIG_ACENIC is not set | ||
528 | # CONFIG_DL2K is not set | ||
529 | # CONFIG_E1000 is not set | ||
530 | # CONFIG_NS83820 is not set | ||
531 | # CONFIG_HAMACHI is not set | ||
532 | # CONFIG_YELLOWFIN is not set | ||
533 | # CONFIG_R8169 is not set | ||
534 | # CONFIG_SIS190 is not set | ||
535 | # CONFIG_SKGE is not set | ||
536 | # CONFIG_SKY2 is not set | ||
537 | # CONFIG_SK98LIN is not set | ||
538 | # CONFIG_VIA_VELOCITY is not set | ||
539 | # CONFIG_TIGON3 is not set | ||
540 | # CONFIG_BNX2 is not set | ||
541 | CONFIG_TSI108_ETH=y | ||
542 | |||
543 | # | ||
544 | # Ethernet (10000 Mbit) | ||
545 | # | ||
546 | # CONFIG_CHELSIO_T1 is not set | ||
547 | # CONFIG_IXGB is not set | ||
548 | # CONFIG_S2IO is not set | ||
549 | |||
550 | # | ||
551 | # Token Ring devices | ||
552 | # | ||
553 | # CONFIG_TR is not set | ||
554 | |||
555 | # | ||
556 | # Wireless LAN (non-hamradio) | ||
557 | # | ||
558 | # CONFIG_NET_RADIO is not set | ||
559 | |||
560 | # | ||
561 | # Wan interfaces | ||
562 | # | ||
563 | # CONFIG_WAN is not set | ||
564 | # CONFIG_FDDI is not set | ||
565 | # CONFIG_HIPPI is not set | ||
566 | # CONFIG_PPP is not set | ||
567 | # CONFIG_SLIP is not set | ||
568 | # CONFIG_NET_FC is not set | ||
569 | # CONFIG_SHAPER is not set | ||
570 | # CONFIG_NETCONSOLE is not set | ||
571 | # CONFIG_NETPOLL is not set | ||
572 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
573 | |||
574 | # | ||
575 | # ISDN subsystem | ||
576 | # | ||
577 | # CONFIG_ISDN is not set | ||
578 | |||
579 | # | ||
580 | # Telephony Support | ||
581 | # | ||
582 | # CONFIG_PHONE is not set | ||
583 | |||
584 | # | ||
585 | # Input device support | ||
586 | # | ||
587 | CONFIG_INPUT=y | ||
588 | |||
589 | # | ||
590 | # Userland interfaces | ||
591 | # | ||
592 | # CONFIG_INPUT_MOUSEDEV is not set | ||
593 | # CONFIG_INPUT_JOYDEV is not set | ||
594 | # CONFIG_INPUT_TSDEV is not set | ||
595 | # CONFIG_INPUT_EVDEV is not set | ||
596 | # CONFIG_INPUT_EVBUG is not set | ||
597 | |||
598 | # | ||
599 | # Input Device Drivers | ||
600 | # | ||
601 | # CONFIG_INPUT_KEYBOARD is not set | ||
602 | # CONFIG_INPUT_MOUSE is not set | ||
603 | # CONFIG_INPUT_JOYSTICK is not set | ||
604 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
605 | # CONFIG_INPUT_MISC is not set | ||
606 | |||
607 | # | ||
608 | # Hardware I/O ports | ||
609 | # | ||
610 | # CONFIG_SERIO is not set | ||
611 | # CONFIG_GAMEPORT is not set | ||
612 | |||
613 | # | ||
614 | # Character devices | ||
615 | # | ||
616 | # CONFIG_VT is not set | ||
617 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
618 | |||
619 | # | ||
620 | # Serial drivers | ||
621 | # | ||
622 | CONFIG_SERIAL_8250=y | ||
623 | CONFIG_SERIAL_8250_CONSOLE=y | ||
624 | CONFIG_SERIAL_8250_PCI=y | ||
625 | CONFIG_SERIAL_8250_NR_UARTS=4 | ||
626 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | ||
627 | # CONFIG_SERIAL_8250_EXTENDED is not set | ||
628 | |||
629 | # | ||
630 | # Non-8250 serial port support | ||
631 | # | ||
632 | CONFIG_SERIAL_CORE=y | ||
633 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
634 | # CONFIG_SERIAL_JSM is not set | ||
635 | CONFIG_UNIX98_PTYS=y | ||
636 | CONFIG_LEGACY_PTYS=y | ||
637 | CONFIG_LEGACY_PTY_COUNT=256 | ||
638 | |||
639 | # | ||
640 | # IPMI | ||
641 | # | ||
642 | # CONFIG_IPMI_HANDLER is not set | ||
643 | |||
644 | # | ||
645 | # Watchdog Cards | ||
646 | # | ||
647 | # CONFIG_WATCHDOG is not set | ||
648 | # CONFIG_NVRAM is not set | ||
649 | CONFIG_GEN_RTC=y | ||
650 | # CONFIG_GEN_RTC_X is not set | ||
651 | # CONFIG_DTLK is not set | ||
652 | # CONFIG_R3964 is not set | ||
653 | # CONFIG_APPLICOM is not set | ||
654 | |||
655 | # | ||
656 | # Ftape, the floppy tape device driver | ||
657 | # | ||
658 | # CONFIG_AGP is not set | ||
659 | # CONFIG_DRM is not set | ||
660 | # CONFIG_RAW_DRIVER is not set | ||
661 | |||
662 | # | ||
663 | # TPM devices | ||
664 | # | ||
665 | # CONFIG_TCG_TPM is not set | ||
666 | # CONFIG_TELCLOCK is not set | ||
667 | |||
668 | # | ||
669 | # I2C support | ||
670 | # | ||
671 | # CONFIG_I2C is not set | ||
672 | |||
673 | # | ||
674 | # SPI support | ||
675 | # | ||
676 | # CONFIG_SPI is not set | ||
677 | # CONFIG_SPI_MASTER is not set | ||
678 | |||
679 | # | ||
680 | # Dallas's 1-wire bus | ||
681 | # | ||
682 | # CONFIG_W1 is not set | ||
683 | |||
684 | # | ||
685 | # Hardware Monitoring support | ||
686 | # | ||
687 | CONFIG_HWMON=y | ||
688 | # CONFIG_HWMON_VID is not set | ||
689 | # CONFIG_SENSORS_F71805F is not set | ||
690 | # CONFIG_HWMON_DEBUG_CHIP is not set | ||
691 | |||
692 | # | ||
693 | # Misc devices | ||
694 | # | ||
695 | |||
696 | # | ||
697 | # Multimedia devices | ||
698 | # | ||
699 | # CONFIG_VIDEO_DEV is not set | ||
700 | |||
701 | # | ||
702 | # Digital Video Broadcasting Devices | ||
703 | # | ||
704 | # CONFIG_DVB is not set | ||
705 | |||
706 | # | ||
707 | # Graphics support | ||
708 | # | ||
709 | # CONFIG_FB is not set | ||
710 | |||
711 | # | ||
712 | # Sound | ||
713 | # | ||
714 | # CONFIG_SOUND is not set | ||
715 | |||
716 | # | ||
717 | # USB support | ||
718 | # | ||
719 | CONFIG_USB_ARCH_HAS_HCD=y | ||
720 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
721 | CONFIG_USB_ARCH_HAS_EHCI=y | ||
722 | # CONFIG_USB is not set | ||
723 | |||
724 | # | ||
725 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | ||
726 | # | ||
727 | |||
728 | # | ||
729 | # USB Gadget Support | ||
730 | # | ||
731 | # CONFIG_USB_GADGET is not set | ||
732 | |||
733 | # | ||
734 | # MMC/SD Card support | ||
735 | # | ||
736 | # CONFIG_MMC is not set | ||
737 | |||
738 | # | ||
739 | # LED devices | ||
740 | # | ||
741 | # CONFIG_NEW_LEDS is not set | ||
742 | |||
743 | # | ||
744 | # LED drivers | ||
745 | # | ||
746 | |||
747 | # | ||
748 | # LED Triggers | ||
749 | # | ||
750 | |||
751 | # | ||
752 | # InfiniBand support | ||
753 | # | ||
754 | # CONFIG_INFINIBAND is not set | ||
755 | |||
756 | # | ||
757 | # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) | ||
758 | # | ||
759 | |||
760 | # | ||
761 | # Real Time Clock | ||
762 | # | ||
763 | # CONFIG_RTC_CLASS is not set | ||
764 | |||
765 | # | ||
766 | # File systems | ||
767 | # | ||
768 | CONFIG_EXT2_FS=y | ||
769 | # CONFIG_EXT2_FS_XATTR is not set | ||
770 | # CONFIG_EXT2_FS_XIP is not set | ||
771 | CONFIG_EXT3_FS=y | ||
772 | CONFIG_EXT3_FS_XATTR=y | ||
773 | # CONFIG_EXT3_FS_POSIX_ACL is not set | ||
774 | # CONFIG_EXT3_FS_SECURITY is not set | ||
775 | CONFIG_JBD=y | ||
776 | # CONFIG_JBD_DEBUG is not set | ||
777 | CONFIG_FS_MBCACHE=y | ||
778 | # CONFIG_REISERFS_FS is not set | ||
779 | # CONFIG_JFS_FS is not set | ||
780 | # CONFIG_FS_POSIX_ACL is not set | ||
781 | # CONFIG_XFS_FS is not set | ||
782 | # CONFIG_OCFS2_FS is not set | ||
783 | # CONFIG_MINIX_FS is not set | ||
784 | # CONFIG_ROMFS_FS is not set | ||
785 | CONFIG_INOTIFY=y | ||
786 | # CONFIG_QUOTA is not set | ||
787 | CONFIG_DNOTIFY=y | ||
788 | # CONFIG_AUTOFS_FS is not set | ||
789 | # CONFIG_AUTOFS4_FS is not set | ||
790 | # CONFIG_FUSE_FS is not set | ||
791 | |||
792 | # | ||
793 | # CD-ROM/DVD Filesystems | ||
794 | # | ||
795 | # CONFIG_ISO9660_FS is not set | ||
796 | # CONFIG_UDF_FS is not set | ||
797 | |||
798 | # | ||
799 | # DOS/FAT/NT Filesystems | ||
800 | # | ||
801 | # CONFIG_MSDOS_FS is not set | ||
802 | # CONFIG_VFAT_FS is not set | ||
803 | # CONFIG_NTFS_FS is not set | ||
804 | |||
805 | # | ||
806 | # Pseudo filesystems | ||
807 | # | ||
808 | CONFIG_PROC_FS=y | ||
809 | CONFIG_PROC_KCORE=y | ||
810 | CONFIG_SYSFS=y | ||
811 | CONFIG_TMPFS=y | ||
812 | # CONFIG_HUGETLB_PAGE is not set | ||
813 | CONFIG_RAMFS=y | ||
814 | # CONFIG_CONFIGFS_FS is not set | ||
815 | |||
816 | # | ||
817 | # Miscellaneous filesystems | ||
818 | # | ||
819 | # CONFIG_ADFS_FS is not set | ||
820 | # CONFIG_AFFS_FS is not set | ||
821 | # CONFIG_HFS_FS is not set | ||
822 | # CONFIG_HFSPLUS_FS is not set | ||
823 | # CONFIG_BEFS_FS is not set | ||
824 | # CONFIG_BFS_FS is not set | ||
825 | # CONFIG_EFS_FS is not set | ||
826 | # CONFIG_CRAMFS is not set | ||
827 | # CONFIG_VXFS_FS is not set | ||
828 | # CONFIG_HPFS_FS is not set | ||
829 | # CONFIG_QNX4FS_FS is not set | ||
830 | # CONFIG_SYSV_FS is not set | ||
831 | # CONFIG_UFS_FS is not set | ||
832 | |||
833 | # | ||
834 | # Network File Systems | ||
835 | # | ||
836 | CONFIG_NFS_FS=y | ||
837 | # CONFIG_NFS_V3 is not set | ||
838 | # CONFIG_NFS_V4 is not set | ||
839 | # CONFIG_NFS_DIRECTIO is not set | ||
840 | # CONFIG_NFSD is not set | ||
841 | CONFIG_ROOT_NFS=y | ||
842 | CONFIG_LOCKD=y | ||
843 | CONFIG_NFS_COMMON=y | ||
844 | CONFIG_SUNRPC=y | ||
845 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
846 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
847 | # CONFIG_SMB_FS is not set | ||
848 | # CONFIG_CIFS is not set | ||
849 | # CONFIG_NCP_FS is not set | ||
850 | # CONFIG_CODA_FS is not set | ||
851 | # CONFIG_AFS_FS is not set | ||
852 | # CONFIG_9P_FS is not set | ||
853 | |||
854 | # | ||
855 | # Partition Types | ||
856 | # | ||
857 | CONFIG_PARTITION_ADVANCED=y | ||
858 | # CONFIG_ACORN_PARTITION is not set | ||
859 | # CONFIG_OSF_PARTITION is not set | ||
860 | # CONFIG_AMIGA_PARTITION is not set | ||
861 | # CONFIG_ATARI_PARTITION is not set | ||
862 | # CONFIG_MAC_PARTITION is not set | ||
863 | CONFIG_MSDOS_PARTITION=y | ||
864 | # CONFIG_BSD_DISKLABEL is not set | ||
865 | # CONFIG_MINIX_SUBPARTITION is not set | ||
866 | # CONFIG_SOLARIS_X86_PARTITION is not set | ||
867 | # CONFIG_UNIXWARE_DISKLABEL is not set | ||
868 | # CONFIG_LDM_PARTITION is not set | ||
869 | # CONFIG_SGI_PARTITION is not set | ||
870 | # CONFIG_ULTRIX_PARTITION is not set | ||
871 | # CONFIG_SUN_PARTITION is not set | ||
872 | # CONFIG_KARMA_PARTITION is not set | ||
873 | # CONFIG_EFI_PARTITION is not set | ||
874 | |||
875 | # | ||
876 | # Native Language Support | ||
877 | # | ||
878 | # CONFIG_NLS is not set | ||
879 | |||
880 | # | ||
881 | # Library routines | ||
882 | # | ||
883 | # CONFIG_CRC_CCITT is not set | ||
884 | # CONFIG_CRC16 is not set | ||
885 | CONFIG_CRC32=y | ||
886 | # CONFIG_LIBCRC32C is not set | ||
887 | |||
888 | # | ||
889 | # Instrumentation Support | ||
890 | # | ||
891 | # CONFIG_PROFILING is not set | ||
892 | |||
893 | # | ||
894 | # Kernel hacking | ||
895 | # | ||
896 | # CONFIG_PRINTK_TIME is not set | ||
897 | # CONFIG_MAGIC_SYSRQ is not set | ||
898 | # CONFIG_DEBUG_KERNEL is not set | ||
899 | CONFIG_LOG_BUF_SHIFT=14 | ||
900 | # CONFIG_DEBUG_FS is not set | ||
901 | # CONFIG_UNWIND_INFO is not set | ||
902 | # CONFIG_BOOTX_TEXT is not set | ||
903 | # CONFIG_SERIAL_TEXT_DEBUG is not set | ||
904 | # CONFIG_PPC_EARLY_DEBUG_LPAR is not set | ||
905 | # CONFIG_PPC_EARLY_DEBUG_G5 is not set | ||
906 | # CONFIG_PPC_EARLY_DEBUG_RTAS is not set | ||
907 | # CONFIG_PPC_EARLY_DEBUG_MAPLE is not set | ||
908 | # CONFIG_PPC_EARLY_DEBUG_ISERIES is not set | ||
909 | |||
910 | # | ||
911 | # Security options | ||
912 | # | ||
913 | # CONFIG_KEYS is not set | ||
914 | # CONFIG_SECURITY is not set | ||
915 | |||
916 | # | ||
917 | # Cryptographic options | ||
918 | # | ||
919 | # CONFIG_CRYPTO is not set | ||
920 | |||
921 | # | ||
922 | # Hardware crypto devices | ||
923 | # | ||
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 803858e86160..814f242aeb8c 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -50,7 +50,8 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o | |||
50 | extra-$(CONFIG_8xx) := head_8xx.o | 50 | extra-$(CONFIG_8xx) := head_8xx.o |
51 | extra-y += vmlinux.lds | 51 | extra-y += vmlinux.lds |
52 | 52 | ||
53 | obj-y += time.o prom.o traps.o setup-common.o udbg.o | 53 | obj-y += time.o prom.o traps.o setup-common.o \ |
54 | udbg.o misc.o | ||
54 | obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o | 55 | obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o |
55 | obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o | 56 | obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o |
56 | obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o | 57 | obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o |
diff --git a/arch/powerpc/kernel/cpu_setup_power4.S b/arch/powerpc/kernel/cpu_setup_power4.S index 271418308d53..1fc863261003 100644 --- a/arch/powerpc/kernel/cpu_setup_power4.S +++ b/arch/powerpc/kernel/cpu_setup_power4.S | |||
@@ -125,7 +125,12 @@ _GLOBAL(__save_cpu_setup) | |||
125 | cmpwi r0,0x44 | 125 | cmpwi r0,0x44 |
126 | bne 2f | 126 | bne 2f |
127 | 127 | ||
128 | 1: /* Save HID0,1,4 and 5 */ | 128 | 1: /* skip if not running in HV mode */ |
129 | mfmsr r0 | ||
130 | rldicl. r0,r0,4,63 | ||
131 | beq 2f | ||
132 | |||
133 | /* Save HID0,1,4 and 5 */ | ||
129 | mfspr r3,SPRN_HID0 | 134 | mfspr r3,SPRN_HID0 |
130 | std r3,CS_HID0(r5) | 135 | std r3,CS_HID0(r5) |
131 | mfspr r3,SPRN_HID1 | 136 | mfspr r3,SPRN_HID1 |
@@ -159,7 +164,12 @@ _GLOBAL(__restore_cpu_setup) | |||
159 | cmpwi r0,0x44 | 164 | cmpwi r0,0x44 |
160 | bnelr | 165 | bnelr |
161 | 166 | ||
162 | 1: /* Before accessing memory, we make sure rm_ci is clear */ | 167 | 1: /* skip if not running in HV mode */ |
168 | mfmsr r0 | ||
169 | rldicl. r0,r0,4,63 | ||
170 | beqlr | ||
171 | |||
172 | /* Before accessing memory, we make sure rm_ci is clear */ | ||
163 | li r0,0 | 173 | li r0,0 |
164 | mfspr r3,SPRN_HID4 | 174 | mfspr r3,SPRN_HID4 |
165 | rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ | 175 | rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 1c114880dc05..abf7d42a8b07 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -722,18 +722,6 @@ struct cpu_spec cpu_specs[] = { | |||
722 | .oprofile_type = PPC_OPROFILE_G4, | 722 | .oprofile_type = PPC_OPROFILE_G4, |
723 | .platform = "ppc7450", | 723 | .platform = "ppc7450", |
724 | }, | 724 | }, |
725 | { /* 8641 */ | ||
726 | .pvr_mask = 0xffffffff, | ||
727 | .pvr_value = 0x80040010, | ||
728 | .cpu_name = "8641", | ||
729 | .cpu_features = CPU_FTRS_7447A, | ||
730 | .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, | ||
731 | .icache_bsize = 32, | ||
732 | .dcache_bsize = 32, | ||
733 | .num_pmcs = 6, | ||
734 | .cpu_setup = __setup_cpu_745x | ||
735 | }, | ||
736 | |||
737 | { /* 82xx (8240, 8245, 8260 are all 603e cores) */ | 725 | { /* 82xx (8240, 8245, 8260 are all 603e cores) */ |
738 | .pvr_mask = 0x7fff0000, | 726 | .pvr_mask = 0x7fff0000, |
739 | .pvr_value = 0x00810000, | 727 | .pvr_value = 0x00810000, |
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 22ceba844bf4..358cecdc6aef 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c | |||
@@ -24,9 +24,11 @@ | |||
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/irq.h> | 25 | #include <linux/irq.h> |
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <linux/irq.h> | ||
27 | 28 | ||
28 | #include <asm/processor.h> | 29 | #include <asm/processor.h> |
29 | #include <asm/machdep.h> | 30 | #include <asm/machdep.h> |
31 | #include <asm/kexec.h> | ||
30 | #include <asm/kdump.h> | 32 | #include <asm/kdump.h> |
31 | #include <asm/lmb.h> | 33 | #include <asm/lmb.h> |
32 | #include <asm/firmware.h> | 34 | #include <asm/firmware.h> |
@@ -41,6 +43,7 @@ | |||
41 | 43 | ||
42 | /* This keeps a track of which one is crashing cpu. */ | 44 | /* This keeps a track of which one is crashing cpu. */ |
43 | int crashing_cpu = -1; | 45 | int crashing_cpu = -1; |
46 | static cpumask_t cpus_in_crash = CPU_MASK_NONE; | ||
44 | 47 | ||
45 | static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, | 48 | static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, |
46 | size_t data_len) | 49 | size_t data_len) |
@@ -98,34 +101,66 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu) | |||
98 | } | 101 | } |
99 | 102 | ||
100 | #ifdef CONFIG_SMP | 103 | #ifdef CONFIG_SMP |
101 | static atomic_t waiting_for_crash_ipi; | 104 | static atomic_t enter_on_soft_reset = ATOMIC_INIT(0); |
102 | 105 | ||
103 | void crash_ipi_callback(struct pt_regs *regs) | 106 | void crash_ipi_callback(struct pt_regs *regs) |
104 | { | 107 | { |
105 | int cpu = smp_processor_id(); | 108 | int cpu = smp_processor_id(); |
106 | 109 | ||
107 | if (cpu == crashing_cpu) | ||
108 | return; | ||
109 | |||
110 | if (!cpu_online(cpu)) | 110 | if (!cpu_online(cpu)) |
111 | return; | 111 | return; |
112 | 112 | ||
113 | if (ppc_md.kexec_cpu_down) | ||
114 | ppc_md.kexec_cpu_down(1, 1); | ||
115 | |||
116 | local_irq_disable(); | 113 | local_irq_disable(); |
114 | if (!cpu_isset(cpu, cpus_in_crash)) | ||
115 | crash_save_this_cpu(regs, cpu); | ||
116 | cpu_set(cpu, cpus_in_crash); | ||
117 | 117 | ||
118 | crash_save_this_cpu(regs, cpu); | 118 | /* |
119 | atomic_dec(&waiting_for_crash_ipi); | 119 | * Entered via soft-reset - could be the kdump |
120 | * process is invoked using soft-reset or user activated | ||
121 | * it if some CPU did not respond to an IPI. | ||
122 | * For soft-reset, the secondary CPU can enter this func | ||
123 | * twice. 1 - using IPI, and 2. soft-reset. | ||
124 | * Tell the kexec CPU that entered via soft-reset and ready | ||
125 | * to go down. | ||
126 | */ | ||
127 | if (cpu_isset(cpu, cpus_in_sr)) { | ||
128 | cpu_clear(cpu, cpus_in_sr); | ||
129 | atomic_inc(&enter_on_soft_reset); | ||
130 | } | ||
131 | |||
132 | /* | ||
133 | * Starting the kdump boot. | ||
134 | * This barrier is needed to make sure that all CPUs are stopped. | ||
135 | * If not, soft-reset will be invoked to bring other CPUs. | ||
136 | */ | ||
137 | while (!cpu_isset(crashing_cpu, cpus_in_crash)) | ||
138 | cpu_relax(); | ||
139 | |||
140 | if (ppc_md.kexec_cpu_down) | ||
141 | ppc_md.kexec_cpu_down(1, 1); | ||
120 | kexec_smp_wait(); | 142 | kexec_smp_wait(); |
121 | /* NOTREACHED */ | 143 | /* NOTREACHED */ |
122 | } | 144 | } |
123 | 145 | ||
124 | static void crash_kexec_prepare_cpus(void) | 146 | /* |
147 | * Wait until all CPUs are entered via soft-reset. | ||
148 | */ | ||
149 | static void crash_soft_reset_check(int cpu) | ||
150 | { | ||
151 | unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ | ||
152 | |||
153 | cpu_clear(cpu, cpus_in_sr); | ||
154 | while (atomic_read(&enter_on_soft_reset) != ncpus) | ||
155 | cpu_relax(); | ||
156 | } | ||
157 | |||
158 | |||
159 | static void crash_kexec_prepare_cpus(int cpu) | ||
125 | { | 160 | { |
126 | unsigned int msecs; | 161 | unsigned int msecs; |
127 | 162 | ||
128 | atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); | 163 | unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ |
129 | 164 | ||
130 | crash_send_ipi(crash_ipi_callback); | 165 | crash_send_ipi(crash_ipi_callback); |
131 | smp_wmb(); | 166 | smp_wmb(); |
@@ -133,14 +168,13 @@ static void crash_kexec_prepare_cpus(void) | |||
133 | /* | 168 | /* |
134 | * FIXME: Until we will have the way to stop other CPUSs reliabally, | 169 | * FIXME: Until we will have the way to stop other CPUSs reliabally, |
135 | * the crash CPU will send an IPI and wait for other CPUs to | 170 | * the crash CPU will send an IPI and wait for other CPUs to |
136 | * respond. If not, proceed the kexec boot even though we failed to | 171 | * respond. |
137 | * capture other CPU states. | ||
138 | * Delay of at least 10 seconds. | 172 | * Delay of at least 10 seconds. |
139 | */ | 173 | */ |
140 | printk(KERN_ALERT "Sending IPI to other cpus...\n"); | 174 | printk(KERN_EMERG "Sending IPI to other cpus...\n"); |
141 | msecs = 10000; | 175 | msecs = 10000; |
142 | while ((atomic_read(&waiting_for_crash_ipi) > 0) && (--msecs > 0)) { | 176 | while ((cpus_weight(cpus_in_crash) < ncpus) && (--msecs > 0)) { |
143 | barrier(); | 177 | cpu_relax(); |
144 | mdelay(1); | 178 | mdelay(1); |
145 | } | 179 | } |
146 | 180 | ||
@@ -149,18 +183,71 @@ static void crash_kexec_prepare_cpus(void) | |||
149 | /* | 183 | /* |
150 | * FIXME: In case if we do not get all CPUs, one possibility: ask the | 184 | * FIXME: In case if we do not get all CPUs, one possibility: ask the |
151 | * user to do soft reset such that we get all. | 185 | * user to do soft reset such that we get all. |
152 | * IPI handler is already set by the panic cpu initially. Therefore, | 186 | * Soft-reset will be used until better mechanism is implemented. |
153 | * all cpus could invoke this handler from die() and the panic CPU | 187 | */ |
154 | * will call machine_kexec() directly from this handler to do | 188 | if (cpus_weight(cpus_in_crash) < ncpus) { |
155 | * kexec boot. | 189 | printk(KERN_EMERG "done waiting: %d cpu(s) not responding\n", |
190 | ncpus - cpus_weight(cpus_in_crash)); | ||
191 | printk(KERN_EMERG "Activate soft-reset to stop other cpu(s)\n"); | ||
192 | cpus_in_sr = CPU_MASK_NONE; | ||
193 | atomic_set(&enter_on_soft_reset, 0); | ||
194 | while (cpus_weight(cpus_in_crash) < ncpus) | ||
195 | cpu_relax(); | ||
196 | } | ||
197 | /* | ||
198 | * Make sure all CPUs are entered via soft-reset if the kdump is | ||
199 | * invoked using soft-reset. | ||
156 | */ | 200 | */ |
157 | if (atomic_read(&waiting_for_crash_ipi)) | 201 | if (cpu_isset(cpu, cpus_in_sr)) |
158 | printk(KERN_ALERT "done waiting: %d cpus not responding\n", | 202 | crash_soft_reset_check(cpu); |
159 | atomic_read(&waiting_for_crash_ipi)); | ||
160 | /* Leave the IPI callback set */ | 203 | /* Leave the IPI callback set */ |
161 | } | 204 | } |
205 | |||
206 | /* | ||
207 | * This function will be called by secondary cpus or by kexec cpu | ||
208 | * if soft-reset is activated to stop some CPUs. | ||
209 | */ | ||
210 | void crash_kexec_secondary(struct pt_regs *regs) | ||
211 | { | ||
212 | int cpu = smp_processor_id(); | ||
213 | unsigned long flags; | ||
214 | int msecs = 5; | ||
215 | |||
216 | local_irq_save(flags); | ||
217 | /* Wait 5ms if the kexec CPU is not entered yet. */ | ||
218 | while (crashing_cpu < 0) { | ||
219 | if (--msecs < 0) { | ||
220 | /* | ||
221 | * Either kdump image is not loaded or | ||
222 | * kdump process is not started - Probably xmon | ||
223 | * exited using 'x'(exit and recover) or | ||
224 | * kexec_should_crash() failed for all running tasks. | ||
225 | */ | ||
226 | cpu_clear(cpu, cpus_in_sr); | ||
227 | local_irq_restore(flags); | ||
228 | return; | ||
229 | } | ||
230 | mdelay(1); | ||
231 | cpu_relax(); | ||
232 | } | ||
233 | if (cpu == crashing_cpu) { | ||
234 | /* | ||
235 | * Panic CPU will enter this func only via soft-reset. | ||
236 | * Wait until all secondary CPUs entered and | ||
237 | * then start kexec boot. | ||
238 | */ | ||
239 | crash_soft_reset_check(cpu); | ||
240 | cpu_set(crashing_cpu, cpus_in_crash); | ||
241 | if (ppc_md.kexec_cpu_down) | ||
242 | ppc_md.kexec_cpu_down(1, 0); | ||
243 | machine_kexec(kexec_crash_image); | ||
244 | /* NOTREACHED */ | ||
245 | } | ||
246 | crash_ipi_callback(regs); | ||
247 | } | ||
248 | |||
162 | #else | 249 | #else |
163 | static void crash_kexec_prepare_cpus(void) | 250 | static void crash_kexec_prepare_cpus(int cpu) |
164 | { | 251 | { |
165 | /* | 252 | /* |
166 | * move the secondarys to us so that we can copy | 253 | * move the secondarys to us so that we can copy |
@@ -171,6 +258,10 @@ static void crash_kexec_prepare_cpus(void) | |||
171 | smp_release_cpus(); | 258 | smp_release_cpus(); |
172 | } | 259 | } |
173 | 260 | ||
261 | void crash_kexec_secondary(struct pt_regs *regs) | ||
262 | { | ||
263 | cpus_in_sr = CPU_MASK_NONE; | ||
264 | } | ||
174 | #endif | 265 | #endif |
175 | 266 | ||
176 | void default_machine_crash_shutdown(struct pt_regs *regs) | 267 | void default_machine_crash_shutdown(struct pt_regs *regs) |
@@ -199,14 +290,14 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
199 | desc->chip->disable(irq); | 290 | desc->chip->disable(irq); |
200 | } | 291 | } |
201 | 292 | ||
202 | if (ppc_md.kexec_cpu_down) | ||
203 | ppc_md.kexec_cpu_down(1, 0); | ||
204 | |||
205 | /* | 293 | /* |
206 | * Make a note of crashing cpu. Will be used in machine_kexec | 294 | * Make a note of crashing cpu. Will be used in machine_kexec |
207 | * such that another IPI will not be sent. | 295 | * such that another IPI will not be sent. |
208 | */ | 296 | */ |
209 | crashing_cpu = smp_processor_id(); | 297 | crashing_cpu = smp_processor_id(); |
210 | crash_kexec_prepare_cpus(); | ||
211 | crash_save_this_cpu(regs, crashing_cpu); | 298 | crash_save_this_cpu(regs, crashing_cpu); |
299 | crash_kexec_prepare_cpus(crashing_cpu); | ||
300 | cpu_set(crashing_cpu, cpus_in_crash); | ||
301 | if (ppc_md.kexec_cpu_down) | ||
302 | ppc_md.kexec_cpu_down(1, 0); | ||
212 | } | 303 | } |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 831acbdf2592..8cfd040d1f50 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -85,34 +85,6 @@ END_FTR_SECTION(0, 1) | |||
85 | /* Catch branch to 0 in real mode */ | 85 | /* Catch branch to 0 in real mode */ |
86 | trap | 86 | trap |
87 | 87 | ||
88 | #ifdef CONFIG_PPC_ISERIES | ||
89 | /* | ||
90 | * At offset 0x20, there is a pointer to iSeries LPAR data. | ||
91 | * This is required by the hypervisor | ||
92 | */ | ||
93 | . = 0x20 | ||
94 | .llong hvReleaseData-KERNELBASE | ||
95 | |||
96 | /* | ||
97 | * At offset 0x28 and 0x30 are offsets to the mschunks_map | ||
98 | * array (used by the iSeries LPAR debugger to do translation | ||
99 | * between physical addresses and absolute addresses) and | ||
100 | * to the pidhash table (also used by the debugger) | ||
101 | */ | ||
102 | .llong mschunks_map-KERNELBASE | ||
103 | .llong 0 /* pidhash-KERNELBASE SFRXXX */ | ||
104 | |||
105 | /* Offset 0x38 - Pointer to start of embedded System.map */ | ||
106 | .globl embedded_sysmap_start | ||
107 | embedded_sysmap_start: | ||
108 | .llong 0 | ||
109 | /* Offset 0x40 - Pointer to end of embedded System.map */ | ||
110 | .globl embedded_sysmap_end | ||
111 | embedded_sysmap_end: | ||
112 | .llong 0 | ||
113 | |||
114 | #endif /* CONFIG_PPC_ISERIES */ | ||
115 | |||
116 | /* Secondary processors spin on this value until it goes to 1. */ | 88 | /* Secondary processors spin on this value until it goes to 1. */ |
117 | .globl __secondary_hold_spinloop | 89 | .globl __secondary_hold_spinloop |
118 | __secondary_hold_spinloop: | 90 | __secondary_hold_spinloop: |
@@ -124,6 +96,15 @@ __secondary_hold_spinloop: | |||
124 | __secondary_hold_acknowledge: | 96 | __secondary_hold_acknowledge: |
125 | .llong 0x0 | 97 | .llong 0x0 |
126 | 98 | ||
99 | #ifdef CONFIG_PPC_ISERIES | ||
100 | /* | ||
101 | * At offset 0x20, there is a pointer to iSeries LPAR data. | ||
102 | * This is required by the hypervisor | ||
103 | */ | ||
104 | . = 0x20 | ||
105 | .llong hvReleaseData-KERNELBASE | ||
106 | #endif /* CONFIG_PPC_ISERIES */ | ||
107 | |||
127 | . = 0x60 | 108 | . = 0x60 |
128 | /* | 109 | /* |
129 | * The following code is used on pSeries to hold secondary processors | 110 | * The following code is used on pSeries to hold secondary processors |
@@ -1602,9 +1583,6 @@ _GLOBAL(__start_initialization_multiplatform) | |||
1602 | /* Setup some critical 970 SPRs before switching MMU off */ | 1583 | /* Setup some critical 970 SPRs before switching MMU off */ |
1603 | bl .__970_cpu_preinit | 1584 | bl .__970_cpu_preinit |
1604 | 1585 | ||
1605 | /* cpu # */ | ||
1606 | li r24,0 | ||
1607 | |||
1608 | /* Switch off MMU if not already */ | 1586 | /* Switch off MMU if not already */ |
1609 | LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE) | 1587 | LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE) |
1610 | add r4,r4,r30 | 1588 | add r4,r4,r30 |
@@ -1683,6 +1661,9 @@ _STATIC(__after_prom_start) | |||
1683 | /* i.e. where we are running */ | 1661 | /* i.e. where we are running */ |
1684 | /* the source addr */ | 1662 | /* the source addr */ |
1685 | 1663 | ||
1664 | cmpdi r4,0 /* In some cases the loader may */ | ||
1665 | beq .start_here_multiplatform /* have already put us at zero */ | ||
1666 | /* so we can skip the copy. */ | ||
1686 | LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ | 1667 | LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ |
1687 | sub r5,r5,r27 | 1668 | sub r5,r5,r27 |
1688 | 1669 | ||
@@ -1962,14 +1943,6 @@ _STATIC(start_here_common) | |||
1962 | li r3,0 | 1943 | li r3,0 |
1963 | bl .do_cpu_ftr_fixups | 1944 | bl .do_cpu_ftr_fixups |
1964 | 1945 | ||
1965 | LOAD_REG_IMMEDIATE(r26, boot_cpuid) | ||
1966 | lwz r26,0(r26) | ||
1967 | |||
1968 | LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */ | ||
1969 | mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */ | ||
1970 | add r13,r13,r24 /* for this processor. */ | ||
1971 | mtspr SPRN_SPRG3,r13 | ||
1972 | |||
1973 | /* ptr to current */ | 1946 | /* ptr to current */ |
1974 | LOAD_REG_IMMEDIATE(r4, init_task) | 1947 | LOAD_REG_IMMEDIATE(r4, init_task) |
1975 | std r4,PACACURRENT(r13) | 1948 | std r4,PACACURRENT(r13) |
@@ -1995,17 +1968,6 @@ _STATIC(start_here_common) | |||
1995 | /* Not reached */ | 1968 | /* Not reached */ |
1996 | BUG_OPCODE | 1969 | BUG_OPCODE |
1997 | 1970 | ||
1998 | /* Put the paca pointer into r13 and SPRG3 */ | ||
1999 | _GLOBAL(setup_boot_paca) | ||
2000 | LOAD_REG_IMMEDIATE(r3, boot_cpuid) | ||
2001 | lwz r3,0(r3) | ||
2002 | LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */ | ||
2003 | mulli r3,r3,PACA_SIZE /* Calculate vaddr of right paca */ | ||
2004 | add r13,r3,r4 /* for this processor. */ | ||
2005 | mtspr SPRN_SPRG3,r13 | ||
2006 | |||
2007 | blr | ||
2008 | |||
2009 | /* | 1971 | /* |
2010 | * We put a few things here that have to be page-aligned. | 1972 | * We put a few things here that have to be page-aligned. |
2011 | * This stuff goes at the beginning of the bss, which is page-aligned. | 1973 | * This stuff goes at the beginning of the bss, which is page-aligned. |
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 7cb77c20fc5d..3d677ac99659 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <asm/iommu.h> | 38 | #include <asm/iommu.h> |
39 | #include <asm/pci-bridge.h> | 39 | #include <asm/pci-bridge.h> |
40 | #include <asm/machdep.h> | 40 | #include <asm/machdep.h> |
41 | #include <asm/kdump.h> | ||
41 | 42 | ||
42 | #define DBG(...) | 43 | #define DBG(...) |
43 | 44 | ||
@@ -440,8 +441,37 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) | |||
440 | tbl->it_largehint = tbl->it_halfpoint; | 441 | tbl->it_largehint = tbl->it_halfpoint; |
441 | spin_lock_init(&tbl->it_lock); | 442 | spin_lock_init(&tbl->it_lock); |
442 | 443 | ||
444 | #ifdef CONFIG_CRASH_DUMP | ||
445 | if (ppc_md.tce_get) { | ||
446 | unsigned long index, tceval; | ||
447 | unsigned long tcecount = 0; | ||
448 | |||
449 | /* | ||
450 | * Reserve the existing mappings left by the first kernel. | ||
451 | */ | ||
452 | for (index = 0; index < tbl->it_size; index++) { | ||
453 | tceval = ppc_md.tce_get(tbl, index + tbl->it_offset); | ||
454 | /* | ||
455 | * Freed TCE entry contains 0x7fffffffffffffff on JS20 | ||
456 | */ | ||
457 | if (tceval && (tceval != 0x7fffffffffffffffUL)) { | ||
458 | __set_bit(index, tbl->it_map); | ||
459 | tcecount++; | ||
460 | } | ||
461 | } | ||
462 | if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) { | ||
463 | printk(KERN_WARNING "TCE table is full; "); | ||
464 | printk(KERN_WARNING "freeing %d entries for the kdump boot\n", | ||
465 | KDUMP_MIN_TCE_ENTRIES); | ||
466 | for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES; | ||
467 | index < tbl->it_size; index++) | ||
468 | __clear_bit(index, tbl->it_map); | ||
469 | } | ||
470 | } | ||
471 | #else | ||
443 | /* Clear the hardware table in case firmware left allocations in it */ | 472 | /* Clear the hardware table in case firmware left allocations in it */ |
444 | ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); | 473 | ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); |
474 | #endif | ||
445 | 475 | ||
446 | if (!welcomed) { | 476 | if (!welcomed) { |
447 | printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", | 477 | printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", |
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 6e67b5b49ba1..3a9b78d03542 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c | |||
@@ -302,6 +302,17 @@ void __init find_legacy_serial_ports(void) | |||
302 | of_node_put(isa); | 302 | of_node_put(isa); |
303 | } | 303 | } |
304 | 304 | ||
305 | /* First fill our array with tsi-bridge ports */ | ||
306 | for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) { | ||
307 | struct device_node *tsi = of_get_parent(np); | ||
308 | if (tsi && !strcmp(tsi->type, "tsi-bridge")) { | ||
309 | index = add_legacy_soc_port(np, np); | ||
310 | if (index >= 0 && np == stdout) | ||
311 | legacy_serial_console = index; | ||
312 | } | ||
313 | of_node_put(tsi); | ||
314 | } | ||
315 | |||
305 | #ifdef CONFIG_PCI | 316 | #ifdef CONFIG_PCI |
306 | /* Next, try to locate PCI ports */ | 317 | /* Next, try to locate PCI ports */ |
307 | for (np = NULL; (np = of_find_all_nodes(np));) { | 318 | for (np = NULL; (np = of_find_all_nodes(np));) { |
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index c02deaab26c7..73edc3c16137 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c | |||
@@ -45,11 +45,9 @@ | |||
45 | static struct proc_dir_entry *proc_ppc64_lparcfg; | 45 | static struct proc_dir_entry *proc_ppc64_lparcfg; |
46 | #define LPARCFG_BUFF_SIZE 4096 | 46 | #define LPARCFG_BUFF_SIZE 4096 |
47 | 47 | ||
48 | #ifdef CONFIG_PPC_ISERIES | ||
49 | |||
50 | /* | 48 | /* |
51 | * For iSeries legacy systems, the PPA purr function is available from the | 49 | * Track sum of all purrs across all processors. This is used to further |
52 | * emulated_time_base field in the paca. | 50 | * calculate usage values by different applications |
53 | */ | 51 | */ |
54 | static unsigned long get_purr(void) | 52 | static unsigned long get_purr(void) |
55 | { | 53 | { |
@@ -57,48 +55,31 @@ static unsigned long get_purr(void) | |||
57 | int cpu; | 55 | int cpu; |
58 | 56 | ||
59 | for_each_possible_cpu(cpu) { | 57 | for_each_possible_cpu(cpu) { |
60 | sum_purr += lppaca[cpu].emulated_time_base; | 58 | if (firmware_has_feature(FW_FEATURE_ISERIES)) |
59 | sum_purr += lppaca[cpu].emulated_time_base; | ||
60 | else { | ||
61 | struct cpu_usage *cu; | ||
61 | 62 | ||
62 | #ifdef PURR_DEBUG | 63 | cu = &per_cpu(cpu_usage_array, cpu); |
63 | printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n", | 64 | sum_purr += cu->current_tb; |
64 | cpu, lppaca[cpu].emulated_time_base); | 65 | } |
65 | #endif | ||
66 | } | 66 | } |
67 | return sum_purr; | 67 | return sum_purr; |
68 | } | 68 | } |
69 | 69 | ||
70 | #define lparcfg_write NULL | 70 | #ifdef CONFIG_PPC_ISERIES |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * Methods used to fetch LPAR data when running on an iSeries platform. | 73 | * Methods used to fetch LPAR data when running on an iSeries platform. |
74 | */ | 74 | */ |
75 | static int lparcfg_data(struct seq_file *m, void *v) | 75 | static int iseries_lparcfg_data(struct seq_file *m, void *v) |
76 | { | 76 | { |
77 | unsigned long pool_id, lp_index; | 77 | unsigned long pool_id; |
78 | int shared, entitled_capacity, max_entitled_capacity; | 78 | int shared, entitled_capacity, max_entitled_capacity; |
79 | int processors, max_processors; | 79 | int processors, max_processors; |
80 | unsigned long purr = get_purr(); | 80 | unsigned long purr = get_purr(); |
81 | 81 | ||
82 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); | ||
83 | |||
84 | shared = (int)(get_lppaca()->shared_proc); | 82 | shared = (int)(get_lppaca()->shared_proc); |
85 | seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n", | ||
86 | e2a(xItExtVpdPanel.mfgID[2]), | ||
87 | e2a(xItExtVpdPanel.mfgID[3]), | ||
88 | e2a(xItExtVpdPanel.systemSerial[1]), | ||
89 | e2a(xItExtVpdPanel.systemSerial[2]), | ||
90 | e2a(xItExtVpdPanel.systemSerial[3]), | ||
91 | e2a(xItExtVpdPanel.systemSerial[4]), | ||
92 | e2a(xItExtVpdPanel.systemSerial[5])); | ||
93 | |||
94 | seq_printf(m, "system_type=%c%c%c%c\n", | ||
95 | e2a(xItExtVpdPanel.machineType[0]), | ||
96 | e2a(xItExtVpdPanel.machineType[1]), | ||
97 | e2a(xItExtVpdPanel.machineType[2]), | ||
98 | e2a(xItExtVpdPanel.machineType[3])); | ||
99 | |||
100 | lp_index = HvLpConfig_getLpIndex(); | ||
101 | seq_printf(m, "partition_id=%d\n", (int)lp_index); | ||
102 | 83 | ||
103 | seq_printf(m, "system_active_processors=%d\n", | 84 | seq_printf(m, "system_active_processors=%d\n", |
104 | (int)HvLpConfig_getSystemPhysicalProcessors()); | 85 | (int)HvLpConfig_getSystemPhysicalProcessors()); |
@@ -137,6 +118,14 @@ static int lparcfg_data(struct seq_file *m, void *v) | |||
137 | 118 | ||
138 | return 0; | 119 | return 0; |
139 | } | 120 | } |
121 | |||
122 | #else /* CONFIG_PPC_ISERIES */ | ||
123 | |||
124 | static int iseries_lparcfg_data(struct seq_file *m, void *v) | ||
125 | { | ||
126 | return 0; | ||
127 | } | ||
128 | |||
140 | #endif /* CONFIG_PPC_ISERIES */ | 129 | #endif /* CONFIG_PPC_ISERIES */ |
141 | 130 | ||
142 | #ifdef CONFIG_PPC_PSERIES | 131 | #ifdef CONFIG_PPC_PSERIES |
@@ -213,22 +202,6 @@ static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs) | |||
213 | log_plpar_hcall_return(rc, "H_PIC"); | 202 | log_plpar_hcall_return(rc, "H_PIC"); |
214 | } | 203 | } |
215 | 204 | ||
216 | /* Track sum of all purrs across all processors. This is used to further */ | ||
217 | /* calculate usage values by different applications */ | ||
218 | |||
219 | static unsigned long get_purr(void) | ||
220 | { | ||
221 | unsigned long sum_purr = 0; | ||
222 | int cpu; | ||
223 | struct cpu_usage *cu; | ||
224 | |||
225 | for_each_possible_cpu(cpu) { | ||
226 | cu = &per_cpu(cpu_usage_array, cpu); | ||
227 | sum_purr += cu->current_tb; | ||
228 | } | ||
229 | return sum_purr; | ||
230 | } | ||
231 | |||
232 | #define SPLPAR_CHARACTERISTICS_TOKEN 20 | 205 | #define SPLPAR_CHARACTERISTICS_TOKEN 20 |
233 | #define SPLPAR_MAXLENGTH 1026*(sizeof(char)) | 206 | #define SPLPAR_MAXLENGTH 1026*(sizeof(char)) |
234 | 207 | ||
@@ -333,35 +306,13 @@ static int lparcfg_count_active_processors(void) | |||
333 | return count; | 306 | return count; |
334 | } | 307 | } |
335 | 308 | ||
336 | static int lparcfg_data(struct seq_file *m, void *v) | 309 | static int pseries_lparcfg_data(struct seq_file *m, void *v) |
337 | { | 310 | { |
338 | int partition_potential_processors; | 311 | int partition_potential_processors; |
339 | int partition_active_processors; | 312 | int partition_active_processors; |
340 | struct device_node *rootdn; | ||
341 | const char *model = ""; | ||
342 | const char *system_id = ""; | ||
343 | unsigned int *lp_index_ptr, lp_index = 0; | ||
344 | struct device_node *rtas_node; | 313 | struct device_node *rtas_node; |
345 | int *lrdrp = NULL; | 314 | int *lrdrp = NULL; |
346 | 315 | ||
347 | rootdn = find_path_device("/"); | ||
348 | if (rootdn) { | ||
349 | model = get_property(rootdn, "model", NULL); | ||
350 | system_id = get_property(rootdn, "system-id", NULL); | ||
351 | lp_index_ptr = (unsigned int *) | ||
352 | get_property(rootdn, "ibm,partition-no", NULL); | ||
353 | if (lp_index_ptr) | ||
354 | lp_index = *lp_index_ptr; | ||
355 | } | ||
356 | |||
357 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); | ||
358 | |||
359 | seq_printf(m, "serial_number=%s\n", system_id); | ||
360 | |||
361 | seq_printf(m, "system_type=%s\n", model); | ||
362 | |||
363 | seq_printf(m, "partition_id=%d\n", (int)lp_index); | ||
364 | |||
365 | rtas_node = find_path_device("/rtas"); | 316 | rtas_node = find_path_device("/rtas"); |
366 | if (rtas_node) | 317 | if (rtas_node) |
367 | lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", | 318 | lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", |
@@ -549,8 +500,61 @@ out: | |||
549 | return retval; | 500 | return retval; |
550 | } | 501 | } |
551 | 502 | ||
503 | #else /* CONFIG_PPC_PSERIES */ | ||
504 | |||
505 | static int pseries_lparcfg_data(struct seq_file *m, void *v) | ||
506 | { | ||
507 | return 0; | ||
508 | } | ||
509 | |||
510 | static ssize_t lparcfg_write(struct file *file, const char __user * buf, | ||
511 | size_t count, loff_t * off) | ||
512 | { | ||
513 | return count; | ||
514 | } | ||
515 | |||
552 | #endif /* CONFIG_PPC_PSERIES */ | 516 | #endif /* CONFIG_PPC_PSERIES */ |
553 | 517 | ||
518 | static int lparcfg_data(struct seq_file *m, void *v) | ||
519 | { | ||
520 | struct device_node *rootdn; | ||
521 | const char *model = ""; | ||
522 | const char *system_id = ""; | ||
523 | const char *tmp; | ||
524 | unsigned int *lp_index_ptr, lp_index = 0; | ||
525 | |||
526 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); | ||
527 | |||
528 | rootdn = find_path_device("/"); | ||
529 | if (rootdn) { | ||
530 | tmp = get_property(rootdn, "model", NULL); | ||
531 | if (tmp) { | ||
532 | model = tmp; | ||
533 | /* Skip "IBM," - see platforms/iseries/dt.c */ | ||
534 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
535 | model += 4; | ||
536 | } | ||
537 | tmp = get_property(rootdn, "system-id", NULL); | ||
538 | if (tmp) { | ||
539 | system_id = tmp; | ||
540 | /* Skip "IBM," - see platforms/iseries/dt.c */ | ||
541 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
542 | system_id += 4; | ||
543 | } | ||
544 | lp_index_ptr = (unsigned int *) | ||
545 | get_property(rootdn, "ibm,partition-no", NULL); | ||
546 | if (lp_index_ptr) | ||
547 | lp_index = *lp_index_ptr; | ||
548 | } | ||
549 | seq_printf(m, "serial_number=%s\n", system_id); | ||
550 | seq_printf(m, "system_type=%s\n", model); | ||
551 | seq_printf(m, "partition_id=%d\n", (int)lp_index); | ||
552 | |||
553 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
554 | return iseries_lparcfg_data(m, v); | ||
555 | return pseries_lparcfg_data(m, v); | ||
556 | } | ||
557 | |||
554 | static int lparcfg_open(struct inode *inode, struct file *file) | 558 | static int lparcfg_open(struct inode *inode, struct file *file) |
555 | { | 559 | { |
556 | return single_open(file, lparcfg_data, NULL); | 560 | return single_open(file, lparcfg_data, NULL); |
@@ -569,7 +573,8 @@ int __init lparcfg_init(void) | |||
569 | mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; | 573 | mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; |
570 | 574 | ||
571 | /* Allow writing if we have FW_FEATURE_SPLPAR */ | 575 | /* Allow writing if we have FW_FEATURE_SPLPAR */ |
572 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { | 576 | if (firmware_has_feature(FW_FEATURE_SPLPAR) && |
577 | !firmware_has_feature(FW_FEATURE_ISERIES)) { | ||
573 | lparcfg_fops.write = lparcfg_write; | 578 | lparcfg_fops.write = lparcfg_write; |
574 | mode |= S_IWUSR; | 579 | mode |= S_IWUSR; |
575 | } | 580 | } |
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index a8fa04ef27cd..b438d45a068c 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
@@ -378,11 +378,13 @@ static void __init export_crashk_values(void) | |||
378 | of_node_put(node); | 378 | of_node_put(node); |
379 | } | 379 | } |
380 | 380 | ||
381 | void __init kexec_setup(void) | 381 | static int __init kexec_setup(void) |
382 | { | 382 | { |
383 | export_htab_values(); | 383 | export_htab_values(); |
384 | export_crashk_values(); | 384 | export_crashk_values(); |
385 | return 0; | ||
385 | } | 386 | } |
387 | __initcall(kexec_setup); | ||
386 | 388 | ||
387 | static int __init early_parse_crashk(char *p) | 389 | static int __init early_parse_crashk(char *p) |
388 | { | 390 | { |
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S new file mode 100644 index 000000000000..fc23040d5a26 --- /dev/null +++ b/arch/powerpc/kernel/misc.S | |||
@@ -0,0 +1,203 @@ | |||
1 | /* | ||
2 | * This file contains miscellaneous low-level functions. | ||
3 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | ||
4 | * | ||
5 | * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) | ||
6 | * and Paul Mackerras. | ||
7 | * | ||
8 | * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) | ||
9 | * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version | ||
14 | * 2 of the License, or (at your option) any later version. | ||
15 | */ | ||
16 | #include <asm/ppc_asm.h> | ||
17 | |||
18 | .text | ||
19 | |||
20 | #ifdef CONFIG_PPC64 | ||
21 | #define IN_SYNC twi 0,r5,0; isync | ||
22 | #define EIEIO_32 | ||
23 | #define SYNC_64 sync | ||
24 | #else /* CONFIG_PPC32 */ | ||
25 | #define IN_SYNC | ||
26 | #define EIEIO_32 eieio | ||
27 | #define SYNC_64 | ||
28 | #endif | ||
29 | /* | ||
30 | * Returns (address we are running at) - (address we were linked at) | ||
31 | * for use before the text and data are mapped to KERNELBASE. | ||
32 | */ | ||
33 | |||
34 | _GLOBAL(reloc_offset) | ||
35 | mflr r0 | ||
36 | bl 1f | ||
37 | 1: mflr r3 | ||
38 | LOAD_REG_IMMEDIATE(r4,1b) | ||
39 | subf r3,r4,r3 | ||
40 | mtlr r0 | ||
41 | blr | ||
42 | |||
43 | /* | ||
44 | * add_reloc_offset(x) returns x + reloc_offset(). | ||
45 | */ | ||
46 | _GLOBAL(add_reloc_offset) | ||
47 | mflr r0 | ||
48 | bl 1f | ||
49 | 1: mflr r5 | ||
50 | LOAD_REG_IMMEDIATE(r4,1b) | ||
51 | subf r5,r4,r5 | ||
52 | add r3,r3,r5 | ||
53 | mtlr r0 | ||
54 | blr | ||
55 | |||
56 | /* | ||
57 | * I/O string operations | ||
58 | * | ||
59 | * insb(port, buf, len) | ||
60 | * outsb(port, buf, len) | ||
61 | * insw(port, buf, len) | ||
62 | * outsw(port, buf, len) | ||
63 | * insl(port, buf, len) | ||
64 | * outsl(port, buf, len) | ||
65 | * insw_ns(port, buf, len) | ||
66 | * outsw_ns(port, buf, len) | ||
67 | * insl_ns(port, buf, len) | ||
68 | * outsl_ns(port, buf, len) | ||
69 | * | ||
70 | * The *_ns versions don't do byte-swapping. | ||
71 | */ | ||
72 | _GLOBAL(_insb) | ||
73 | cmpwi 0,r5,0 | ||
74 | mtctr r5 | ||
75 | subi r4,r4,1 | ||
76 | blelr- | ||
77 | 00: lbz r5,0(r3) | ||
78 | eieio | ||
79 | stbu r5,1(r4) | ||
80 | bdnz 00b | ||
81 | IN_SYNC | ||
82 | blr | ||
83 | |||
84 | _GLOBAL(_outsb) | ||
85 | cmpwi 0,r5,0 | ||
86 | mtctr r5 | ||
87 | subi r4,r4,1 | ||
88 | blelr- | ||
89 | 00: lbzu r5,1(r4) | ||
90 | stb r5,0(r3) | ||
91 | EIEIO_32 | ||
92 | bdnz 00b | ||
93 | SYNC_64 | ||
94 | blr | ||
95 | |||
96 | _GLOBAL(_insw) | ||
97 | cmpwi 0,r5,0 | ||
98 | mtctr r5 | ||
99 | subi r4,r4,2 | ||
100 | blelr- | ||
101 | 00: lhbrx r5,0,r3 | ||
102 | eieio | ||
103 | sthu r5,2(r4) | ||
104 | bdnz 00b | ||
105 | IN_SYNC | ||
106 | blr | ||
107 | |||
108 | _GLOBAL(_outsw) | ||
109 | cmpwi 0,r5,0 | ||
110 | mtctr r5 | ||
111 | subi r4,r4,2 | ||
112 | blelr- | ||
113 | 00: lhzu r5,2(r4) | ||
114 | EIEIO_32 | ||
115 | sthbrx r5,0,r3 | ||
116 | bdnz 00b | ||
117 | SYNC_64 | ||
118 | blr | ||
119 | |||
120 | _GLOBAL(_insl) | ||
121 | cmpwi 0,r5,0 | ||
122 | mtctr r5 | ||
123 | subi r4,r4,4 | ||
124 | blelr- | ||
125 | 00: lwbrx r5,0,r3 | ||
126 | eieio | ||
127 | stwu r5,4(r4) | ||
128 | bdnz 00b | ||
129 | IN_SYNC | ||
130 | blr | ||
131 | |||
132 | _GLOBAL(_outsl) | ||
133 | cmpwi 0,r5,0 | ||
134 | mtctr r5 | ||
135 | subi r4,r4,4 | ||
136 | blelr- | ||
137 | 00: lwzu r5,4(r4) | ||
138 | stwbrx r5,0,r3 | ||
139 | EIEIO_32 | ||
140 | bdnz 00b | ||
141 | SYNC_64 | ||
142 | blr | ||
143 | |||
144 | #ifdef CONFIG_PPC32 | ||
145 | _GLOBAL(__ide_mm_insw) | ||
146 | #endif | ||
147 | _GLOBAL(_insw_ns) | ||
148 | cmpwi 0,r5,0 | ||
149 | mtctr r5 | ||
150 | subi r4,r4,2 | ||
151 | blelr- | ||
152 | 00: lhz r5,0(r3) | ||
153 | eieio | ||
154 | sthu r5,2(r4) | ||
155 | bdnz 00b | ||
156 | IN_SYNC | ||
157 | blr | ||
158 | |||
159 | #ifdef CONFIG_PPC32 | ||
160 | _GLOBAL(__ide_mm_outsw) | ||
161 | #endif | ||
162 | _GLOBAL(_outsw_ns) | ||
163 | cmpwi 0,r5,0 | ||
164 | mtctr r5 | ||
165 | subi r4,r4,2 | ||
166 | blelr- | ||
167 | 00: lhzu r5,2(r4) | ||
168 | sth r5,0(r3) | ||
169 | EIEIO_32 | ||
170 | bdnz 00b | ||
171 | SYNC_64 | ||
172 | blr | ||
173 | |||
174 | #ifdef CONFIG_PPC32 | ||
175 | _GLOBAL(__ide_mm_insl) | ||
176 | #endif | ||
177 | _GLOBAL(_insl_ns) | ||
178 | cmpwi 0,r5,0 | ||
179 | mtctr r5 | ||
180 | subi r4,r4,4 | ||
181 | blelr- | ||
182 | 00: lwz r5,0(r3) | ||
183 | eieio | ||
184 | stwu r5,4(r4) | ||
185 | bdnz 00b | ||
186 | IN_SYNC | ||
187 | blr | ||
188 | |||
189 | #ifdef CONFIG_PPC32 | ||
190 | _GLOBAL(__ide_mm_outsl) | ||
191 | #endif | ||
192 | _GLOBAL(_outsl_ns) | ||
193 | cmpwi 0,r5,0 | ||
194 | mtctr r5 | ||
195 | subi r4,r4,4 | ||
196 | blelr- | ||
197 | 00: lwzu r5,4(r4) | ||
198 | stw r5,0(r3) | ||
199 | EIEIO_32 | ||
200 | bdnz 00b | ||
201 | SYNC_64 | ||
202 | blr | ||
203 | |||
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 01d3916c4cb1..c74774e2175d 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -61,32 +61,6 @@ _GLOBAL(mulhdu) | |||
61 | blr | 61 | blr |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * Returns (address we're running at) - (address we were linked at) | ||
65 | * for use before the text and data are mapped to KERNELBASE. | ||
66 | */ | ||
67 | _GLOBAL(reloc_offset) | ||
68 | mflr r0 | ||
69 | bl 1f | ||
70 | 1: mflr r3 | ||
71 | LOAD_REG_IMMEDIATE(r4,1b) | ||
72 | subf r3,r4,r3 | ||
73 | mtlr r0 | ||
74 | blr | ||
75 | |||
76 | /* | ||
77 | * add_reloc_offset(x) returns x + reloc_offset(). | ||
78 | */ | ||
79 | _GLOBAL(add_reloc_offset) | ||
80 | mflr r0 | ||
81 | bl 1f | ||
82 | 1: mflr r5 | ||
83 | LOAD_REG_IMMEDIATE(r4,1b) | ||
84 | subf r5,r4,r5 | ||
85 | add r3,r3,r5 | ||
86 | mtlr r0 | ||
87 | blr | ||
88 | |||
89 | /* | ||
90 | * sub_reloc_offset(x) returns x - reloc_offset(). | 64 | * sub_reloc_offset(x) returns x - reloc_offset(). |
91 | */ | 65 | */ |
92 | _GLOBAL(sub_reloc_offset) | 66 | _GLOBAL(sub_reloc_offset) |
@@ -781,136 +755,6 @@ _GLOBAL(atomic_set_mask) | |||
781 | blr | 755 | blr |
782 | 756 | ||
783 | /* | 757 | /* |
784 | * I/O string operations | ||
785 | * | ||
786 | * insb(port, buf, len) | ||
787 | * outsb(port, buf, len) | ||
788 | * insw(port, buf, len) | ||
789 | * outsw(port, buf, len) | ||
790 | * insl(port, buf, len) | ||
791 | * outsl(port, buf, len) | ||
792 | * insw_ns(port, buf, len) | ||
793 | * outsw_ns(port, buf, len) | ||
794 | * insl_ns(port, buf, len) | ||
795 | * outsl_ns(port, buf, len) | ||
796 | * | ||
797 | * The *_ns versions don't do byte-swapping. | ||
798 | */ | ||
799 | _GLOBAL(_insb) | ||
800 | cmpwi 0,r5,0 | ||
801 | mtctr r5 | ||
802 | subi r4,r4,1 | ||
803 | blelr- | ||
804 | 00: lbz r5,0(r3) | ||
805 | eieio | ||
806 | stbu r5,1(r4) | ||
807 | bdnz 00b | ||
808 | blr | ||
809 | |||
810 | _GLOBAL(_outsb) | ||
811 | cmpwi 0,r5,0 | ||
812 | mtctr r5 | ||
813 | subi r4,r4,1 | ||
814 | blelr- | ||
815 | 00: lbzu r5,1(r4) | ||
816 | stb r5,0(r3) | ||
817 | eieio | ||
818 | bdnz 00b | ||
819 | blr | ||
820 | |||
821 | _GLOBAL(_insw) | ||
822 | cmpwi 0,r5,0 | ||
823 | mtctr r5 | ||
824 | subi r4,r4,2 | ||
825 | blelr- | ||
826 | 00: lhbrx r5,0,r3 | ||
827 | eieio | ||
828 | sthu r5,2(r4) | ||
829 | bdnz 00b | ||
830 | blr | ||
831 | |||
832 | _GLOBAL(_outsw) | ||
833 | cmpwi 0,r5,0 | ||
834 | mtctr r5 | ||
835 | subi r4,r4,2 | ||
836 | blelr- | ||
837 | 00: lhzu r5,2(r4) | ||
838 | eieio | ||
839 | sthbrx r5,0,r3 | ||
840 | bdnz 00b | ||
841 | blr | ||
842 | |||
843 | _GLOBAL(_insl) | ||
844 | cmpwi 0,r5,0 | ||
845 | mtctr r5 | ||
846 | subi r4,r4,4 | ||
847 | blelr- | ||
848 | 00: lwbrx r5,0,r3 | ||
849 | eieio | ||
850 | stwu r5,4(r4) | ||
851 | bdnz 00b | ||
852 | blr | ||
853 | |||
854 | _GLOBAL(_outsl) | ||
855 | cmpwi 0,r5,0 | ||
856 | mtctr r5 | ||
857 | subi r4,r4,4 | ||
858 | blelr- | ||
859 | 00: lwzu r5,4(r4) | ||
860 | stwbrx r5,0,r3 | ||
861 | eieio | ||
862 | bdnz 00b | ||
863 | blr | ||
864 | |||
865 | _GLOBAL(__ide_mm_insw) | ||
866 | _GLOBAL(_insw_ns) | ||
867 | cmpwi 0,r5,0 | ||
868 | mtctr r5 | ||
869 | subi r4,r4,2 | ||
870 | blelr- | ||
871 | 00: lhz r5,0(r3) | ||
872 | eieio | ||
873 | sthu r5,2(r4) | ||
874 | bdnz 00b | ||
875 | blr | ||
876 | |||
877 | _GLOBAL(__ide_mm_outsw) | ||
878 | _GLOBAL(_outsw_ns) | ||
879 | cmpwi 0,r5,0 | ||
880 | mtctr r5 | ||
881 | subi r4,r4,2 | ||
882 | blelr- | ||
883 | 00: lhzu r5,2(r4) | ||
884 | sth r5,0(r3) | ||
885 | eieio | ||
886 | bdnz 00b | ||
887 | blr | ||
888 | |||
889 | _GLOBAL(__ide_mm_insl) | ||
890 | _GLOBAL(_insl_ns) | ||
891 | cmpwi 0,r5,0 | ||
892 | mtctr r5 | ||
893 | subi r4,r4,4 | ||
894 | blelr- | ||
895 | 00: lwz r5,0(r3) | ||
896 | eieio | ||
897 | stwu r5,4(r4) | ||
898 | bdnz 00b | ||
899 | blr | ||
900 | |||
901 | _GLOBAL(__ide_mm_outsl) | ||
902 | _GLOBAL(_outsl_ns) | ||
903 | cmpwi 0,r5,0 | ||
904 | mtctr r5 | ||
905 | subi r4,r4,4 | ||
906 | blelr- | ||
907 | 00: lwzu r5,4(r4) | ||
908 | stw r5,0(r3) | ||
909 | eieio | ||
910 | bdnz 00b | ||
911 | blr | ||
912 | |||
913 | /* | ||
914 | * Extended precision shifts. | 758 | * Extended precision shifts. |
915 | * | 759 | * |
916 | * Updated to be valid for shift counts from 0 to 63 inclusive. | 760 | * Updated to be valid for shift counts from 0 to 63 inclusive. |
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index e8883d42c43c..580891cb8ccb 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * arch/powerpc/kernel/misc64.S | ||
3 | * | ||
4 | * This file contains miscellaneous low-level functions. | 2 | * This file contains miscellaneous low-level functions. |
5 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | 3 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) |
6 | * | 4 | * |
7 | * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) | 5 | * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) |
8 | * and Paul Mackerras. | 6 | * and Paul Mackerras. |
9 | * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) | 7 | * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) |
10 | * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) | 8 | * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) |
11 | * | 9 | * |
12 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License | 11 | * modify it under the terms of the GNU General Public License |
14 | * as published by the Free Software Foundation; either version | 12 | * as published by the Free Software Foundation; either version |
@@ -30,41 +28,10 @@ | |||
30 | 28 | ||
31 | .text | 29 | .text |
32 | 30 | ||
33 | /* | ||
34 | * Returns (address we are running at) - (address we were linked at) | ||
35 | * for use before the text and data are mapped to KERNELBASE. | ||
36 | */ | ||
37 | |||
38 | _GLOBAL(reloc_offset) | ||
39 | mflr r0 | ||
40 | bl 1f | ||
41 | 1: mflr r3 | ||
42 | LOAD_REG_IMMEDIATE(r4,1b) | ||
43 | subf r3,r4,r3 | ||
44 | mtlr r0 | ||
45 | blr | ||
46 | |||
47 | /* | ||
48 | * add_reloc_offset(x) returns x + reloc_offset(). | ||
49 | */ | ||
50 | _GLOBAL(add_reloc_offset) | ||
51 | mflr r0 | ||
52 | bl 1f | ||
53 | 1: mflr r5 | ||
54 | LOAD_REG_IMMEDIATE(r4,1b) | ||
55 | subf r5,r4,r5 | ||
56 | add r3,r3,r5 | ||
57 | mtlr r0 | ||
58 | blr | ||
59 | |||
60 | _GLOBAL(get_msr) | 31 | _GLOBAL(get_msr) |
61 | mfmsr r3 | 32 | mfmsr r3 |
62 | blr | 33 | blr |
63 | 34 | ||
64 | _GLOBAL(get_dar) | ||
65 | mfdar r3 | ||
66 | blr | ||
67 | |||
68 | _GLOBAL(get_srr0) | 35 | _GLOBAL(get_srr0) |
69 | mfsrr0 r3 | 36 | mfsrr0 r3 |
70 | blr | 37 | blr |
@@ -72,10 +39,6 @@ _GLOBAL(get_srr0) | |||
72 | _GLOBAL(get_srr1) | 39 | _GLOBAL(get_srr1) |
73 | mfsrr1 r3 | 40 | mfsrr1 r3 |
74 | blr | 41 | blr |
75 | |||
76 | _GLOBAL(get_sp) | ||
77 | mr r3,r1 | ||
78 | blr | ||
79 | 42 | ||
80 | #ifdef CONFIG_IRQSTACKS | 43 | #ifdef CONFIG_IRQSTACKS |
81 | _GLOBAL(call_do_softirq) | 44 | _GLOBAL(call_do_softirq) |
@@ -101,48 +64,6 @@ _GLOBAL(call___do_IRQ) | |||
101 | blr | 64 | blr |
102 | #endif /* CONFIG_IRQSTACKS */ | 65 | #endif /* CONFIG_IRQSTACKS */ |
103 | 66 | ||
104 | /* | ||
105 | * To be called by C code which needs to do some operations with MMU | ||
106 | * disabled. Note that interrupts have to be disabled by the caller | ||
107 | * prior to calling us. The code called _MUST_ be in the RMO of course | ||
108 | * and part of the linear mapping as we don't attempt to translate the | ||
109 | * stack pointer at all. The function is called with the stack switched | ||
110 | * to this CPU emergency stack | ||
111 | * | ||
112 | * prototype is void *call_with_mmu_off(void *func, void *data); | ||
113 | * | ||
114 | * the called function is expected to be of the form | ||
115 | * | ||
116 | * void *called(void *data); | ||
117 | */ | ||
118 | _GLOBAL(call_with_mmu_off) | ||
119 | mflr r0 /* get link, save it on stackframe */ | ||
120 | std r0,16(r1) | ||
121 | mr r1,r5 /* save old stack ptr */ | ||
122 | ld r1,PACAEMERGSP(r13) /* get emerg. stack */ | ||
123 | subi r1,r1,STACK_FRAME_OVERHEAD | ||
124 | std r0,16(r1) /* save link on emerg. stack */ | ||
125 | std r5,0(r1) /* save old stack ptr in backchain */ | ||
126 | ld r3,0(r3) /* get to real function ptr (assume same TOC) */ | ||
127 | bl 2f /* we need LR to return, continue at label 2 */ | ||
128 | |||
129 | ld r0,16(r1) /* we return here from the call, get LR and */ | ||
130 | ld r1,0(r1) /* .. old stack ptr */ | ||
131 | mtspr SPRN_SRR0,r0 /* and get back to virtual mode with these */ | ||
132 | mfmsr r4 | ||
133 | ori r4,r4,MSR_IR|MSR_DR | ||
134 | mtspr SPRN_SRR1,r4 | ||
135 | rfid | ||
136 | |||
137 | 2: mtspr SPRN_SRR0,r3 /* coming from above, enter real mode */ | ||
138 | mr r3,r4 /* get parameter */ | ||
139 | mfmsr r0 | ||
140 | ori r0,r0,MSR_IR|MSR_DR | ||
141 | xori r0,r0,MSR_IR|MSR_DR | ||
142 | mtspr SPRN_SRR1,r0 | ||
143 | rfid | ||
144 | |||
145 | |||
146 | .section ".toc","aw" | 67 | .section ".toc","aw" |
147 | PPC64_CACHES: | 68 | PPC64_CACHES: |
148 | .tc ppc64_caches[TC],ppc64_caches | 69 | .tc ppc64_caches[TC],ppc64_caches |
@@ -323,144 +244,6 @@ _GLOBAL(__flush_dcache_icache) | |||
323 | bdnz 1b | 244 | bdnz 1b |
324 | isync | 245 | isync |
325 | blr | 246 | blr |
326 | |||
327 | /* | ||
328 | * I/O string operations | ||
329 | * | ||
330 | * insb(port, buf, len) | ||
331 | * outsb(port, buf, len) | ||
332 | * insw(port, buf, len) | ||
333 | * outsw(port, buf, len) | ||
334 | * insl(port, buf, len) | ||
335 | * outsl(port, buf, len) | ||
336 | * insw_ns(port, buf, len) | ||
337 | * outsw_ns(port, buf, len) | ||
338 | * insl_ns(port, buf, len) | ||
339 | * outsl_ns(port, buf, len) | ||
340 | * | ||
341 | * The *_ns versions don't do byte-swapping. | ||
342 | */ | ||
343 | _GLOBAL(_insb) | ||
344 | cmpwi 0,r5,0 | ||
345 | mtctr r5 | ||
346 | subi r4,r4,1 | ||
347 | blelr- | ||
348 | 00: lbz r5,0(r3) | ||
349 | eieio | ||
350 | stbu r5,1(r4) | ||
351 | bdnz 00b | ||
352 | twi 0,r5,0 | ||
353 | isync | ||
354 | blr | ||
355 | |||
356 | _GLOBAL(_outsb) | ||
357 | cmpwi 0,r5,0 | ||
358 | mtctr r5 | ||
359 | subi r4,r4,1 | ||
360 | blelr- | ||
361 | 00: lbzu r5,1(r4) | ||
362 | stb r5,0(r3) | ||
363 | bdnz 00b | ||
364 | sync | ||
365 | blr | ||
366 | |||
367 | _GLOBAL(_insw) | ||
368 | cmpwi 0,r5,0 | ||
369 | mtctr r5 | ||
370 | subi r4,r4,2 | ||
371 | blelr- | ||
372 | 00: lhbrx r5,0,r3 | ||
373 | eieio | ||
374 | sthu r5,2(r4) | ||
375 | bdnz 00b | ||
376 | twi 0,r5,0 | ||
377 | isync | ||
378 | blr | ||
379 | |||
380 | _GLOBAL(_outsw) | ||
381 | cmpwi 0,r5,0 | ||
382 | mtctr r5 | ||
383 | subi r4,r4,2 | ||
384 | blelr- | ||
385 | 00: lhzu r5,2(r4) | ||
386 | sthbrx r5,0,r3 | ||
387 | bdnz 00b | ||
388 | sync | ||
389 | blr | ||
390 | |||
391 | _GLOBAL(_insl) | ||
392 | cmpwi 0,r5,0 | ||
393 | mtctr r5 | ||
394 | subi r4,r4,4 | ||
395 | blelr- | ||
396 | 00: lwbrx r5,0,r3 | ||
397 | eieio | ||
398 | stwu r5,4(r4) | ||
399 | bdnz 00b | ||
400 | twi 0,r5,0 | ||
401 | isync | ||
402 | blr | ||
403 | |||
404 | _GLOBAL(_outsl) | ||
405 | cmpwi 0,r5,0 | ||
406 | mtctr r5 | ||
407 | subi r4,r4,4 | ||
408 | blelr- | ||
409 | 00: lwzu r5,4(r4) | ||
410 | stwbrx r5,0,r3 | ||
411 | bdnz 00b | ||
412 | sync | ||
413 | blr | ||
414 | |||
415 | /* _GLOBAL(ide_insw) now in drivers/ide/ide-iops.c */ | ||
416 | _GLOBAL(_insw_ns) | ||
417 | cmpwi 0,r5,0 | ||
418 | mtctr r5 | ||
419 | subi r4,r4,2 | ||
420 | blelr- | ||
421 | 00: lhz r5,0(r3) | ||
422 | eieio | ||
423 | sthu r5,2(r4) | ||
424 | bdnz 00b | ||
425 | twi 0,r5,0 | ||
426 | isync | ||
427 | blr | ||
428 | |||
429 | /* _GLOBAL(ide_outsw) now in drivers/ide/ide-iops.c */ | ||
430 | _GLOBAL(_outsw_ns) | ||
431 | cmpwi 0,r5,0 | ||
432 | mtctr r5 | ||
433 | subi r4,r4,2 | ||
434 | blelr- | ||
435 | 00: lhzu r5,2(r4) | ||
436 | sth r5,0(r3) | ||
437 | bdnz 00b | ||
438 | sync | ||
439 | blr | ||
440 | |||
441 | _GLOBAL(_insl_ns) | ||
442 | cmpwi 0,r5,0 | ||
443 | mtctr r5 | ||
444 | subi r4,r4,4 | ||
445 | blelr- | ||
446 | 00: lwz r5,0(r3) | ||
447 | eieio | ||
448 | stwu r5,4(r4) | ||
449 | bdnz 00b | ||
450 | twi 0,r5,0 | ||
451 | isync | ||
452 | blr | ||
453 | |||
454 | _GLOBAL(_outsl_ns) | ||
455 | cmpwi 0,r5,0 | ||
456 | mtctr r5 | ||
457 | subi r4,r4,4 | ||
458 | blelr- | ||
459 | 00: lwzu r5,4(r4) | ||
460 | stw r5,0(r3) | ||
461 | bdnz 00b | ||
462 | sync | ||
463 | blr | ||
464 | 247 | ||
465 | /* | 248 | /* |
466 | * identify_cpu and calls setup_cpu | 249 | * identify_cpu and calls setup_cpu |
@@ -605,6 +388,7 @@ _GLOBAL(real_writeb) | |||
605 | blr | 388 | blr |
606 | #endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */ | 389 | #endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */ |
607 | 390 | ||
391 | #ifdef CONFIG_CPU_FREQ_PMAC64 | ||
608 | /* | 392 | /* |
609 | * SCOM access functions for 970 (FX only for now) | 393 | * SCOM access functions for 970 (FX only for now) |
610 | * | 394 | * |
@@ -673,6 +457,7 @@ _GLOBAL(scom970_write) | |||
673 | /* restore interrupts */ | 457 | /* restore interrupts */ |
674 | mtmsrd r5,1 | 458 | mtmsrd r5,1 |
675 | blr | 459 | blr |
460 | #endif /* CONFIG_CPU_FREQ_PMAC64 */ | ||
676 | 461 | ||
677 | 462 | ||
678 | /* | 463 | /* |
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index f505a8827e3e..a0bb354c1c08 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <asm/ptrace.h> | 16 | #include <asm/ptrace.h> |
17 | #include <asm/page.h> | 17 | #include <asm/page.h> |
18 | #include <asm/lppaca.h> | 18 | #include <asm/lppaca.h> |
19 | #include <asm/iseries/it_lp_queue.h> | ||
20 | #include <asm/iseries/it_lp_reg_save.h> | 19 | #include <asm/iseries/it_lp_reg_save.h> |
21 | #include <asm/paca.h> | 20 | #include <asm/paca.h> |
22 | 21 | ||
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 483455c5bb02..320c913435cd 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/bitops.h> | 30 | #include <linux/bitops.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/kexec.h> | 32 | #include <linux/kexec.h> |
33 | #include <linux/debugfs.h> | ||
33 | 34 | ||
34 | #include <asm/prom.h> | 35 | #include <asm/prom.h> |
35 | #include <asm/rtas.h> | 36 | #include <asm/rtas.h> |
@@ -952,6 +953,7 @@ static struct ibm_pa_feature { | |||
952 | /* put this back once we know how to test if firmware does 64k IO */ | 953 | /* put this back once we know how to test if firmware does 64k IO */ |
953 | {CPU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, | 954 | {CPU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, |
954 | #endif | 955 | #endif |
956 | {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, | ||
955 | }; | 957 | }; |
956 | 958 | ||
957 | static void __init check_cpu_pa_features(unsigned long node) | 959 | static void __init check_cpu_pa_features(unsigned long node) |
@@ -1124,24 +1126,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node, | |||
1124 | tce_alloc_end = *lprop; | 1126 | tce_alloc_end = *lprop; |
1125 | #endif | 1127 | #endif |
1126 | 1128 | ||
1127 | #ifdef CONFIG_PPC_RTAS | ||
1128 | /* To help early debugging via the front panel, we retrieve a minimal | ||
1129 | * set of RTAS infos now if available | ||
1130 | */ | ||
1131 | { | ||
1132 | u64 *basep, *entryp, *sizep; | ||
1133 | |||
1134 | basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL); | ||
1135 | entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); | ||
1136 | sizep = of_get_flat_dt_prop(node, "linux,rtas-size", NULL); | ||
1137 | if (basep && entryp && sizep) { | ||
1138 | rtas.base = *basep; | ||
1139 | rtas.entry = *entryp; | ||
1140 | rtas.size = *sizep; | ||
1141 | } | ||
1142 | } | ||
1143 | #endif /* CONFIG_PPC_RTAS */ | ||
1144 | |||
1145 | #ifdef CONFIG_KEXEC | 1129 | #ifdef CONFIG_KEXEC |
1146 | lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL); | 1130 | lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL); |
1147 | if (lprop) | 1131 | if (lprop) |
@@ -1326,6 +1310,11 @@ void __init early_init_devtree(void *params) | |||
1326 | /* Setup flat device-tree pointer */ | 1310 | /* Setup flat device-tree pointer */ |
1327 | initial_boot_params = params; | 1311 | initial_boot_params = params; |
1328 | 1312 | ||
1313 | #ifdef CONFIG_PPC_RTAS | ||
1314 | /* Some machines might need RTAS info for debugging, grab it now. */ | ||
1315 | of_scan_flat_dt(early_init_dt_scan_rtas, NULL); | ||
1316 | #endif | ||
1317 | |||
1329 | /* Retrieve various informations from the /chosen node of the | 1318 | /* Retrieve various informations from the /chosen node of the |
1330 | * device-tree, including the platform type, initrd location and | 1319 | * device-tree, including the platform type, initrd location and |
1331 | * size, TCE reserve, and more ... | 1320 | * size, TCE reserve, and more ... |
@@ -2148,3 +2137,27 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) | |||
2148 | } | 2137 | } |
2149 | return NULL; | 2138 | return NULL; |
2150 | } | 2139 | } |
2140 | |||
2141 | #ifdef DEBUG | ||
2142 | static struct debugfs_blob_wrapper flat_dt_blob; | ||
2143 | |||
2144 | static int __init export_flat_device_tree(void) | ||
2145 | { | ||
2146 | struct dentry *d; | ||
2147 | |||
2148 | d = debugfs_create_dir("powerpc", NULL); | ||
2149 | if (!d) | ||
2150 | return 1; | ||
2151 | |||
2152 | flat_dt_blob.data = initial_boot_params; | ||
2153 | flat_dt_blob.size = initial_boot_params->totalsize; | ||
2154 | |||
2155 | d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR, | ||
2156 | d, &flat_dt_blob); | ||
2157 | if (!d) | ||
2158 | return 1; | ||
2159 | |||
2160 | return 0; | ||
2161 | } | ||
2162 | __initcall(export_flat_device_tree); | ||
2163 | #endif | ||
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 17dc79198515..4a4cb5598402 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
@@ -38,16 +38,19 @@ | |||
38 | struct rtas_t rtas = { | 38 | struct rtas_t rtas = { |
39 | .lock = SPIN_LOCK_UNLOCKED | 39 | .lock = SPIN_LOCK_UNLOCKED |
40 | }; | 40 | }; |
41 | EXPORT_SYMBOL(rtas); | ||
41 | 42 | ||
42 | struct rtas_suspend_me_data { | 43 | struct rtas_suspend_me_data { |
43 | long waiting; | 44 | long waiting; |
44 | struct rtas_args *args; | 45 | struct rtas_args *args; |
45 | }; | 46 | }; |
46 | 47 | ||
47 | EXPORT_SYMBOL(rtas); | ||
48 | |||
49 | DEFINE_SPINLOCK(rtas_data_buf_lock); | 48 | DEFINE_SPINLOCK(rtas_data_buf_lock); |
49 | EXPORT_SYMBOL(rtas_data_buf_lock); | ||
50 | |||
50 | char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned; | 51 | char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned; |
52 | EXPORT_SYMBOL(rtas_data_buf); | ||
53 | |||
51 | unsigned long rtas_rmo_buf; | 54 | unsigned long rtas_rmo_buf; |
52 | 55 | ||
53 | /* | 56 | /* |
@@ -106,11 +109,71 @@ static void call_rtas_display_status_delay(char c) | |||
106 | } | 109 | } |
107 | } | 110 | } |
108 | 111 | ||
109 | void __init udbg_init_rtas(void) | 112 | void __init udbg_init_rtas_panel(void) |
110 | { | 113 | { |
111 | udbg_putc = call_rtas_display_status_delay; | 114 | udbg_putc = call_rtas_display_status_delay; |
112 | } | 115 | } |
113 | 116 | ||
117 | #ifdef CONFIG_UDBG_RTAS_CONSOLE | ||
118 | |||
119 | /* If you think you're dying before early_init_dt_scan_rtas() does its | ||
120 | * work, you can hard code the token values for your firmware here and | ||
121 | * hardcode rtas.base/entry etc. | ||
122 | */ | ||
123 | static unsigned int rtas_putchar_token = RTAS_UNKNOWN_SERVICE; | ||
124 | static unsigned int rtas_getchar_token = RTAS_UNKNOWN_SERVICE; | ||
125 | |||
126 | static void udbg_rtascon_putc(char c) | ||
127 | { | ||
128 | int tries; | ||
129 | |||
130 | if (!rtas.base) | ||
131 | return; | ||
132 | |||
133 | /* Add CRs before LFs */ | ||
134 | if (c == '\n') | ||
135 | udbg_rtascon_putc('\r'); | ||
136 | |||
137 | /* if there is more than one character to be displayed, wait a bit */ | ||
138 | for (tries = 0; tries < 16; tries++) { | ||
139 | if (rtas_call(rtas_putchar_token, 1, 1, NULL, c) == 0) | ||
140 | break; | ||
141 | udelay(1000); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | static int udbg_rtascon_getc_poll(void) | ||
146 | { | ||
147 | int c; | ||
148 | |||
149 | if (!rtas.base) | ||
150 | return -1; | ||
151 | |||
152 | if (rtas_call(rtas_getchar_token, 0, 2, &c)) | ||
153 | return -1; | ||
154 | |||
155 | return c; | ||
156 | } | ||
157 | |||
158 | static int udbg_rtascon_getc(void) | ||
159 | { | ||
160 | int c; | ||
161 | |||
162 | while ((c = udbg_rtascon_getc_poll()) == -1) | ||
163 | ; | ||
164 | |||
165 | return c; | ||
166 | } | ||
167 | |||
168 | |||
169 | void __init udbg_init_rtas_console(void) | ||
170 | { | ||
171 | udbg_putc = udbg_rtascon_putc; | ||
172 | udbg_getc = udbg_rtascon_getc; | ||
173 | udbg_getc_poll = udbg_rtascon_getc_poll; | ||
174 | } | ||
175 | #endif /* CONFIG_UDBG_RTAS_CONSOLE */ | ||
176 | |||
114 | void rtas_progress(char *s, unsigned short hex) | 177 | void rtas_progress(char *s, unsigned short hex) |
115 | { | 178 | { |
116 | struct device_node *root; | 179 | struct device_node *root; |
@@ -236,6 +299,7 @@ int rtas_token(const char *service) | |||
236 | tokp = (int *) get_property(rtas.dev, service, NULL); | 299 | tokp = (int *) get_property(rtas.dev, service, NULL); |
237 | return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; | 300 | return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; |
238 | } | 301 | } |
302 | EXPORT_SYMBOL(rtas_token); | ||
239 | 303 | ||
240 | #ifdef CONFIG_RTAS_ERROR_LOGGING | 304 | #ifdef CONFIG_RTAS_ERROR_LOGGING |
241 | /* | 305 | /* |
@@ -328,7 +392,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) | |||
328 | char *buff_copy = NULL; | 392 | char *buff_copy = NULL; |
329 | int ret; | 393 | int ret; |
330 | 394 | ||
331 | if (token == RTAS_UNKNOWN_SERVICE) | 395 | if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE) |
332 | return -1; | 396 | return -1; |
333 | 397 | ||
334 | /* Gotta do something different here, use global lock for now... */ | 398 | /* Gotta do something different here, use global lock for now... */ |
@@ -369,6 +433,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) | |||
369 | } | 433 | } |
370 | return ret; | 434 | return ret; |
371 | } | 435 | } |
436 | EXPORT_SYMBOL(rtas_call); | ||
372 | 437 | ||
373 | /* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status | 438 | /* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status |
374 | * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds. | 439 | * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds. |
@@ -388,6 +453,7 @@ unsigned int rtas_busy_delay_time(int status) | |||
388 | 453 | ||
389 | return ms; | 454 | return ms; |
390 | } | 455 | } |
456 | EXPORT_SYMBOL(rtas_busy_delay_time); | ||
391 | 457 | ||
392 | /* For an RTAS busy status code, perform the hinted delay. */ | 458 | /* For an RTAS busy status code, perform the hinted delay. */ |
393 | unsigned int rtas_busy_delay(int status) | 459 | unsigned int rtas_busy_delay(int status) |
@@ -401,6 +467,7 @@ unsigned int rtas_busy_delay(int status) | |||
401 | 467 | ||
402 | return ms; | 468 | return ms; |
403 | } | 469 | } |
470 | EXPORT_SYMBOL(rtas_busy_delay); | ||
404 | 471 | ||
405 | int rtas_error_rc(int rtas_rc) | 472 | int rtas_error_rc(int rtas_rc) |
406 | { | 473 | { |
@@ -446,6 +513,7 @@ int rtas_get_power_level(int powerdomain, int *level) | |||
446 | return rtas_error_rc(rc); | 513 | return rtas_error_rc(rc); |
447 | return rc; | 514 | return rc; |
448 | } | 515 | } |
516 | EXPORT_SYMBOL(rtas_get_power_level); | ||
449 | 517 | ||
450 | int rtas_set_power_level(int powerdomain, int level, int *setlevel) | 518 | int rtas_set_power_level(int powerdomain, int level, int *setlevel) |
451 | { | 519 | { |
@@ -463,6 +531,7 @@ int rtas_set_power_level(int powerdomain, int level, int *setlevel) | |||
463 | return rtas_error_rc(rc); | 531 | return rtas_error_rc(rc); |
464 | return rc; | 532 | return rc; |
465 | } | 533 | } |
534 | EXPORT_SYMBOL(rtas_set_power_level); | ||
466 | 535 | ||
467 | int rtas_get_sensor(int sensor, int index, int *state) | 536 | int rtas_get_sensor(int sensor, int index, int *state) |
468 | { | 537 | { |
@@ -480,6 +549,7 @@ int rtas_get_sensor(int sensor, int index, int *state) | |||
480 | return rtas_error_rc(rc); | 549 | return rtas_error_rc(rc); |
481 | return rc; | 550 | return rc; |
482 | } | 551 | } |
552 | EXPORT_SYMBOL(rtas_get_sensor); | ||
483 | 553 | ||
484 | int rtas_set_indicator(int indicator, int index, int new_value) | 554 | int rtas_set_indicator(int indicator, int index, int new_value) |
485 | { | 555 | { |
@@ -497,6 +567,7 @@ int rtas_set_indicator(int indicator, int index, int new_value) | |||
497 | return rtas_error_rc(rc); | 567 | return rtas_error_rc(rc); |
498 | return rc; | 568 | return rc; |
499 | } | 569 | } |
570 | EXPORT_SYMBOL(rtas_set_indicator); | ||
500 | 571 | ||
501 | void rtas_restart(char *cmd) | 572 | void rtas_restart(char *cmd) |
502 | { | 573 | { |
@@ -791,14 +862,34 @@ void __init rtas_initialize(void) | |||
791 | #endif | 862 | #endif |
792 | } | 863 | } |
793 | 864 | ||
865 | int __init early_init_dt_scan_rtas(unsigned long node, | ||
866 | const char *uname, int depth, void *data) | ||
867 | { | ||
868 | u32 *basep, *entryp, *sizep; | ||
794 | 869 | ||
795 | EXPORT_SYMBOL(rtas_token); | 870 | if (depth != 1 || strcmp(uname, "rtas") != 0) |
796 | EXPORT_SYMBOL(rtas_call); | 871 | return 0; |
797 | EXPORT_SYMBOL(rtas_data_buf); | 872 | |
798 | EXPORT_SYMBOL(rtas_data_buf_lock); | 873 | basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL); |
799 | EXPORT_SYMBOL(rtas_busy_delay_time); | 874 | entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); |
800 | EXPORT_SYMBOL(rtas_busy_delay); | 875 | sizep = of_get_flat_dt_prop(node, "rtas-size", NULL); |
801 | EXPORT_SYMBOL(rtas_get_sensor); | 876 | |
802 | EXPORT_SYMBOL(rtas_get_power_level); | 877 | if (basep && entryp && sizep) { |
803 | EXPORT_SYMBOL(rtas_set_power_level); | 878 | rtas.base = *basep; |
804 | EXPORT_SYMBOL(rtas_set_indicator); | 879 | rtas.entry = *entryp; |
880 | rtas.size = *sizep; | ||
881 | } | ||
882 | |||
883 | #ifdef CONFIG_UDBG_RTAS_CONSOLE | ||
884 | basep = of_get_flat_dt_prop(node, "put-term-char", NULL); | ||
885 | if (basep) | ||
886 | rtas_putchar_token = *basep; | ||
887 | |||
888 | basep = of_get_flat_dt_prop(node, "get-term-char", NULL); | ||
889 | if (basep) | ||
890 | rtas_getchar_token = *basep; | ||
891 | #endif | ||
892 | |||
893 | /* break now */ | ||
894 | return 1; | ||
895 | } | ||
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 78f3a5fd43f6..175539c9afa0 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -149,6 +149,13 @@ early_param("smt-enabled", early_smt_enabled); | |||
149 | #define check_smt_enabled() | 149 | #define check_smt_enabled() |
150 | #endif /* CONFIG_SMP */ | 150 | #endif /* CONFIG_SMP */ |
151 | 151 | ||
152 | /* Put the paca pointer into r13 and SPRG3 */ | ||
153 | void __init setup_paca(int cpu) | ||
154 | { | ||
155 | local_paca = &paca[cpu]; | ||
156 | mtspr(SPRN_SPRG3, local_paca); | ||
157 | } | ||
158 | |||
152 | /* | 159 | /* |
153 | * Early initialization entry point. This is called by head.S | 160 | * Early initialization entry point. This is called by head.S |
154 | * with MMU translation disabled. We rely on the "feature" of | 161 | * with MMU translation disabled. We rely on the "feature" of |
@@ -170,6 +177,9 @@ early_param("smt-enabled", early_smt_enabled); | |||
170 | 177 | ||
171 | void __init early_setup(unsigned long dt_ptr) | 178 | void __init early_setup(unsigned long dt_ptr) |
172 | { | 179 | { |
180 | /* Assume we're on cpu 0 for now. Don't write to the paca yet! */ | ||
181 | setup_paca(0); | ||
182 | |||
173 | /* Enable early debugging if any specified (see udbg.h) */ | 183 | /* Enable early debugging if any specified (see udbg.h) */ |
174 | udbg_early_init(); | 184 | udbg_early_init(); |
175 | 185 | ||
@@ -183,7 +193,7 @@ void __init early_setup(unsigned long dt_ptr) | |||
183 | early_init_devtree(__va(dt_ptr)); | 193 | early_init_devtree(__va(dt_ptr)); |
184 | 194 | ||
185 | /* Now we know the logical id of our boot cpu, setup the paca. */ | 195 | /* Now we know the logical id of our boot cpu, setup the paca. */ |
186 | setup_boot_paca(); | 196 | setup_paca(boot_cpuid); |
187 | 197 | ||
188 | /* Fix up paca fields required for the boot cpu */ | 198 | /* Fix up paca fields required for the boot cpu */ |
189 | get_paca()->cpu_start = 1; | 199 | get_paca()->cpu_start = 1; |
@@ -350,19 +360,11 @@ void __init setup_system(void) | |||
350 | */ | 360 | */ |
351 | unflatten_device_tree(); | 361 | unflatten_device_tree(); |
352 | 362 | ||
353 | #ifdef CONFIG_KEXEC | ||
354 | kexec_setup(); /* requires unflattened device tree. */ | ||
355 | #endif | ||
356 | |||
357 | /* | 363 | /* |
358 | * Fill the ppc64_caches & systemcfg structures with informations | 364 | * Fill the ppc64_caches & systemcfg structures with informations |
359 | * retrieved from the device-tree. Need to be called before | 365 | * retrieved from the device-tree. Need to be called before |
360 | * finish_device_tree() since the later requires some of the | 366 | * finish_device_tree() since the later requires some of the |
361 | * informations filled up here to properly parse the interrupt | 367 | * informations filled up here to properly parse the interrupt tree. |
362 | * tree. | ||
363 | * It also sets up the cache line sizes which allows to call | ||
364 | * routines like flush_icache_range (used by the hash init | ||
365 | * later on). | ||
366 | */ | 368 | */ |
367 | initialize_cache_info(); | 369 | initialize_cache_info(); |
368 | 370 | ||
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 52f5659534f4..fa6bd97b6b9d 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -52,9 +52,13 @@ | |||
52 | #include <asm/firmware.h> | 52 | #include <asm/firmware.h> |
53 | #include <asm/processor.h> | 53 | #include <asm/processor.h> |
54 | #endif | 54 | #endif |
55 | #include <asm/kexec.h> | ||
55 | 56 | ||
56 | #ifdef CONFIG_PPC64 /* XXX */ | 57 | #ifdef CONFIG_PPC64 /* XXX */ |
57 | #define _IO_BASE pci_io_base | 58 | #define _IO_BASE pci_io_base |
59 | #ifdef CONFIG_KEXEC | ||
60 | cpumask_t cpus_in_sr = CPU_MASK_NONE; | ||
61 | #endif | ||
58 | #endif | 62 | #endif |
59 | 63 | ||
60 | #ifdef CONFIG_DEBUGGER | 64 | #ifdef CONFIG_DEBUGGER |
@@ -97,7 +101,7 @@ static DEFINE_SPINLOCK(die_lock); | |||
97 | 101 | ||
98 | int die(const char *str, struct pt_regs *regs, long err) | 102 | int die(const char *str, struct pt_regs *regs, long err) |
99 | { | 103 | { |
100 | static int die_counter, crash_dump_start = 0; | 104 | static int die_counter; |
101 | 105 | ||
102 | if (debugger(regs)) | 106 | if (debugger(regs)) |
103 | return 1; | 107 | return 1; |
@@ -137,21 +141,12 @@ int die(const char *str, struct pt_regs *regs, long err) | |||
137 | print_modules(); | 141 | print_modules(); |
138 | show_regs(regs); | 142 | show_regs(regs); |
139 | bust_spinlocks(0); | 143 | bust_spinlocks(0); |
144 | spin_unlock_irq(&die_lock); | ||
140 | 145 | ||
141 | if (!crash_dump_start && kexec_should_crash(current)) { | 146 | if (kexec_should_crash(current) || |
142 | crash_dump_start = 1; | 147 | kexec_sr_activated(smp_processor_id())) |
143 | spin_unlock_irq(&die_lock); | ||
144 | crash_kexec(regs); | 148 | crash_kexec(regs); |
145 | /* NOTREACHED */ | 149 | crash_kexec_secondary(regs); |
146 | } | ||
147 | spin_unlock_irq(&die_lock); | ||
148 | if (crash_dump_start) | ||
149 | /* | ||
150 | * Only for soft-reset: Other CPUs will be responded to an IPI | ||
151 | * sent by first kexec CPU. | ||
152 | */ | ||
153 | for(;;) | ||
154 | ; | ||
155 | 150 | ||
156 | if (in_interrupt()) | 151 | if (in_interrupt()) |
157 | panic("Fatal exception in interrupt"); | 152 | panic("Fatal exception in interrupt"); |
@@ -215,6 +210,10 @@ void system_reset_exception(struct pt_regs *regs) | |||
215 | return; | 210 | return; |
216 | } | 211 | } |
217 | 212 | ||
213 | #ifdef CONFIG_KEXEC | ||
214 | cpu_set(smp_processor_id(), cpus_in_sr); | ||
215 | #endif | ||
216 | |||
218 | die("System Reset", regs, SIGABRT); | 217 | die("System Reset", regs, SIGABRT); |
219 | 218 | ||
220 | /* Must die if the interrupt is not recoverable */ | 219 | /* Must die if the interrupt is not recoverable */ |
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index 67d9fd9ae2b5..759afd5e0d8a 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c | |||
@@ -34,9 +34,12 @@ void __init udbg_early_init(void) | |||
34 | #elif defined(CONFIG_PPC_EARLY_DEBUG_G5) | 34 | #elif defined(CONFIG_PPC_EARLY_DEBUG_G5) |
35 | /* For use on Apple G5 machines */ | 35 | /* For use on Apple G5 machines */ |
36 | udbg_init_pmac_realmode(); | 36 | udbg_init_pmac_realmode(); |
37 | #elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS) | 37 | #elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL) |
38 | /* RTAS panel debug */ | 38 | /* RTAS panel debug */ |
39 | udbg_init_rtas(); | 39 | udbg_init_rtas_panel(); |
40 | #elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE) | ||
41 | /* RTAS console debug */ | ||
42 | udbg_init_rtas_console(); | ||
40 | #elif defined(CONFIG_PPC_EARLY_DEBUG_MAPLE) | 43 | #elif defined(CONFIG_PPC_EARLY_DEBUG_MAPLE) |
41 | /* Maple real mode debug */ | 44 | /* Maple real mode debug */ |
42 | udbg_init_maple_realmode(); | 45 | udbg_init_maple_realmode(); |
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index a0f3cbd00d39..c90f124f3c71 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c | |||
@@ -520,7 +520,7 @@ static inline int tlb_batching_enabled(void) | |||
520 | } | 520 | } |
521 | #endif | 521 | #endif |
522 | 522 | ||
523 | void hpte_init_native(void) | 523 | void __init hpte_init_native(void) |
524 | { | 524 | { |
525 | ppc_md.hpte_invalidate = native_hpte_invalidate; | 525 | ppc_md.hpte_invalidate = native_hpte_invalidate; |
526 | ppc_md.hpte_updatepp = native_hpte_updatepp; | 526 | ppc_md.hpte_updatepp = native_hpte_updatepp; |
@@ -530,5 +530,4 @@ void hpte_init_native(void) | |||
530 | ppc_md.hpte_clear_all = native_hpte_clear; | 530 | ppc_md.hpte_clear_all = native_hpte_clear; |
531 | if (tlb_batching_enabled()) | 531 | if (tlb_batching_enabled()) |
532 | ppc_md.flush_hash_range = native_flush_hash_range; | 532 | ppc_md.flush_hash_range = native_flush_hash_range; |
533 | htab_finish_init(); | ||
534 | } | 533 | } |
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index d03fd2b4445e..3cc6d68f7117 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -167,34 +167,12 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | |||
167 | hash = hpt_hash(va, shift); | 167 | hash = hpt_hash(va, shift); |
168 | hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); | 168 | hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); |
169 | 169 | ||
170 | /* The crap below can be cleaned once ppd_md.probe() can | 170 | DBG("htab_bolt_mapping: calling %p\n", ppc_md.hpte_insert); |
171 | * set up the hash callbacks, thus we can just used the | 171 | |
172 | * normal insert callback here. | 172 | BUG_ON(!ppc_md.hpte_insert); |
173 | */ | 173 | ret = ppc_md.hpte_insert(hpteg, va, paddr, |
174 | #ifdef CONFIG_PPC_ISERIES | 174 | tmp_mode, HPTE_V_BOLTED, psize); |
175 | if (machine_is(iseries)) | 175 | |
176 | ret = iSeries_hpte_insert(hpteg, va, | ||
177 | paddr, | ||
178 | tmp_mode, | ||
179 | HPTE_V_BOLTED, | ||
180 | psize); | ||
181 | else | ||
182 | #endif | ||
183 | #ifdef CONFIG_PPC_PSERIES | ||
184 | if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR)) | ||
185 | ret = pSeries_lpar_hpte_insert(hpteg, va, | ||
186 | paddr, | ||
187 | tmp_mode, | ||
188 | HPTE_V_BOLTED, | ||
189 | psize); | ||
190 | else | ||
191 | #endif | ||
192 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
193 | ret = native_hpte_insert(hpteg, va, | ||
194 | paddr, | ||
195 | tmp_mode, HPTE_V_BOLTED, | ||
196 | psize); | ||
197 | #endif | ||
198 | if (ret < 0) | 176 | if (ret < 0) |
199 | break; | 177 | break; |
200 | } | 178 | } |
@@ -413,6 +391,41 @@ void create_section_mapping(unsigned long start, unsigned long end) | |||
413 | } | 391 | } |
414 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 392 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
415 | 393 | ||
394 | static inline void make_bl(unsigned int *insn_addr, void *func) | ||
395 | { | ||
396 | unsigned long funcp = *((unsigned long *)func); | ||
397 | int offset = funcp - (unsigned long)insn_addr; | ||
398 | |||
399 | *insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc)); | ||
400 | flush_icache_range((unsigned long)insn_addr, 4+ | ||
401 | (unsigned long)insn_addr); | ||
402 | } | ||
403 | |||
404 | static void __init htab_finish_init(void) | ||
405 | { | ||
406 | extern unsigned int *htab_call_hpte_insert1; | ||
407 | extern unsigned int *htab_call_hpte_insert2; | ||
408 | extern unsigned int *htab_call_hpte_remove; | ||
409 | extern unsigned int *htab_call_hpte_updatepp; | ||
410 | |||
411 | #ifdef CONFIG_PPC_64K_PAGES | ||
412 | extern unsigned int *ht64_call_hpte_insert1; | ||
413 | extern unsigned int *ht64_call_hpte_insert2; | ||
414 | extern unsigned int *ht64_call_hpte_remove; | ||
415 | extern unsigned int *ht64_call_hpte_updatepp; | ||
416 | |||
417 | make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert); | ||
418 | make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert); | ||
419 | make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove); | ||
420 | make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp); | ||
421 | #endif /* CONFIG_PPC_64K_PAGES */ | ||
422 | |||
423 | make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert); | ||
424 | make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert); | ||
425 | make_bl(htab_call_hpte_remove, ppc_md.hpte_remove); | ||
426 | make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp); | ||
427 | } | ||
428 | |||
416 | void __init htab_initialize(void) | 429 | void __init htab_initialize(void) |
417 | { | 430 | { |
418 | unsigned long table; | 431 | unsigned long table; |
@@ -525,6 +538,8 @@ void __init htab_initialize(void) | |||
525 | mmu_linear_psize)); | 538 | mmu_linear_psize)); |
526 | } | 539 | } |
527 | 540 | ||
541 | htab_finish_init(); | ||
542 | |||
528 | DBG(" <- htab_initialize()\n"); | 543 | DBG(" <- htab_initialize()\n"); |
529 | } | 544 | } |
530 | #undef KB | 545 | #undef KB |
@@ -787,16 +802,6 @@ void flush_hash_range(unsigned long number, int local) | |||
787 | } | 802 | } |
788 | } | 803 | } |
789 | 804 | ||
790 | static inline void make_bl(unsigned int *insn_addr, void *func) | ||
791 | { | ||
792 | unsigned long funcp = *((unsigned long *)func); | ||
793 | int offset = funcp - (unsigned long)insn_addr; | ||
794 | |||
795 | *insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc)); | ||
796 | flush_icache_range((unsigned long)insn_addr, 4+ | ||
797 | (unsigned long)insn_addr); | ||
798 | } | ||
799 | |||
800 | /* | 805 | /* |
801 | * low_hash_fault is called when we the low level hash code failed | 806 | * low_hash_fault is called when we the low level hash code failed |
802 | * to instert a PTE due to an hypervisor error | 807 | * to instert a PTE due to an hypervisor error |
@@ -815,28 +820,3 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address) | |||
815 | } | 820 | } |
816 | bad_page_fault(regs, address, SIGBUS); | 821 | bad_page_fault(regs, address, SIGBUS); |
817 | } | 822 | } |
818 | |||
819 | void __init htab_finish_init(void) | ||
820 | { | ||
821 | extern unsigned int *htab_call_hpte_insert1; | ||
822 | extern unsigned int *htab_call_hpte_insert2; | ||
823 | extern unsigned int *htab_call_hpte_remove; | ||
824 | extern unsigned int *htab_call_hpte_updatepp; | ||
825 | |||
826 | #ifdef CONFIG_PPC_64K_PAGES | ||
827 | extern unsigned int *ht64_call_hpte_insert1; | ||
828 | extern unsigned int *ht64_call_hpte_insert2; | ||
829 | extern unsigned int *ht64_call_hpte_remove; | ||
830 | extern unsigned int *ht64_call_hpte_updatepp; | ||
831 | |||
832 | make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert); | ||
833 | make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert); | ||
834 | make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove); | ||
835 | make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp); | ||
836 | #endif /* CONFIG_PPC_64K_PAGES */ | ||
837 | |||
838 | make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert); | ||
839 | make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert); | ||
840 | make_bl(htab_call_hpte_remove, ppc_md.hpte_remove); | ||
841 | make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp); | ||
842 | } | ||
diff --git a/arch/powerpc/mm/mmu_context_64.c b/arch/powerpc/mm/mmu_context_64.c index 65d18dca266f..e2051efa09c5 100644 --- a/arch/powerpc/mm/mmu_context_64.c +++ b/arch/powerpc/mm/mmu_context_64.c | |||
@@ -44,7 +44,9 @@ again: | |||
44 | return err; | 44 | return err; |
45 | 45 | ||
46 | if (index > MAX_CONTEXT) { | 46 | if (index > MAX_CONTEXT) { |
47 | spin_lock(&mmu_context_lock); | ||
47 | idr_remove(&mmu_context_idr, index); | 48 | idr_remove(&mmu_context_idr, index); |
49 | spin_unlock(&mmu_context_lock); | ||
48 | return -ENOMEM; | 50 | return -ENOMEM; |
49 | } | 51 | } |
50 | 52 | ||
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig index 3a87863d2876..d1ecc0f9ab58 100644 --- a/arch/powerpc/platforms/86xx/Kconfig +++ b/arch/powerpc/platforms/86xx/Kconfig | |||
@@ -7,6 +7,7 @@ choice | |||
7 | 7 | ||
8 | config MPC8641_HPCN | 8 | config MPC8641_HPCN |
9 | bool "Freescale MPC8641 HPCN" | 9 | bool "Freescale MPC8641 HPCN" |
10 | select PPC_I8259 | ||
10 | help | 11 | help |
11 | This option enables support for the MPC8641 HPCN board. | 12 | This option enables support for the MPC8641 HPCN board. |
12 | 13 | ||
@@ -28,9 +29,4 @@ config PPC_INDIRECT_PCI_BE | |||
28 | depends on PPC_86xx | 29 | depends on PPC_86xx |
29 | default y | 30 | default y |
30 | 31 | ||
31 | config PPC_STD_MMU | ||
32 | bool | ||
33 | depends on PPC_86xx | ||
34 | default y | ||
35 | |||
36 | endmenu | 32 | endmenu |
diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile index 7be796c5d5c9..476a6eeee710 100644 --- a/arch/powerpc/platforms/86xx/Makefile +++ b/arch/powerpc/platforms/86xx/Makefile | |||
@@ -2,9 +2,6 @@ | |||
2 | # Makefile for the PowerPC 86xx linux kernel. | 2 | # Makefile for the PowerPC 86xx linux kernel. |
3 | # | 3 | # |
4 | 4 | ||
5 | |||
6 | ifeq ($(CONFIG_PPC_86xx),y) | ||
7 | obj-$(CONFIG_SMP) += mpc86xx_smp.o | 5 | obj-$(CONFIG_SMP) += mpc86xx_smp.o |
8 | endif | ||
9 | obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o | 6 | obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o |
10 | obj-$(CONFIG_PCI) += pci.o mpc86xx_pcie.o | 7 | obj-$(CONFIG_PCI) += pci.o mpc86xx_pcie.o |
diff --git a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h index 5042253758b7..5d2bcf78cef7 100644 --- a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h +++ b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h | |||
@@ -14,7 +14,6 @@ | |||
14 | #ifndef __MPC8641_HPCN_H__ | 14 | #ifndef __MPC8641_HPCN_H__ |
15 | #define __MPC8641_HPCN_H__ | 15 | #define __MPC8641_HPCN_H__ |
16 | 16 | ||
17 | #include <linux/config.h> | ||
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
19 | 18 | ||
20 | /* PCI interrupt controller */ | 19 | /* PCI interrupt controller */ |
diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h index e3c9e4f417d3..2834462590b8 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx.h +++ b/arch/powerpc/platforms/86xx/mpc86xx.h | |||
@@ -15,11 +15,13 @@ | |||
15 | * mpc86xx_* files. Mostly for use by mpc86xx_setup(). | 15 | * mpc86xx_* files. Mostly for use by mpc86xx_setup(). |
16 | */ | 16 | */ |
17 | 17 | ||
18 | extern int __init add_bridge(struct device_node *dev); | 18 | extern int add_bridge(struct device_node *dev); |
19 | 19 | ||
20 | extern void __init setup_indirect_pcie(struct pci_controller *hose, | 20 | extern int mpc86xx_exclude_device(u_char bus, u_char devfn); |
21 | |||
22 | extern void setup_indirect_pcie(struct pci_controller *hose, | ||
21 | u32 cfg_addr, u32 cfg_data); | 23 | u32 cfg_addr, u32 cfg_data); |
22 | extern void __init setup_indirect_pcie_nomap(struct pci_controller *hose, | 24 | extern void setup_indirect_pcie_nomap(struct pci_controller *hose, |
23 | void __iomem *cfg_addr, | 25 | void __iomem *cfg_addr, |
24 | void __iomem *cfg_data); | 26 | void __iomem *cfg_data); |
25 | 27 | ||
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 483c21df181e..ebae73eb0063 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | |||
@@ -12,7 +12,6 @@ | |||
12 | * option) any later version. | 12 | * option) any later version. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/config.h> | ||
16 | #include <linux/stddef.h> | 15 | #include <linux/stddef.h> |
17 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
18 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
@@ -36,6 +35,7 @@ | |||
36 | #include <sysdev/fsl_soc.h> | 35 | #include <sysdev/fsl_soc.h> |
37 | 36 | ||
38 | #include "mpc86xx.h" | 37 | #include "mpc86xx.h" |
38 | #include "mpc8641_hpcn.h" | ||
39 | 39 | ||
40 | #ifndef CONFIG_PCI | 40 | #ifndef CONFIG_PCI |
41 | unsigned long isa_io_base = 0; | 41 | unsigned long isa_io_base = 0; |
@@ -186,17 +186,130 @@ mpc86xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | |||
186 | return PCI_IRQ_TABLE_LOOKUP + I8259_OFFSET; | 186 | return PCI_IRQ_TABLE_LOOKUP + I8259_OFFSET; |
187 | } | 187 | } |
188 | 188 | ||
189 | static void __devinit quirk_ali1575(struct pci_dev *dev) | ||
190 | { | ||
191 | unsigned short temp; | ||
192 | |||
193 | /* | ||
194 | * ALI1575 interrupts route table setup: | ||
195 | * | ||
196 | * IRQ pin IRQ# | ||
197 | * PIRQA ---- 3 | ||
198 | * PIRQB ---- 4 | ||
199 | * PIRQC ---- 5 | ||
200 | * PIRQD ---- 6 | ||
201 | * PIRQE ---- 9 | ||
202 | * PIRQF ---- 10 | ||
203 | * PIRQG ---- 11 | ||
204 | * PIRQH ---- 12 | ||
205 | * | ||
206 | * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD | ||
207 | * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA | ||
208 | */ | ||
209 | pci_write_config_dword(dev, 0x48, 0xb9317542); | ||
210 | |||
211 | /* USB 1.1 OHCI controller 1, interrupt: PIRQE */ | ||
212 | pci_write_config_byte(dev, 0x86, 0x0c); | ||
213 | |||
214 | /* USB 1.1 OHCI controller 2, interrupt: PIRQF */ | ||
215 | pci_write_config_byte(dev, 0x87, 0x0d); | ||
216 | |||
217 | /* USB 1.1 OHCI controller 3, interrupt: PIRQH */ | ||
218 | pci_write_config_byte(dev, 0x88, 0x0f); | ||
219 | |||
220 | /* USB 2.0 controller, interrupt: PIRQ7 */ | ||
221 | pci_write_config_byte(dev, 0x74, 0x06); | ||
222 | |||
223 | /* Audio controller, interrupt: PIRQE */ | ||
224 | pci_write_config_byte(dev, 0x8a, 0x0c); | ||
225 | |||
226 | /* Modem controller, interrupt: PIRQF */ | ||
227 | pci_write_config_byte(dev, 0x8b, 0x0d); | ||
228 | |||
229 | /* HD audio controller, interrupt: PIRQG */ | ||
230 | pci_write_config_byte(dev, 0x8c, 0x0e); | ||
231 | |||
232 | /* Serial ATA interrupt: PIRQD */ | ||
233 | pci_write_config_byte(dev, 0x8d, 0x0b); | ||
234 | |||
235 | /* SMB interrupt: PIRQH */ | ||
236 | pci_write_config_byte(dev, 0x8e, 0x0f); | ||
237 | |||
238 | /* PMU ACPI SCI interrupt: PIRQH */ | ||
239 | pci_write_config_byte(dev, 0x8f, 0x0f); | ||
240 | |||
241 | /* Primary PATA IDE IRQ: 14 | ||
242 | * Secondary PATA IDE IRQ: 15 | ||
243 | */ | ||
244 | pci_write_config_byte(dev, 0x44, 0x3d); | ||
245 | pci_write_config_byte(dev, 0x75, 0x0f); | ||
246 | |||
247 | /* Set IRQ14 and IRQ15 to legacy IRQs */ | ||
248 | pci_read_config_word(dev, 0x46, &temp); | ||
249 | temp |= 0xc000; | ||
250 | pci_write_config_word(dev, 0x46, temp); | ||
251 | |||
252 | /* Set i8259 interrupt trigger | ||
253 | * IRQ 3: Level | ||
254 | * IRQ 4: Level | ||
255 | * IRQ 5: Level | ||
256 | * IRQ 6: Level | ||
257 | * IRQ 7: Level | ||
258 | * IRQ 9: Level | ||
259 | * IRQ 10: Level | ||
260 | * IRQ 11: Level | ||
261 | * IRQ 12: Level | ||
262 | * IRQ 14: Edge | ||
263 | * IRQ 15: Edge | ||
264 | */ | ||
265 | outb(0xfa, 0x4d0); | ||
266 | outb(0x1e, 0x4d1); | ||
267 | } | ||
189 | 268 | ||
190 | int | 269 | static void __devinit quirk_uli5288(struct pci_dev *dev) |
191 | mpc86xx_exclude_device(u_char bus, u_char devfn) | ||
192 | { | 270 | { |
193 | #if !defined(CONFIG_PCI) | 271 | unsigned char c; |
194 | if (bus == 0 && PCI_SLOT(devfn) == 0) | 272 | |
195 | return PCIBIOS_DEVICE_NOT_FOUND; | 273 | pci_read_config_byte(dev,0x83,&c); |
196 | #endif | 274 | c |= 0x80; |
275 | pci_write_config_byte(dev, 0x83, c); | ||
276 | |||
277 | pci_write_config_byte(dev, 0x09, 0x01); | ||
278 | pci_write_config_byte(dev, 0x0a, 0x06); | ||
279 | |||
280 | pci_read_config_byte(dev,0x83,&c); | ||
281 | c &= 0x7f; | ||
282 | pci_write_config_byte(dev, 0x83, c); | ||
197 | 283 | ||
198 | return PCIBIOS_SUCCESSFUL; | 284 | pci_read_config_byte(dev,0x84,&c); |
285 | c |= 0x01; | ||
286 | pci_write_config_byte(dev, 0x84, c); | ||
199 | } | 287 | } |
288 | |||
289 | static void __devinit quirk_uli5229(struct pci_dev *dev) | ||
290 | { | ||
291 | unsigned short temp; | ||
292 | pci_write_config_word(dev, 0x04, 0x0405); | ||
293 | pci_read_config_word(dev, 0x4a, &temp); | ||
294 | temp |= 0x1000; | ||
295 | pci_write_config_word(dev, 0x4a, temp); | ||
296 | } | ||
297 | |||
298 | static void __devinit early_uli5249(struct pci_dev *dev) | ||
299 | { | ||
300 | unsigned char temp; | ||
301 | pci_write_config_word(dev, 0x04, 0x0007); | ||
302 | pci_read_config_byte(dev, 0x7c, &temp); | ||
303 | pci_write_config_byte(dev, 0x7c, 0x80); | ||
304 | pci_write_config_byte(dev, 0x09, 0x01); | ||
305 | pci_write_config_byte(dev, 0x7c, temp); | ||
306 | dev->class |= 0x1; | ||
307 | } | ||
308 | |||
309 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575); | ||
310 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); | ||
311 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); | ||
312 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); | ||
200 | #endif /* CONFIG_PCI */ | 313 | #endif /* CONFIG_PCI */ |
201 | 314 | ||
202 | 315 | ||
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_smp.c b/arch/powerpc/platforms/86xx/mpc86xx_smp.c index 944ec4b71416..bb7fb41933ad 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_smp.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_smp.c | |||
@@ -10,7 +10,6 @@ | |||
10 | * option) any later version. | 10 | * option) any later version. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/config.h> | ||
14 | #include <linux/stddef.h> | 13 | #include <linux/stddef.h> |
15 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | 15 | #include <linux/init.h> |
@@ -34,8 +33,8 @@ extern unsigned long __secondary_hold_acknowledge; | |||
34 | static void __init | 33 | static void __init |
35 | smp_86xx_release_core(int nr) | 34 | smp_86xx_release_core(int nr) |
36 | { | 35 | { |
37 | void *mcm_vaddr; | 36 | __be32 __iomem *mcm_vaddr; |
38 | unsigned long vaddr, pcr; | 37 | unsigned long pcr; |
39 | 38 | ||
40 | if (nr < 0 || nr >= NR_CPUS) | 39 | if (nr < 0 || nr >= NR_CPUS) |
41 | return; | 40 | return; |
@@ -45,10 +44,9 @@ smp_86xx_release_core(int nr) | |||
45 | */ | 44 | */ |
46 | mcm_vaddr = ioremap(get_immrbase() + MPC86xx_MCM_OFFSET, | 45 | mcm_vaddr = ioremap(get_immrbase() + MPC86xx_MCM_OFFSET, |
47 | MPC86xx_MCM_SIZE); | 46 | MPC86xx_MCM_SIZE); |
48 | vaddr = (unsigned long)mcm_vaddr + MCM_PORT_CONFIG_OFFSET; | 47 | pcr = in_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2)); |
49 | pcr = in_be32((volatile unsigned *)vaddr); | ||
50 | pcr |= 1 << (nr + 24); | 48 | pcr |= 1 << (nr + 24); |
51 | out_be32((volatile unsigned *)vaddr, pcr); | 49 | out_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2), pcr); |
52 | } | 50 | } |
53 | 51 | ||
54 | 52 | ||
diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c index 5180df7c75bc..bc5139043112 100644 --- a/arch/powerpc/platforms/86xx/pci.c +++ b/arch/powerpc/platforms/86xx/pci.c | |||
@@ -12,7 +12,6 @@ | |||
12 | * option) any later version. | 12 | * option) any later version. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/config.h> | ||
16 | #include <linux/types.h> | 15 | #include <linux/types.h> |
17 | #include <linux/module.h> | 16 | #include <linux/module.h> |
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
@@ -122,15 +121,12 @@ static void __init setup_pcie_atmu(struct pci_controller *hose, struct resource | |||
122 | static void __init | 121 | static void __init |
123 | mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) | 122 | mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) |
124 | { | 123 | { |
125 | volatile struct ccsr_pex *pcie; | ||
126 | u16 cmd; | 124 | u16 cmd; |
127 | unsigned int temps; | 125 | unsigned int temps; |
128 | 126 | ||
129 | DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n", | 127 | DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n", |
130 | pcie_offset, pcie_size); | 128 | pcie_offset, pcie_size); |
131 | 129 | ||
132 | pcie = ioremap(pcie_offset, pcie_size); | ||
133 | |||
134 | early_read_config_word(hose, 0, 0, PCI_COMMAND, &cmd); | 130 | early_read_config_word(hose, 0, 0, PCI_COMMAND, &cmd); |
135 | cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | 131 | cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY |
136 | | PCI_COMMAND_IO; | 132 | | PCI_COMMAND_IO; |
@@ -144,6 +140,14 @@ mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) | |||
144 | early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps); | 140 | early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps); |
145 | } | 141 | } |
146 | 142 | ||
143 | int mpc86xx_exclude_device(u_char bus, u_char devfn) | ||
144 | { | ||
145 | if (bus == 0 && PCI_SLOT(devfn) == 0) | ||
146 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
147 | |||
148 | return PCIBIOS_SUCCESSFUL; | ||
149 | } | ||
150 | |||
147 | int __init add_bridge(struct device_node *dev) | 151 | int __init add_bridge(struct device_node *dev) |
148 | { | 152 | { |
149 | int len; | 153 | int len; |
@@ -198,128 +202,3 @@ int __init add_bridge(struct device_node *dev) | |||
198 | 202 | ||
199 | return 0; | 203 | return 0; |
200 | } | 204 | } |
201 | |||
202 | static void __devinit quirk_ali1575(struct pci_dev *dev) | ||
203 | { | ||
204 | unsigned short temp; | ||
205 | |||
206 | /* | ||
207 | * ALI1575 interrupts route table setup: | ||
208 | * | ||
209 | * IRQ pin IRQ# | ||
210 | * PIRQA ---- 3 | ||
211 | * PIRQB ---- 4 | ||
212 | * PIRQC ---- 5 | ||
213 | * PIRQD ---- 6 | ||
214 | * PIRQE ---- 9 | ||
215 | * PIRQF ---- 10 | ||
216 | * PIRQG ---- 11 | ||
217 | * PIRQH ---- 12 | ||
218 | * | ||
219 | * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD | ||
220 | * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA | ||
221 | */ | ||
222 | pci_write_config_dword(dev, 0x48, 0xb9317542); | ||
223 | |||
224 | /* USB 1.1 OHCI controller 1, interrupt: PIRQE */ | ||
225 | pci_write_config_byte(dev, 0x86, 0x0c); | ||
226 | |||
227 | /* USB 1.1 OHCI controller 2, interrupt: PIRQF */ | ||
228 | pci_write_config_byte(dev, 0x87, 0x0d); | ||
229 | |||
230 | /* USB 1.1 OHCI controller 3, interrupt: PIRQH */ | ||
231 | pci_write_config_byte(dev, 0x88, 0x0f); | ||
232 | |||
233 | /* USB 2.0 controller, interrupt: PIRQ7 */ | ||
234 | pci_write_config_byte(dev, 0x74, 0x06); | ||
235 | |||
236 | /* Audio controller, interrupt: PIRQE */ | ||
237 | pci_write_config_byte(dev, 0x8a, 0x0c); | ||
238 | |||
239 | /* Modem controller, interrupt: PIRQF */ | ||
240 | pci_write_config_byte(dev, 0x8b, 0x0d); | ||
241 | |||
242 | /* HD audio controller, interrupt: PIRQG */ | ||
243 | pci_write_config_byte(dev, 0x8c, 0x0e); | ||
244 | |||
245 | /* Serial ATA interrupt: PIRQD */ | ||
246 | pci_write_config_byte(dev, 0x8d, 0x0b); | ||
247 | |||
248 | /* SMB interrupt: PIRQH */ | ||
249 | pci_write_config_byte(dev, 0x8e, 0x0f); | ||
250 | |||
251 | /* PMU ACPI SCI interrupt: PIRQH */ | ||
252 | pci_write_config_byte(dev, 0x8f, 0x0f); | ||
253 | |||
254 | /* Primary PATA IDE IRQ: 14 | ||
255 | * Secondary PATA IDE IRQ: 15 | ||
256 | */ | ||
257 | pci_write_config_byte(dev, 0x44, 0x3d); | ||
258 | pci_write_config_byte(dev, 0x75, 0x0f); | ||
259 | |||
260 | /* Set IRQ14 and IRQ15 to legacy IRQs */ | ||
261 | pci_read_config_word(dev, 0x46, &temp); | ||
262 | temp |= 0xc000; | ||
263 | pci_write_config_word(dev, 0x46, temp); | ||
264 | |||
265 | /* Set i8259 interrupt trigger | ||
266 | * IRQ 3: Level | ||
267 | * IRQ 4: Level | ||
268 | * IRQ 5: Level | ||
269 | * IRQ 6: Level | ||
270 | * IRQ 7: Level | ||
271 | * IRQ 9: Level | ||
272 | * IRQ 10: Level | ||
273 | * IRQ 11: Level | ||
274 | * IRQ 12: Level | ||
275 | * IRQ 14: Edge | ||
276 | * IRQ 15: Edge | ||
277 | */ | ||
278 | outb(0xfa, 0x4d0); | ||
279 | outb(0x1e, 0x4d1); | ||
280 | } | ||
281 | |||
282 | static void __devinit quirk_uli5288(struct pci_dev *dev) | ||
283 | { | ||
284 | unsigned char c; | ||
285 | |||
286 | pci_read_config_byte(dev,0x83,&c); | ||
287 | c |= 0x80; | ||
288 | pci_write_config_byte(dev, 0x83, c); | ||
289 | |||
290 | pci_write_config_byte(dev, 0x09, 0x01); | ||
291 | pci_write_config_byte(dev, 0x0a, 0x06); | ||
292 | |||
293 | pci_read_config_byte(dev,0x83,&c); | ||
294 | c &= 0x7f; | ||
295 | pci_write_config_byte(dev, 0x83, c); | ||
296 | |||
297 | pci_read_config_byte(dev,0x84,&c); | ||
298 | c |= 0x01; | ||
299 | pci_write_config_byte(dev, 0x84, c); | ||
300 | } | ||
301 | |||
302 | static void __devinit quirk_uli5229(struct pci_dev *dev) | ||
303 | { | ||
304 | unsigned short temp; | ||
305 | pci_write_config_word(dev, 0x04, 0x0405); | ||
306 | pci_read_config_word(dev, 0x4a, &temp); | ||
307 | temp |= 0x1000; | ||
308 | pci_write_config_word(dev, 0x4a, temp); | ||
309 | } | ||
310 | |||
311 | static void __devinit early_uli5249(struct pci_dev *dev) | ||
312 | { | ||
313 | unsigned char temp; | ||
314 | pci_write_config_word(dev, 0x04, 0x0007); | ||
315 | pci_read_config_byte(dev, 0x7c, &temp); | ||
316 | pci_write_config_byte(dev, 0x7c, 0x80); | ||
317 | pci_write_config_byte(dev, 0x09, 0x01); | ||
318 | pci_write_config_byte(dev, 0x7c, temp); | ||
319 | dev->class |= 0x1; | ||
320 | } | ||
321 | |||
322 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575); | ||
323 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); | ||
324 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); | ||
325 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); | ||
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 292863694562..5cf46dc57895 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile | |||
@@ -14,3 +14,4 @@ obj-$(CONFIG_PPC_PSERIES) += pseries/ | |||
14 | obj-$(CONFIG_PPC_ISERIES) += iseries/ | 14 | obj-$(CONFIG_PPC_ISERIES) += iseries/ |
15 | obj-$(CONFIG_PPC_MAPLE) += maple/ | 15 | obj-$(CONFIG_PPC_MAPLE) += maple/ |
16 | obj-$(CONFIG_PPC_CELL) += cell/ | 16 | obj-$(CONFIG_PPC_CELL) += cell/ |
17 | obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/ | ||
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig index 352bbbacde9a..0c8c7b6ab897 100644 --- a/arch/powerpc/platforms/cell/Kconfig +++ b/arch/powerpc/platforms/cell/Kconfig | |||
@@ -6,6 +6,7 @@ config SPU_FS | |||
6 | default m | 6 | default m |
7 | depends on PPC_CELL | 7 | depends on PPC_CELL |
8 | select SPU_BASE | 8 | select SPU_BASE |
9 | select MEMORY_HOTPLUG | ||
9 | help | 10 | help |
10 | The SPU file system is used to access Synergistic Processing | 11 | The SPU file system is used to access Synergistic Processing |
11 | Units on machines implementing the Broadband Processor | 12 | Units on machines implementing the Broadband Processor |
@@ -18,7 +19,6 @@ config SPU_BASE | |||
18 | config SPUFS_MMAP | 19 | config SPUFS_MMAP |
19 | bool | 20 | bool |
20 | depends on SPU_FS && SPARSEMEM | 21 | depends on SPU_FS && SPARSEMEM |
21 | select MEMORY_HOTPLUG | ||
22 | default y | 22 | default y |
23 | 23 | ||
24 | config CBE_RAS | 24 | config CBE_RAS |
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 3d1831d331e5..00d112f92272 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c | |||
@@ -125,8 +125,6 @@ static void __init cell_init_early(void) | |||
125 | { | 125 | { |
126 | DBG(" -> cell_init_early()\n"); | 126 | DBG(" -> cell_init_early()\n"); |
127 | 127 | ||
128 | hpte_init_native(); | ||
129 | |||
130 | cell_init_iommu(); | 128 | cell_init_iommu(); |
131 | 129 | ||
132 | ppc64_interrupt_controller = IC_CELL_PIC; | 130 | ppc64_interrupt_controller = IC_CELL_PIC; |
@@ -139,11 +137,17 @@ static int __init cell_probe(void) | |||
139 | { | 137 | { |
140 | unsigned long root = of_get_flat_dt_root(); | 138 | unsigned long root = of_get_flat_dt_root(); |
141 | 139 | ||
142 | if (of_flat_dt_is_compatible(root, "IBM,CBEA") || | 140 | if (!of_flat_dt_is_compatible(root, "IBM,CBEA") && |
143 | of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) | 141 | !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) |
144 | return 1; | 142 | return 0; |
143 | |||
144 | #ifdef CONFIG_UDBG_RTAS_CONSOLE | ||
145 | udbg_init_rtas_console(); | ||
146 | #endif | ||
147 | |||
148 | hpte_init_native(); | ||
145 | 149 | ||
146 | return 0; | 150 | return 1; |
147 | } | 151 | } |
148 | 152 | ||
149 | /* | 153 | /* |
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index db82f503ba2c..b306723abb87 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
@@ -168,12 +168,12 @@ spu_irq_class_0_bottom(struct spu *spu) | |||
168 | 168 | ||
169 | stat &= mask; | 169 | stat &= mask; |
170 | 170 | ||
171 | if (stat & 1) /* invalid MFC DMA */ | 171 | if (stat & 1) /* invalid DMA alignment */ |
172 | __spu_trap_invalid_dma(spu); | ||
173 | |||
174 | if (stat & 2) /* invalid DMA alignment */ | ||
175 | __spu_trap_dma_align(spu); | 172 | __spu_trap_dma_align(spu); |
176 | 173 | ||
174 | if (stat & 2) /* invalid MFC DMA */ | ||
175 | __spu_trap_invalid_dma(spu); | ||
176 | |||
177 | if (stat & 4) /* error on SPU */ | 177 | if (stat & 4) /* error on SPU */ |
178 | __spu_trap_error(spu); | 178 | __spu_trap_error(spu); |
179 | 179 | ||
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 7854a380dce2..58e794f9da1b 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
@@ -204,7 +204,7 @@ static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma) | |||
204 | 204 | ||
205 | vma->vm_flags |= VM_RESERVED; | 205 | vma->vm_flags |= VM_RESERVED; |
206 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | 206 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) |
207 | | _PAGE_NO_CACHE); | 207 | | _PAGE_NO_CACHE | _PAGE_GUARDED); |
208 | 208 | ||
209 | vma->vm_ops = &spufs_cntl_mmap_vmops; | 209 | vma->vm_ops = &spufs_cntl_mmap_vmops; |
210 | return 0; | 210 | return 0; |
@@ -675,7 +675,7 @@ static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma) | |||
675 | 675 | ||
676 | vma->vm_flags |= VM_RESERVED; | 676 | vma->vm_flags |= VM_RESERVED; |
677 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | 677 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) |
678 | | _PAGE_NO_CACHE); | 678 | | _PAGE_NO_CACHE | _PAGE_GUARDED); |
679 | 679 | ||
680 | vma->vm_ops = &spufs_signal1_mmap_vmops; | 680 | vma->vm_ops = &spufs_signal1_mmap_vmops; |
681 | return 0; | 681 | return 0; |
@@ -762,7 +762,7 @@ static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma) | |||
762 | /* FIXME: */ | 762 | /* FIXME: */ |
763 | vma->vm_flags |= VM_RESERVED; | 763 | vma->vm_flags |= VM_RESERVED; |
764 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | 764 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) |
765 | | _PAGE_NO_CACHE); | 765 | | _PAGE_NO_CACHE | _PAGE_GUARDED); |
766 | 766 | ||
767 | vma->vm_ops = &spufs_signal2_mmap_vmops; | 767 | vma->vm_ops = &spufs_signal2_mmap_vmops; |
768 | return 0; | 768 | return 0; |
@@ -850,7 +850,7 @@ static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma) | |||
850 | 850 | ||
851 | vma->vm_flags |= VM_RESERVED; | 851 | vma->vm_flags |= VM_RESERVED; |
852 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | 852 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) |
853 | | _PAGE_NO_CACHE); | 853 | | _PAGE_NO_CACHE | _PAGE_GUARDED); |
854 | 854 | ||
855 | vma->vm_ops = &spufs_mss_mmap_vmops; | 855 | vma->vm_ops = &spufs_mss_mmap_vmops; |
856 | return 0; | 856 | return 0; |
@@ -899,7 +899,7 @@ static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma) | |||
899 | 899 | ||
900 | vma->vm_flags |= VM_RESERVED; | 900 | vma->vm_flags |= VM_RESERVED; |
901 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | 901 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) |
902 | | _PAGE_NO_CACHE); | 902 | | _PAGE_NO_CACHE | _PAGE_GUARDED); |
903 | 903 | ||
904 | vma->vm_ops = &spufs_mfc_mmap_vmops; | 904 | vma->vm_ops = &spufs_mfc_mmap_vmops; |
905 | return 0; | 905 | return 0; |
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index a656d810a44a..c7fea2cca534 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c | |||
@@ -464,7 +464,8 @@ static inline void wait_purge_complete(struct spu_state *csa, struct spu *spu) | |||
464 | * Poll MFC_CNTL[Ps] until value '11' is read | 464 | * Poll MFC_CNTL[Ps] until value '11' is read |
465 | * (purge complete). | 465 | * (purge complete). |
466 | */ | 466 | */ |
467 | POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) & | 467 | POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) & |
468 | MFC_CNTL_PURGE_DMA_STATUS_MASK) == | ||
468 | MFC_CNTL_PURGE_DMA_COMPLETE); | 469 | MFC_CNTL_PURGE_DMA_COMPLETE); |
469 | } | 470 | } |
470 | 471 | ||
@@ -1028,7 +1029,8 @@ static inline void wait_suspend_mfc_complete(struct spu_state *csa, | |||
1028 | * Restore, Step 47. | 1029 | * Restore, Step 47. |
1029 | * Poll MFC_CNTL[Ss] until 11 is returned. | 1030 | * Poll MFC_CNTL[Ss] until 11 is returned. |
1030 | */ | 1031 | */ |
1031 | POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) & | 1032 | POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) & |
1033 | MFC_CNTL_SUSPEND_DMA_STATUS_MASK) == | ||
1032 | MFC_CNTL_SUSPEND_COMPLETE); | 1034 | MFC_CNTL_SUSPEND_COMPLETE); |
1033 | } | 1035 | } |
1034 | 1036 | ||
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 4fdbc9ae876b..ba07a9a7c039 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig | |||
@@ -74,6 +74,16 @@ config SANDPOINT | |||
74 | Select SANDPOINT if configuring for a Motorola Sandpoint X3 | 74 | Select SANDPOINT if configuring for a Motorola Sandpoint X3 |
75 | (any flavor). | 75 | (any flavor). |
76 | 76 | ||
77 | config MPC7448HPC2 | ||
78 | bool "Freescale MPC7448HPC2(Taiga)" | ||
79 | select TSI108_BRIDGE | ||
80 | select DEFAULT_UIMAGE | ||
81 | select PPC_UDBG_16550 | ||
82 | select MPIC | ||
83 | help | ||
84 | Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga) | ||
85 | platform | ||
86 | |||
77 | config RADSTONE_PPC7D | 87 | config RADSTONE_PPC7D |
78 | bool "Radstone Technology PPC7D board" | 88 | bool "Radstone Technology PPC7D board" |
79 | select PPC_I8259 | 89 | select PPC_I8259 |
@@ -221,6 +231,11 @@ config MV64X60 | |||
221 | select PPC_INDIRECT_PCI | 231 | select PPC_INDIRECT_PCI |
222 | default y | 232 | default y |
223 | 233 | ||
234 | config TSI108_BRIDGE | ||
235 | bool | ||
236 | depends on MPC7448HPC2 | ||
237 | default y | ||
238 | |||
224 | menu "Set bridge options" | 239 | menu "Set bridge options" |
225 | depends on MV64X60 | 240 | depends on MV64X60 |
226 | 241 | ||
diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile new file mode 100644 index 000000000000..fa499fe59291 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/Makefile | |||
@@ -0,0 +1,4 @@ | |||
1 | # | ||
2 | # Makefile for the 6xx/7xx/7xxxx linux kernel. | ||
3 | # | ||
4 | obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o | ||
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c new file mode 100644 index 000000000000..d7a4fc7ca238 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | |||
@@ -0,0 +1,335 @@ | |||
1 | /* | ||
2 | * mpc7448_hpc2.c | ||
3 | * | ||
4 | * Board setup routines for the Freescale Taiga platform | ||
5 | * | ||
6 | * Author: Jacob Pan | ||
7 | * jacob.pan@freescale.com | ||
8 | * Author: Xianghua Xiao | ||
9 | * x.xiao@freescale.com | ||
10 | * Maintainer: Roy Zang <tie-fei.zang@freescale.com> | ||
11 | * Add Flat Device Tree support fot mpc7448hpc2 board | ||
12 | * | ||
13 | * Copyright 2004-2006 Freescale Semiconductor, Inc. | ||
14 | * | ||
15 | * This file is licensed under | ||
16 | * the terms of the GNU General Public License version 2. This program | ||
17 | * is licensed "as is" without any warranty of any kind, whether express | ||
18 | * or implied. | ||
19 | */ | ||
20 | |||
21 | #include <linux/config.h> | ||
22 | #include <linux/stddef.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <linux/kdev_t.h> | ||
26 | #include <linux/console.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/irq.h> | ||
29 | #include <linux/ide.h> | ||
30 | #include <linux/seq_file.h> | ||
31 | #include <linux/root_dev.h> | ||
32 | #include <linux/serial.h> | ||
33 | #include <linux/tty.h> | ||
34 | #include <linux/serial_core.h> | ||
35 | |||
36 | #include <asm/system.h> | ||
37 | #include <asm/time.h> | ||
38 | #include <asm/machdep.h> | ||
39 | #include <asm/prom.h> | ||
40 | #include <asm/udbg.h> | ||
41 | #include <asm/tsi108.h> | ||
42 | #include <asm/pci-bridge.h> | ||
43 | #include <asm/reg.h> | ||
44 | #include <mm/mmu_decl.h> | ||
45 | #include "mpc7448_hpc2.h" | ||
46 | #include <asm/tsi108_irq.h> | ||
47 | #include <asm/mpic.h> | ||
48 | |||
49 | #undef DEBUG | ||
50 | #ifdef DEBUG | ||
51 | #define DBG(fmt...) do { printk(fmt); } while(0) | ||
52 | #else | ||
53 | #define DBG(fmt...) do { } while(0) | ||
54 | #endif | ||
55 | |||
56 | #ifndef CONFIG_PCI | ||
57 | isa_io_base = MPC7448_HPC2_ISA_IO_BASE; | ||
58 | isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE; | ||
59 | pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET; | ||
60 | #endif | ||
61 | |||
62 | extern int tsi108_setup_pci(struct device_node *dev); | ||
63 | extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); | ||
64 | extern void tsi108_pci_int_init(void); | ||
65 | extern int tsi108_irq_cascade(struct pt_regs *regs, void *unused); | ||
66 | |||
67 | /* | ||
68 | * Define all of the IRQ senses and polarities. Taken from the | ||
69 | * mpc7448hpc manual. | ||
70 | * Note: Likely, this table and the following function should be | ||
71 | * obtained and derived from the OF Device Tree. | ||
72 | */ | ||
73 | |||
74 | static u_char mpc7448_hpc2_pic_initsenses[] __initdata = { | ||
75 | /* External on-board sources */ | ||
76 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[0] XINT0 from FPGA */ | ||
77 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[1] XINT1 from FPGA */ | ||
78 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[2] PHY_INT from both GIGE */ | ||
79 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[3] RESERVED */ | ||
80 | /* Internal Tsi108/109 interrupt sources */ | ||
81 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ | ||
82 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ | ||
83 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ | ||
84 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ | ||
85 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA0 */ | ||
86 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA1 */ | ||
87 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA2 */ | ||
88 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA3 */ | ||
89 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART0 */ | ||
90 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART1 */ | ||
91 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* I2C */ | ||
92 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* GPIO */ | ||
93 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE0 */ | ||
94 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE1 */ | ||
95 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ | ||
96 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* HLP */ | ||
97 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* SDC */ | ||
98 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Processor IF */ | ||
99 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ | ||
100 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* PCI/X block */ | ||
101 | }; | ||
102 | |||
103 | int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) | ||
104 | { | ||
105 | if (bus == 0 && PCI_SLOT(devfn) == 0) | ||
106 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
107 | else | ||
108 | return PCIBIOS_SUCCESSFUL; | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * find pci slot by devfn in interrupt map of OF tree | ||
113 | */ | ||
114 | u8 find_slot_by_devfn(unsigned int *interrupt_map, unsigned int devfn) | ||
115 | { | ||
116 | int i; | ||
117 | unsigned int tmp; | ||
118 | for (i = 0; i < 4; i++){ | ||
119 | tmp = interrupt_map[i*4*7]; | ||
120 | if ((tmp >> 11) == (devfn >> 3)) | ||
121 | return i; | ||
122 | } | ||
123 | return i; | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * Scans the interrupt map for pci device | ||
128 | */ | ||
129 | void mpc7448_hpc2_fixup_irq(struct pci_dev *dev) | ||
130 | { | ||
131 | struct pci_controller *hose; | ||
132 | struct device_node *node; | ||
133 | unsigned int *interrupt; | ||
134 | int busnr; | ||
135 | int len; | ||
136 | u8 slot; | ||
137 | u8 pin; | ||
138 | |||
139 | /* Lookup the hose */ | ||
140 | busnr = dev->bus->number; | ||
141 | hose = pci_bus_to_hose(busnr); | ||
142 | if (!hose) | ||
143 | printk(KERN_ERR "No pci hose found\n"); | ||
144 | |||
145 | /* Check it has an OF node associated */ | ||
146 | node = (struct device_node *) hose->arch_data; | ||
147 | if (!node) | ||
148 | printk(KERN_ERR "No pci node found\n"); | ||
149 | |||
150 | interrupt = (unsigned int *) get_property(node, "interrupt-map", &len); | ||
151 | slot = find_slot_by_devfn(interrupt, dev->devfn); | ||
152 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); | ||
153 | if (pin == 0 || pin > 4) | ||
154 | pin = 1; | ||
155 | pin--; | ||
156 | dev->irq = interrupt[slot*4*7 + pin*7 + 5]; | ||
157 | DBG("TSI_PCI: dev->irq = 0x%x\n", dev->irq); | ||
158 | } | ||
159 | /* temporary pci irq map fixup*/ | ||
160 | |||
161 | void __init mpc7448_hpc2_pcibios_fixup(void) | ||
162 | { | ||
163 | struct pci_dev *dev = NULL; | ||
164 | for_each_pci_dev(dev) { | ||
165 | mpc7448_hpc2_fixup_irq(dev); | ||
166 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | static void __init mpc7448_hpc2_setup_arch(void) | ||
171 | { | ||
172 | struct device_node *cpu; | ||
173 | struct device_node *np; | ||
174 | if (ppc_md.progress) | ||
175 | ppc_md.progress("mpc7448_hpc2_setup_arch():set_bridge", 0); | ||
176 | |||
177 | cpu = of_find_node_by_type(NULL, "cpu"); | ||
178 | if (cpu != 0) { | ||
179 | unsigned int *fp; | ||
180 | |||
181 | fp = (int *)get_property(cpu, "clock-frequency", NULL); | ||
182 | if (fp != 0) | ||
183 | loops_per_jiffy = *fp / HZ; | ||
184 | else | ||
185 | loops_per_jiffy = 50000000 / HZ; | ||
186 | of_node_put(cpu); | ||
187 | } | ||
188 | tsi108_csr_vir_base = get_vir_csrbase(); | ||
189 | |||
190 | #ifdef CONFIG_ROOT_NFS | ||
191 | ROOT_DEV = Root_NFS; | ||
192 | #else | ||
193 | ROOT_DEV = Root_HDA1; | ||
194 | #endif | ||
195 | |||
196 | #ifdef CONFIG_BLK_DEV_INITRD | ||
197 | ROOT_DEV = Root_RAM0; | ||
198 | #endif | ||
199 | |||
200 | /* setup PCI host bridge */ | ||
201 | #ifdef CONFIG_PCI | ||
202 | for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) | ||
203 | tsi108_setup_pci(np); | ||
204 | |||
205 | ppc_md.pci_exclude_device = mpc7448_hpc2_exclude_device; | ||
206 | if (ppc_md.progress) | ||
207 | ppc_md.progress("tsi108: resources set", 0x100); | ||
208 | #endif | ||
209 | |||
210 | printk(KERN_INFO "MPC7448HPC2 (TAIGA) Platform\n"); | ||
211 | printk(KERN_INFO | ||
212 | "Jointly ported by Freescale and Tundra Semiconductor\n"); | ||
213 | printk(KERN_INFO | ||
214 | "Enabling L2 cache then enabling the HID0 prefetch engine.\n"); | ||
215 | } | ||
216 | |||
217 | /* | ||
218 | * Interrupt setup and service. Interrrupts on the mpc7448_hpc2 come | ||
219 | * from the four external INT pins, PCI interrupts are routed via | ||
220 | * PCI interrupt control registers, it generates internal IRQ23 | ||
221 | * | ||
222 | * Interrupt routing on the Taiga Board: | ||
223 | * TSI108:PB_INT[0] -> CPU0:INT# | ||
224 | * TSI108:PB_INT[1] -> CPU0:MCP# | ||
225 | * TSI108:PB_INT[2] -> N/C | ||
226 | * TSI108:PB_INT[3] -> N/C | ||
227 | */ | ||
228 | static void __init mpc7448_hpc2_init_IRQ(void) | ||
229 | { | ||
230 | struct mpic *mpic; | ||
231 | phys_addr_t mpic_paddr = 0; | ||
232 | struct device_node *tsi_pic; | ||
233 | |||
234 | tsi_pic = of_find_node_by_type(NULL, "open-pic"); | ||
235 | if (tsi_pic) { | ||
236 | unsigned int size; | ||
237 | void *prop = get_property(tsi_pic, "reg", &size); | ||
238 | mpic_paddr = of_translate_address(tsi_pic, prop); | ||
239 | } | ||
240 | |||
241 | if (mpic_paddr == 0) { | ||
242 | printk("%s: No tsi108 PIC found !\n", __FUNCTION__); | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | DBG("%s: tsi108pic phys_addr = 0x%x\n", __FUNCTION__, | ||
247 | (u32) mpic_paddr); | ||
248 | |||
249 | mpic = mpic_alloc(mpic_paddr, | ||
250 | MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | | ||
251 | MPIC_SPV_EOI | MPIC_MOD_ID(MPIC_ID_TSI108), | ||
252 | 0, /* num_sources used */ | ||
253 | TSI108_IRQ_BASE, | ||
254 | 0, /* num_sources used */ | ||
255 | NR_IRQS - 4 /* XXXX */, | ||
256 | mpc7448_hpc2_pic_initsenses, | ||
257 | sizeof(mpc7448_hpc2_pic_initsenses), "Tsi108_PIC"); | ||
258 | |||
259 | BUG_ON(mpic == NULL); /* XXXX */ | ||
260 | |||
261 | mpic_init(mpic); | ||
262 | mpic_setup_cascade(IRQ_TSI108_PCI, tsi108_irq_cascade, mpic); | ||
263 | tsi108_pci_int_init(); | ||
264 | |||
265 | /* Configure MPIC outputs to CPU0 */ | ||
266 | tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); | ||
267 | } | ||
268 | |||
269 | void mpc7448_hpc2_show_cpuinfo(struct seq_file *m) | ||
270 | { | ||
271 | seq_printf(m, "vendor\t\t: Freescale Semiconductor\n"); | ||
272 | seq_printf(m, "machine\t\t: MPC7448hpc2\n"); | ||
273 | } | ||
274 | |||
275 | void mpc7448_hpc2_restart(char *cmd) | ||
276 | { | ||
277 | local_irq_disable(); | ||
278 | |||
279 | /* Set exception prefix high - to the firmware */ | ||
280 | _nmask_and_or_msr(0, MSR_IP); | ||
281 | |||
282 | for (;;) ; /* Spin until reset happens */ | ||
283 | } | ||
284 | |||
285 | void mpc7448_hpc2_power_off(void) | ||
286 | { | ||
287 | local_irq_disable(); | ||
288 | for (;;) ; /* No way to shut power off with software */ | ||
289 | } | ||
290 | |||
291 | void mpc7448_hpc2_halt(void) | ||
292 | { | ||
293 | mpc7448_hpc2_power_off(); | ||
294 | } | ||
295 | |||
296 | /* | ||
297 | * Called very early, device-tree isn't unflattened | ||
298 | */ | ||
299 | static int __init mpc7448_hpc2_probe(void) | ||
300 | { | ||
301 | unsigned long root = of_get_flat_dt_root(); | ||
302 | |||
303 | if (!of_flat_dt_is_compatible(root, "mpc74xx")) | ||
304 | return 0; | ||
305 | return 1; | ||
306 | } | ||
307 | |||
308 | static int mpc7448_machine_check_exception(struct pt_regs *regs) | ||
309 | { | ||
310 | extern void tsi108_clear_pci_cfg_error(void); | ||
311 | const struct exception_table_entry *entry; | ||
312 | |||
313 | /* Are we prepared to handle this fault */ | ||
314 | if ((entry = search_exception_tables(regs->nip)) != NULL) { | ||
315 | tsi108_clear_pci_cfg_error(); | ||
316 | regs->msr |= MSR_RI; | ||
317 | regs->nip = entry->fixup; | ||
318 | return 1; | ||
319 | } | ||
320 | return 0; | ||
321 | |||
322 | } | ||
323 | define_machine(mpc7448_hpc2){ | ||
324 | .name = "MPC7448 HPC2", | ||
325 | .probe = mpc7448_hpc2_probe, | ||
326 | .setup_arch = mpc7448_hpc2_setup_arch, | ||
327 | .init_IRQ = mpc7448_hpc2_init_IRQ, | ||
328 | .show_cpuinfo = mpc7448_hpc2_show_cpuinfo, | ||
329 | .get_irq = mpic_get_irq, | ||
330 | .pcibios_fixup = mpc7448_hpc2_pcibios_fixup, | ||
331 | .restart = mpc7448_hpc2_restart, | ||
332 | .calibrate_decr = generic_calibrate_decr, | ||
333 | .machine_check_exception= mpc7448_machine_check_exception, | ||
334 | .progress = udbg_progress, | ||
335 | }; | ||
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h new file mode 100644 index 000000000000..a543a5242e34 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * mpc7448_hpc2.h | ||
3 | * | ||
4 | * Definitions for Freescale MPC7448_HPC2 platform | ||
5 | * | ||
6 | * Author: Jacob Pan | ||
7 | * jacob.pan@freescale.com | ||
8 | * Maintainer: Roy Zang <roy.zang@freescale.com> | ||
9 | * | ||
10 | * 2006 (c) Freescale Semiconductor, Inc. This file is licensed under | ||
11 | * the terms of the GNU General Public License version 2. This program | ||
12 | * is licensed "as is" without any warranty of any kind, whether express | ||
13 | * or implied. | ||
14 | */ | ||
15 | |||
16 | #ifndef __PPC_PLATFORMS_MPC7448_HPC2_H | ||
17 | #define __PPC_PLATFORMS_MPC7448_HPC2_H | ||
18 | |||
19 | #include <asm/ppcboot.h> | ||
20 | |||
21 | /* Base Addresses for the PCI bus | ||
22 | */ | ||
23 | #define MPC7448_HPC2_PCI_MEM_OFFSET (0x00000000) | ||
24 | #define MPC7448_HPC2_ISA_IO_BASE (0x00000000) | ||
25 | #define MPC7448_HPC2_ISA_MEM_BASE (0x00000000) | ||
26 | #endif /* __PPC_PLATFORMS_MPC7448_HPC2_H */ | ||
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c index d3444aabe76e..d194140c1ebf 100644 --- a/arch/powerpc/platforms/iseries/dt.c +++ b/arch/powerpc/platforms/iseries/dt.c | |||
@@ -252,6 +252,7 @@ static void __init dt_model(struct iseries_flat_dt *dt) | |||
252 | { | 252 | { |
253 | char buf[16] = "IBM,"; | 253 | char buf[16] = "IBM,"; |
254 | 254 | ||
255 | /* N.B. lparcfg.c knows about the "IBM," prefixes ... */ | ||
255 | /* "IBM," + mfgId[2:3] + systemSerial[1:5] */ | 256 | /* "IBM," + mfgId[2:3] + systemSerial[1:5] */ |
256 | strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2); | 257 | strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2); |
257 | strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5); | 258 | strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5); |
@@ -264,6 +265,7 @@ static void __init dt_model(struct iseries_flat_dt *dt) | |||
264 | dt_prop_str(dt, "model", buf); | 265 | dt_prop_str(dt, "model", buf); |
265 | 266 | ||
266 | dt_prop_str(dt, "compatible", "IBM,iSeries"); | 267 | dt_prop_str(dt, "compatible", "IBM,iSeries"); |
268 | dt_prop_u32(dt, "ibm,partition-no", HvLpConfig_getLpIndex()); | ||
267 | } | 269 | } |
268 | 270 | ||
269 | static void __init dt_do_vdevice(struct iseries_flat_dt *dt, | 271 | static void __init dt_do_vdevice(struct iseries_flat_dt *dt, |
diff --git a/arch/powerpc/platforms/iseries/htab.c b/arch/powerpc/platforms/iseries/htab.c index 30bdcf3925d9..ed44dfceaa45 100644 --- a/arch/powerpc/platforms/iseries/htab.c +++ b/arch/powerpc/platforms/iseries/htab.c | |||
@@ -242,13 +242,11 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va, | |||
242 | local_irq_restore(flags); | 242 | local_irq_restore(flags); |
243 | } | 243 | } |
244 | 244 | ||
245 | void hpte_init_iSeries(void) | 245 | void __init hpte_init_iSeries(void) |
246 | { | 246 | { |
247 | ppc_md.hpte_invalidate = iSeries_hpte_invalidate; | 247 | ppc_md.hpte_invalidate = iSeries_hpte_invalidate; |
248 | ppc_md.hpte_updatepp = iSeries_hpte_updatepp; | 248 | ppc_md.hpte_updatepp = iSeries_hpte_updatepp; |
249 | ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp; | 249 | ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp; |
250 | ppc_md.hpte_insert = iSeries_hpte_insert; | 250 | ppc_md.hpte_insert = iSeries_hpte_insert; |
251 | ppc_md.hpte_remove = iSeries_hpte_remove; | 251 | ppc_md.hpte_remove = iSeries_hpte_remove; |
252 | |||
253 | htab_finish_init(); | ||
254 | } | 252 | } |
diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c index 8ca7b9396355..2a9f81ea27d6 100644 --- a/arch/powerpc/platforms/iseries/lpevents.c +++ b/arch/powerpc/platforms/iseries/lpevents.c | |||
@@ -51,20 +51,21 @@ static unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes]; | |||
51 | static struct HvLpEvent * get_next_hvlpevent(void) | 51 | static struct HvLpEvent * get_next_hvlpevent(void) |
52 | { | 52 | { |
53 | struct HvLpEvent * event; | 53 | struct HvLpEvent * event; |
54 | event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; | 54 | event = (struct HvLpEvent *)hvlpevent_queue.hq_current_event; |
55 | 55 | ||
56 | if (hvlpevent_is_valid(event)) { | 56 | if (hvlpevent_is_valid(event)) { |
57 | /* rmb() needed only for weakly consistent machines (regatta) */ | 57 | /* rmb() needed only for weakly consistent machines (regatta) */ |
58 | rmb(); | 58 | rmb(); |
59 | /* Set pointer to next potential event */ | 59 | /* Set pointer to next potential event */ |
60 | hvlpevent_queue.xSlicCurEventPtr += ((event->xSizeMinus1 + | 60 | hvlpevent_queue.hq_current_event += ((event->xSizeMinus1 + |
61 | LpEventAlign) / LpEventAlign) * LpEventAlign; | 61 | IT_LP_EVENT_ALIGN) / IT_LP_EVENT_ALIGN) * |
62 | IT_LP_EVENT_ALIGN; | ||
62 | 63 | ||
63 | /* Wrap to beginning if no room at end */ | 64 | /* Wrap to beginning if no room at end */ |
64 | if (hvlpevent_queue.xSlicCurEventPtr > | 65 | if (hvlpevent_queue.hq_current_event > |
65 | hvlpevent_queue.xSlicLastValidEventPtr) { | 66 | hvlpevent_queue.hq_last_event) { |
66 | hvlpevent_queue.xSlicCurEventPtr = | 67 | hvlpevent_queue.hq_current_event = |
67 | hvlpevent_queue.xSlicEventStackPtr; | 68 | hvlpevent_queue.hq_event_stack; |
68 | } | 69 | } |
69 | } else { | 70 | } else { |
70 | event = NULL; | 71 | event = NULL; |
@@ -82,10 +83,10 @@ int hvlpevent_is_pending(void) | |||
82 | if (smp_processor_id() >= spread_lpevents) | 83 | if (smp_processor_id() >= spread_lpevents) |
83 | return 0; | 84 | return 0; |
84 | 85 | ||
85 | next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; | 86 | next_event = (struct HvLpEvent *)hvlpevent_queue.hq_current_event; |
86 | 87 | ||
87 | return hvlpevent_is_valid(next_event) || | 88 | return hvlpevent_is_valid(next_event) || |
88 | hvlpevent_queue.xPlicOverflowIntPending; | 89 | hvlpevent_queue.hq_overflow_pending; |
89 | } | 90 | } |
90 | 91 | ||
91 | static void hvlpevent_clear_valid(struct HvLpEvent * event) | 92 | static void hvlpevent_clear_valid(struct HvLpEvent * event) |
@@ -95,18 +96,18 @@ static void hvlpevent_clear_valid(struct HvLpEvent * event) | |||
95 | * ie. on 64-byte boundaries. | 96 | * ie. on 64-byte boundaries. |
96 | */ | 97 | */ |
97 | struct HvLpEvent *tmp; | 98 | struct HvLpEvent *tmp; |
98 | unsigned extra = ((event->xSizeMinus1 + LpEventAlign) / | 99 | unsigned extra = ((event->xSizeMinus1 + IT_LP_EVENT_ALIGN) / |
99 | LpEventAlign) - 1; | 100 | IT_LP_EVENT_ALIGN) - 1; |
100 | 101 | ||
101 | switch (extra) { | 102 | switch (extra) { |
102 | case 3: | 103 | case 3: |
103 | tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign); | 104 | tmp = (struct HvLpEvent*)((char*)event + 3 * IT_LP_EVENT_ALIGN); |
104 | hvlpevent_invalidate(tmp); | 105 | hvlpevent_invalidate(tmp); |
105 | case 2: | 106 | case 2: |
106 | tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign); | 107 | tmp = (struct HvLpEvent*)((char*)event + 2 * IT_LP_EVENT_ALIGN); |
107 | hvlpevent_invalidate(tmp); | 108 | hvlpevent_invalidate(tmp); |
108 | case 1: | 109 | case 1: |
109 | tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign); | 110 | tmp = (struct HvLpEvent*)((char*)event + 1 * IT_LP_EVENT_ALIGN); |
110 | hvlpevent_invalidate(tmp); | 111 | hvlpevent_invalidate(tmp); |
111 | } | 112 | } |
112 | 113 | ||
@@ -120,7 +121,7 @@ void process_hvlpevents(struct pt_regs *regs) | |||
120 | struct HvLpEvent * event; | 121 | struct HvLpEvent * event; |
121 | 122 | ||
122 | /* If we have recursed, just return */ | 123 | /* If we have recursed, just return */ |
123 | if (!spin_trylock(&hvlpevent_queue.lock)) | 124 | if (!spin_trylock(&hvlpevent_queue.hq_lock)) |
124 | return; | 125 | return; |
125 | 126 | ||
126 | for (;;) { | 127 | for (;;) { |
@@ -148,17 +149,17 @@ void process_hvlpevents(struct pt_regs *regs) | |||
148 | printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType ); | 149 | printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType ); |
149 | 150 | ||
150 | hvlpevent_clear_valid(event); | 151 | hvlpevent_clear_valid(event); |
151 | } else if (hvlpevent_queue.xPlicOverflowIntPending) | 152 | } else if (hvlpevent_queue.hq_overflow_pending) |
152 | /* | 153 | /* |
153 | * No more valid events. If overflow events are | 154 | * No more valid events. If overflow events are |
154 | * pending process them | 155 | * pending process them |
155 | */ | 156 | */ |
156 | HvCallEvent_getOverflowLpEvents(hvlpevent_queue.xIndex); | 157 | HvCallEvent_getOverflowLpEvents(hvlpevent_queue.hq_index); |
157 | else | 158 | else |
158 | break; | 159 | break; |
159 | } | 160 | } |
160 | 161 | ||
161 | spin_unlock(&hvlpevent_queue.lock); | 162 | spin_unlock(&hvlpevent_queue.hq_lock); |
162 | } | 163 | } |
163 | 164 | ||
164 | static int set_spread_lpevents(char *str) | 165 | static int set_spread_lpevents(char *str) |
@@ -184,20 +185,20 @@ void setup_hvlpevent_queue(void) | |||
184 | { | 185 | { |
185 | void *eventStack; | 186 | void *eventStack; |
186 | 187 | ||
187 | spin_lock_init(&hvlpevent_queue.lock); | 188 | spin_lock_init(&hvlpevent_queue.hq_lock); |
188 | 189 | ||
189 | /* Allocate a page for the Event Stack. */ | 190 | /* Allocate a page for the Event Stack. */ |
190 | eventStack = alloc_bootmem_pages(LpEventStackSize); | 191 | eventStack = alloc_bootmem_pages(IT_LP_EVENT_STACK_SIZE); |
191 | memset(eventStack, 0, LpEventStackSize); | 192 | memset(eventStack, 0, IT_LP_EVENT_STACK_SIZE); |
192 | 193 | ||
193 | /* Invoke the hypervisor to initialize the event stack */ | 194 | /* Invoke the hypervisor to initialize the event stack */ |
194 | HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); | 195 | HvCallEvent_setLpEventStack(0, eventStack, IT_LP_EVENT_STACK_SIZE); |
195 | 196 | ||
196 | hvlpevent_queue.xSlicEventStackPtr = (char *)eventStack; | 197 | hvlpevent_queue.hq_event_stack = eventStack; |
197 | hvlpevent_queue.xSlicCurEventPtr = (char *)eventStack; | 198 | hvlpevent_queue.hq_current_event = eventStack; |
198 | hvlpevent_queue.xSlicLastValidEventPtr = (char *)eventStack + | 199 | hvlpevent_queue.hq_last_event = (char *)eventStack + |
199 | (LpEventStackSize - LpEventMaxSize); | 200 | (IT_LP_EVENT_STACK_SIZE - IT_LP_EVENT_MAX_SIZE); |
200 | hvlpevent_queue.xIndex = 0; | 201 | hvlpevent_queue.hq_index = 0; |
201 | } | 202 | } |
202 | 203 | ||
203 | /* Register a handler for an LpEvent type */ | 204 | /* Register a handler for an LpEvent type */ |
diff --git a/arch/powerpc/platforms/iseries/proc.c b/arch/powerpc/platforms/iseries/proc.c index e68b6b5fa89f..c241413629ac 100644 --- a/arch/powerpc/platforms/iseries/proc.c +++ b/arch/powerpc/platforms/iseries/proc.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <asm/processor.h> | 24 | #include <asm/processor.h> |
25 | #include <asm/time.h> | 25 | #include <asm/time.h> |
26 | #include <asm/lppaca.h> | 26 | #include <asm/lppaca.h> |
27 | #include <asm/iseries/it_lp_queue.h> | ||
28 | #include <asm/iseries/hv_call_xm.h> | 27 | #include <asm/iseries/hv_call_xm.h> |
29 | 28 | ||
30 | #include "processor_vpd.h" | 29 | #include "processor_vpd.h" |
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 617c724c4590..66c77e4f8ec2 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c | |||
@@ -81,8 +81,6 @@ static void iSeries_pci_final_fixup(void) { } | |||
81 | #endif | 81 | #endif |
82 | 82 | ||
83 | extern int rd_size; /* Defined in drivers/block/rd.c */ | 83 | extern int rd_size; /* Defined in drivers/block/rd.c */ |
84 | extern unsigned long embedded_sysmap_start; | ||
85 | extern unsigned long embedded_sysmap_end; | ||
86 | 84 | ||
87 | extern unsigned long iSeries_recal_tb; | 85 | extern unsigned long iSeries_recal_tb; |
88 | extern unsigned long iSeries_recal_titan; | 86 | extern unsigned long iSeries_recal_titan; |
@@ -321,11 +319,6 @@ static void __init iSeries_init_early(void) | |||
321 | iSeries_recal_titan = HvCallXm_loadTod(); | 319 | iSeries_recal_titan = HvCallXm_loadTod(); |
322 | 320 | ||
323 | /* | 321 | /* |
324 | * Initialize the hash table management pointers | ||
325 | */ | ||
326 | hpte_init_iSeries(); | ||
327 | |||
328 | /* | ||
329 | * Initialize the DMA/TCE management | 322 | * Initialize the DMA/TCE management |
330 | */ | 323 | */ |
331 | iommu_init_early_iSeries(); | 324 | iommu_init_early_iSeries(); |
@@ -563,16 +556,6 @@ static void __init iSeries_fixup_klimit(void) | |||
563 | if (naca.xRamDisk) | 556 | if (naca.xRamDisk) |
564 | klimit = KERNELBASE + (u64)naca.xRamDisk + | 557 | klimit = KERNELBASE + (u64)naca.xRamDisk + |
565 | (naca.xRamDiskSize * HW_PAGE_SIZE); | 558 | (naca.xRamDiskSize * HW_PAGE_SIZE); |
566 | else { | ||
567 | /* | ||
568 | * No ram disk was included - check and see if there | ||
569 | * was an embedded system map. Change klimit to take | ||
570 | * into account any embedded system map | ||
571 | */ | ||
572 | if (embedded_sysmap_end) | ||
573 | klimit = KERNELBASE + ((embedded_sysmap_end + 4095) & | ||
574 | 0xfffffffffffff000); | ||
575 | } | ||
576 | } | 559 | } |
577 | 560 | ||
578 | static int __init iSeries_src_init(void) | 561 | static int __init iSeries_src_init(void) |
@@ -683,6 +666,8 @@ static int __init iseries_probe(void) | |||
683 | */ | 666 | */ |
684 | virt_irq_max = 255; | 667 | virt_irq_max = 255; |
685 | 668 | ||
669 | hpte_init_iSeries(); | ||
670 | |||
686 | return 1; | 671 | return 1; |
687 | } | 672 | } |
688 | 673 | ||
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index a0505ea48a86..4e32a5417fd1 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c | |||
@@ -199,11 +199,6 @@ static void __init maple_init_early(void) | |||
199 | { | 199 | { |
200 | DBG(" -> maple_init_early\n"); | 200 | DBG(" -> maple_init_early\n"); |
201 | 201 | ||
202 | /* Initialize hash table, from now on, we can take hash faults | ||
203 | * and call ioremap | ||
204 | */ | ||
205 | hpte_init_native(); | ||
206 | |||
207 | /* Setup interrupt mapping options */ | 202 | /* Setup interrupt mapping options */ |
208 | ppc64_interrupt_controller = IC_OPEN_PIC; | 203 | ppc64_interrupt_controller = IC_OPEN_PIC; |
209 | 204 | ||
@@ -272,6 +267,8 @@ static int __init maple_probe(void) | |||
272 | */ | 267 | */ |
273 | alloc_dart_table(); | 268 | alloc_dart_table(); |
274 | 269 | ||
270 | hpte_init_native(); | ||
271 | |||
275 | return 1; | 272 | return 1; |
276 | } | 273 | } |
277 | 274 | ||
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 9cc7db7a8bdc..89c5775f83be 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c | |||
@@ -600,13 +600,6 @@ pmac_halt(void) | |||
600 | */ | 600 | */ |
601 | static void __init pmac_init_early(void) | 601 | static void __init pmac_init_early(void) |
602 | { | 602 | { |
603 | #ifdef CONFIG_PPC64 | ||
604 | /* Initialize hash table, from now on, we can take hash faults | ||
605 | * and call ioremap | ||
606 | */ | ||
607 | hpte_init_native(); | ||
608 | #endif | ||
609 | |||
610 | /* Enable early btext debug if requested */ | 603 | /* Enable early btext debug if requested */ |
611 | if (strstr(cmd_line, "btextdbg")) { | 604 | if (strstr(cmd_line, "btextdbg")) { |
612 | udbg_adb_init_early(); | 605 | udbg_adb_init_early(); |
@@ -683,6 +676,8 @@ static int __init pmac_probe(void) | |||
683 | * part of the cacheable linar mapping | 676 | * part of the cacheable linar mapping |
684 | */ | 677 | */ |
685 | alloc_dart_table(); | 678 | alloc_dart_table(); |
679 | |||
680 | hpte_init_native(); | ||
686 | #endif | 681 | #endif |
687 | 682 | ||
688 | #ifdef CONFIG_PPC32 | 683 | #ifdef CONFIG_PPC32 |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index d03a8b078f9d..8cfb5706790e 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -92,6 +92,15 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) | |||
92 | *(tcep++) = 0; | 92 | *(tcep++) = 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | static unsigned long tce_get_pseries(struct iommu_table *tbl, long index) | ||
96 | { | ||
97 | u64 *tcep; | ||
98 | |||
99 | index <<= TCE_PAGE_FACTOR; | ||
100 | tcep = ((u64 *)tbl->it_base) + index; | ||
101 | |||
102 | return *tcep; | ||
103 | } | ||
95 | 104 | ||
96 | static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, | 105 | static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, |
97 | long npages, unsigned long uaddr, | 106 | long npages, unsigned long uaddr, |
@@ -235,6 +244,25 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n | |||
235 | } | 244 | } |
236 | } | 245 | } |
237 | 246 | ||
247 | static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum) | ||
248 | { | ||
249 | u64 rc; | ||
250 | unsigned long tce_ret; | ||
251 | |||
252 | tcenum <<= TCE_PAGE_FACTOR; | ||
253 | rc = plpar_tce_get((u64)tbl->it_index, (u64)tcenum << 12, &tce_ret); | ||
254 | |||
255 | if (rc && printk_ratelimit()) { | ||
256 | printk("tce_get_pSeriesLP: plpar_tce_get failed. rc=%ld\n", | ||
257 | rc); | ||
258 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); | ||
259 | printk("\ttcenum = 0x%lx\n", (u64)tcenum); | ||
260 | show_stack(current, (unsigned long *)__get_SP()); | ||
261 | } | ||
262 | |||
263 | return tce_ret; | ||
264 | } | ||
265 | |||
238 | static void iommu_table_setparms(struct pci_controller *phb, | 266 | static void iommu_table_setparms(struct pci_controller *phb, |
239 | struct device_node *dn, | 267 | struct device_node *dn, |
240 | struct iommu_table *tbl) | 268 | struct iommu_table *tbl) |
@@ -254,7 +282,10 @@ static void iommu_table_setparms(struct pci_controller *phb, | |||
254 | } | 282 | } |
255 | 283 | ||
256 | tbl->it_base = (unsigned long)__va(*basep); | 284 | tbl->it_base = (unsigned long)__va(*basep); |
285 | |||
286 | #ifndef CONFIG_CRASH_DUMP | ||
257 | memset((void *)tbl->it_base, 0, *sizep); | 287 | memset((void *)tbl->it_base, 0, *sizep); |
288 | #endif | ||
258 | 289 | ||
259 | tbl->it_busno = phb->bus->number; | 290 | tbl->it_busno = phb->bus->number; |
260 | 291 | ||
@@ -560,11 +591,13 @@ void iommu_init_early_pSeries(void) | |||
560 | ppc_md.tce_build = tce_build_pSeriesLP; | 591 | ppc_md.tce_build = tce_build_pSeriesLP; |
561 | ppc_md.tce_free = tce_free_pSeriesLP; | 592 | ppc_md.tce_free = tce_free_pSeriesLP; |
562 | } | 593 | } |
594 | ppc_md.tce_get = tce_get_pSeriesLP; | ||
563 | ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP; | 595 | ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP; |
564 | ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP; | 596 | ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP; |
565 | } else { | 597 | } else { |
566 | ppc_md.tce_build = tce_build_pSeries; | 598 | ppc_md.tce_build = tce_build_pSeries; |
567 | ppc_md.tce_free = tce_free_pSeries; | 599 | ppc_md.tce_free = tce_free_pSeries; |
600 | ppc_md.tce_get = tce_get_pseries; | ||
568 | ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries; | 601 | ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries; |
569 | ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries; | 602 | ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries; |
570 | } | 603 | } |
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 634b7d06d3cc..27480705996f 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
@@ -513,7 +513,7 @@ void pSeries_lpar_flush_hash_range(unsigned long number, int local) | |||
513 | spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); | 513 | spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); |
514 | } | 514 | } |
515 | 515 | ||
516 | void hpte_init_lpar(void) | 516 | void __init hpte_init_lpar(void) |
517 | { | 517 | { |
518 | ppc_md.hpte_invalidate = pSeries_lpar_hpte_invalidate; | 518 | ppc_md.hpte_invalidate = pSeries_lpar_hpte_invalidate; |
519 | ppc_md.hpte_updatepp = pSeries_lpar_hpte_updatepp; | 519 | ppc_md.hpte_updatepp = pSeries_lpar_hpte_updatepp; |
@@ -522,6 +522,4 @@ void hpte_init_lpar(void) | |||
522 | ppc_md.hpte_remove = pSeries_lpar_hpte_remove; | 522 | ppc_md.hpte_remove = pSeries_lpar_hpte_remove; |
523 | ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range; | 523 | ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range; |
524 | ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear; | 524 | ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear; |
525 | |||
526 | htab_finish_init(); | ||
527 | } | 525 | } |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 1e28518c6121..b3197ff156c6 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -322,11 +322,6 @@ static void __init pSeries_init_early(void) | |||
322 | DBG(" -> pSeries_init_early()\n"); | 322 | DBG(" -> pSeries_init_early()\n"); |
323 | 323 | ||
324 | fw_feature_init(); | 324 | fw_feature_init(); |
325 | |||
326 | if (firmware_has_feature(FW_FEATURE_LPAR)) | ||
327 | hpte_init_lpar(); | ||
328 | else | ||
329 | hpte_init_native(); | ||
330 | 325 | ||
331 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 326 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
332 | find_udbg_vterm(); | 327 | find_udbg_vterm(); |
@@ -384,6 +379,11 @@ static int __init pSeries_probe_hypertas(unsigned long node, | |||
384 | if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL) | 379 | if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL) |
385 | powerpc_firmware_features |= FW_FEATURE_LPAR; | 380 | powerpc_firmware_features |= FW_FEATURE_LPAR; |
386 | 381 | ||
382 | if (firmware_has_feature(FW_FEATURE_LPAR)) | ||
383 | hpte_init_lpar(); | ||
384 | else | ||
385 | hpte_init_native(); | ||
386 | |||
387 | return 1; | 387 | return 1; |
388 | } | 388 | } |
389 | 389 | ||
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index cef95b023730..054bd8b41ef5 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile | |||
@@ -12,3 +12,5 @@ obj-$(CONFIG_U3_DART) += dart_iommu.o | |||
12 | obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o | 12 | obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o |
13 | obj-$(CONFIG_PPC_83xx) += ipic.o | 13 | obj-$(CONFIG_PPC_83xx) += ipic.o |
14 | obj-$(CONFIG_FSL_SOC) += fsl_soc.o | 14 | obj-$(CONFIG_FSL_SOC) += fsl_soc.o |
15 | obj-$(CONFIG_PPC_TODC) += todc.o | ||
16 | obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o | ||
diff --git a/arch/powerpc/sysdev/dart.h b/arch/powerpc/sysdev/dart.h index c2d05763ccbe..1c8817c4835e 100644 --- a/arch/powerpc/sysdev/dart.h +++ b/arch/powerpc/sysdev/dart.h | |||
@@ -47,8 +47,12 @@ | |||
47 | /* U4 registers */ | 47 | /* U4 registers */ |
48 | #define DART_BASE_U4_BASE_MASK 0xffffff | 48 | #define DART_BASE_U4_BASE_MASK 0xffffff |
49 | #define DART_BASE_U4_BASE_SHIFT 0 | 49 | #define DART_BASE_U4_BASE_SHIFT 0 |
50 | #define DART_CNTL_U4_FLUSHTLB 0x20000000 | ||
51 | #define DART_CNTL_U4_ENABLE 0x80000000 | 50 | #define DART_CNTL_U4_ENABLE 0x80000000 |
51 | #define DART_CNTL_U4_IONE 0x40000000 | ||
52 | #define DART_CNTL_U4_FLUSHTLB 0x20000000 | ||
53 | #define DART_CNTL_U4_IDLE 0x10000000 | ||
54 | #define DART_CNTL_U4_PAR_EN 0x08000000 | ||
55 | #define DART_CNTL_U4_IONE_MASK 0x07ffffff | ||
52 | #define DART_SIZE_U4_SIZE_MASK 0x1fff | 56 | #define DART_SIZE_U4_SIZE_MASK 0x1fff |
53 | #define DART_SIZE_U4_SIZE_SHIFT 0 | 57 | #define DART_SIZE_U4_SIZE_SHIFT 0 |
54 | 58 | ||
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 6232091cc72b..7c7f34ce4986 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c | |||
@@ -101,8 +101,8 @@ retry: | |||
101 | if (l == (1L << limit)) { | 101 | if (l == (1L << limit)) { |
102 | if (limit < 4) { | 102 | if (limit < 4) { |
103 | limit++; | 103 | limit++; |
104 | reg = DART_IN(DART_CNTL); | 104 | reg = DART_IN(DART_CNTL); |
105 | reg &= ~inv_bit; | 105 | reg &= ~inv_bit; |
106 | DART_OUT(DART_CNTL, reg); | 106 | DART_OUT(DART_CNTL, reg); |
107 | goto retry; | 107 | goto retry; |
108 | } else | 108 | } else |
@@ -111,11 +111,39 @@ retry: | |||
111 | } | 111 | } |
112 | } | 112 | } |
113 | 113 | ||
114 | static inline void dart_tlb_invalidate_one(unsigned long bus_rpn) | ||
115 | { | ||
116 | unsigned int reg; | ||
117 | unsigned int l, limit; | ||
118 | |||
119 | reg = DART_CNTL_U4_ENABLE | DART_CNTL_U4_IONE | | ||
120 | (bus_rpn & DART_CNTL_U4_IONE_MASK); | ||
121 | DART_OUT(DART_CNTL, reg); | ||
122 | |||
123 | limit = 0; | ||
124 | wait_more: | ||
125 | l = 0; | ||
126 | while ((DART_IN(DART_CNTL) & DART_CNTL_U4_IONE) && l < (1L << limit)) { | ||
127 | rmb(); | ||
128 | l++; | ||
129 | } | ||
130 | |||
131 | if (l == (1L << limit)) { | ||
132 | if (limit < 4) { | ||
133 | limit++; | ||
134 | goto wait_more; | ||
135 | } else | ||
136 | panic("DART: TLB did not flush after waiting a long " | ||
137 | "time. Buggy U4 ?"); | ||
138 | } | ||
139 | } | ||
140 | |||
114 | static void dart_flush(struct iommu_table *tbl) | 141 | static void dart_flush(struct iommu_table *tbl) |
115 | { | 142 | { |
116 | if (dart_dirty) | 143 | if (dart_dirty) { |
117 | dart_tlb_invalidate_all(); | 144 | dart_tlb_invalidate_all(); |
118 | dart_dirty = 0; | 145 | dart_dirty = 0; |
146 | } | ||
119 | } | 147 | } |
120 | 148 | ||
121 | static void dart_build(struct iommu_table *tbl, long index, | 149 | static void dart_build(struct iommu_table *tbl, long index, |
@@ -124,6 +152,7 @@ static void dart_build(struct iommu_table *tbl, long index, | |||
124 | { | 152 | { |
125 | unsigned int *dp; | 153 | unsigned int *dp; |
126 | unsigned int rpn; | 154 | unsigned int rpn; |
155 | long l; | ||
127 | 156 | ||
128 | DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr); | 157 | DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr); |
129 | 158 | ||
@@ -135,7 +164,8 @@ static void dart_build(struct iommu_table *tbl, long index, | |||
135 | /* On U3, all memory is contigous, so we can move this | 164 | /* On U3, all memory is contigous, so we can move this |
136 | * out of the loop. | 165 | * out of the loop. |
137 | */ | 166 | */ |
138 | while (npages--) { | 167 | l = npages; |
168 | while (l--) { | ||
139 | rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT; | 169 | rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT; |
140 | 170 | ||
141 | *(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK); | 171 | *(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK); |
@@ -143,7 +173,14 @@ static void dart_build(struct iommu_table *tbl, long index, | |||
143 | uaddr += DART_PAGE_SIZE; | 173 | uaddr += DART_PAGE_SIZE; |
144 | } | 174 | } |
145 | 175 | ||
146 | dart_dirty = 1; | 176 | if (dart_is_u4) { |
177 | rpn = index; | ||
178 | mb(); /* make sure all updates have reached memory */ | ||
179 | while (npages--) | ||
180 | dart_tlb_invalidate_one(rpn++); | ||
181 | } else { | ||
182 | dart_dirty = 1; | ||
183 | } | ||
147 | } | 184 | } |
148 | 185 | ||
149 | 186 | ||
diff --git a/arch/powerpc/sysdev/todc.c b/arch/powerpc/sysdev/todc.c new file mode 100644 index 000000000000..0a65980efb50 --- /dev/null +++ b/arch/powerpc/sysdev/todc.c | |||
@@ -0,0 +1,392 @@ | |||
1 | /* | ||
2 | * Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818 | ||
3 | * Real Time Clocks/Timekeepers. | ||
4 | * | ||
5 | * Author: Mark A. Greer <mgreer@mvista.com> | ||
6 | * | ||
7 | * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under | ||
8 | * the terms of the GNU General Public License version 2. This program | ||
9 | * is licensed "as is" without any warranty of any kind, whether express | ||
10 | * or implied. | ||
11 | */ | ||
12 | #include <linux/errno.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/time.h> | ||
16 | #include <linux/timex.h> | ||
17 | #include <linux/bcd.h> | ||
18 | #include <linux/mc146818rtc.h> | ||
19 | |||
20 | #include <asm/machdep.h> | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/time.h> | ||
23 | #include <asm/todc.h> | ||
24 | |||
25 | /* | ||
26 | * Depending on the hardware on your board and your board design, the | ||
27 | * RTC/NVRAM may be accessed either directly (like normal memory) or via | ||
28 | * address/data registers. If your board uses the direct method, set | ||
29 | * 'nvram_data' to the base address of your nvram and leave 'nvram_as0' and | ||
30 | * 'nvram_as1' NULL. If your board uses address/data regs to access nvram, | ||
31 | * set 'nvram_as0' to the address of the lower byte, set 'nvram_as1' to the | ||
32 | * address of the upper byte (leave NULL if using mc146818), and set | ||
33 | * 'nvram_data' to the address of the 8-bit data register. | ||
34 | * | ||
35 | * Note: Even though the documentation for the various RTC chips say that it | ||
36 | * take up to a second before it starts updating once the 'R' bit is | ||
37 | * cleared, they always seem to update even though we bang on it many | ||
38 | * times a second. This is true, except for the Dallas Semi 1746/1747 | ||
39 | * (possibly others). Those chips seem to have a real problem whenever | ||
40 | * we set the 'R' bit before reading them, they basically stop counting. | ||
41 | * --MAG | ||
42 | */ | ||
43 | |||
44 | /* | ||
45 | * 'todc_info' should be initialized in your *_setup.c file to | ||
46 | * point to a fully initialized 'todc_info_t' structure. | ||
47 | * This structure holds all the register offsets for your particular | ||
48 | * TODC/RTC chip. | ||
49 | * TODC_ALLOC()/TODC_INIT() will allocate and initialize this table for you. | ||
50 | */ | ||
51 | |||
52 | #ifdef RTC_FREQ_SELECT | ||
53 | #undef RTC_FREQ_SELECT | ||
54 | #define RTC_FREQ_SELECT control_b /* Register A */ | ||
55 | #endif | ||
56 | |||
57 | #ifdef RTC_CONTROL | ||
58 | #undef RTC_CONTROL | ||
59 | #define RTC_CONTROL control_a /* Register B */ | ||
60 | #endif | ||
61 | |||
62 | #ifdef RTC_INTR_FLAGS | ||
63 | #undef RTC_INTR_FLAGS | ||
64 | #define RTC_INTR_FLAGS watchdog /* Register C */ | ||
65 | #endif | ||
66 | |||
67 | #ifdef RTC_VALID | ||
68 | #undef RTC_VALID | ||
69 | #define RTC_VALID interrupts /* Register D */ | ||
70 | #endif | ||
71 | |||
72 | /* Access routines when RTC accessed directly (like normal memory) */ | ||
73 | u_char | ||
74 | todc_direct_read_val(int addr) | ||
75 | { | ||
76 | return readb((void __iomem *)(todc_info->nvram_data + addr)); | ||
77 | } | ||
78 | |||
79 | void | ||
80 | todc_direct_write_val(int addr, unsigned char val) | ||
81 | { | ||
82 | writeb(val, (void __iomem *)(todc_info->nvram_data + addr)); | ||
83 | return; | ||
84 | } | ||
85 | |||
86 | /* Access routines for accessing m48txx type chips via addr/data regs */ | ||
87 | u_char | ||
88 | todc_m48txx_read_val(int addr) | ||
89 | { | ||
90 | outb(addr, todc_info->nvram_as0); | ||
91 | outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); | ||
92 | return inb(todc_info->nvram_data); | ||
93 | } | ||
94 | |||
95 | void | ||
96 | todc_m48txx_write_val(int addr, unsigned char val) | ||
97 | { | ||
98 | outb(addr, todc_info->nvram_as0); | ||
99 | outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); | ||
100 | outb(val, todc_info->nvram_data); | ||
101 | return; | ||
102 | } | ||
103 | |||
104 | /* Access routines for accessing mc146818 type chips via addr/data regs */ | ||
105 | u_char | ||
106 | todc_mc146818_read_val(int addr) | ||
107 | { | ||
108 | outb_p(addr, todc_info->nvram_as0); | ||
109 | return inb_p(todc_info->nvram_data); | ||
110 | } | ||
111 | |||
112 | void | ||
113 | todc_mc146818_write_val(int addr, unsigned char val) | ||
114 | { | ||
115 | outb_p(addr, todc_info->nvram_as0); | ||
116 | outb_p(val, todc_info->nvram_data); | ||
117 | } | ||
118 | |||
119 | |||
120 | /* | ||
121 | * Routines to make RTC chips with NVRAM buried behind an addr/data pair | ||
122 | * have the NVRAM and clock regs appear at the same level. | ||
123 | * The NVRAM will appear to start at addr 0 and the clock regs will appear | ||
124 | * to start immediately after the NVRAM (actually, start at offset | ||
125 | * todc_info->nvram_size). | ||
126 | */ | ||
127 | static inline u_char | ||
128 | todc_read_val(int addr) | ||
129 | { | ||
130 | u_char val; | ||
131 | |||
132 | if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) { | ||
133 | if (addr < todc_info->nvram_size) { /* NVRAM */ | ||
134 | ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr); | ||
135 | val = ppc_md.rtc_read_val(todc_info->nvram_data_reg); | ||
136 | } else { /* Clock Reg */ | ||
137 | addr -= todc_info->nvram_size; | ||
138 | val = ppc_md.rtc_read_val(addr); | ||
139 | } | ||
140 | } else | ||
141 | val = ppc_md.rtc_read_val(addr); | ||
142 | |||
143 | return val; | ||
144 | } | ||
145 | |||
146 | static inline void | ||
147 | todc_write_val(int addr, u_char val) | ||
148 | { | ||
149 | if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) { | ||
150 | if (addr < todc_info->nvram_size) { /* NVRAM */ | ||
151 | ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr); | ||
152 | ppc_md.rtc_write_val(todc_info->nvram_data_reg, val); | ||
153 | } else { /* Clock Reg */ | ||
154 | addr -= todc_info->nvram_size; | ||
155 | ppc_md.rtc_write_val(addr, val); | ||
156 | } | ||
157 | } else | ||
158 | ppc_md.rtc_write_val(addr, val); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * TODC routines | ||
163 | * | ||
164 | * There is some ugly stuff in that there are assumptions for the mc146818. | ||
165 | * | ||
166 | * Assumptions: | ||
167 | * - todc_info->control_a has the offset as mc146818 Register B reg | ||
168 | * - todc_info->control_b has the offset as mc146818 Register A reg | ||
169 | * - m48txx control reg's write enable or 'W' bit is same as | ||
170 | * mc146818 Register B 'SET' bit (i.e., 0x80) | ||
171 | * | ||
172 | * These assumptions were made to make the code simpler. | ||
173 | */ | ||
174 | long __init | ||
175 | todc_time_init(void) | ||
176 | { | ||
177 | u_char cntl_b; | ||
178 | |||
179 | if (!ppc_md.rtc_read_val) | ||
180 | ppc_md.rtc_read_val = ppc_md.nvram_read_val; | ||
181 | if (!ppc_md.rtc_write_val) | ||
182 | ppc_md.rtc_write_val = ppc_md.nvram_write_val; | ||
183 | |||
184 | cntl_b = todc_read_val(todc_info->control_b); | ||
185 | |||
186 | if (todc_info->rtc_type == TODC_TYPE_MC146818) { | ||
187 | if ((cntl_b & 0x70) != 0x20) { | ||
188 | printk(KERN_INFO "TODC real-time-clock was stopped." | ||
189 | " Now starting..."); | ||
190 | cntl_b &= ~0x70; | ||
191 | cntl_b |= 0x20; | ||
192 | } | ||
193 | |||
194 | todc_write_val(todc_info->control_b, cntl_b); | ||
195 | } else if (todc_info->rtc_type == TODC_TYPE_DS17285) { | ||
196 | u_char mode; | ||
197 | |||
198 | mode = todc_read_val(TODC_TYPE_DS17285_CNTL_A); | ||
199 | /* Make sure countdown clear is not set */ | ||
200 | mode &= ~0x40; | ||
201 | /* Enable oscillator, extended register set */ | ||
202 | mode |= 0x30; | ||
203 | todc_write_val(TODC_TYPE_DS17285_CNTL_A, mode); | ||
204 | |||
205 | } else if (todc_info->rtc_type == TODC_TYPE_DS1501) { | ||
206 | u_char month; | ||
207 | |||
208 | todc_info->enable_read = TODC_DS1501_CNTL_B_TE; | ||
209 | todc_info->enable_write = TODC_DS1501_CNTL_B_TE; | ||
210 | |||
211 | month = todc_read_val(todc_info->month); | ||
212 | |||
213 | if ((month & 0x80) == 0x80) { | ||
214 | printk(KERN_INFO "TODC %s %s\n", | ||
215 | "real-time-clock was stopped.", | ||
216 | "Now starting..."); | ||
217 | month &= ~0x80; | ||
218 | todc_write_val(todc_info->month, month); | ||
219 | } | ||
220 | |||
221 | cntl_b &= ~TODC_DS1501_CNTL_B_TE; | ||
222 | todc_write_val(todc_info->control_b, cntl_b); | ||
223 | } else { /* must be a m48txx type */ | ||
224 | u_char cntl_a; | ||
225 | |||
226 | todc_info->enable_read = TODC_MK48TXX_CNTL_A_R; | ||
227 | todc_info->enable_write = TODC_MK48TXX_CNTL_A_W; | ||
228 | |||
229 | cntl_a = todc_read_val(todc_info->control_a); | ||
230 | |||
231 | /* Check & clear STOP bit in control B register */ | ||
232 | if (cntl_b & TODC_MK48TXX_DAY_CB) { | ||
233 | printk(KERN_INFO "TODC %s %s\n", | ||
234 | "real-time-clock was stopped.", | ||
235 | "Now starting..."); | ||
236 | |||
237 | cntl_a |= todc_info->enable_write; | ||
238 | cntl_b &= ~TODC_MK48TXX_DAY_CB;/* Start Oscil */ | ||
239 | |||
240 | todc_write_val(todc_info->control_a, cntl_a); | ||
241 | todc_write_val(todc_info->control_b, cntl_b); | ||
242 | } | ||
243 | |||
244 | /* Make sure READ & WRITE bits are cleared. */ | ||
245 | cntl_a &= ~(todc_info->enable_write | todc_info->enable_read); | ||
246 | todc_write_val(todc_info->control_a, cntl_a); | ||
247 | } | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * There is some ugly stuff in that there are assumptions that for a mc146818, | ||
254 | * the todc_info->control_a has the offset of the mc146818 Register B reg and | ||
255 | * that the register'ss 'SET' bit is the same as the m48txx's write enable | ||
256 | * bit in the control register of the m48txx (i.e., 0x80). | ||
257 | * | ||
258 | * It was done to make the code look simpler. | ||
259 | */ | ||
260 | void | ||
261 | todc_get_rtc_time(struct rtc_time *tm) | ||
262 | { | ||
263 | uint year = 0, mon = 0, mday = 0, hour = 0, min = 0, sec = 0; | ||
264 | uint limit, i; | ||
265 | u_char save_control, uip = 0; | ||
266 | extern void GregorianDay(struct rtc_time *); | ||
267 | |||
268 | spin_lock(&rtc_lock); | ||
269 | save_control = todc_read_val(todc_info->control_a); | ||
270 | |||
271 | if (todc_info->rtc_type != TODC_TYPE_MC146818) { | ||
272 | limit = 1; | ||
273 | |||
274 | switch (todc_info->rtc_type) { | ||
275 | case TODC_TYPE_DS1553: | ||
276 | case TODC_TYPE_DS1557: | ||
277 | case TODC_TYPE_DS1743: | ||
278 | case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ | ||
279 | case TODC_TYPE_DS1747: | ||
280 | case TODC_TYPE_DS17285: | ||
281 | break; | ||
282 | default: | ||
283 | todc_write_val(todc_info->control_a, | ||
284 | (save_control | todc_info->enable_read)); | ||
285 | } | ||
286 | } else | ||
287 | limit = 100000000; | ||
288 | |||
289 | for (i=0; i<limit; i++) { | ||
290 | if (todc_info->rtc_type == TODC_TYPE_MC146818) | ||
291 | uip = todc_read_val(todc_info->RTC_FREQ_SELECT); | ||
292 | |||
293 | sec = todc_read_val(todc_info->seconds) & 0x7f; | ||
294 | min = todc_read_val(todc_info->minutes) & 0x7f; | ||
295 | hour = todc_read_val(todc_info->hours) & 0x3f; | ||
296 | mday = todc_read_val(todc_info->day_of_month) & 0x3f; | ||
297 | mon = todc_read_val(todc_info->month) & 0x1f; | ||
298 | year = todc_read_val(todc_info->year) & 0xff; | ||
299 | |||
300 | if (todc_info->rtc_type == TODC_TYPE_MC146818) { | ||
301 | uip |= todc_read_val(todc_info->RTC_FREQ_SELECT); | ||
302 | if ((uip & RTC_UIP) == 0) | ||
303 | break; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | if (todc_info->rtc_type != TODC_TYPE_MC146818) { | ||
308 | switch (todc_info->rtc_type) { | ||
309 | case TODC_TYPE_DS1553: | ||
310 | case TODC_TYPE_DS1557: | ||
311 | case TODC_TYPE_DS1743: | ||
312 | case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ | ||
313 | case TODC_TYPE_DS1747: | ||
314 | case TODC_TYPE_DS17285: | ||
315 | break; | ||
316 | default: | ||
317 | save_control &= ~(todc_info->enable_read); | ||
318 | todc_write_val(todc_info->control_a, save_control); | ||
319 | } | ||
320 | } | ||
321 | spin_unlock(&rtc_lock); | ||
322 | |||
323 | if ((todc_info->rtc_type != TODC_TYPE_MC146818) | ||
324 | || ((save_control & RTC_DM_BINARY) == 0) | ||
325 | || RTC_ALWAYS_BCD) { | ||
326 | BCD_TO_BIN(sec); | ||
327 | BCD_TO_BIN(min); | ||
328 | BCD_TO_BIN(hour); | ||
329 | BCD_TO_BIN(mday); | ||
330 | BCD_TO_BIN(mon); | ||
331 | BCD_TO_BIN(year); | ||
332 | } | ||
333 | |||
334 | if ((year + 1900) < 1970) { | ||
335 | year += 100; | ||
336 | } | ||
337 | |||
338 | tm->tm_sec = sec; | ||
339 | tm->tm_min = min; | ||
340 | tm->tm_hour = hour; | ||
341 | tm->tm_mday = mday; | ||
342 | tm->tm_mon = mon; | ||
343 | tm->tm_year = year; | ||
344 | |||
345 | GregorianDay(tm); | ||
346 | } | ||
347 | |||
348 | int | ||
349 | todc_set_rtc_time(struct rtc_time *tm) | ||
350 | { | ||
351 | u_char save_control, save_freq_select = 0; | ||
352 | |||
353 | spin_lock(&rtc_lock); | ||
354 | save_control = todc_read_val(todc_info->control_a); | ||
355 | |||
356 | /* Assuming MK48T59_RTC_CA_WRITE & RTC_SET are equal */ | ||
357 | todc_write_val(todc_info->control_a, | ||
358 | (save_control | todc_info->enable_write)); | ||
359 | save_control &= ~(todc_info->enable_write); /* in case it was set */ | ||
360 | |||
361 | if (todc_info->rtc_type == TODC_TYPE_MC146818) { | ||
362 | save_freq_select = todc_read_val(todc_info->RTC_FREQ_SELECT); | ||
363 | todc_write_val(todc_info->RTC_FREQ_SELECT, | ||
364 | save_freq_select | RTC_DIV_RESET2); | ||
365 | } | ||
366 | |||
367 | if ((todc_info->rtc_type != TODC_TYPE_MC146818) | ||
368 | || ((save_control & RTC_DM_BINARY) == 0) | ||
369 | || RTC_ALWAYS_BCD) { | ||
370 | BIN_TO_BCD(tm->tm_sec); | ||
371 | BIN_TO_BCD(tm->tm_min); | ||
372 | BIN_TO_BCD(tm->tm_hour); | ||
373 | BIN_TO_BCD(tm->tm_mon); | ||
374 | BIN_TO_BCD(tm->tm_mday); | ||
375 | BIN_TO_BCD(tm->tm_year); | ||
376 | } | ||
377 | |||
378 | todc_write_val(todc_info->seconds, tm->tm_sec); | ||
379 | todc_write_val(todc_info->minutes, tm->tm_min); | ||
380 | todc_write_val(todc_info->hours, tm->tm_hour); | ||
381 | todc_write_val(todc_info->month, tm->tm_mon); | ||
382 | todc_write_val(todc_info->day_of_month, tm->tm_mday); | ||
383 | todc_write_val(todc_info->year, tm->tm_year); | ||
384 | |||
385 | todc_write_val(todc_info->control_a, save_control); | ||
386 | |||
387 | if (todc_info->rtc_type == TODC_TYPE_MC146818) | ||
388 | todc_write_val(todc_info->RTC_FREQ_SELECT, save_freq_select); | ||
389 | |||
390 | spin_unlock(&rtc_lock); | ||
391 | return 0; | ||
392 | } | ||
diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c new file mode 100644 index 000000000000..26a0cc820cde --- /dev/null +++ b/arch/powerpc/sysdev/tsi108_dev.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * tsi108/109 device setup code | ||
3 | * | ||
4 | * Maintained by Roy Zang < tie-fei.zang@freescale.com > | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/stddef.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/major.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/irq.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <asm/tsi108.h> | ||
24 | |||
25 | #include <asm/system.h> | ||
26 | #include <asm/atomic.h> | ||
27 | #include <asm/io.h> | ||
28 | #include <asm/irq.h> | ||
29 | #include <asm/prom.h> | ||
30 | #include <mm/mmu_decl.h> | ||
31 | |||
32 | #undef DEBUG | ||
33 | |||
34 | #ifdef DEBUG | ||
35 | #define DBG(fmt...) do { printk(fmt); } while(0) | ||
36 | #else | ||
37 | #define DBG(fmt...) do { } while(0) | ||
38 | #endif | ||
39 | |||
40 | static phys_addr_t tsi108_csr_base = -1; | ||
41 | |||
42 | phys_addr_t get_csrbase(void) | ||
43 | { | ||
44 | struct device_node *tsi; | ||
45 | |||
46 | if (tsi108_csr_base != -1) | ||
47 | return tsi108_csr_base; | ||
48 | |||
49 | tsi = of_find_node_by_type(NULL, "tsi-bridge"); | ||
50 | if (tsi) { | ||
51 | unsigned int size; | ||
52 | void *prop = get_property(tsi, "reg", &size); | ||
53 | tsi108_csr_base = of_translate_address(tsi, prop); | ||
54 | of_node_put(tsi); | ||
55 | }; | ||
56 | return tsi108_csr_base; | ||
57 | } | ||
58 | |||
59 | u32 get_vir_csrbase(void) | ||
60 | { | ||
61 | return (u32) (ioremap(get_csrbase(), 0x10000)); | ||
62 | } | ||
63 | |||
64 | EXPORT_SYMBOL(get_csrbase); | ||
65 | EXPORT_SYMBOL(get_vir_csrbase); | ||
66 | |||
67 | static int __init tsi108_eth_of_init(void) | ||
68 | { | ||
69 | struct device_node *np; | ||
70 | unsigned int i; | ||
71 | struct platform_device *tsi_eth_dev; | ||
72 | struct resource res; | ||
73 | int ret; | ||
74 | |||
75 | for (np = NULL, i = 0; | ||
76 | (np = of_find_compatible_node(np, "network", "tsi-ethernet")) != NULL; | ||
77 | i++) { | ||
78 | struct resource r[2]; | ||
79 | struct device_node *phy; | ||
80 | hw_info tsi_eth_data; | ||
81 | unsigned int *id; | ||
82 | unsigned int *phy_id; | ||
83 | void *mac_addr; | ||
84 | phandle *ph; | ||
85 | |||
86 | memset(r, 0, sizeof(r)); | ||
87 | memset(&tsi_eth_data, 0, sizeof(tsi_eth_data)); | ||
88 | |||
89 | ret = of_address_to_resource(np, 0, &r[0]); | ||
90 | DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n", | ||
91 | __FUNCTION__,r[0].name, r[0].start, r[0].end); | ||
92 | if (ret) | ||
93 | goto err; | ||
94 | |||
95 | r[1].name = "tx"; | ||
96 | r[1].start = np->intrs[0].line; | ||
97 | r[1].end = np->intrs[0].line; | ||
98 | r[1].flags = IORESOURCE_IRQ; | ||
99 | |||
100 | tsi_eth_dev = | ||
101 | platform_device_register_simple("tsi-ethernet", i, &r[0], | ||
102 | np->n_intrs + 1); | ||
103 | |||
104 | if (IS_ERR(tsi_eth_dev)) { | ||
105 | ret = PTR_ERR(tsi_eth_dev); | ||
106 | goto err; | ||
107 | } | ||
108 | |||
109 | mac_addr = get_property(np, "address", NULL); | ||
110 | memcpy(tsi_eth_data.mac_addr, mac_addr, 6); | ||
111 | |||
112 | ph = (phandle *) get_property(np, "phy-handle", NULL); | ||
113 | phy = of_find_node_by_phandle(*ph); | ||
114 | |||
115 | if (phy == NULL) { | ||
116 | ret = -ENODEV; | ||
117 | goto unreg; | ||
118 | } | ||
119 | |||
120 | id = (u32 *) get_property(phy, "reg", NULL); | ||
121 | phy_id = (u32 *) get_property(phy, "phy-id", NULL); | ||
122 | ret = of_address_to_resource(phy, 0, &res); | ||
123 | if (ret) { | ||
124 | of_node_put(phy); | ||
125 | goto unreg; | ||
126 | } | ||
127 | tsi_eth_data.regs = r[0].start; | ||
128 | tsi_eth_data.phyregs = res.start; | ||
129 | tsi_eth_data.phy = *phy_id; | ||
130 | tsi_eth_data.irq_num = np->intrs[0].line; | ||
131 | of_node_put(phy); | ||
132 | ret = | ||
133 | platform_device_add_data(tsi_eth_dev, &tsi_eth_data, | ||
134 | sizeof(hw_info)); | ||
135 | if (ret) | ||
136 | goto unreg; | ||
137 | } | ||
138 | return 0; | ||
139 | unreg: | ||
140 | platform_device_unregister(tsi_eth_dev); | ||
141 | err: | ||
142 | return ret; | ||
143 | } | ||
144 | |||
145 | arch_initcall(tsi108_eth_of_init); | ||
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c new file mode 100644 index 000000000000..3265d54c82ed --- /dev/null +++ b/arch/powerpc/sysdev/tsi108_pci.c | |||
@@ -0,0 +1,412 @@ | |||
1 | /* | ||
2 | * Common routines for Tundra Semiconductor TSI108 host bridge. | ||
3 | * | ||
4 | * 2004-2005 (c) Tundra Semiconductor Corp. | ||
5 | * Author: Alex Bounine (alexandreb@tundra.com) | ||
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 Free | ||
9 | * Software Foundation; either version 2 of the License, or (at your option) | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
19 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/irq.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | |||
29 | |||
30 | #include <asm/byteorder.h> | ||
31 | #include <asm/io.h> | ||
32 | #include <asm/irq.h> | ||
33 | #include <asm/uaccess.h> | ||
34 | #include <asm/machdep.h> | ||
35 | #include <asm/pci-bridge.h> | ||
36 | #include <asm/tsi108.h> | ||
37 | #include <asm/tsi108_irq.h> | ||
38 | #include <asm/prom.h> | ||
39 | |||
40 | #undef DEBUG | ||
41 | #ifdef DEBUG | ||
42 | #define DBG(x...) printk(x) | ||
43 | #else | ||
44 | #define DBG(x...) | ||
45 | #endif | ||
46 | |||
47 | #define tsi_mk_config_addr(bus, devfunc, offset) \ | ||
48 | ((((bus)<<16) | ((devfunc)<<8) | (offset & 0xfc)) + tsi108_pci_cfg_base) | ||
49 | |||
50 | u32 tsi108_pci_cfg_base; | ||
51 | u32 tsi108_csr_vir_base; | ||
52 | |||
53 | extern u32 get_vir_csrbase(void); | ||
54 | extern u32 tsi108_read_reg(u32 reg_offset); | ||
55 | extern void tsi108_write_reg(u32 reg_offset, u32 val); | ||
56 | |||
57 | int | ||
58 | tsi108_direct_write_config(struct pci_bus *bus, unsigned int devfunc, | ||
59 | int offset, int len, u32 val) | ||
60 | { | ||
61 | volatile unsigned char *cfg_addr; | ||
62 | |||
63 | if (ppc_md.pci_exclude_device) | ||
64 | if (ppc_md.pci_exclude_device(bus->number, devfunc)) | ||
65 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
66 | |||
67 | cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number, | ||
68 | devfunc, offset) | | ||
69 | (offset & 0x03)); | ||
70 | |||
71 | #ifdef DEBUG | ||
72 | printk("PCI CFG write : "); | ||
73 | printk("%d:0x%x:0x%x ", bus->number, devfunc, offset); | ||
74 | printk("%d ADDR=0x%08x ", len, (uint) cfg_addr); | ||
75 | printk("data = 0x%08x\n", val); | ||
76 | #endif | ||
77 | |||
78 | switch (len) { | ||
79 | case 1: | ||
80 | out_8((u8 *) cfg_addr, val); | ||
81 | break; | ||
82 | case 2: | ||
83 | out_le16((u16 *) cfg_addr, val); | ||
84 | break; | ||
85 | default: | ||
86 | out_le32((u32 *) cfg_addr, val); | ||
87 | break; | ||
88 | } | ||
89 | |||
90 | return PCIBIOS_SUCCESSFUL; | ||
91 | } | ||
92 | |||
93 | void tsi108_clear_pci_error(u32 pci_cfg_base) | ||
94 | { | ||
95 | u32 err_stat, err_addr, pci_stat; | ||
96 | |||
97 | /* | ||
98 | * Quietly clear PB and PCI error flags set as result | ||
99 | * of PCI/X configuration read requests. | ||
100 | */ | ||
101 | |||
102 | /* Read PB Error Log Registers */ | ||
103 | |||
104 | err_stat = tsi108_read_reg(TSI108_PB_OFFSET + TSI108_PB_ERRCS); | ||
105 | err_addr = tsi108_read_reg(TSI108_PB_OFFSET + TSI108_PB_AERR); | ||
106 | |||
107 | if (err_stat & TSI108_PB_ERRCS_ES) { | ||
108 | /* Clear error flag */ | ||
109 | tsi108_write_reg(TSI108_PB_OFFSET + TSI108_PB_ERRCS, | ||
110 | TSI108_PB_ERRCS_ES); | ||
111 | |||
112 | /* Clear read error reported in PB_ISR */ | ||
113 | tsi108_write_reg(TSI108_PB_OFFSET + TSI108_PB_ISR, | ||
114 | TSI108_PB_ISR_PBS_RD_ERR); | ||
115 | |||
116 | /* Clear PCI/X bus cfg errors if applicable */ | ||
117 | if ((err_addr & 0xFF000000) == pci_cfg_base) { | ||
118 | pci_stat = | ||
119 | tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_CSR); | ||
120 | tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_CSR, | ||
121 | pci_stat); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | return; | ||
126 | } | ||
127 | |||
128 | #define __tsi108_read_pci_config(x, addr, op) \ | ||
129 | __asm__ __volatile__( \ | ||
130 | " "op" %0,0,%1\n" \ | ||
131 | "1: eieio\n" \ | ||
132 | "2:\n" \ | ||
133 | ".section .fixup,\"ax\"\n" \ | ||
134 | "3: li %0,-1\n" \ | ||
135 | " b 2b\n" \ | ||
136 | ".section __ex_table,\"a\"\n" \ | ||
137 | " .align 2\n" \ | ||
138 | " .long 1b,3b\n" \ | ||
139 | ".text" \ | ||
140 | : "=r"(x) : "r"(addr)) | ||
141 | |||
142 | int | ||
143 | tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
144 | int len, u32 * val) | ||
145 | { | ||
146 | volatile unsigned char *cfg_addr; | ||
147 | u32 temp; | ||
148 | |||
149 | if (ppc_md.pci_exclude_device) | ||
150 | if (ppc_md.pci_exclude_device(bus->number, devfn)) | ||
151 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
152 | |||
153 | cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number, | ||
154 | devfn, | ||
155 | offset) | (offset & | ||
156 | 0x03)); | ||
157 | |||
158 | switch (len) { | ||
159 | case 1: | ||
160 | __tsi108_read_pci_config(temp, cfg_addr, "lbzx"); | ||
161 | break; | ||
162 | case 2: | ||
163 | __tsi108_read_pci_config(temp, cfg_addr, "lhbrx"); | ||
164 | break; | ||
165 | default: | ||
166 | __tsi108_read_pci_config(temp, cfg_addr, "lwbrx"); | ||
167 | break; | ||
168 | } | ||
169 | |||
170 | *val = temp; | ||
171 | |||
172 | #ifdef DEBUG | ||
173 | if ((0xFFFFFFFF != temp) && (0xFFFF != temp) && (0xFF != temp)) { | ||
174 | printk("PCI CFG read : "); | ||
175 | printk("%d:0x%x:0x%x ", bus->number, devfn, offset); | ||
176 | printk("%d ADDR=0x%08x ", len, (uint) cfg_addr); | ||
177 | printk("data = 0x%x\n", *val); | ||
178 | } | ||
179 | #endif | ||
180 | return PCIBIOS_SUCCESSFUL; | ||
181 | } | ||
182 | |||
183 | void tsi108_clear_pci_cfg_error(void) | ||
184 | { | ||
185 | tsi108_clear_pci_error(TSI108_PCI_CFG_BASE_PHYS); | ||
186 | } | ||
187 | |||
188 | static struct pci_ops tsi108_direct_pci_ops = { | ||
189 | tsi108_direct_read_config, | ||
190 | tsi108_direct_write_config | ||
191 | }; | ||
192 | |||
193 | int __init tsi108_setup_pci(struct device_node *dev) | ||
194 | { | ||
195 | int len; | ||
196 | struct pci_controller *hose; | ||
197 | struct resource rsrc; | ||
198 | int *bus_range; | ||
199 | int primary = 0, has_address = 0; | ||
200 | |||
201 | /* PCI Config mapping */ | ||
202 | tsi108_pci_cfg_base = (u32)ioremap(TSI108_PCI_CFG_BASE_PHYS, | ||
203 | TSI108_PCI_CFG_SIZE); | ||
204 | DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __FUNCTION__, | ||
205 | tsi108_pci_cfg_base); | ||
206 | |||
207 | /* Fetch host bridge registers address */ | ||
208 | has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); | ||
209 | |||
210 | /* Get bus range if any */ | ||
211 | bus_range = (int *)get_property(dev, "bus-range", &len); | ||
212 | if (bus_range == NULL || len < 2 * sizeof(int)) { | ||
213 | printk(KERN_WARNING "Can't get bus-range for %s, assume" | ||
214 | " bus 0\n", dev->full_name); | ||
215 | } | ||
216 | |||
217 | hose = pcibios_alloc_controller(); | ||
218 | |||
219 | if (!hose) { | ||
220 | printk("PCI Host bridge init failed\n"); | ||
221 | return -ENOMEM; | ||
222 | } | ||
223 | hose->arch_data = dev; | ||
224 | hose->set_cfg_type = 1; | ||
225 | |||
226 | hose->first_busno = bus_range ? bus_range[0] : 0; | ||
227 | hose->last_busno = bus_range ? bus_range[1] : 0xff; | ||
228 | |||
229 | (hose)->ops = &tsi108_direct_pci_ops; | ||
230 | |||
231 | printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08lx. " | ||
232 | "Firmware bus number: %d->%d\n", | ||
233 | rsrc.start, hose->first_busno, hose->last_busno); | ||
234 | |||
235 | /* Interpret the "ranges" property */ | ||
236 | /* This also maps the I/O region and sets isa_io/mem_base */ | ||
237 | pci_process_bridge_OF_ranges(hose, dev, primary); | ||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | /* | ||
242 | * Low level utility functions | ||
243 | */ | ||
244 | |||
245 | static void tsi108_pci_int_mask(u_int irq) | ||
246 | { | ||
247 | u_int irp_cfg; | ||
248 | int int_line = (irq - IRQ_PCI_INTAD_BASE); | ||
249 | |||
250 | irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); | ||
251 | mb(); | ||
252 | irp_cfg |= (1 << int_line); /* INTx_DIR = output */ | ||
253 | irp_cfg &= ~(3 << (8 + (int_line * 2))); /* INTx_TYPE = unused */ | ||
254 | tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg); | ||
255 | mb(); | ||
256 | irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); | ||
257 | } | ||
258 | |||
259 | static void tsi108_pci_int_unmask(u_int irq) | ||
260 | { | ||
261 | u_int irp_cfg; | ||
262 | int int_line = (irq - IRQ_PCI_INTAD_BASE); | ||
263 | |||
264 | irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); | ||
265 | mb(); | ||
266 | irp_cfg &= ~(1 << int_line); | ||
267 | irp_cfg |= (3 << (8 + (int_line * 2))); | ||
268 | tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg); | ||
269 | mb(); | ||
270 | } | ||
271 | |||
272 | static void init_pci_source(void) | ||
273 | { | ||
274 | tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, | ||
275 | 0x0000ff00); | ||
276 | tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE, | ||
277 | TSI108_PCI_IRP_ENABLE_P_INT); | ||
278 | mb(); | ||
279 | } | ||
280 | |||
281 | static inline int get_pci_source(void) | ||
282 | { | ||
283 | u_int temp = 0; | ||
284 | int irq = -1; | ||
285 | int i; | ||
286 | u_int pci_irp_stat; | ||
287 | static int mask = 0; | ||
288 | |||
289 | /* Read PCI/X block interrupt status register */ | ||
290 | pci_irp_stat = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT); | ||
291 | mb(); | ||
292 | |||
293 | if (pci_irp_stat & TSI108_PCI_IRP_STAT_P_INT) { | ||
294 | /* Process Interrupt from PCI bus INTA# - INTD# lines */ | ||
295 | temp = | ||
296 | tsi108_read_reg(TSI108_PCI_OFFSET + | ||
297 | TSI108_PCI_IRP_INTAD) & 0xf; | ||
298 | mb(); | ||
299 | for (i = 0; i < 4; i++, mask++) { | ||
300 | if (temp & (1 << mask % 4)) { | ||
301 | irq = IRQ_PCI_INTA + mask % 4; | ||
302 | mask++; | ||
303 | break; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | /* Disable interrupts from PCI block */ | ||
308 | temp = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE); | ||
309 | tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE, | ||
310 | temp & ~TSI108_PCI_IRP_ENABLE_P_INT); | ||
311 | mb(); | ||
312 | (void)tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE); | ||
313 | mb(); | ||
314 | } | ||
315 | #ifdef DEBUG | ||
316 | else { | ||
317 | printk("TSI108_PIC: error in TSI108_PCI_IRP_STAT\n"); | ||
318 | pci_irp_stat = | ||
319 | tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT); | ||
320 | temp = | ||
321 | tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_INTAD); | ||
322 | mb(); | ||
323 | printk(">> stat=0x%08x intad=0x%08x ", pci_irp_stat, temp); | ||
324 | temp = | ||
325 | tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); | ||
326 | mb(); | ||
327 | printk("cfg_ctl=0x%08x ", temp); | ||
328 | temp = | ||
329 | tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE); | ||
330 | mb(); | ||
331 | printk("irp_enable=0x%08x\n", temp); | ||
332 | } | ||
333 | #endif /* end of DEBUG */ | ||
334 | |||
335 | return irq; | ||
336 | } | ||
337 | |||
338 | |||
339 | /* | ||
340 | * Linux descriptor level callbacks | ||
341 | */ | ||
342 | |||
343 | static void tsi108_pci_irq_enable(u_int irq) | ||
344 | { | ||
345 | tsi108_pci_int_unmask(irq); | ||
346 | } | ||
347 | |||
348 | static void tsi108_pci_irq_disable(u_int irq) | ||
349 | { | ||
350 | tsi108_pci_int_mask(irq); | ||
351 | } | ||
352 | |||
353 | static void tsi108_pci_irq_ack(u_int irq) | ||
354 | { | ||
355 | tsi108_pci_int_mask(irq); | ||
356 | } | ||
357 | |||
358 | static void tsi108_pci_irq_end(u_int irq) | ||
359 | { | ||
360 | tsi108_pci_int_unmask(irq); | ||
361 | |||
362 | /* Enable interrupts from PCI block */ | ||
363 | tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE, | ||
364 | tsi108_read_reg(TSI108_PCI_OFFSET + | ||
365 | TSI108_PCI_IRP_ENABLE) | | ||
366 | TSI108_PCI_IRP_ENABLE_P_INT); | ||
367 | mb(); | ||
368 | } | ||
369 | |||
370 | /* | ||
371 | * Interrupt controller descriptor for cascaded PCI interrupt controller. | ||
372 | */ | ||
373 | |||
374 | struct hw_interrupt_type tsi108_pci_irq = { | ||
375 | .typename = "tsi108_PCI_int", | ||
376 | .enable = tsi108_pci_irq_enable, | ||
377 | .disable = tsi108_pci_irq_disable, | ||
378 | .ack = tsi108_pci_irq_ack, | ||
379 | .end = tsi108_pci_irq_end, | ||
380 | }; | ||
381 | |||
382 | /* | ||
383 | * Exported functions | ||
384 | */ | ||
385 | |||
386 | /* | ||
387 | * The Tsi108 PCI interrupts initialization routine. | ||
388 | * | ||
389 | * The INTA# - INTD# interrupts on the PCI bus are reported by the PCI block | ||
390 | * to the MPIC using single interrupt source (IRQ_TSI108_PCI). Therefore the | ||
391 | * PCI block has to be treated as a cascaded interrupt controller connected | ||
392 | * to the MPIC. | ||
393 | */ | ||
394 | |||
395 | void __init tsi108_pci_int_init(void) | ||
396 | { | ||
397 | u_int i; | ||
398 | |||
399 | DBG("Tsi108_pci_int_init: initializing PCI interrupts\n"); | ||
400 | |||
401 | for (i = 0; i < NUM_PCI_IRQS; i++) { | ||
402 | irq_desc[i + IRQ_PCI_INTAD_BASE].handler = &tsi108_pci_irq; | ||
403 | irq_desc[i + IRQ_PCI_INTAD_BASE].status |= IRQ_LEVEL; | ||
404 | } | ||
405 | |||
406 | init_pci_source(); | ||
407 | } | ||
408 | |||
409 | int tsi108_irq_cascade(struct pt_regs *regs, void *unused) | ||
410 | { | ||
411 | return get_pci_source(); | ||
412 | } | ||