diff options
Diffstat (limited to 'arch/sparc64')
-rw-r--r-- | arch/sparc64/Kconfig | 2 | ||||
-rw-r--r-- | arch/sparc64/defconfig | 41 | ||||
-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 | 63 | ||||
-rw-r--r-- | arch/sparc64/kernel/setup.c | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/sparc64_ksyms.c | 1 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sparc.c | 18 | ||||
-rw-r--r-- | arch/sparc64/kernel/time.c | 2 | ||||
-rw-r--r-- | arch/sparc64/mm/fault.c | 3 | ||||
-rw-r--r-- | arch/sparc64/prom/tree.c | 85 |
13 files changed, 308 insertions, 279 deletions
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index a7a111db25b2..8a36ba8868db 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig | |||
@@ -334,7 +334,7 @@ config COMPAT | |||
334 | default y | 334 | default y |
335 | 335 | ||
336 | config BINFMT_ELF32 | 336 | config BINFMT_ELF32 |
337 | tristate "Kernel support for 32-bit ELF binaries" | 337 | bool "Kernel support for 32-bit ELF binaries" |
338 | depends on SPARC32_COMPAT | 338 | depends on SPARC32_COMPAT |
339 | help | 339 | help |
340 | This allows you to run 32-bit Linux/ELF binaries on your Ultra. | 340 | 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/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 99daeee4209d..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 |
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 237524d87cab..beffc82a1e85 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -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..054d0abdb7ee 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c | |||
@@ -701,21 +701,21 @@ extern void check_pending(int signum); | |||
701 | 701 | ||
702 | asmlinkage long sys_getdomainname(char __user *name, int len) | 702 | asmlinkage long sys_getdomainname(char __user *name, int len) |
703 | { | 703 | { |
704 | int nlen; | 704 | int nlen, err; |
705 | int err = -EFAULT; | 705 | |
706 | if (len < 0 || len > __NEW_UTS_LEN) | ||
707 | return -EINVAL; | ||
706 | 708 | ||
707 | down_read(&uts_sem); | 709 | down_read(&uts_sem); |
708 | 710 | ||
709 | nlen = strlen(system_utsname.domainname) + 1; | 711 | nlen = strlen(system_utsname.domainname) + 1; |
710 | |||
711 | if (nlen < len) | 712 | if (nlen < len) |
712 | len = nlen; | 713 | len = nlen; |
713 | if (len > __NEW_UTS_LEN) | 714 | |
714 | goto done; | 715 | err = -EFAULT; |
715 | if (copy_to_user(name, system_utsname.domainname, len)) | 716 | if (!copy_to_user(name, system_utsname.domainname, len)) |
716 | goto done; | 717 | err = 0; |
717 | err = 0; | 718 | |
718 | done: | ||
719 | up_read(&uts_sem); | 719 | up_read(&uts_sem); |
720 | return err; | 720 | return err; |
721 | } | 721 | } |
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index b43de647ba73..094d3e35be18 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c | |||
@@ -928,8 +928,6 @@ static void sparc64_start_timers(void) | |||
928 | __asm__ __volatile__("wrpr %0, 0x0, %%pstate" | 928 | __asm__ __volatile__("wrpr %0, 0x0, %%pstate" |
929 | : /* no outputs */ | 929 | : /* no outputs */ |
930 | : "r" (pstate)); | 930 | : "r" (pstate)); |
931 | |||
932 | local_irq_enable(); | ||
933 | } | 931 | } |
934 | 932 | ||
935 | 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/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 | */ |