diff options
Diffstat (limited to 'arch/sparc64')
-rw-r--r-- | arch/sparc64/Kconfig | 6 | ||||
-rw-r--r-- | arch/sparc64/defconfig | 41 | ||||
-rw-r--r-- | arch/sparc64/kernel/Makefile | 3 | ||||
-rw-r--r-- | arch/sparc64/kernel/audit.c | 66 | ||||
-rw-r--r-- | arch/sparc64/kernel/compat_audit.c | 37 | ||||
-rw-r--r-- | arch/sparc64/kernel/devices.c | 3 | ||||
-rw-r--r-- | arch/sparc64/kernel/head.S | 13 | ||||
-rw-r--r-- | arch/sparc64/kernel/of_device.c | 348 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_psycho.c | 6 | ||||
-rw-r--r-- | arch/sparc64/kernel/prom.c | 65 | ||||
-rw-r--r-- | arch/sparc64/kernel/setup.c | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/sparc64_ksyms.c | 11 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sparc.c | 58 | ||||
-rw-r--r-- | arch/sparc64/kernel/time.c | 7 | ||||
-rw-r--r-- | arch/sparc64/mm/fault.c | 3 | ||||
-rw-r--r-- | arch/sparc64/mm/generic.c | 2 | ||||
-rw-r--r-- | arch/sparc64/prom/tree.c | 85 |
17 files changed, 454 insertions, 302 deletions
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index a7a111db25b2..8d8ca716f7a7 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig | |||
@@ -34,6 +34,10 @@ config ARCH_MAY_HAVE_PC_FDC | |||
34 | bool | 34 | bool |
35 | default y | 35 | default y |
36 | 36 | ||
37 | config AUDIT_ARCH | ||
38 | bool | ||
39 | default y | ||
40 | |||
37 | choice | 41 | choice |
38 | prompt "Kernel page size" | 42 | prompt "Kernel page size" |
39 | default SPARC64_PAGE_SIZE_8KB | 43 | default SPARC64_PAGE_SIZE_8KB |
@@ -334,7 +338,7 @@ config COMPAT | |||
334 | default y | 338 | default y |
335 | 339 | ||
336 | config BINFMT_ELF32 | 340 | config BINFMT_ELF32 |
337 | tristate "Kernel support for 32-bit ELF binaries" | 341 | bool "Kernel support for 32-bit ELF binaries" |
338 | depends on SPARC32_COMPAT | 342 | depends on SPARC32_COMPAT |
339 | help | 343 | help |
340 | This allows you to run 32-bit Linux/ELF binaries on your Ultra. | 344 | This allows you to run 32-bit Linux/ELF binaries on your Ultra. |
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index b2f41147d0e4..43d9229fca07 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/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.18-rc2 |
4 | # Fri Jun 23 23:17:09 2006 | 4 | # Fri Jul 21 14:19:24 2006 |
5 | # | 5 | # |
6 | CONFIG_SPARC=y | 6 | CONFIG_SPARC=y |
7 | CONFIG_SPARC64=y | 7 | CONFIG_SPARC64=y |
@@ -18,6 +18,7 @@ CONFIG_SECCOMP=y | |||
18 | CONFIG_HZ_250=y | 18 | CONFIG_HZ_250=y |
19 | # CONFIG_HZ_1000 is not set | 19 | # CONFIG_HZ_1000 is not set |
20 | CONFIG_HZ=250 | 20 | CONFIG_HZ=250 |
21 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
21 | 22 | ||
22 | # | 23 | # |
23 | # Code maturity level options | 24 | # Code maturity level options |
@@ -35,6 +36,7 @@ CONFIG_SWAP=y | |||
35 | CONFIG_SYSVIPC=y | 36 | CONFIG_SYSVIPC=y |
36 | CONFIG_POSIX_MQUEUE=y | 37 | CONFIG_POSIX_MQUEUE=y |
37 | # CONFIG_BSD_PROCESS_ACCT is not set | 38 | # CONFIG_BSD_PROCESS_ACCT is not set |
39 | # CONFIG_TASKSTATS is not set | ||
38 | CONFIG_SYSCTL=y | 40 | CONFIG_SYSCTL=y |
39 | # CONFIG_AUDIT is not set | 41 | # CONFIG_AUDIT is not set |
40 | # CONFIG_IKCONFIG is not set | 42 | # CONFIG_IKCONFIG is not set |
@@ -51,10 +53,12 @@ CONFIG_PRINTK=y | |||
51 | CONFIG_BUG=y | 53 | CONFIG_BUG=y |
52 | CONFIG_ELF_CORE=y | 54 | CONFIG_ELF_CORE=y |
53 | CONFIG_BASE_FULL=y | 55 | CONFIG_BASE_FULL=y |
56 | CONFIG_RT_MUTEXES=y | ||
54 | CONFIG_FUTEX=y | 57 | CONFIG_FUTEX=y |
55 | CONFIG_EPOLL=y | 58 | CONFIG_EPOLL=y |
56 | CONFIG_SHMEM=y | 59 | CONFIG_SHMEM=y |
57 | CONFIG_SLAB=y | 60 | CONFIG_SLAB=y |
61 | CONFIG_VM_EVENT_COUNTERS=y | ||
58 | # CONFIG_TINY_SHMEM is not set | 62 | # CONFIG_TINY_SHMEM is not set |
59 | CONFIG_BASE_SMALL=0 | 63 | CONFIG_BASE_SMALL=0 |
60 | # CONFIG_SLOB is not set | 64 | # CONFIG_SLOB is not set |
@@ -127,8 +131,8 @@ CONFIG_SPARSEMEM=y | |||
127 | CONFIG_HAVE_MEMORY_PRESENT=y | 131 | CONFIG_HAVE_MEMORY_PRESENT=y |
128 | # CONFIG_SPARSEMEM_STATIC is not set | 132 | # CONFIG_SPARSEMEM_STATIC is not set |
129 | CONFIG_SPARSEMEM_EXTREME=y | 133 | CONFIG_SPARSEMEM_EXTREME=y |
130 | CONFIG_MEMORY_HOTPLUG=y | ||
131 | CONFIG_SPLIT_PTLOCK_CPUS=4 | 134 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
135 | CONFIG_RESOURCES_64BIT=y | ||
132 | CONFIG_GENERIC_ISA_DMA=y | 136 | CONFIG_GENERIC_ISA_DMA=y |
133 | CONFIG_SBUS=y | 137 | CONFIG_SBUS=y |
134 | CONFIG_SBUSCHAR=y | 138 | CONFIG_SBUSCHAR=y |
@@ -203,7 +207,6 @@ CONFIG_TCP_CONG_VEGAS=m | |||
203 | CONFIG_TCP_CONG_SCALABLE=m | 207 | CONFIG_TCP_CONG_SCALABLE=m |
204 | CONFIG_TCP_CONG_LP=m | 208 | CONFIG_TCP_CONG_LP=m |
205 | CONFIG_TCP_CONG_VENO=m | 209 | CONFIG_TCP_CONG_VENO=m |
206 | CONFIG_TCP_CONG_COMPOUND=m | ||
207 | CONFIG_IPV6=m | 210 | CONFIG_IPV6=m |
208 | CONFIG_IPV6_PRIVACY=y | 211 | CONFIG_IPV6_PRIVACY=y |
209 | CONFIG_IPV6_ROUTER_PREF=y | 212 | CONFIG_IPV6_ROUTER_PREF=y |
@@ -461,9 +464,8 @@ CONFIG_MD_LINEAR=m | |||
461 | CONFIG_MD_RAID0=m | 464 | CONFIG_MD_RAID0=m |
462 | CONFIG_MD_RAID1=m | 465 | CONFIG_MD_RAID1=m |
463 | CONFIG_MD_RAID10=m | 466 | CONFIG_MD_RAID10=m |
464 | CONFIG_MD_RAID5=m | 467 | CONFIG_MD_RAID456=m |
465 | # CONFIG_MD_RAID5_RESHAPE is not set | 468 | # CONFIG_MD_RAID5_RESHAPE is not set |
466 | CONFIG_MD_RAID6=m | ||
467 | CONFIG_MD_MULTIPATH=m | 469 | CONFIG_MD_MULTIPATH=m |
468 | # CONFIG_MD_FAULTY is not set | 470 | # CONFIG_MD_FAULTY is not set |
469 | CONFIG_BLK_DEV_DM=m | 471 | CONFIG_BLK_DEV_DM=m |
@@ -663,6 +665,7 @@ CONFIG_SERIO_RAW=m | |||
663 | CONFIG_VT=y | 665 | CONFIG_VT=y |
664 | CONFIG_VT_CONSOLE=y | 666 | CONFIG_VT_CONSOLE=y |
665 | CONFIG_HW_CONSOLE=y | 667 | CONFIG_HW_CONSOLE=y |
668 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | ||
666 | # CONFIG_SERIAL_NONSTANDARD is not set | 669 | # CONFIG_SERIAL_NONSTANDARD is not set |
667 | 670 | ||
668 | # | 671 | # |
@@ -693,6 +696,7 @@ CONFIG_UNIX98_PTYS=y | |||
693 | # Watchdog Cards | 696 | # Watchdog Cards |
694 | # | 697 | # |
695 | # CONFIG_WATCHDOG is not set | 698 | # CONFIG_WATCHDOG is not set |
699 | # CONFIG_HW_RANDOM is not set | ||
696 | CONFIG_RTC=y | 700 | CONFIG_RTC=y |
697 | # CONFIG_DTLK is not set | 701 | # CONFIG_DTLK is not set |
698 | # CONFIG_R3964 is not set | 702 | # CONFIG_R3964 is not set |
@@ -839,12 +843,13 @@ CONFIG_VIDEO_V4L2=y | |||
839 | # | 843 | # |
840 | # Graphics support | 844 | # Graphics support |
841 | # | 845 | # |
846 | # CONFIG_FIRMWARE_EDID is not set | ||
842 | CONFIG_FB=y | 847 | CONFIG_FB=y |
843 | CONFIG_FB_CFB_FILLRECT=y | 848 | CONFIG_FB_CFB_FILLRECT=y |
844 | CONFIG_FB_CFB_COPYAREA=y | 849 | CONFIG_FB_CFB_COPYAREA=y |
845 | CONFIG_FB_CFB_IMAGEBLIT=y | 850 | CONFIG_FB_CFB_IMAGEBLIT=y |
846 | # CONFIG_FB_MACMODES is not set | 851 | # CONFIG_FB_MACMODES is not set |
847 | # CONFIG_FB_FIRMWARE_EDID is not set | 852 | # CONFIG_FB_BACKLIGHT is not set |
848 | CONFIG_FB_MODE_HELPERS=y | 853 | CONFIG_FB_MODE_HELPERS=y |
849 | CONFIG_FB_TILEBLITTING=y | 854 | CONFIG_FB_TILEBLITTING=y |
850 | # CONFIG_FB_CIRRUS is not set | 855 | # CONFIG_FB_CIRRUS is not set |
@@ -954,6 +959,18 @@ CONFIG_SND_ALI5451=m | |||
954 | # CONFIG_SND_CMIPCI is not set | 959 | # CONFIG_SND_CMIPCI is not set |
955 | # CONFIG_SND_CS4281 is not set | 960 | # CONFIG_SND_CS4281 is not set |
956 | # CONFIG_SND_CS46XX is not set | 961 | # CONFIG_SND_CS46XX is not set |
962 | # CONFIG_SND_DARLA20 is not set | ||
963 | # CONFIG_SND_GINA20 is not set | ||
964 | # CONFIG_SND_LAYLA20 is not set | ||
965 | # CONFIG_SND_DARLA24 is not set | ||
966 | # CONFIG_SND_GINA24 is not set | ||
967 | # CONFIG_SND_LAYLA24 is not set | ||
968 | # CONFIG_SND_MONA is not set | ||
969 | # CONFIG_SND_MIA is not set | ||
970 | # CONFIG_SND_ECHO3G is not set | ||
971 | # CONFIG_SND_INDIGO is not set | ||
972 | # CONFIG_SND_INDIGOIO is not set | ||
973 | # CONFIG_SND_INDIGODJ is not set | ||
957 | # CONFIG_SND_EMU10K1 is not set | 974 | # CONFIG_SND_EMU10K1 is not set |
958 | # CONFIG_SND_EMU10K1X is not set | 975 | # CONFIG_SND_EMU10K1X is not set |
959 | # CONFIG_SND_ENS1370 is not set | 976 | # CONFIG_SND_ENS1370 is not set |
@@ -1104,7 +1121,7 @@ CONFIG_USB_HIDDEV=y | |||
1104 | # CONFIG_USB_LEGOTOWER is not set | 1121 | # CONFIG_USB_LEGOTOWER is not set |
1105 | # CONFIG_USB_LCD is not set | 1122 | # CONFIG_USB_LCD is not set |
1106 | # CONFIG_USB_LED is not set | 1123 | # CONFIG_USB_LED is not set |
1107 | # CONFIG_USB_CY7C63 is not set | 1124 | # CONFIG_USB_CYPRESS_CY7C63 is not set |
1108 | # CONFIG_USB_CYTHERM is not set | 1125 | # CONFIG_USB_CYTHERM is not set |
1109 | # CONFIG_USB_PHIDGETKIT is not set | 1126 | # CONFIG_USB_PHIDGETKIT is not set |
1110 | # CONFIG_USB_PHIDGETSERVO is not set | 1127 | # CONFIG_USB_PHIDGETSERVO is not set |
@@ -1331,14 +1348,19 @@ CONFIG_KPROBES=y | |||
1331 | # | 1348 | # |
1332 | CONFIG_PRINTK_TIME=y | 1349 | CONFIG_PRINTK_TIME=y |
1333 | CONFIG_MAGIC_SYSRQ=y | 1350 | CONFIG_MAGIC_SYSRQ=y |
1351 | # CONFIG_UNUSED_SYMBOLS is not set | ||
1334 | CONFIG_DEBUG_KERNEL=y | 1352 | CONFIG_DEBUG_KERNEL=y |
1335 | CONFIG_LOG_BUF_SHIFT=18 | 1353 | CONFIG_LOG_BUF_SHIFT=18 |
1336 | CONFIG_DETECT_SOFTLOCKUP=y | 1354 | CONFIG_DETECT_SOFTLOCKUP=y |
1337 | CONFIG_SCHEDSTATS=y | 1355 | CONFIG_SCHEDSTATS=y |
1338 | # CONFIG_DEBUG_SLAB is not set | 1356 | # CONFIG_DEBUG_SLAB is not set |
1339 | # CONFIG_DEBUG_MUTEXES is not set | 1357 | # CONFIG_DEBUG_RT_MUTEXES is not set |
1358 | # CONFIG_RT_MUTEX_TESTER is not set | ||
1340 | # CONFIG_DEBUG_SPINLOCK is not set | 1359 | # CONFIG_DEBUG_SPINLOCK is not set |
1360 | # CONFIG_DEBUG_MUTEXES is not set | ||
1361 | # CONFIG_DEBUG_RWSEMS is not set | ||
1341 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 1362 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
1363 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | ||
1342 | # CONFIG_DEBUG_KOBJECT is not set | 1364 | # CONFIG_DEBUG_KOBJECT is not set |
1343 | CONFIG_DEBUG_BUGVERBOSE=y | 1365 | CONFIG_DEBUG_BUGVERBOSE=y |
1344 | # CONFIG_DEBUG_INFO is not set | 1366 | # CONFIG_DEBUG_INFO is not set |
@@ -1402,3 +1424,4 @@ CONFIG_CRC32=y | |||
1402 | CONFIG_LIBCRC32C=m | 1424 | CONFIG_LIBCRC32C=m |
1403 | CONFIG_ZLIB_INFLATE=y | 1425 | CONFIG_ZLIB_INFLATE=y |
1404 | CONFIG_ZLIB_DEFLATE=y | 1426 | CONFIG_ZLIB_DEFLATE=y |
1427 | CONFIG_PLIST=y | ||
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index 86c9fe3f3e4a..e1eabebaed39 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile | |||
@@ -25,6 +25,9 @@ obj-$(CONFIG_MODULES) += module.o | |||
25 | obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o | 25 | obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o |
26 | obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o | 26 | obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o |
27 | obj-$(CONFIG_KPROBES) += kprobes.o | 27 | obj-$(CONFIG_KPROBES) += kprobes.o |
28 | obj-$(CONFIG_AUDIT) += audit.o | ||
29 | obj-$(CONFIG_AUDIT)$(CONFIG_SPARC32_COMPAT) += compat_audit.o | ||
30 | obj-y += $(obj-yy) | ||
28 | 31 | ||
29 | ifdef CONFIG_SUNOS_EMUL | 32 | ifdef CONFIG_SUNOS_EMUL |
30 | obj-y += sys_sunos32.o sunos_ioctl32.o | 33 | obj-y += sys_sunos32.o sunos_ioctl32.o |
diff --git a/arch/sparc64/kernel/audit.c b/arch/sparc64/kernel/audit.c new file mode 100644 index 000000000000..aef19cc27072 --- /dev/null +++ b/arch/sparc64/kernel/audit.c | |||
@@ -0,0 +1,66 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/types.h> | ||
3 | #include <linux/audit.h> | ||
4 | #include <asm/unistd.h> | ||
5 | |||
6 | static unsigned dir_class[] = { | ||
7 | #include <asm-generic/audit_dir_write.h> | ||
8 | ~0U | ||
9 | }; | ||
10 | |||
11 | static unsigned read_class[] = { | ||
12 | #include <asm-generic/audit_read.h> | ||
13 | ~0U | ||
14 | }; | ||
15 | |||
16 | static unsigned write_class[] = { | ||
17 | #include <asm-generic/audit_write.h> | ||
18 | ~0U | ||
19 | }; | ||
20 | |||
21 | static unsigned chattr_class[] = { | ||
22 | #include <asm-generic/audit_change_attr.h> | ||
23 | ~0U | ||
24 | }; | ||
25 | |||
26 | int audit_classify_syscall(int abi, unsigned syscall) | ||
27 | { | ||
28 | #ifdef CONFIG_SPARC32_COMPAT | ||
29 | extern int sparc32_classify_syscall(unsigned); | ||
30 | if (abi == AUDIT_ARCH_SPARC) | ||
31 | return sparc32_classify_syscall(syscall); | ||
32 | #endif | ||
33 | switch(syscall) { | ||
34 | case __NR_open: | ||
35 | return 2; | ||
36 | case __NR_openat: | ||
37 | return 3; | ||
38 | case __NR_socketcall: | ||
39 | return 4; | ||
40 | case __NR_execve: | ||
41 | return 5; | ||
42 | default: | ||
43 | return 0; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | static int __init audit_classes_init(void) | ||
48 | { | ||
49 | #ifdef CONFIG_SPARC32_COMPAT | ||
50 | extern __u32 sparc32_dir_class[]; | ||
51 | extern __u32 sparc32_write_class[]; | ||
52 | extern __u32 sparc32_read_class[]; | ||
53 | extern __u32 sparc32_chattr_class[]; | ||
54 | audit_register_class(AUDIT_CLASS_WRITE_32, sparc32_write_class); | ||
55 | audit_register_class(AUDIT_CLASS_READ_32, sparc32_read_class); | ||
56 | audit_register_class(AUDIT_CLASS_DIR_WRITE_32, sparc32_dir_class); | ||
57 | audit_register_class(AUDIT_CLASS_CHATTR_32, sparc32_chattr_class); | ||
58 | #endif | ||
59 | audit_register_class(AUDIT_CLASS_WRITE, write_class); | ||
60 | audit_register_class(AUDIT_CLASS_READ, read_class); | ||
61 | audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class); | ||
62 | audit_register_class(AUDIT_CLASS_CHATTR, chattr_class); | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | __initcall(audit_classes_init); | ||
diff --git a/arch/sparc64/kernel/compat_audit.c b/arch/sparc64/kernel/compat_audit.c new file mode 100644 index 000000000000..cca96c91b780 --- /dev/null +++ b/arch/sparc64/kernel/compat_audit.c | |||
@@ -0,0 +1,37 @@ | |||
1 | #include <asm-sparc/unistd.h> | ||
2 | |||
3 | unsigned sparc32_dir_class[] = { | ||
4 | #include <asm-generic/audit_dir_write.h> | ||
5 | ~0U | ||
6 | }; | ||
7 | |||
8 | unsigned sparc32_chattr_class[] = { | ||
9 | #include <asm-generic/audit_change_attr.h> | ||
10 | ~0U | ||
11 | }; | ||
12 | |||
13 | unsigned sparc32_write_class[] = { | ||
14 | #include <asm-generic/audit_write.h> | ||
15 | ~0U | ||
16 | }; | ||
17 | |||
18 | unsigned sparc32_read_class[] = { | ||
19 | #include <asm-generic/audit_read.h> | ||
20 | ~0U | ||
21 | }; | ||
22 | |||
23 | int sparc32_classify_syscall(unsigned syscall) | ||
24 | { | ||
25 | switch(syscall) { | ||
26 | case __NR_open: | ||
27 | return 2; | ||
28 | case __NR_openat: | ||
29 | return 3; | ||
30 | case __NR_socketcall: | ||
31 | return 4; | ||
32 | case __NR_execve: | ||
33 | return 5; | ||
34 | default: | ||
35 | return 1; | ||
36 | } | ||
37 | } | ||
diff --git a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c index f8ef2f2b9b37..ec10f7edcf86 100644 --- a/arch/sparc64/kernel/devices.c +++ b/arch/sparc64/kernel/devices.c | |||
@@ -66,9 +66,6 @@ static int check_cpu_node(struct device_node *dp, int *cur_inst, | |||
66 | void *compare_arg, | 66 | void *compare_arg, |
67 | struct device_node **dev_node, int *mid) | 67 | struct device_node **dev_node, int *mid) |
68 | { | 68 | { |
69 | if (strcmp(dp->type, "cpu")) | ||
70 | return -ENODEV; | ||
71 | |||
72 | if (!compare(dp, *cur_inst, compare_arg)) { | 69 | if (!compare(dp, *cur_inst, compare_arg)) { |
73 | if (dev_node) | 70 | if (dev_node) |
74 | *dev_node = dp; | 71 | *dev_node = dp; |
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index 75684b56767e..c8e9dc9d68a9 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S | |||
@@ -551,9 +551,10 @@ setup_trap_table: | |||
551 | save %sp, -192, %sp | 551 | save %sp, -192, %sp |
552 | 552 | ||
553 | /* Force interrupts to be disabled. */ | 553 | /* Force interrupts to be disabled. */ |
554 | rdpr %pstate, %o1 | 554 | rdpr %pstate, %l0 |
555 | andn %o1, PSTATE_IE, %o1 | 555 | andn %l0, PSTATE_IE, %o1 |
556 | wrpr %o1, 0x0, %pstate | 556 | wrpr %o1, 0x0, %pstate |
557 | rdpr %pil, %l1 | ||
557 | wrpr %g0, 15, %pil | 558 | wrpr %g0, 15, %pil |
558 | 559 | ||
559 | /* Make the firmware call to jump over to the Linux trap table. */ | 560 | /* Make the firmware call to jump over to the Linux trap table. */ |
@@ -622,11 +623,9 @@ setup_trap_table: | |||
622 | call init_irqwork_curcpu | 623 | call init_irqwork_curcpu |
623 | nop | 624 | nop |
624 | 625 | ||
625 | /* Now we can turn interrupts back on. */ | 626 | /* Now we can restore interrupt state. */ |
626 | rdpr %pstate, %o1 | 627 | wrpr %l0, 0, %pstate |
627 | or %o1, PSTATE_IE, %o1 | 628 | wrpr %l1, 0x0, %pil |
628 | wrpr %o1, 0, %pstate | ||
629 | wrpr %g0, 0x0, %pil | ||
630 | 629 | ||
631 | ret | 630 | ret |
632 | restore | 631 | restore |
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 169b017eec0b..238bbf6de07d 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c | |||
@@ -210,7 +210,7 @@ struct bus_type of_bus_type = { | |||
210 | }; | 210 | }; |
211 | EXPORT_SYMBOL(of_bus_type); | 211 | EXPORT_SYMBOL(of_bus_type); |
212 | 212 | ||
213 | static inline u64 of_read_addr(u32 *cell, int size) | 213 | static inline u64 of_read_addr(const u32 *cell, int size) |
214 | { | 214 | { |
215 | u64 r = 0; | 215 | u64 r = 0; |
216 | while (size--) | 216 | while (size--) |
@@ -236,8 +236,8 @@ struct of_bus { | |||
236 | int (*match)(struct device_node *parent); | 236 | int (*match)(struct device_node *parent); |
237 | void (*count_cells)(struct device_node *child, | 237 | void (*count_cells)(struct device_node *child, |
238 | int *addrc, int *sizec); | 238 | int *addrc, int *sizec); |
239 | u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna); | 239 | int (*map)(u32 *addr, const u32 *range, |
240 | int (*translate)(u32 *addr, u64 offset, int na); | 240 | int na, int ns, int pna); |
241 | unsigned int (*get_flags)(u32 *addr); | 241 | unsigned int (*get_flags)(u32 *addr); |
242 | }; | 242 | }; |
243 | 243 | ||
@@ -251,27 +251,49 @@ static void of_bus_default_count_cells(struct device_node *dev, | |||
251 | get_cells(dev, addrc, sizec); | 251 | get_cells(dev, addrc, sizec); |
252 | } | 252 | } |
253 | 253 | ||
254 | static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna) | 254 | /* Make sure the least significant 64-bits are in-range. Even |
255 | * for 3 or 4 cell values it is a good enough approximation. | ||
256 | */ | ||
257 | static int of_out_of_range(const u32 *addr, const u32 *base, | ||
258 | const u32 *size, int na, int ns) | ||
255 | { | 259 | { |
256 | u64 cp, s, da; | 260 | u64 a = of_read_addr(addr, na); |
261 | u64 b = of_read_addr(base, na); | ||
262 | |||
263 | if (a < b) | ||
264 | return 1; | ||
257 | 265 | ||
258 | cp = of_read_addr(range, na); | 266 | b += of_read_addr(size, ns); |
259 | s = of_read_addr(range + na + pna, ns); | 267 | if (a >= b) |
260 | da = of_read_addr(addr, na); | 268 | return 1; |
261 | 269 | ||
262 | if (da < cp || da >= (cp + s)) | 270 | return 0; |
263 | return OF_BAD_ADDR; | ||
264 | return da - cp; | ||
265 | } | 271 | } |
266 | 272 | ||
267 | static int of_bus_default_translate(u32 *addr, u64 offset, int na) | 273 | static int of_bus_default_map(u32 *addr, const u32 *range, |
274 | int na, int ns, int pna) | ||
268 | { | 275 | { |
269 | u64 a = of_read_addr(addr, na); | 276 | u32 result[OF_MAX_ADDR_CELLS]; |
270 | memset(addr, 0, na * 4); | 277 | int i; |
271 | a += offset; | 278 | |
272 | if (na > 1) | 279 | if (ns > 2) { |
273 | addr[na - 2] = a >> 32; | 280 | printk("of_device: Cannot handle size cells (%d) > 2.", ns); |
274 | addr[na - 1] = a & 0xffffffffu; | 281 | return -EINVAL; |
282 | } | ||
283 | |||
284 | if (of_out_of_range(addr, range, range + na + pna, na, ns)) | ||
285 | return -EINVAL; | ||
286 | |||
287 | /* Start with the parent range base. */ | ||
288 | memcpy(result, range + na, pna * 4); | ||
289 | |||
290 | /* Add in the child address offset. */ | ||
291 | for (i = 0; i < na; i++) | ||
292 | result[pna - 1 - i] += | ||
293 | (addr[na - 1 - i] - | ||
294 | range[na - 1 - i]); | ||
295 | |||
296 | memcpy(addr, result, pna * 4); | ||
275 | 297 | ||
276 | return 0; | 298 | return 0; |
277 | } | 299 | } |
@@ -287,7 +309,20 @@ static unsigned int of_bus_default_get_flags(u32 *addr) | |||
287 | 309 | ||
288 | static int of_bus_pci_match(struct device_node *np) | 310 | static int of_bus_pci_match(struct device_node *np) |
289 | { | 311 | { |
290 | return !strcmp(np->type, "pci") || !strcmp(np->type, "pciex"); | 312 | if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) { |
313 | /* Do not do PCI specific frobbing if the | ||
314 | * PCI bridge lacks a ranges property. We | ||
315 | * want to pass it through up to the next | ||
316 | * parent as-is, not with the PCI translate | ||
317 | * method which chops off the top address cell. | ||
318 | */ | ||
319 | if (!of_find_property(np, "ranges", NULL)) | ||
320 | return 0; | ||
321 | |||
322 | return 1; | ||
323 | } | ||
324 | |||
325 | return 0; | ||
291 | } | 326 | } |
292 | 327 | ||
293 | static void of_bus_pci_count_cells(struct device_node *np, | 328 | static void of_bus_pci_count_cells(struct device_node *np, |
@@ -299,27 +334,32 @@ static void of_bus_pci_count_cells(struct device_node *np, | |||
299 | *sizec = 2; | 334 | *sizec = 2; |
300 | } | 335 | } |
301 | 336 | ||
302 | static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna) | 337 | static int of_bus_pci_map(u32 *addr, const u32 *range, |
338 | int na, int ns, int pna) | ||
303 | { | 339 | { |
304 | u64 cp, s, da; | 340 | u32 result[OF_MAX_ADDR_CELLS]; |
341 | int i; | ||
305 | 342 | ||
306 | /* Check address type match */ | 343 | /* Check address type match */ |
307 | if ((addr[0] ^ range[0]) & 0x03000000) | 344 | if ((addr[0] ^ range[0]) & 0x03000000) |
308 | return OF_BAD_ADDR; | 345 | return -EINVAL; |
309 | 346 | ||
310 | /* Read address values, skipping high cell */ | 347 | if (of_out_of_range(addr + 1, range + 1, range + na + pna, |
311 | cp = of_read_addr(range + 1, na - 1); | 348 | na - 1, ns)) |
312 | s = of_read_addr(range + na + pna, ns); | 349 | return -EINVAL; |
313 | da = of_read_addr(addr + 1, na - 1); | ||
314 | 350 | ||
315 | if (da < cp || da >= (cp + s)) | 351 | /* Start with the parent range base. */ |
316 | return OF_BAD_ADDR; | 352 | memcpy(result, range + na, pna * 4); |
317 | return da - cp; | ||
318 | } | ||
319 | 353 | ||
320 | static int of_bus_pci_translate(u32 *addr, u64 offset, int na) | 354 | /* Add in the child address offset, skipping high cell. */ |
321 | { | 355 | for (i = 0; i < na - 1; i++) |
322 | return of_bus_default_translate(addr + 1, offset, na - 1); | 356 | result[pna - 1 - i] += |
357 | (addr[na - 1 - i] - | ||
358 | range[na - 1 - i]); | ||
359 | |||
360 | memcpy(addr, result, pna * 4); | ||
361 | |||
362 | return 0; | ||
323 | } | 363 | } |
324 | 364 | ||
325 | static unsigned int of_bus_pci_get_flags(u32 *addr) | 365 | static unsigned int of_bus_pci_get_flags(u32 *addr) |
@@ -340,59 +380,6 @@ static unsigned int of_bus_pci_get_flags(u32 *addr) | |||
340 | } | 380 | } |
341 | 381 | ||
342 | /* | 382 | /* |
343 | * ISA bus specific translator | ||
344 | */ | ||
345 | |||
346 | static int of_bus_isa_match(struct device_node *np) | ||
347 | { | ||
348 | return !strcmp(np->name, "isa"); | ||
349 | } | ||
350 | |||
351 | static void of_bus_isa_count_cells(struct device_node *child, | ||
352 | int *addrc, int *sizec) | ||
353 | { | ||
354 | if (addrc) | ||
355 | *addrc = 2; | ||
356 | if (sizec) | ||
357 | *sizec = 1; | ||
358 | } | ||
359 | |||
360 | static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna) | ||
361 | { | ||
362 | u64 cp, s, da; | ||
363 | |||
364 | /* Check address type match */ | ||
365 | if ((addr[0] ^ range[0]) & 0x00000001) | ||
366 | return OF_BAD_ADDR; | ||
367 | |||
368 | /* Read address values, skipping high cell */ | ||
369 | cp = of_read_addr(range + 1, na - 1); | ||
370 | s = of_read_addr(range + na + pna, ns); | ||
371 | da = of_read_addr(addr + 1, na - 1); | ||
372 | |||
373 | if (da < cp || da >= (cp + s)) | ||
374 | return OF_BAD_ADDR; | ||
375 | return da - cp; | ||
376 | } | ||
377 | |||
378 | static int of_bus_isa_translate(u32 *addr, u64 offset, int na) | ||
379 | { | ||
380 | return of_bus_default_translate(addr + 1, offset, na - 1); | ||
381 | } | ||
382 | |||
383 | static unsigned int of_bus_isa_get_flags(u32 *addr) | ||
384 | { | ||
385 | unsigned int flags = 0; | ||
386 | u32 w = addr[0]; | ||
387 | |||
388 | if (w & 1) | ||
389 | flags |= IORESOURCE_IO; | ||
390 | else | ||
391 | flags |= IORESOURCE_MEM; | ||
392 | return flags; | ||
393 | } | ||
394 | |||
395 | /* | ||
396 | * SBUS bus specific translator | 383 | * SBUS bus specific translator |
397 | */ | 384 | */ |
398 | 385 | ||
@@ -411,16 +398,11 @@ static void of_bus_sbus_count_cells(struct device_node *child, | |||
411 | *sizec = 1; | 398 | *sizec = 1; |
412 | } | 399 | } |
413 | 400 | ||
414 | static u64 of_bus_sbus_map(u32 *addr, u32 *range, int na, int ns, int pna) | 401 | static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int pna) |
415 | { | 402 | { |
416 | return of_bus_default_map(addr, range, na, ns, pna); | 403 | return of_bus_default_map(addr, range, na, ns, pna); |
417 | } | 404 | } |
418 | 405 | ||
419 | static int of_bus_sbus_translate(u32 *addr, u64 offset, int na) | ||
420 | { | ||
421 | return of_bus_default_translate(addr, offset, na); | ||
422 | } | ||
423 | |||
424 | static unsigned int of_bus_sbus_get_flags(u32 *addr) | 406 | static unsigned int of_bus_sbus_get_flags(u32 *addr) |
425 | { | 407 | { |
426 | return IORESOURCE_MEM; | 408 | return IORESOURCE_MEM; |
@@ -439,19 +421,8 @@ static struct of_bus of_busses[] = { | |||
439 | .match = of_bus_pci_match, | 421 | .match = of_bus_pci_match, |
440 | .count_cells = of_bus_pci_count_cells, | 422 | .count_cells = of_bus_pci_count_cells, |
441 | .map = of_bus_pci_map, | 423 | .map = of_bus_pci_map, |
442 | .translate = of_bus_pci_translate, | ||
443 | .get_flags = of_bus_pci_get_flags, | 424 | .get_flags = of_bus_pci_get_flags, |
444 | }, | 425 | }, |
445 | /* ISA */ | ||
446 | { | ||
447 | .name = "isa", | ||
448 | .addr_prop_name = "reg", | ||
449 | .match = of_bus_isa_match, | ||
450 | .count_cells = of_bus_isa_count_cells, | ||
451 | .map = of_bus_isa_map, | ||
452 | .translate = of_bus_isa_translate, | ||
453 | .get_flags = of_bus_isa_get_flags, | ||
454 | }, | ||
455 | /* SBUS */ | 426 | /* SBUS */ |
456 | { | 427 | { |
457 | .name = "sbus", | 428 | .name = "sbus", |
@@ -459,7 +430,6 @@ static struct of_bus of_busses[] = { | |||
459 | .match = of_bus_sbus_match, | 430 | .match = of_bus_sbus_match, |
460 | .count_cells = of_bus_sbus_count_cells, | 431 | .count_cells = of_bus_sbus_count_cells, |
461 | .map = of_bus_sbus_map, | 432 | .map = of_bus_sbus_map, |
462 | .translate = of_bus_sbus_translate, | ||
463 | .get_flags = of_bus_sbus_get_flags, | 433 | .get_flags = of_bus_sbus_get_flags, |
464 | }, | 434 | }, |
465 | /* Default */ | 435 | /* Default */ |
@@ -469,7 +439,6 @@ static struct of_bus of_busses[] = { | |||
469 | .match = NULL, | 439 | .match = NULL, |
470 | .count_cells = of_bus_default_count_cells, | 440 | .count_cells = of_bus_default_count_cells, |
471 | .map = of_bus_default_map, | 441 | .map = of_bus_default_map, |
472 | .translate = of_bus_default_translate, | ||
473 | .get_flags = of_bus_default_get_flags, | 442 | .get_flags = of_bus_default_get_flags, |
474 | }, | 443 | }, |
475 | }; | 444 | }; |
@@ -494,33 +463,62 @@ static int __init build_one_resource(struct device_node *parent, | |||
494 | u32 *ranges; | 463 | u32 *ranges; |
495 | unsigned int rlen; | 464 | unsigned int rlen; |
496 | int rone; | 465 | int rone; |
497 | u64 offset = OF_BAD_ADDR; | ||
498 | 466 | ||
499 | ranges = of_get_property(parent, "ranges", &rlen); | 467 | ranges = of_get_property(parent, "ranges", &rlen); |
500 | if (ranges == NULL || rlen == 0) { | 468 | if (ranges == NULL || rlen == 0) { |
501 | offset = of_read_addr(addr, na); | 469 | u32 result[OF_MAX_ADDR_CELLS]; |
502 | memset(addr, 0, pna * 4); | 470 | int i; |
503 | goto finish; | 471 | |
472 | memset(result, 0, pna * 4); | ||
473 | for (i = 0; i < na; i++) | ||
474 | result[pna - 1 - i] = | ||
475 | addr[na - 1 - i]; | ||
476 | |||
477 | memcpy(addr, result, pna * 4); | ||
478 | return 0; | ||
504 | } | 479 | } |
505 | 480 | ||
506 | /* Now walk through the ranges */ | 481 | /* Now walk through the ranges */ |
507 | rlen /= 4; | 482 | rlen /= 4; |
508 | rone = na + pna + ns; | 483 | rone = na + pna + ns; |
509 | for (; rlen >= rone; rlen -= rone, ranges += rone) { | 484 | for (; rlen >= rone; rlen -= rone, ranges += rone) { |
510 | offset = bus->map(addr, ranges, na, ns, pna); | 485 | if (!bus->map(addr, ranges, na, ns, pna)) |
511 | if (offset != OF_BAD_ADDR) | 486 | return 0; |
512 | break; | ||
513 | } | 487 | } |
514 | if (offset == OF_BAD_ADDR) | 488 | |
489 | return 1; | ||
490 | } | ||
491 | |||
492 | static int __init use_1to1_mapping(struct device_node *pp) | ||
493 | { | ||
494 | char *model; | ||
495 | |||
496 | /* If this is on the PMU bus, don't try to translate it even | ||
497 | * if a ranges property exists. | ||
498 | */ | ||
499 | if (!strcmp(pp->name, "pmu")) | ||
515 | return 1; | 500 | return 1; |
516 | 501 | ||
517 | memcpy(addr, ranges + na, 4 * pna); | 502 | /* If we have a ranges property in the parent, use it. */ |
503 | if (of_find_property(pp, "ranges", NULL) != NULL) | ||
504 | return 0; | ||
505 | |||
506 | /* If the parent is the dma node of an ISA bus, pass | ||
507 | * the translation up to the root. | ||
508 | */ | ||
509 | if (!strcmp(pp->name, "dma")) | ||
510 | return 0; | ||
511 | |||
512 | /* Similarly for Simba PCI bridges. */ | ||
513 | model = of_get_property(pp, "model", NULL); | ||
514 | if (model && !strcmp(model, "SUNW,simba")) | ||
515 | return 0; | ||
518 | 516 | ||
519 | finish: | 517 | return 1; |
520 | /* Translate it into parent bus space */ | ||
521 | return pbus->translate(addr, offset, pna); | ||
522 | } | 518 | } |
523 | 519 | ||
520 | static int of_resource_verbose; | ||
521 | |||
524 | static void __init build_device_resources(struct of_device *op, | 522 | static void __init build_device_resources(struct of_device *op, |
525 | struct device *parent) | 523 | struct device *parent) |
526 | { | 524 | { |
@@ -544,9 +542,17 @@ static void __init build_device_resources(struct of_device *op, | |||
544 | /* Convert to num-cells. */ | 542 | /* Convert to num-cells. */ |
545 | num_reg /= 4; | 543 | num_reg /= 4; |
546 | 544 | ||
547 | /* Conver to num-entries. */ | 545 | /* Convert to num-entries. */ |
548 | num_reg /= na + ns; | 546 | num_reg /= na + ns; |
549 | 547 | ||
548 | /* Prevent overruning the op->resources[] array. */ | ||
549 | if (num_reg > PROMREG_MAX) { | ||
550 | printk(KERN_WARNING "%s: Too many regs (%d), " | ||
551 | "limiting to %d.\n", | ||
552 | op->node->full_name, num_reg, PROMREG_MAX); | ||
553 | num_reg = PROMREG_MAX; | ||
554 | } | ||
555 | |||
550 | for (index = 0; index < num_reg; index++) { | 556 | for (index = 0; index < num_reg; index++) { |
551 | struct resource *r = &op->resource[index]; | 557 | struct resource *r = &op->resource[index]; |
552 | u32 addr[OF_MAX_ADDR_CELLS]; | 558 | u32 addr[OF_MAX_ADDR_CELLS]; |
@@ -564,15 +570,7 @@ static void __init build_device_resources(struct of_device *op, | |||
564 | 570 | ||
565 | memcpy(addr, reg, na * 4); | 571 | memcpy(addr, reg, na * 4); |
566 | 572 | ||
567 | /* If the immediate parent has no ranges property to apply, | 573 | if (use_1to1_mapping(pp)) { |
568 | * just use a 1<->1 mapping. Unless it is the 'dma' child | ||
569 | * of an isa bus, which must be passed up towards the root. | ||
570 | * | ||
571 | * Also, don't try to translate PMU bus device registers. | ||
572 | */ | ||
573 | if ((of_find_property(pp, "ranges", NULL) == NULL && | ||
574 | strcmp(pp->name, "dma") != 0) || | ||
575 | !strcmp(pp->name, "pmu")) { | ||
576 | result = of_read_addr(addr, na); | 574 | result = of_read_addr(addr, na); |
577 | goto build_res; | 575 | goto build_res; |
578 | } | 576 | } |
@@ -591,7 +589,8 @@ static void __init build_device_resources(struct of_device *op, | |||
591 | pbus = of_match_bus(pp); | 589 | pbus = of_match_bus(pp); |
592 | pbus->count_cells(dp, &pna, &pns); | 590 | pbus->count_cells(dp, &pna, &pns); |
593 | 591 | ||
594 | if (build_one_resource(dp, bus, pbus, addr, dna, dns, pna)) | 592 | if (build_one_resource(dp, bus, pbus, addr, |
593 | dna, dns, pna)) | ||
595 | break; | 594 | break; |
596 | 595 | ||
597 | dna = pna; | 596 | dna = pna; |
@@ -601,6 +600,12 @@ static void __init build_device_resources(struct of_device *op, | |||
601 | 600 | ||
602 | build_res: | 601 | build_res: |
603 | memset(r, 0, sizeof(*r)); | 602 | memset(r, 0, sizeof(*r)); |
603 | |||
604 | if (of_resource_verbose) | ||
605 | printk("%s reg[%d] -> %lx\n", | ||
606 | op->node->full_name, index, | ||
607 | result); | ||
608 | |||
604 | if (result != OF_BAD_ADDR) { | 609 | if (result != OF_BAD_ADDR) { |
605 | if (tlb_type == hypervisor) | 610 | if (tlb_type == hypervisor) |
606 | result &= 0x0fffffffffffffffUL; | 611 | result &= 0x0fffffffffffffffUL; |
@@ -653,8 +658,22 @@ apply_interrupt_map(struct device_node *dp, struct device_node *pp, | |||
653 | next: | 658 | next: |
654 | imap += (na + 3); | 659 | imap += (na + 3); |
655 | } | 660 | } |
656 | if (i == imlen) | 661 | if (i == imlen) { |
662 | /* Psycho and Sabre PCI controllers can have 'interrupt-map' | ||
663 | * properties that do not include the on-board device | ||
664 | * interrupts. Instead, the device's 'interrupts' property | ||
665 | * is already a fully specified INO value. | ||
666 | * | ||
667 | * Handle this by deciding that, if we didn't get a | ||
668 | * match in the parent's 'interrupt-map', and the | ||
669 | * parent is an IRQ translater, then use the parent as | ||
670 | * our IRQ controller. | ||
671 | */ | ||
672 | if (pp->irq_trans) | ||
673 | return pp; | ||
674 | |||
657 | return NULL; | 675 | return NULL; |
676 | } | ||
658 | 677 | ||
659 | *irq_p = irq; | 678 | *irq_p = irq; |
660 | cp = of_find_node_by_phandle(handle); | 679 | cp = of_find_node_by_phandle(handle); |
@@ -684,6 +703,8 @@ static unsigned int __init pci_irq_swizzle(struct device_node *dp, | |||
684 | return ret; | 703 | return ret; |
685 | } | 704 | } |
686 | 705 | ||
706 | static int of_irq_verbose; | ||
707 | |||
687 | static unsigned int __init build_one_device_irq(struct of_device *op, | 708 | static unsigned int __init build_one_device_irq(struct of_device *op, |
688 | struct device *parent, | 709 | struct device *parent, |
689 | unsigned int irq) | 710 | unsigned int irq) |
@@ -698,10 +719,11 @@ static unsigned int __init build_one_device_irq(struct of_device *op, | |||
698 | if (dp->irq_trans) { | 719 | if (dp->irq_trans) { |
699 | irq = dp->irq_trans->irq_build(dp, irq, | 720 | irq = dp->irq_trans->irq_build(dp, irq, |
700 | dp->irq_trans->data); | 721 | dp->irq_trans->data); |
701 | #if 1 | 722 | |
702 | printk("%s: direct translate %x --> %x\n", | 723 | if (of_irq_verbose) |
703 | dp->full_name, orig_irq, irq); | 724 | printk("%s: direct translate %x --> %x\n", |
704 | #endif | 725 | dp->full_name, orig_irq, irq); |
726 | |||
705 | return irq; | 727 | return irq; |
706 | } | 728 | } |
707 | 729 | ||
@@ -728,12 +750,13 @@ static unsigned int __init build_one_device_irq(struct of_device *op, | |||
728 | iret = apply_interrupt_map(dp, pp, | 750 | iret = apply_interrupt_map(dp, pp, |
729 | imap, imlen, imsk, | 751 | imap, imlen, imsk, |
730 | &irq); | 752 | &irq); |
731 | #if 1 | 753 | |
732 | printk("%s: Apply [%s:%x] imap --> [%s:%x]\n", | 754 | if (of_irq_verbose) |
733 | op->node->full_name, | 755 | printk("%s: Apply [%s:%x] imap --> [%s:%x]\n", |
734 | pp->full_name, this_orig_irq, | 756 | op->node->full_name, |
735 | (iret ? iret->full_name : "NULL"), irq); | 757 | pp->full_name, this_orig_irq, |
736 | #endif | 758 | (iret ? iret->full_name : "NULL"), irq); |
759 | |||
737 | if (!iret) | 760 | if (!iret) |
738 | break; | 761 | break; |
739 | 762 | ||
@@ -747,11 +770,13 @@ static unsigned int __init build_one_device_irq(struct of_device *op, | |||
747 | unsigned int this_orig_irq = irq; | 770 | unsigned int this_orig_irq = irq; |
748 | 771 | ||
749 | irq = pci_irq_swizzle(dp, pp, irq); | 772 | irq = pci_irq_swizzle(dp, pp, irq); |
750 | #if 1 | 773 | if (of_irq_verbose) |
751 | printk("%s: PCI swizzle [%s] %x --> %x\n", | 774 | printk("%s: PCI swizzle [%s] " |
752 | op->node->full_name, | 775 | "%x --> %x\n", |
753 | pp->full_name, this_orig_irq, irq); | 776 | op->node->full_name, |
754 | #endif | 777 | pp->full_name, this_orig_irq, |
778 | irq); | ||
779 | |||
755 | } | 780 | } |
756 | 781 | ||
757 | if (pp->irq_trans) { | 782 | if (pp->irq_trans) { |
@@ -767,10 +792,9 @@ static unsigned int __init build_one_device_irq(struct of_device *op, | |||
767 | 792 | ||
768 | irq = ip->irq_trans->irq_build(op->node, irq, | 793 | irq = ip->irq_trans->irq_build(op->node, irq, |
769 | ip->irq_trans->data); | 794 | ip->irq_trans->data); |
770 | #if 1 | 795 | if (of_irq_verbose) |
771 | printk("%s: Apply IRQ trans [%s] %x --> %x\n", | 796 | printk("%s: Apply IRQ trans [%s] %x --> %x\n", |
772 | op->node->full_name, ip->full_name, orig_irq, irq); | 797 | op->node->full_name, ip->full_name, orig_irq, irq); |
773 | #endif | ||
774 | 798 | ||
775 | return irq; | 799 | return irq; |
776 | } | 800 | } |
@@ -801,6 +825,14 @@ static struct of_device * __init scan_one_device(struct device_node *dp, | |||
801 | op->num_irqs = 0; | 825 | op->num_irqs = 0; |
802 | } | 826 | } |
803 | 827 | ||
828 | /* Prevent overruning the op->irqs[] array. */ | ||
829 | if (op->num_irqs > PROMINTR_MAX) { | ||
830 | printk(KERN_WARNING "%s: Too many irqs (%d), " | ||
831 | "limiting to %d.\n", | ||
832 | dp->full_name, op->num_irqs, PROMINTR_MAX); | ||
833 | op->num_irqs = PROMINTR_MAX; | ||
834 | } | ||
835 | |||
804 | build_device_resources(op, parent); | 836 | build_device_resources(op, parent); |
805 | for (i = 0; i < op->num_irqs; i++) | 837 | for (i = 0; i < op->num_irqs; i++) |
806 | op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]); | 838 | op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]); |
@@ -870,6 +902,20 @@ static int __init of_bus_driver_init(void) | |||
870 | 902 | ||
871 | postcore_initcall(of_bus_driver_init); | 903 | postcore_initcall(of_bus_driver_init); |
872 | 904 | ||
905 | static int __init of_debug(char *str) | ||
906 | { | ||
907 | int val = 0; | ||
908 | |||
909 | get_option(&str, &val); | ||
910 | if (val & 1) | ||
911 | of_resource_verbose = 1; | ||
912 | if (val & 2) | ||
913 | of_irq_verbose = 1; | ||
914 | return 1; | ||
915 | } | ||
916 | |||
917 | __setup("of_debug=", of_debug); | ||
918 | |||
873 | int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) | 919 | int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) |
874 | { | 920 | { |
875 | /* initialize common driver fields */ | 921 | /* initialize common driver fields */ |
@@ -922,9 +968,11 @@ int of_device_register(struct of_device *ofdev) | |||
922 | if (rc) | 968 | if (rc) |
923 | return rc; | 969 | return rc; |
924 | 970 | ||
925 | device_create_file(&ofdev->dev, &dev_attr_devspec); | 971 | rc = device_create_file(&ofdev->dev, &dev_attr_devspec); |
972 | if (rc) | ||
973 | device_unregister(&ofdev->dev); | ||
926 | 974 | ||
927 | return 0; | 975 | return rc; |
928 | } | 976 | } |
929 | 977 | ||
930 | void of_device_unregister(struct of_device *ofdev) | 978 | void of_device_unregister(struct of_device *ofdev) |
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 197a7ffd57ee..1ec0aab68c08 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c | |||
@@ -1099,9 +1099,6 @@ static void pbm_register_toplevel_resources(struct pci_controller_info *p, | |||
1099 | { | 1099 | { |
1100 | char *name = pbm->name; | 1100 | char *name = pbm->name; |
1101 | 1101 | ||
1102 | sprintf(name, "PSYCHO%d PBM%c", | ||
1103 | p->index, | ||
1104 | (pbm == &p->pbm_A ? 'A' : 'B')); | ||
1105 | pbm->io_space.name = pbm->mem_space.name = name; | 1102 | pbm->io_space.name = pbm->mem_space.name = name; |
1106 | 1103 | ||
1107 | request_resource(&ioport_resource, &pbm->io_space); | 1104 | request_resource(&ioport_resource, &pbm->io_space); |
@@ -1203,12 +1200,13 @@ static void psycho_pbm_init(struct pci_controller_info *p, | |||
1203 | pbm->io_space.flags = IORESOURCE_IO; | 1200 | pbm->io_space.flags = IORESOURCE_IO; |
1204 | pbm->mem_space.end = pbm->mem_space.start + PSYCHO_MEMSPACE_SIZE; | 1201 | pbm->mem_space.end = pbm->mem_space.start + PSYCHO_MEMSPACE_SIZE; |
1205 | pbm->mem_space.flags = IORESOURCE_MEM; | 1202 | pbm->mem_space.flags = IORESOURCE_MEM; |
1206 | pbm_register_toplevel_resources(p, pbm); | ||
1207 | 1203 | ||
1208 | pbm->parent = p; | 1204 | pbm->parent = p; |
1209 | pbm->prom_node = dp; | 1205 | pbm->prom_node = dp; |
1210 | pbm->name = dp->full_name; | 1206 | pbm->name = dp->full_name; |
1211 | 1207 | ||
1208 | pbm_register_toplevel_resources(p, pbm); | ||
1209 | |||
1212 | printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n", | 1210 | printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n", |
1213 | pbm->name, | 1211 | pbm->name, |
1214 | pbm->chip_version, pbm->chip_revision); | 1212 | pbm->chip_version, pbm->chip_revision); |
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index fa484d4f241e..5cc5ab63293f 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c | |||
@@ -344,10 +344,12 @@ static unsigned long __psycho_onboard_imap_off[] = { | |||
344 | /*0x2f*/ PSYCHO_IMAP_CE, | 344 | /*0x2f*/ PSYCHO_IMAP_CE, |
345 | /*0x30*/ PSYCHO_IMAP_A_ERR, | 345 | /*0x30*/ PSYCHO_IMAP_A_ERR, |
346 | /*0x31*/ PSYCHO_IMAP_B_ERR, | 346 | /*0x31*/ PSYCHO_IMAP_B_ERR, |
347 | /*0x32*/ PSYCHO_IMAP_PMGMT | 347 | /*0x32*/ PSYCHO_IMAP_PMGMT, |
348 | /*0x33*/ PSYCHO_IMAP_GFX, | ||
349 | /*0x34*/ PSYCHO_IMAP_EUPA, | ||
348 | }; | 350 | }; |
349 | #define PSYCHO_ONBOARD_IRQ_BASE 0x20 | 351 | #define PSYCHO_ONBOARD_IRQ_BASE 0x20 |
350 | #define PSYCHO_ONBOARD_IRQ_LAST 0x32 | 352 | #define PSYCHO_ONBOARD_IRQ_LAST 0x34 |
351 | #define psycho_onboard_imap_offset(__ino) \ | 353 | #define psycho_onboard_imap_offset(__ino) \ |
352 | __psycho_onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE] | 354 | __psycho_onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE] |
353 | 355 | ||
@@ -529,6 +531,10 @@ static unsigned long __sabre_onboard_imap_off[] = { | |||
529 | /*0x2e*/ SABRE_IMAP_UE, | 531 | /*0x2e*/ SABRE_IMAP_UE, |
530 | /*0x2f*/ SABRE_IMAP_CE, | 532 | /*0x2f*/ SABRE_IMAP_CE, |
531 | /*0x30*/ SABRE_IMAP_PCIERR, | 533 | /*0x30*/ SABRE_IMAP_PCIERR, |
534 | /*0x31*/ 0 /* reserved */, | ||
535 | /*0x32*/ 0 /* reserved */, | ||
536 | /*0x33*/ SABRE_IMAP_GFX, | ||
537 | /*0x34*/ SABRE_IMAP_EUPA, | ||
532 | }; | 538 | }; |
533 | #define SABRE_ONBOARD_IRQ_BASE 0x20 | 539 | #define SABRE_ONBOARD_IRQ_BASE 0x20 |
534 | #define SABRE_ONBOARD_IRQ_LAST 0x30 | 540 | #define SABRE_ONBOARD_IRQ_LAST 0x30 |
@@ -539,6 +545,45 @@ static unsigned long __sabre_onboard_imap_off[] = { | |||
539 | ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \ | 545 | ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \ |
540 | (SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3))) | 546 | (SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3))) |
541 | 547 | ||
548 | static int sabre_device_needs_wsync(struct device_node *dp) | ||
549 | { | ||
550 | struct device_node *parent = dp->parent; | ||
551 | char *parent_model, *parent_compat; | ||
552 | |||
553 | /* This traversal up towards the root is meant to | ||
554 | * handle two cases: | ||
555 | * | ||
556 | * 1) non-PCI bus sitting under PCI, such as 'ebus' | ||
557 | * 2) the PCI controller interrupts themselves, which | ||
558 | * will use the sabre_irq_build but do not need | ||
559 | * the DMA synchronization handling | ||
560 | */ | ||
561 | while (parent) { | ||
562 | if (!strcmp(parent->type, "pci")) | ||
563 | break; | ||
564 | parent = parent->parent; | ||
565 | } | ||
566 | |||
567 | if (!parent) | ||
568 | return 0; | ||
569 | |||
570 | parent_model = of_get_property(parent, | ||
571 | "model", NULL); | ||
572 | if (parent_model && | ||
573 | (!strcmp(parent_model, "SUNW,sabre") || | ||
574 | !strcmp(parent_model, "SUNW,simba"))) | ||
575 | return 0; | ||
576 | |||
577 | parent_compat = of_get_property(parent, | ||
578 | "compatible", NULL); | ||
579 | if (parent_compat && | ||
580 | (!strcmp(parent_compat, "pci108e,a000") || | ||
581 | !strcmp(parent_compat, "pci108e,a001"))) | ||
582 | return 0; | ||
583 | |||
584 | return 1; | ||
585 | } | ||
586 | |||
542 | static unsigned int sabre_irq_build(struct device_node *dp, | 587 | static unsigned int sabre_irq_build(struct device_node *dp, |
543 | unsigned int ino, | 588 | unsigned int ino, |
544 | void *_data) | 589 | void *_data) |
@@ -577,15 +622,17 @@ static unsigned int sabre_irq_build(struct device_node *dp, | |||
577 | 622 | ||
578 | virt_irq = build_irq(inofixup, iclr, imap); | 623 | virt_irq = build_irq(inofixup, iclr, imap); |
579 | 624 | ||
625 | /* If the parent device is a PCI<->PCI bridge other than | ||
626 | * APB, we have to install a pre-handler to ensure that | ||
627 | * all pending DMA is drained before the interrupt handler | ||
628 | * is run. | ||
629 | */ | ||
580 | regs = of_get_property(dp, "reg", NULL); | 630 | regs = of_get_property(dp, "reg", NULL); |
581 | if (regs && | 631 | if (regs && sabre_device_needs_wsync(dp)) { |
582 | ((regs->phys_hi >> 16) & 0xff) != irq_data->pci_first_busno) { | ||
583 | irq_install_pre_handler(virt_irq, | 632 | irq_install_pre_handler(virt_irq, |
584 | sabre_wsync_handler, | 633 | sabre_wsync_handler, |
585 | (void *) (long) regs->phys_hi, | 634 | (void *) (long) regs->phys_hi, |
586 | (void *) | 635 | (void *) irq_data); |
587 | controller_regs + | ||
588 | SABRE_WRSYNC); | ||
589 | } | 636 | } |
590 | 637 | ||
591 | return virt_irq; | 638 | return virt_irq; |
@@ -854,6 +901,8 @@ static unsigned long sysio_irq_offsets[] = { | |||
854 | SYSIO_IMAP_CE, | 901 | SYSIO_IMAP_CE, |
855 | SYSIO_IMAP_SBERR, | 902 | SYSIO_IMAP_SBERR, |
856 | SYSIO_IMAP_PMGMT, | 903 | SYSIO_IMAP_PMGMT, |
904 | SYSIO_IMAP_GFX, | ||
905 | SYSIO_IMAP_EUPA, | ||
857 | }; | 906 | }; |
858 | 907 | ||
859 | #undef bogon | 908 | #undef bogon |
@@ -1032,7 +1081,9 @@ static void sun4v_vdev_irq_trans_init(struct device_node *dp) | |||
1032 | static void irq_trans_init(struct device_node *dp) | 1081 | static void irq_trans_init(struct device_node *dp) |
1033 | { | 1082 | { |
1034 | const char *model; | 1083 | const char *model; |
1084 | #ifdef CONFIG_PCI | ||
1035 | int i; | 1085 | int i; |
1086 | #endif | ||
1036 | 1087 | ||
1037 | model = of_get_property(dp, "model", NULL); | 1088 | model = of_get_property(dp, "model", NULL); |
1038 | if (!model) | 1089 | if (!model) |
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index a73140466e01..958287448cfe 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <asm/smp.h> | 16 | #include <asm/smp.h> |
17 | #include <linux/user.h> | 17 | #include <linux/user.h> |
18 | #include <linux/a.out.h> | 18 | #include <linux/a.out.h> |
19 | #include <linux/tty.h> | 19 | #include <linux/screen_info.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 4173de425f09..beffc82a1e85 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -124,11 +124,6 @@ EXPORT_SYMBOL(__write_lock); | |||
124 | EXPORT_SYMBOL(__write_unlock); | 124 | EXPORT_SYMBOL(__write_unlock); |
125 | EXPORT_SYMBOL(__write_trylock); | 125 | EXPORT_SYMBOL(__write_trylock); |
126 | 126 | ||
127 | #if defined(CONFIG_MCOUNT) | ||
128 | extern void _mcount(void); | ||
129 | EXPORT_SYMBOL(_mcount); | ||
130 | #endif | ||
131 | |||
132 | /* CPU online map and active count. */ | 127 | /* CPU online map and active count. */ |
133 | EXPORT_SYMBOL(cpu_online_map); | 128 | EXPORT_SYMBOL(cpu_online_map); |
134 | EXPORT_SYMBOL(phys_cpu_present_map); | 129 | EXPORT_SYMBOL(phys_cpu_present_map); |
@@ -136,6 +131,11 @@ EXPORT_SYMBOL(phys_cpu_present_map); | |||
136 | EXPORT_SYMBOL(smp_call_function); | 131 | EXPORT_SYMBOL(smp_call_function); |
137 | #endif /* CONFIG_SMP */ | 132 | #endif /* CONFIG_SMP */ |
138 | 133 | ||
134 | #if defined(CONFIG_MCOUNT) | ||
135 | extern void _mcount(void); | ||
136 | EXPORT_SYMBOL(_mcount); | ||
137 | #endif | ||
138 | |||
139 | EXPORT_SYMBOL(sparc64_get_clock_tick); | 139 | EXPORT_SYMBOL(sparc64_get_clock_tick); |
140 | 140 | ||
141 | /* semaphores */ | 141 | /* semaphores */ |
@@ -254,7 +254,6 @@ EXPORT_SYMBOL(prom_getproperty); | |||
254 | EXPORT_SYMBOL(prom_node_has_property); | 254 | EXPORT_SYMBOL(prom_node_has_property); |
255 | EXPORT_SYMBOL(prom_setprop); | 255 | EXPORT_SYMBOL(prom_setprop); |
256 | EXPORT_SYMBOL(saved_command_line); | 256 | EXPORT_SYMBOL(saved_command_line); |
257 | EXPORT_SYMBOL(prom_getname); | ||
258 | EXPORT_SYMBOL(prom_finddevice); | 257 | EXPORT_SYMBOL(prom_finddevice); |
259 | EXPORT_SYMBOL(prom_feval); | 258 | EXPORT_SYMBOL(prom_feval); |
260 | EXPORT_SYMBOL(prom_getbool); | 259 | EXPORT_SYMBOL(prom_getbool); |
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 51c056df528e..c608c947e6c3 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c | |||
@@ -548,6 +548,26 @@ asmlinkage long sparc64_personality(unsigned long personality) | |||
548 | return ret; | 548 | return ret; |
549 | } | 549 | } |
550 | 550 | ||
551 | int sparc64_mmap_check(unsigned long addr, unsigned long len, | ||
552 | unsigned long flags) | ||
553 | { | ||
554 | if (test_thread_flag(TIF_32BIT)) { | ||
555 | if (len >= STACK_TOP32) | ||
556 | return -EINVAL; | ||
557 | |||
558 | if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len) | ||
559 | return -EINVAL; | ||
560 | } else { | ||
561 | if (len >= VA_EXCLUDE_START) | ||
562 | return -EINVAL; | ||
563 | |||
564 | if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len)) | ||
565 | return -EINVAL; | ||
566 | } | ||
567 | |||
568 | return 0; | ||
569 | } | ||
570 | |||
551 | /* Linux version of mmap */ | 571 | /* Linux version of mmap */ |
552 | asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, | 572 | asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, |
553 | unsigned long prot, unsigned long flags, unsigned long fd, | 573 | unsigned long prot, unsigned long flags, unsigned long fd, |
@@ -563,27 +583,11 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, | |||
563 | } | 583 | } |
564 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | 584 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); |
565 | len = PAGE_ALIGN(len); | 585 | len = PAGE_ALIGN(len); |
566 | retval = -EINVAL; | ||
567 | |||
568 | if (test_thread_flag(TIF_32BIT)) { | ||
569 | if (len >= STACK_TOP32) | ||
570 | goto out_putf; | ||
571 | |||
572 | if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len) | ||
573 | goto out_putf; | ||
574 | } else { | ||
575 | if (len >= VA_EXCLUDE_START) | ||
576 | goto out_putf; | ||
577 | |||
578 | if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len)) | ||
579 | goto out_putf; | ||
580 | } | ||
581 | 586 | ||
582 | down_write(¤t->mm->mmap_sem); | 587 | down_write(¤t->mm->mmap_sem); |
583 | retval = do_mmap(file, addr, len, prot, flags, off); | 588 | retval = do_mmap(file, addr, len, prot, flags, off); |
584 | up_write(¤t->mm->mmap_sem); | 589 | up_write(¤t->mm->mmap_sem); |
585 | 590 | ||
586 | out_putf: | ||
587 | if (file) | 591 | if (file) |
588 | fput(file); | 592 | fput(file); |
589 | out: | 593 | out: |
@@ -701,21 +705,23 @@ extern void check_pending(int signum); | |||
701 | 705 | ||
702 | asmlinkage long sys_getdomainname(char __user *name, int len) | 706 | asmlinkage long sys_getdomainname(char __user *name, int len) |
703 | { | 707 | { |
704 | int nlen; | 708 | int nlen, err; |
705 | int err = -EFAULT; | 709 | |
710 | if (len < 0) | ||
711 | return -EINVAL; | ||
706 | 712 | ||
707 | down_read(&uts_sem); | 713 | down_read(&uts_sem); |
708 | 714 | ||
709 | nlen = strlen(system_utsname.domainname) + 1; | 715 | nlen = strlen(system_utsname.domainname) + 1; |
716 | err = -EINVAL; | ||
717 | if (nlen > len) | ||
718 | goto out; | ||
710 | 719 | ||
711 | if (nlen < len) | 720 | err = -EFAULT; |
712 | len = nlen; | 721 | if (!copy_to_user(name, system_utsname.domainname, nlen)) |
713 | if (len > __NEW_UTS_LEN) | 722 | err = 0; |
714 | goto done; | 723 | |
715 | if (copy_to_user(name, system_utsname.domainname, len)) | 724 | out: |
716 | goto done; | ||
717 | err = 0; | ||
718 | done: | ||
719 | up_read(&uts_sem); | 725 | up_read(&uts_sem); |
720 | return err; | 726 | return err; |
721 | } | 727 | } |
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 8dcbfbffacc9..094d3e35be18 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c | |||
@@ -788,12 +788,15 @@ static int __devinit clock_probe(struct of_device *op, const struct of_device_id | |||
788 | if (!regs) | 788 | if (!regs) |
789 | return -ENOMEM; | 789 | return -ENOMEM; |
790 | 790 | ||
791 | #ifdef CONFIG_PCI | ||
791 | if (!strcmp(model, "ds1287") || | 792 | if (!strcmp(model, "ds1287") || |
792 | !strcmp(model, "m5819") || | 793 | !strcmp(model, "m5819") || |
793 | !strcmp(model, "m5819p") || | 794 | !strcmp(model, "m5819p") || |
794 | !strcmp(model, "m5823")) { | 795 | !strcmp(model, "m5823")) { |
795 | ds1287_regs = (unsigned long) regs; | 796 | ds1287_regs = (unsigned long) regs; |
796 | } else if (model[5] == '0' && model[6] == '2') { | 797 | } else |
798 | #endif | ||
799 | if (model[5] == '0' && model[6] == '2') { | ||
797 | mstk48t02_regs = regs; | 800 | mstk48t02_regs = regs; |
798 | } else if(model[5] == '0' && model[6] == '8') { | 801 | } else if(model[5] == '0' && model[6] == '8') { |
799 | mstk48t08_regs = regs; | 802 | mstk48t08_regs = regs; |
@@ -925,8 +928,6 @@ static void sparc64_start_timers(void) | |||
925 | __asm__ __volatile__("wrpr %0, 0x0, %%pstate" | 928 | __asm__ __volatile__("wrpr %0, 0x0, %%pstate" |
926 | : /* no outputs */ | 929 | : /* no outputs */ |
927 | : "r" (pstate)); | 930 | : "r" (pstate)); |
928 | |||
929 | local_irq_enable(); | ||
930 | } | 931 | } |
931 | 932 | ||
932 | struct freq_table { | 933 | struct freq_table { |
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index 1605967cce91..55ae802dc0ad 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/kprobes.h> | 21 | #include <linux/kprobes.h> |
22 | #include <linux/kallsyms.h> | ||
22 | 23 | ||
23 | #include <asm/page.h> | 24 | #include <asm/page.h> |
24 | #include <asm/pgtable.h> | 25 | #include <asm/pgtable.h> |
@@ -132,6 +133,8 @@ static void bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr) | |||
132 | 133 | ||
133 | printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n", | 134 | printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n", |
134 | regs->tpc); | 135 | regs->tpc); |
136 | printk(KERN_CRIT "OOPS: RPC [%016lx]\n", regs->u_regs[15]); | ||
137 | print_symbol("RPC: <%s>\n", regs->u_regs[15]); | ||
135 | printk(KERN_CRIT "OOPS: Fault was to vaddr[%lx]\n", vaddr); | 138 | printk(KERN_CRIT "OOPS: Fault was to vaddr[%lx]\n", vaddr); |
136 | __asm__("mov %%sp, %0" : "=r" (ksp)); | 139 | __asm__("mov %%sp, %0" : "=r" (ksp)); |
137 | show_stack(current, ksp); | 140 | show_stack(current, ksp); |
diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c index 8cb06205d265..af9d81db0b38 100644 --- a/arch/sparc64/mm/generic.c +++ b/arch/sparc64/mm/generic.c | |||
@@ -69,6 +69,8 @@ static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte, | |||
69 | } else | 69 | } else |
70 | offset += PAGE_SIZE; | 70 | offset += PAGE_SIZE; |
71 | 71 | ||
72 | if (pte_write(entry)) | ||
73 | entry = pte_mkdirty(entry); | ||
72 | do { | 74 | do { |
73 | BUG_ON(!pte_none(*pte)); | 75 | BUG_ON(!pte_none(*pte)); |
74 | set_pte_at(mm, address, pte, entry); | 76 | set_pte_at(mm, address, pte, entry); |
diff --git a/arch/sparc64/prom/tree.c b/arch/sparc64/prom/tree.c index 49075abd7cbc..500f05e2cfcb 100644 --- a/arch/sparc64/prom/tree.c +++ b/arch/sparc64/prom/tree.c | |||
@@ -193,91 +193,6 @@ prom_searchsiblings(int node_start, const char *nodename) | |||
193 | return 0; | 193 | return 0; |
194 | } | 194 | } |
195 | 195 | ||
196 | /* Gets name in the {name@x,yyyyy|name (if no reg)} form */ | ||
197 | int | ||
198 | prom_getname (int node, char *buffer, int len) | ||
199 | { | ||
200 | int i, sbus = 0; | ||
201 | int pci = 0, ebus = 0, ide = 0; | ||
202 | struct linux_prom_registers *reg; | ||
203 | struct linux_prom64_registers reg64[PROMREG_MAX]; | ||
204 | |||
205 | for (sbus = prom_getparent (node); sbus; sbus = prom_getparent (sbus)) { | ||
206 | i = prom_getproperty (sbus, "name", buffer, len); | ||
207 | if (i > 0) { | ||
208 | buffer [i] = 0; | ||
209 | if (!strcmp (buffer, "sbus")) | ||
210 | goto getit; | ||
211 | } | ||
212 | } | ||
213 | if ((pci = prom_getparent (node))) { | ||
214 | i = prom_getproperty (pci, "name", buffer, len); | ||
215 | if (i > 0) { | ||
216 | buffer [i] = 0; | ||
217 | if (!strcmp (buffer, "pci")) | ||
218 | goto getit; | ||
219 | } | ||
220 | pci = 0; | ||
221 | } | ||
222 | if ((ebus = prom_getparent (node))) { | ||
223 | i = prom_getproperty (ebus, "name", buffer, len); | ||
224 | if (i > 0) { | ||
225 | buffer[i] = 0; | ||
226 | if (!strcmp (buffer, "ebus")) | ||
227 | goto getit; | ||
228 | } | ||
229 | ebus = 0; | ||
230 | } | ||
231 | if ((ide = prom_getparent (node))) { | ||
232 | i = prom_getproperty (ide, "name", buffer, len); | ||
233 | if (i > 0) { | ||
234 | buffer [i] = 0; | ||
235 | if (!strcmp (buffer, "ide")) | ||
236 | goto getit; | ||
237 | } | ||
238 | ide = 0; | ||
239 | } | ||
240 | getit: | ||
241 | i = prom_getproperty (node, "name", buffer, len); | ||
242 | if (i <= 0) { | ||
243 | buffer [0] = 0; | ||
244 | return -1; | ||
245 | } | ||
246 | buffer [i] = 0; | ||
247 | len -= i; | ||
248 | i = prom_getproperty (node, "reg", (char *)reg64, sizeof (reg64)); | ||
249 | if (i <= 0) return 0; | ||
250 | if (len < 16) return -1; | ||
251 | buffer = strchr (buffer, 0); | ||
252 | if (sbus) { | ||
253 | reg = (struct linux_prom_registers *)reg64; | ||
254 | sprintf (buffer, "@%x,%x", reg[0].which_io, (uint)reg[0].phys_addr); | ||
255 | } else if (pci) { | ||
256 | int dev, fn; | ||
257 | reg = (struct linux_prom_registers *)reg64; | ||
258 | fn = (reg[0].which_io >> 8) & 0x07; | ||
259 | dev = (reg[0].which_io >> 11) & 0x1f; | ||
260 | if (fn) | ||
261 | sprintf (buffer, "@%x,%x", dev, fn); | ||
262 | else | ||
263 | sprintf (buffer, "@%x", dev); | ||
264 | } else if (ebus) { | ||
265 | reg = (struct linux_prom_registers *)reg64; | ||
266 | sprintf (buffer, "@%x,%x", reg[0].which_io, reg[0].phys_addr); | ||
267 | } else if (ide) { | ||
268 | reg = (struct linux_prom_registers *)reg64; | ||
269 | sprintf (buffer, "@%x,%x", reg[0].which_io, reg[0].phys_addr); | ||
270 | } else if (i == 4) { /* Happens on 8042's children on Ultra/PCI. */ | ||
271 | reg = (struct linux_prom_registers *)reg64; | ||
272 | sprintf (buffer, "@%x", reg[0].which_io); | ||
273 | } else { | ||
274 | sprintf (buffer, "@%x,%x", | ||
275 | (unsigned int)(reg64[0].phys_addr >> 36), | ||
276 | (unsigned int)(reg64[0].phys_addr)); | ||
277 | } | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | /* Return the first property type for node 'node'. | 196 | /* Return the first property type for node 'node'. |
282 | * buffer should be at least 32B in length | 197 | * buffer should be at least 32B in length |
283 | */ | 198 | */ |