diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-30 11:10:12 -0400 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-30 11:10:12 -0400 | 
| commit | 24a77daf3d80bddcece044e6dc3675e427eef3f3 (patch) | |
| tree | 2c5e0b0bea394d6fe62c5d5857c252e83e48ac48 /arch/powerpc/kernel | |
| parent | e389f9aec689209724105ae80a6c91fd2e747bc9 (diff) | |
| parent | f900e9777fc9b65140cb9570438597bc8fae56ab (diff) | |
Merge branch 'for-2.6.22' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'for-2.6.22' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (255 commits)
  [POWERPC] Remove dev_dbg redefinition in drivers/ps3/vuart.c
  [POWERPC] remove kernel module option for booke wdt
  [POWERPC] Avoid putting cpu node twice
  [POWERPC] Spinlock initializer cleanup
  [POWERPC] ppc4xx_sgdma needs dma-mapping.h
  [POWERPC] arch/powerpc/sysdev/timer.c build fix
  [POWERPC] get_property cleanups
  [POWERPC] Remove the unused HTDMSOUND driver
  [POWERPC] cell: cbe_cpufreq cleanup and crash fix
  [POWERPC] Declare enable_kernel_spe in a header
  [POWERPC] Add dt_xlate_addr() to bootwrapper
  [POWERPC] bootwrapper: CONFIG_ -> CONFIG_DEVICE_TREE
  [POWERPC] Don't define a custom bd_t for Xilixn Virtex based boards.
  [POWERPC] Add sane defaults for Xilinx EDK generated xparameters files
  [POWERPC] Add uartlite boot console driver for the zImage wrapper
  [POWERPC] Stop using ppc_sys for Xilinx Virtex boards
  [POWERPC] New registration for common Xilinx Virtex ppc405 platform devices
  [POWERPC] Merge common virtex header files
  [POWERPC] Rework Kconfig dependancies for Xilinx Virtex ppc405 platform
  [POWERPC] Clean up cpufreq Kconfig dependencies
  ...
Diffstat (limited to 'arch/powerpc/kernel')
38 files changed, 835 insertions, 524 deletions
| diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 8120d428ebfd..e0fa80eca366 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
| @@ -25,8 +25,8 @@ obj-$(CONFIG_PPC_970_NAP) += idle_power4.o | |||
| 25 | obj-$(CONFIG_PPC_OF) += of_device.o of_platform.o prom_parse.o | 25 | obj-$(CONFIG_PPC_OF) += of_device.o of_platform.o prom_parse.o | 
| 26 | procfs-$(CONFIG_PPC64) := proc_ppc64.o | 26 | procfs-$(CONFIG_PPC64) := proc_ppc64.o | 
| 27 | obj-$(CONFIG_PROC_FS) += $(procfs-y) | 27 | obj-$(CONFIG_PROC_FS) += $(procfs-y) | 
| 28 | rtaspci-$(CONFIG_PPC64) := rtas_pci.o | 28 | rtaspci-$(CONFIG_PPC64)-$(CONFIG_PCI) := rtas_pci.o | 
| 29 | obj-$(CONFIG_PPC_RTAS) += rtas.o rtas-rtc.o $(rtaspci-y) | 29 | obj-$(CONFIG_PPC_RTAS) += rtas.o rtas-rtc.o $(rtaspci-y-y) | 
| 30 | obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o | 30 | obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o | 
| 31 | obj-$(CONFIG_RTAS_PROC) += rtas-proc.o | 31 | obj-$(CONFIG_RTAS_PROC) += rtas-proc.o | 
| 32 | obj-$(CONFIG_LPARCFG) += lparcfg.o | 32 | obj-$(CONFIG_LPARCFG) += lparcfg.o | 
| diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index 4734b5de599d..5c9ff7f5c44e 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c | |||
| @@ -241,7 +241,7 @@ static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr) | |||
| 241 | if (user_mode(regs) && !access_ok(VERIFY_WRITE, p, size)) | 241 | if (user_mode(regs) && !access_ok(VERIFY_WRITE, p, size)) | 
| 242 | return -EFAULT; | 242 | return -EFAULT; | 
| 243 | for (i = 0; i < size / sizeof(long); ++i) | 243 | for (i = 0; i < size / sizeof(long); ++i) | 
| 244 | if (__put_user(0, p+i)) | 244 | if (__put_user_inatomic(0, p+i)) | 
| 245 | return -EFAULT; | 245 | return -EFAULT; | 
| 246 | return 1; | 246 | return 1; | 
| 247 | } | 247 | } | 
| @@ -288,7 +288,8 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, | |||
| 288 | } else { | 288 | } else { | 
| 289 | unsigned long pc = regs->nip ^ (swiz & 4); | 289 | unsigned long pc = regs->nip ^ (swiz & 4); | 
| 290 | 290 | ||
| 291 | if (__get_user(instr, (unsigned int __user *)pc)) | 291 | if (__get_user_inatomic(instr, | 
| 292 | (unsigned int __user *)pc)) | ||
| 292 | return -EFAULT; | 293 | return -EFAULT; | 
| 293 | if (swiz == 0 && (flags & SW)) | 294 | if (swiz == 0 && (flags & SW)) | 
| 294 | instr = cpu_to_le32(instr); | 295 | instr = cpu_to_le32(instr); | 
| @@ -324,27 +325,31 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, | |||
| 324 | ((nb0 + 3) / 4) * sizeof(unsigned long)); | 325 | ((nb0 + 3) / 4) * sizeof(unsigned long)); | 
| 325 | 326 | ||
| 326 | for (i = 0; i < nb; ++i, ++p) | 327 | for (i = 0; i < nb; ++i, ++p) | 
| 327 | if (__get_user(REG_BYTE(rptr, i ^ bswiz), SWIZ_PTR(p))) | 328 | if (__get_user_inatomic(REG_BYTE(rptr, i ^ bswiz), | 
| 329 | SWIZ_PTR(p))) | ||
| 328 | return -EFAULT; | 330 | return -EFAULT; | 
| 329 | if (nb0 > 0) { | 331 | if (nb0 > 0) { | 
| 330 | rptr = ®s->gpr[0]; | 332 | rptr = ®s->gpr[0]; | 
| 331 | addr += nb; | 333 | addr += nb; | 
| 332 | for (i = 0; i < nb0; ++i, ++p) | 334 | for (i = 0; i < nb0; ++i, ++p) | 
| 333 | if (__get_user(REG_BYTE(rptr, i ^ bswiz), | 335 | if (__get_user_inatomic(REG_BYTE(rptr, | 
| 334 | SWIZ_PTR(p))) | 336 | i ^ bswiz), | 
| 337 | SWIZ_PTR(p))) | ||
| 335 | return -EFAULT; | 338 | return -EFAULT; | 
| 336 | } | 339 | } | 
| 337 | 340 | ||
| 338 | } else { | 341 | } else { | 
| 339 | for (i = 0; i < nb; ++i, ++p) | 342 | for (i = 0; i < nb; ++i, ++p) | 
| 340 | if (__put_user(REG_BYTE(rptr, i ^ bswiz), SWIZ_PTR(p))) | 343 | if (__put_user_inatomic(REG_BYTE(rptr, i ^ bswiz), | 
| 344 | SWIZ_PTR(p))) | ||
| 341 | return -EFAULT; | 345 | return -EFAULT; | 
| 342 | if (nb0 > 0) { | 346 | if (nb0 > 0) { | 
| 343 | rptr = ®s->gpr[0]; | 347 | rptr = ®s->gpr[0]; | 
| 344 | addr += nb; | 348 | addr += nb; | 
| 345 | for (i = 0; i < nb0; ++i, ++p) | 349 | for (i = 0; i < nb0; ++i, ++p) | 
| 346 | if (__put_user(REG_BYTE(rptr, i ^ bswiz), | 350 | if (__put_user_inatomic(REG_BYTE(rptr, | 
| 347 | SWIZ_PTR(p))) | 351 | i ^ bswiz), | 
| 352 | SWIZ_PTR(p))) | ||
| 348 | return -EFAULT; | 353 | return -EFAULT; | 
| 349 | } | 354 | } | 
| 350 | } | 355 | } | 
| @@ -398,7 +403,8 @@ int fix_alignment(struct pt_regs *regs) | |||
| 398 | 403 | ||
| 399 | if (cpu_has_feature(CPU_FTR_PPC_LE) && (regs->msr & MSR_LE)) | 404 | if (cpu_has_feature(CPU_FTR_PPC_LE) && (regs->msr & MSR_LE)) | 
| 400 | pc ^= 4; | 405 | pc ^= 4; | 
| 401 | if (unlikely(__get_user(instr, (unsigned int __user *)pc))) | 406 | if (unlikely(__get_user_inatomic(instr, | 
| 407 | (unsigned int __user *)pc))) | ||
| 402 | return -EFAULT; | 408 | return -EFAULT; | 
| 403 | if (cpu_has_feature(CPU_FTR_REAL_LE) && (regs->msr & MSR_LE)) | 409 | if (cpu_has_feature(CPU_FTR_REAL_LE) && (regs->msr & MSR_LE)) | 
| 404 | instr = cpu_to_le32(instr); | 410 | instr = cpu_to_le32(instr); | 
| @@ -474,16 +480,16 @@ int fix_alignment(struct pt_regs *regs) | |||
| 474 | p = (unsigned long) addr; | 480 | p = (unsigned long) addr; | 
| 475 | switch (nb) { | 481 | switch (nb) { | 
| 476 | case 8: | 482 | case 8: | 
| 477 | ret |= __get_user(data.v[0], SWIZ_PTR(p++)); | 483 | ret |= __get_user_inatomic(data.v[0], SWIZ_PTR(p++)); | 
| 478 | ret |= __get_user(data.v[1], SWIZ_PTR(p++)); | 484 | ret |= __get_user_inatomic(data.v[1], SWIZ_PTR(p++)); | 
| 479 | ret |= __get_user(data.v[2], SWIZ_PTR(p++)); | 485 | ret |= __get_user_inatomic(data.v[2], SWIZ_PTR(p++)); | 
| 480 | ret |= __get_user(data.v[3], SWIZ_PTR(p++)); | 486 | ret |= __get_user_inatomic(data.v[3], SWIZ_PTR(p++)); | 
| 481 | case 4: | 487 | case 4: | 
| 482 | ret |= __get_user(data.v[4], SWIZ_PTR(p++)); | 488 | ret |= __get_user_inatomic(data.v[4], SWIZ_PTR(p++)); | 
| 483 | ret |= __get_user(data.v[5], SWIZ_PTR(p++)); | 489 | ret |= __get_user_inatomic(data.v[5], SWIZ_PTR(p++)); | 
| 484 | case 2: | 490 | case 2: | 
| 485 | ret |= __get_user(data.v[6], SWIZ_PTR(p++)); | 491 | ret |= __get_user_inatomic(data.v[6], SWIZ_PTR(p++)); | 
| 486 | ret |= __get_user(data.v[7], SWIZ_PTR(p++)); | 492 | ret |= __get_user_inatomic(data.v[7], SWIZ_PTR(p++)); | 
| 487 | if (unlikely(ret)) | 493 | if (unlikely(ret)) | 
| 488 | return -EFAULT; | 494 | return -EFAULT; | 
| 489 | } | 495 | } | 
| @@ -551,16 +557,16 @@ int fix_alignment(struct pt_regs *regs) | |||
| 551 | p = (unsigned long) addr; | 557 | p = (unsigned long) addr; | 
| 552 | switch (nb) { | 558 | switch (nb) { | 
| 553 | case 8: | 559 | case 8: | 
| 554 | ret |= __put_user(data.v[0], SWIZ_PTR(p++)); | 560 | ret |= __put_user_inatomic(data.v[0], SWIZ_PTR(p++)); | 
| 555 | ret |= __put_user(data.v[1], SWIZ_PTR(p++)); | 561 | ret |= __put_user_inatomic(data.v[1], SWIZ_PTR(p++)); | 
| 556 | ret |= __put_user(data.v[2], SWIZ_PTR(p++)); | 562 | ret |= __put_user_inatomic(data.v[2], SWIZ_PTR(p++)); | 
| 557 | ret |= __put_user(data.v[3], SWIZ_PTR(p++)); | 563 | ret |= __put_user_inatomic(data.v[3], SWIZ_PTR(p++)); | 
| 558 | case 4: | 564 | case 4: | 
| 559 | ret |= __put_user(data.v[4], SWIZ_PTR(p++)); | 565 | ret |= __put_user_inatomic(data.v[4], SWIZ_PTR(p++)); | 
| 560 | ret |= __put_user(data.v[5], SWIZ_PTR(p++)); | 566 | ret |= __put_user_inatomic(data.v[5], SWIZ_PTR(p++)); | 
| 561 | case 2: | 567 | case 2: | 
| 562 | ret |= __put_user(data.v[6], SWIZ_PTR(p++)); | 568 | ret |= __put_user_inatomic(data.v[6], SWIZ_PTR(p++)); | 
| 563 | ret |= __put_user(data.v[7], SWIZ_PTR(p++)); | 569 | ret |= __put_user_inatomic(data.v[7], SWIZ_PTR(p++)); | 
| 564 | } | 570 | } | 
| 565 | if (unlikely(ret)) | 571 | if (unlikely(ret)) | 
| 566 | return -EFAULT; | 572 | return -EFAULT; | 
| diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 030d300cd71c..0c5150c69175 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
| @@ -77,7 +77,6 @@ int main(void) | |||
| 77 | DEFINE(KSP_VSID, offsetof(struct thread_struct, ksp_vsid)); | 77 | DEFINE(KSP_VSID, offsetof(struct thread_struct, ksp_vsid)); | 
| 78 | #else /* CONFIG_PPC64 */ | 78 | #else /* CONFIG_PPC64 */ | 
| 79 | DEFINE(PGDIR, offsetof(struct thread_struct, pgdir)); | 79 | DEFINE(PGDIR, offsetof(struct thread_struct, pgdir)); | 
| 80 | DEFINE(LAST_SYSCALL, offsetof(struct thread_struct, last_syscall)); | ||
| 81 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) | 80 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) | 
| 82 | DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0)); | 81 | DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0)); | 
| 83 | DEFINE(PT_PTRACED, PT_PTRACED); | 82 | DEFINE(PT_PTRACED, PT_PTRACED); | 
| @@ -140,6 +139,7 @@ int main(void) | |||
| 140 | DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); | 139 | DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); | 
| 141 | DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr)); | 140 | DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr)); | 
| 142 | DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset)); | 141 | DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset)); | 
| 142 | DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save)); | ||
| 143 | 143 | ||
| 144 | DEFINE(SLBSHADOW_STACKVSID, | 144 | DEFINE(SLBSHADOW_STACKVSID, | 
| 145 | offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].vsid)); | 145 | offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].vsid)); | 
| diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index 3678997339d6..e7b684689e04 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c | |||
| @@ -161,33 +161,33 @@ int btext_initialize(struct device_node *np) | |||
| 161 | unsigned long address = 0; | 161 | unsigned long address = 0; | 
| 162 | const u32 *prop; | 162 | const u32 *prop; | 
| 163 | 163 | ||
| 164 | prop = get_property(np, "linux,bootx-width", NULL); | 164 | prop = of_get_property(np, "linux,bootx-width", NULL); | 
| 165 | if (prop == NULL) | 165 | if (prop == NULL) | 
| 166 | prop = get_property(np, "width", NULL); | 166 | prop = of_get_property(np, "width", NULL); | 
| 167 | if (prop == NULL) | 167 | if (prop == NULL) | 
| 168 | return -EINVAL; | 168 | return -EINVAL; | 
| 169 | width = *prop; | 169 | width = *prop; | 
| 170 | prop = get_property(np, "linux,bootx-height", NULL); | 170 | prop = of_get_property(np, "linux,bootx-height", NULL); | 
| 171 | if (prop == NULL) | 171 | if (prop == NULL) | 
| 172 | prop = get_property(np, "height", NULL); | 172 | prop = of_get_property(np, "height", NULL); | 
| 173 | if (prop == NULL) | 173 | if (prop == NULL) | 
| 174 | return -EINVAL; | 174 | return -EINVAL; | 
| 175 | height = *prop; | 175 | height = *prop; | 
| 176 | prop = get_property(np, "linux,bootx-depth", NULL); | 176 | prop = of_get_property(np, "linux,bootx-depth", NULL); | 
| 177 | if (prop == NULL) | 177 | if (prop == NULL) | 
| 178 | prop = get_property(np, "depth", NULL); | 178 | prop = of_get_property(np, "depth", NULL); | 
| 179 | if (prop == NULL) | 179 | if (prop == NULL) | 
| 180 | return -EINVAL; | 180 | return -EINVAL; | 
| 181 | depth = *prop; | 181 | depth = *prop; | 
| 182 | pitch = width * ((depth + 7) / 8); | 182 | pitch = width * ((depth + 7) / 8); | 
| 183 | prop = get_property(np, "linux,bootx-linebytes", NULL); | 183 | prop = of_get_property(np, "linux,bootx-linebytes", NULL); | 
| 184 | if (prop == NULL) | 184 | if (prop == NULL) | 
| 185 | prop = get_property(np, "linebytes", NULL); | 185 | prop = of_get_property(np, "linebytes", NULL); | 
| 186 | if (prop && *prop != 0xffffffffu) | 186 | if (prop && *prop != 0xffffffffu) | 
| 187 | pitch = *prop; | 187 | pitch = *prop; | 
| 188 | if (pitch == 1) | 188 | if (pitch == 1) | 
| 189 | pitch = 0x1000; | 189 | pitch = 0x1000; | 
| 190 | prop = get_property(np, "address", NULL); | 190 | prop = of_get_property(np, "address", NULL); | 
| 191 | if (prop) | 191 | if (prop) | 
| 192 | address = *prop; | 192 | address = *prop; | 
| 193 | 193 | ||
| @@ -219,7 +219,7 @@ int __init btext_find_display(int allow_nonstdout) | |||
| 219 | struct device_node *np = NULL; | 219 | struct device_node *np = NULL; | 
| 220 | int rc = -ENODEV; | 220 | int rc = -ENODEV; | 
| 221 | 221 | ||
| 222 | name = get_property(of_chosen, "linux,stdout-path", NULL); | 222 | name = of_get_property(of_chosen, "linux,stdout-path", NULL); | 
| 223 | if (name != NULL) { | 223 | if (name != NULL) { | 
| 224 | np = of_find_node_by_path(name); | 224 | np = of_find_node_by_path(name); | 
| 225 | if (np != NULL) { | 225 | if (np != NULL) { | 
| @@ -236,7 +236,7 @@ int __init btext_find_display(int allow_nonstdout) | |||
| 236 | return rc; | 236 | return rc; | 
| 237 | 237 | ||
| 238 | for (np = NULL; (np = of_find_node_by_type(np, "display"));) { | 238 | for (np = NULL; (np = of_find_node_by_type(np, "display"));) { | 
| 239 | if (get_property(np, "linux,opened", NULL)) { | 239 | if (of_get_property(np, "linux,opened", NULL)) { | 
| 240 | printk("trying %s ...\n", np->full_name); | 240 | printk("trying %s ...\n", np->full_name); | 
| 241 | rc = btext_initialize(np); | 241 | rc = btext_initialize(np); | 
| 242 | printk("result: %d\n", rc); | 242 | printk("result: %d\n", rc); | 
| diff --git a/arch/powerpc/kernel/cpu_setup_pa6t.S b/arch/powerpc/kernel/cpu_setup_pa6t.S index 4047be25c4d2..d62cb9cae4e9 100644 --- a/arch/powerpc/kernel/cpu_setup_pa6t.S +++ b/arch/powerpc/kernel/cpu_setup_pa6t.S | |||
| @@ -34,7 +34,7 @@ _GLOBAL(__setup_cpu_pa6t) | |||
| 34 | beqlr | 34 | beqlr | 
| 35 | 35 | ||
| 36 | mfspr r0,SPRN_HID5 | 36 | mfspr r0,SPRN_HID5 | 
| 37 | ori r0,r0,0x30 | 37 | ori r0,r0,0x38 | 
| 38 | mtspr SPRN_HID5,r0 | 38 | mtspr SPRN_HID5,r0 | 
| 39 | 39 | ||
| 40 | mfspr r0,SPRN_LPCR | 40 | mfspr r0,SPRN_LPCR | 
| diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index e4006dc087ca..9cb24d20f0f9 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
| @@ -389,6 +389,8 @@ static struct cpu_spec cpu_specs[] = { | |||
| 389 | .pmc_type = PPC_PMC_PA6T, | 389 | .pmc_type = PPC_PMC_PA6T, | 
| 390 | .cpu_setup = __setup_cpu_pa6t, | 390 | .cpu_setup = __setup_cpu_pa6t, | 
| 391 | .cpu_restore = __restore_cpu_pa6t, | 391 | .cpu_restore = __restore_cpu_pa6t, | 
| 392 | .oprofile_cpu_type = "ppc64/pa6t", | ||
| 393 | .oprofile_type = PPC_OPROFILE_PA6T, | ||
| 392 | .platform = "pa6t", | 394 | .platform = "pa6t", | 
| 393 | }, | 395 | }, | 
| 394 | { /* default match */ | 396 | { /* default match */ | 
| @@ -558,6 +560,18 @@ static struct cpu_spec cpu_specs[] = { | |||
| 558 | .cpu_setup = __setup_cpu_750cx, | 560 | .cpu_setup = __setup_cpu_750cx, | 
| 559 | .platform = "ppc750", | 561 | .platform = "ppc750", | 
| 560 | }, | 562 | }, | 
| 563 | { /* 750CL */ | ||
| 564 | .pvr_mask = 0xfffff0f0, | ||
| 565 | .pvr_value = 0x00087010, | ||
| 566 | .cpu_name = "750CL", | ||
| 567 | .cpu_features = CPU_FTRS_750CL, | ||
| 568 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | ||
| 569 | .icache_bsize = 32, | ||
| 570 | .dcache_bsize = 32, | ||
| 571 | .num_pmcs = 4, | ||
| 572 | .cpu_setup = __setup_cpu_750, | ||
| 573 | .platform = "ppc750", | ||
| 574 | }, | ||
| 561 | { /* 745/755 */ | 575 | { /* 745/755 */ | 
| 562 | .pvr_mask = 0xfffff000, | 576 | .pvr_mask = 0xfffff000, | 
| 563 | .pvr_value = 0x00083000, | 577 | .pvr_value = 0x00083000, | 
| diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index c03e829fee3c..c29d1652a421 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S | |||
| @@ -191,7 +191,6 @@ stack_ovf: | |||
| 191 | 0: | 191 | 0: | 
| 192 | 192 | ||
| 193 | _GLOBAL(DoSyscall) | 193 | _GLOBAL(DoSyscall) | 
| 194 | stw r0,THREAD+LAST_SYSCALL(r2) | ||
| 195 | stw r3,ORIG_GPR3(r1) | 194 | stw r3,ORIG_GPR3(r1) | 
| 196 | li r12,0 | 195 | li r12,0 | 
| 197 | stw r12,RESULT(r1) | 196 | stw r12,RESULT(r1) | 
| diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 97cedcd6c9b4..1111fcec7673 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
| @@ -278,8 +278,12 @@ exception_marker: | |||
| 278 | beq- 1f; \ | 278 | beq- 1f; \ | 
| 279 | ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ | 279 | ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ | 
| 280 | 1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \ | 280 | 1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \ | 
| 281 | bge- cr1,bad_stack; /* abort if it is */ \ | 281 | bge- cr1,2f; /* abort if it is */ \ | 
| 282 | std r9,_CCR(r1); /* save CR in stackframe */ \ | 282 | b 3f; \ | 
| 283 | 2: li r1,(n); /* will be reloaded later */ \ | ||
| 284 | sth r1,PACA_TRAP_SAVE(r13); \ | ||
| 285 | b bad_stack; \ | ||
| 286 | 3: std r9,_CCR(r1); /* save CR in stackframe */ \ | ||
| 283 | std r11,_NIP(r1); /* save SRR0 in stackframe */ \ | 287 | std r11,_NIP(r1); /* save SRR0 in stackframe */ \ | 
| 284 | std r12,_MSR(r1); /* save SRR1 in stackframe */ \ | 288 | std r12,_MSR(r1); /* save SRR1 in stackframe */ \ | 
| 285 | std r10,0(r1); /* make stack chain pointer */ \ | 289 | std r10,0(r1); /* make stack chain pointer */ \ | 
| @@ -940,6 +944,8 @@ bad_stack: | |||
| 940 | SAVE_2GPRS(7,r1) | 944 | SAVE_2GPRS(7,r1) | 
| 941 | SAVE_10GPRS(12,r1) | 945 | SAVE_10GPRS(12,r1) | 
| 942 | SAVE_10GPRS(22,r1) | 946 | SAVE_10GPRS(22,r1) | 
| 947 | lhz r12,PACA_TRAP_SAVE(r13) | ||
| 948 | std r12,_TRAP(r1) | ||
| 943 | addi r11,r1,INT_FRAME_SIZE | 949 | addi r11,r1,INT_FRAME_SIZE | 
| 944 | std r11,0(r1) | 950 | std r11,0(r1) | 
| 945 | li r12,0 | 951 | li r12,0 | 
| @@ -1555,7 +1561,6 @@ _GLOBAL(generic_secondary_smp_init) | |||
| 1555 | 1561 | ||
| 1556 | /* turn on 64-bit mode */ | 1562 | /* turn on 64-bit mode */ | 
| 1557 | bl .enable_64b_mode | 1563 | bl .enable_64b_mode | 
| 1558 | isync | ||
| 1559 | 1564 | ||
| 1560 | /* Set up a paca value for this processor. Since we have the | 1565 | /* Set up a paca value for this processor. Since we have the | 
| 1561 | * physical cpu id in r24, we need to search the pacas to find | 1566 | * physical cpu id in r24, we need to search the pacas to find | 
| @@ -1735,10 +1740,6 @@ _STATIC(__boot_from_prom) | |||
| 1735 | /* We never return */ | 1740 | /* We never return */ | 
| 1736 | trap | 1741 | trap | 
| 1737 | 1742 | ||
| 1738 | /* | ||
| 1739 | * At this point, r3 contains the physical address we are running at, | ||
| 1740 | * returned by prom_init() | ||
| 1741 | */ | ||
| 1742 | _STATIC(__after_prom_start) | 1743 | _STATIC(__after_prom_start) | 
| 1743 | 1744 | ||
| 1744 | /* | 1745 | /* | 
| @@ -1851,7 +1852,6 @@ __secondary_start_pmac_0: | |||
| 1851 | _GLOBAL(pmac_secondary_start) | 1852 | _GLOBAL(pmac_secondary_start) | 
| 1852 | /* turn on 64-bit mode */ | 1853 | /* turn on 64-bit mode */ | 
| 1853 | bl .enable_64b_mode | 1854 | bl .enable_64b_mode | 
| 1854 | isync | ||
| 1855 | 1855 | ||
| 1856 | /* Copy some CPU settings from CPU 0 */ | 1856 | /* Copy some CPU settings from CPU 0 */ | 
| 1857 | bl .__restore_cpu_ppc970 | 1857 | bl .__restore_cpu_ppc970 | 
| diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 82bd2f10770f..9a8c9af43b22 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c | |||
| @@ -2,36 +2,37 @@ | |||
| 2 | * IBM PowerPC IBM eBus Infrastructure Support. | 2 | * IBM PowerPC IBM eBus Infrastructure Support. | 
| 3 | * | 3 | * | 
| 4 | * Copyright (c) 2005 IBM Corporation | 4 | * Copyright (c) 2005 IBM Corporation | 
| 5 | * Joachim Fenkes <fenkes@de.ibm.com> | ||
| 5 | * Heiko J Schick <schickhj@de.ibm.com> | 6 | * Heiko J Schick <schickhj@de.ibm.com> | 
| 6 | * | 7 | * | 
| 7 | * All rights reserved. | 8 | * All rights reserved. | 
| 8 | * | 9 | * | 
| 9 | * This source code is distributed under a dual license of GPL v2.0 and OpenIB | 10 | * This source code is distributed under a dual license of GPL v2.0 and OpenIB | 
| 10 | * BSD. | 11 | * BSD. | 
| 11 | * | 12 | * | 
| 12 | * OpenIB BSD License | 13 | * OpenIB BSD License | 
| 13 | * | 14 | * | 
| 14 | * Redistribution and use in source and binary forms, with or without | 15 | * Redistribution and use in source and binary forms, with or without | 
| 15 | * modification, are permitted provided that the following conditions are met: | 16 | * modification, are permitted provided that the following conditions are met: | 
| 16 | * | 17 | * | 
| 17 | * Redistributions of source code must retain the above copyright notice, this | 18 | * Redistributions of source code must retain the above copyright notice, this | 
| 18 | * list of conditions and the following disclaimer. | 19 | * list of conditions and the following disclaimer. | 
| 19 | * | 20 | * | 
| 20 | * Redistributions in binary form must reproduce the above copyright notice, | 21 | * Redistributions in binary form must reproduce the above copyright notice, | 
| 21 | * this list of conditions and the following disclaimer in the documentation | 22 | * this list of conditions and the following disclaimer in the documentation | 
| 22 | * and/or other materials | 23 | * and/or other materials | 
| 23 | * provided with the distribution. | 24 | * provided with the distribution. | 
| 24 | * | 25 | * | 
| 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 
| 26 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 27 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
| 27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
| 28 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | 29 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | 
| 29 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 30 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 
| 30 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 31 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 
| 31 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | 32 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | 
| 32 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER | 33 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER | 
| 33 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 34 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 
| 34 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 35 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 
| 35 | * POSSIBILITY OF SUCH DAMAGE. | 36 | * POSSIBILITY OF SUCH DAMAGE. | 
| 36 | */ | 37 | */ | 
| 37 | 38 | ||
| @@ -43,19 +44,19 @@ | |||
| 43 | #include <asm/ibmebus.h> | 44 | #include <asm/ibmebus.h> | 
| 44 | #include <asm/abs_addr.h> | 45 | #include <asm/abs_addr.h> | 
| 45 | 46 | ||
| 46 | static struct ibmebus_dev ibmebus_bus_device = { /* fake "parent" device */ | 47 | static struct device ibmebus_bus_device = { /* fake "parent" device */ | 
| 47 | .name = ibmebus_bus_device.ofdev.dev.bus_id, | 48 | .bus_id = "ibmebus", | 
| 48 | .ofdev.dev.bus_id = "ibmebus", | ||
| 49 | .ofdev.dev.bus = &ibmebus_bus_type, | ||
| 50 | }; | 49 | }; | 
| 51 | 50 | ||
| 51 | struct bus_type ibmebus_bus_type; | ||
| 52 | |||
| 52 | static void *ibmebus_alloc_coherent(struct device *dev, | 53 | static void *ibmebus_alloc_coherent(struct device *dev, | 
| 53 | size_t size, | 54 | size_t size, | 
| 54 | dma_addr_t *dma_handle, | 55 | dma_addr_t *dma_handle, | 
| 55 | gfp_t flag) | 56 | gfp_t flag) | 
| 56 | { | 57 | { | 
| 57 | void *mem; | 58 | void *mem; | 
| 58 | 59 | ||
| 59 | mem = kmalloc(size, flag); | 60 | mem = kmalloc(size, flag); | 
| 60 | *dma_handle = (dma_addr_t)mem; | 61 | *dma_handle = (dma_addr_t)mem; | 
| 61 | 62 | ||
| @@ -63,7 +64,7 @@ static void *ibmebus_alloc_coherent(struct device *dev, | |||
| 63 | } | 64 | } | 
| 64 | 65 | ||
| 65 | static void ibmebus_free_coherent(struct device *dev, | 66 | static void ibmebus_free_coherent(struct device *dev, | 
| 66 | size_t size, void *vaddr, | 67 | size_t size, void *vaddr, | 
| 67 | dma_addr_t dma_handle) | 68 | dma_addr_t dma_handle) | 
| 68 | { | 69 | { | 
| 69 | kfree(vaddr); | 70 | kfree(vaddr); | 
| @@ -79,7 +80,7 @@ static dma_addr_t ibmebus_map_single(struct device *dev, | |||
| 79 | 80 | ||
| 80 | static void ibmebus_unmap_single(struct device *dev, | 81 | static void ibmebus_unmap_single(struct device *dev, | 
| 81 | dma_addr_t dma_addr, | 82 | dma_addr_t dma_addr, | 
| 82 | size_t size, | 83 | size_t size, | 
| 83 | enum dma_data_direction direction) | 84 | enum dma_data_direction direction) | 
| 84 | { | 85 | { | 
| 85 | return; | 86 | return; | 
| @@ -90,13 +91,13 @@ static int ibmebus_map_sg(struct device *dev, | |||
| 90 | int nents, enum dma_data_direction direction) | 91 | int nents, enum dma_data_direction direction) | 
| 91 | { | 92 | { | 
| 92 | int i; | 93 | int i; | 
| 93 | 94 | ||
| 94 | for (i = 0; i < nents; i++) { | 95 | for (i = 0; i < nents; i++) { | 
| 95 | sg[i].dma_address = (dma_addr_t)page_address(sg[i].page) | 96 | sg[i].dma_address = (dma_addr_t)page_address(sg[i].page) | 
| 96 | + sg[i].offset; | 97 | + sg[i].offset; | 
| 97 | sg[i].dma_length = sg[i].length; | 98 | sg[i].dma_length = sg[i].length; | 
| 98 | } | 99 | } | 
| 99 | 100 | ||
| 100 | return nents; | 101 | return nents; | 
| 101 | } | 102 | } | 
| 102 | 103 | ||
| @@ -128,15 +129,15 @@ static int ibmebus_bus_probe(struct device *dev) | |||
| 128 | struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver); | 129 | struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver); | 
| 129 | const struct of_device_id *id; | 130 | const struct of_device_id *id; | 
| 130 | int error = -ENODEV; | 131 | int error = -ENODEV; | 
| 131 | 132 | ||
| 132 | if (!ibmebusdrv->probe) | 133 | if (!ibmebusdrv->probe) | 
| 133 | return error; | 134 | return error; | 
| 134 | 135 | ||
| 135 | id = of_match_device(ibmebusdrv->id_table, &ibmebusdev->ofdev); | 136 | id = of_match_device(ibmebusdrv->id_table, &ibmebusdev->ofdev); | 
| 136 | if (id) { | 137 | if (id) { | 
| 137 | error = ibmebusdrv->probe(ibmebusdev, id); | 138 | error = ibmebusdrv->probe(ibmebusdev, id); | 
| 138 | } | 139 | } | 
| 139 | 140 | ||
| 140 | return error; | 141 | return error; | 
| 141 | } | 142 | } | 
| 142 | 143 | ||
| @@ -144,11 +145,11 @@ static int ibmebus_bus_remove(struct device *dev) | |||
| 144 | { | 145 | { | 
| 145 | struct ibmebus_dev *ibmebusdev = to_ibmebus_dev(dev); | 146 | struct ibmebus_dev *ibmebusdev = to_ibmebus_dev(dev); | 
| 146 | struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver); | 147 | struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver); | 
| 147 | 148 | ||
| 148 | if (ibmebusdrv->remove) { | 149 | if (ibmebusdrv->remove) { | 
| 149 | return ibmebusdrv->remove(ibmebusdev); | 150 | return ibmebusdrv->remove(ibmebusdev); | 
| 150 | } | 151 | } | 
| 151 | 152 | ||
| 152 | return 0; | 153 | return 0; | 
| 153 | } | 154 | } | 
| 154 | 155 | ||
| @@ -158,21 +159,12 @@ static void __devinit ibmebus_dev_release(struct device *dev) | |||
| 158 | kfree(to_ibmebus_dev(dev)); | 159 | kfree(to_ibmebus_dev(dev)); | 
| 159 | } | 160 | } | 
| 160 | 161 | ||
| 161 | static ssize_t ibmebusdev_show_name(struct device *dev, | 162 | static int __devinit ibmebus_register_device_common( | 
| 162 | struct device_attribute *attr, char *buf) | ||
| 163 | { | ||
| 164 | return sprintf(buf, "%s\n", to_ibmebus_dev(dev)->name); | ||
| 165 | } | ||
| 166 | static DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, ibmebusdev_show_name, | ||
| 167 | NULL); | ||
| 168 | |||
| 169 | static struct ibmebus_dev* __devinit ibmebus_register_device_common( | ||
| 170 | struct ibmebus_dev *dev, const char *name) | 163 | struct ibmebus_dev *dev, const char *name) | 
| 171 | { | 164 | { | 
| 172 | int err = 0; | 165 | int err = 0; | 
| 173 | 166 | ||
| 174 | dev->name = name; | 167 | dev->ofdev.dev.parent = &ibmebus_bus_device; | 
| 175 | dev->ofdev.dev.parent = &ibmebus_bus_device.ofdev.dev; | ||
| 176 | dev->ofdev.dev.bus = &ibmebus_bus_type; | 168 | dev->ofdev.dev.bus = &ibmebus_bus_type; | 
| 177 | dev->ofdev.dev.release = ibmebus_dev_release; | 169 | dev->ofdev.dev.release = ibmebus_dev_release; | 
| 178 | 170 | ||
| @@ -181,17 +173,15 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_common( | |||
| 181 | dev->ofdev.dev.archdata.numa_node = of_node_to_nid(dev->ofdev.node); | 173 | dev->ofdev.dev.archdata.numa_node = of_node_to_nid(dev->ofdev.node); | 
| 182 | 174 | ||
| 183 | /* An ibmebusdev is based on a of_device. We have to change the | 175 | /* An ibmebusdev is based on a of_device. We have to change the | 
| 184 | * bus type to use our own DMA mapping operations. | 176 | * bus type to use our own DMA mapping operations. | 
| 185 | */ | 177 | */ | 
| 186 | if ((err = of_device_register(&dev->ofdev)) != 0) { | 178 | if ((err = of_device_register(&dev->ofdev)) != 0) { | 
| 187 | printk(KERN_ERR "%s: failed to register device (%d).\n", | 179 | printk(KERN_ERR "%s: failed to register device (%d).\n", | 
| 188 | __FUNCTION__, err); | 180 | __FUNCTION__, err); | 
| 189 | return NULL; | 181 | return -ENODEV; | 
| 190 | } | 182 | } | 
| 191 | 183 | ||
| 192 | device_create_file(&dev->ofdev.dev, &dev_attr_name); | 184 | return 0; | 
| 193 | |||
| 194 | return dev; | ||
| 195 | } | 185 | } | 
| 196 | 186 | ||
| 197 | static struct ibmebus_dev* __devinit ibmebus_register_device_node( | 187 | static struct ibmebus_dev* __devinit ibmebus_register_device_node( | 
| @@ -201,35 +191,35 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_node( | |||
| 201 | const char *loc_code; | 191 | const char *loc_code; | 
| 202 | int length; | 192 | int length; | 
| 203 | 193 | ||
| 204 | loc_code = get_property(dn, "ibm,loc-code", NULL); | 194 | loc_code = of_get_property(dn, "ibm,loc-code", NULL); | 
| 205 | if (!loc_code) { | 195 | if (!loc_code) { | 
| 206 | printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n", | 196 | printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n", | 
| 207 | __FUNCTION__, dn->name ? dn->name : "<unknown>"); | 197 | __FUNCTION__, dn->name ? dn->name : "<unknown>"); | 
| 208 | return NULL; | 198 | return ERR_PTR(-EINVAL); | 
| 209 | } | 199 | } | 
| 210 | 200 | ||
| 211 | if (strlen(loc_code) == 0) { | 201 | if (strlen(loc_code) == 0) { | 
| 212 | printk(KERN_WARNING "%s: 'ibm,loc-code' is invalid\n", | 202 | printk(KERN_WARNING "%s: 'ibm,loc-code' is invalid\n", | 
| 213 | __FUNCTION__); | 203 | __FUNCTION__); | 
| 214 | return NULL; | 204 | return ERR_PTR(-EINVAL); | 
| 215 | } | 205 | } | 
| 216 | 206 | ||
| 217 | dev = kzalloc(sizeof(struct ibmebus_dev), GFP_KERNEL); | 207 | dev = kzalloc(sizeof(struct ibmebus_dev), GFP_KERNEL); | 
| 218 | if (!dev) { | 208 | if (!dev) { | 
| 219 | return NULL; | 209 | return ERR_PTR(-ENOMEM); | 
| 220 | } | 210 | } | 
| 221 | 211 | ||
| 222 | dev->ofdev.node = of_node_get(dn); | 212 | dev->ofdev.node = of_node_get(dn); | 
| 223 | 213 | ||
| 224 | length = strlen(loc_code); | 214 | length = strlen(loc_code); | 
| 225 | memcpy(dev->ofdev.dev.bus_id, loc_code | 215 | memcpy(dev->ofdev.dev.bus_id, loc_code | 
| 226 | + (length - min(length, BUS_ID_SIZE - 1)), | 216 | + (length - min(length, BUS_ID_SIZE - 1)), | 
| 227 | min(length, BUS_ID_SIZE - 1)); | 217 | min(length, BUS_ID_SIZE - 1)); | 
| 228 | 218 | ||
| 229 | /* Register with generic device framework. */ | 219 | /* Register with generic device framework. */ | 
| 230 | if (ibmebus_register_device_common(dev, dn->name) == NULL) { | 220 | if (ibmebus_register_device_common(dev, dn->name) != 0) { | 
| 231 | kfree(dev); | 221 | kfree(dev); | 
| 232 | return NULL; | 222 | return ERR_PTR(-ENODEV); | 
| 233 | } | 223 | } | 
| 234 | 224 | ||
| 235 | return dev; | 225 | return dev; | 
| @@ -238,17 +228,16 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_node( | |||
| 238 | static void ibmebus_probe_of_nodes(char* name) | 228 | static void ibmebus_probe_of_nodes(char* name) | 
| 239 | { | 229 | { | 
| 240 | struct device_node *dn = NULL; | 230 | struct device_node *dn = NULL; | 
| 241 | 231 | ||
| 242 | while ((dn = of_find_node_by_name(dn, name))) { | 232 | while ((dn = of_find_node_by_name(dn, name))) { | 
| 243 | if (ibmebus_register_device_node(dn) == NULL) { | 233 | if (IS_ERR(ibmebus_register_device_node(dn))) { | 
| 244 | of_node_put(dn); | 234 | of_node_put(dn); | 
| 245 | |||
| 246 | return; | 235 | return; | 
| 247 | } | 236 | } | 
| 248 | } | 237 | } | 
| 249 | 238 | ||
| 250 | of_node_put(dn); | 239 | of_node_put(dn); | 
| 251 | 240 | ||
| 252 | return; | 241 | return; | 
| 253 | } | 242 | } | 
| 254 | 243 | ||
| @@ -262,17 +251,21 @@ static void ibmebus_add_devices_by_id(struct of_device_id *idt) | |||
| 262 | return; | 251 | return; | 
| 263 | } | 252 | } | 
| 264 | 253 | ||
| 265 | static int ibmebus_match_helper(struct device *dev, void *data) | 254 | static int ibmebus_match_name(struct device *dev, void *data) | 
| 266 | { | 255 | { | 
| 267 | if (strcmp((char*)data, to_ibmebus_dev(dev)->name) == 0) | 256 | const struct ibmebus_dev *ebus_dev = to_ibmebus_dev(dev); | 
| 257 | const char *name; | ||
| 258 | |||
| 259 | name = of_get_property(ebus_dev->ofdev.node, "name", NULL); | ||
| 260 | |||
| 261 | if (name && (strcmp(data, name) == 0)) | ||
| 268 | return 1; | 262 | return 1; | 
| 269 | 263 | ||
| 270 | return 0; | 264 | return 0; | 
| 271 | } | 265 | } | 
| 272 | 266 | ||
| 273 | static int ibmebus_unregister_device(struct device *dev) | 267 | static int ibmebus_unregister_device(struct device *dev) | 
| 274 | { | 268 | { | 
| 275 | device_remove_file(dev, &dev_attr_name); | ||
| 276 | of_device_unregister(to_of_device(dev)); | 269 | of_device_unregister(to_of_device(dev)); | 
| 277 | 270 | ||
| 278 | return 0; | 271 | return 0; | 
| @@ -281,17 +274,16 @@ static int ibmebus_unregister_device(struct device *dev) | |||
| 281 | static void ibmebus_remove_devices_by_id(struct of_device_id *idt) | 274 | static void ibmebus_remove_devices_by_id(struct of_device_id *idt) | 
| 282 | { | 275 | { | 
| 283 | struct device *dev; | 276 | struct device *dev; | 
| 284 | 277 | ||
| 285 | while (strlen(idt->name) > 0) { | 278 | while (strlen(idt->name) > 0) { | 
| 286 | while ((dev = bus_find_device(&ibmebus_bus_type, NULL, | 279 | while ((dev = bus_find_device(&ibmebus_bus_type, NULL, | 
| 287 | (void*)idt->name, | 280 | (void*)idt->name, | 
| 288 | ibmebus_match_helper))) { | 281 | ibmebus_match_name))) { | 
| 289 | ibmebus_unregister_device(dev); | 282 | ibmebus_unregister_device(dev); | 
| 290 | } | 283 | } | 
| 291 | idt++; | 284 | idt++; | 
| 292 | |||
| 293 | } | 285 | } | 
| 294 | 286 | ||
| 295 | return; | 287 | return; | 
| 296 | } | 288 | } | 
| 297 | 289 | ||
| @@ -307,30 +299,33 @@ int ibmebus_register_driver(struct ibmebus_driver *drv) | |||
| 307 | if ((err = driver_register(&drv->driver) != 0)) | 299 | if ((err = driver_register(&drv->driver) != 0)) | 
| 308 | return err; | 300 | return err; | 
| 309 | 301 | ||
| 302 | /* remove all supported devices first, in case someone | ||
| 303 | * probed them manually before registering the driver */ | ||
| 304 | ibmebus_remove_devices_by_id(drv->id_table); | ||
| 310 | ibmebus_add_devices_by_id(drv->id_table); | 305 | ibmebus_add_devices_by_id(drv->id_table); | 
| 311 | 306 | ||
| 312 | return 0; | 307 | return 0; | 
| 313 | } | 308 | } | 
| 314 | EXPORT_SYMBOL(ibmebus_register_driver); | 309 | EXPORT_SYMBOL(ibmebus_register_driver); | 
| 315 | 310 | ||
| 316 | void ibmebus_unregister_driver(struct ibmebus_driver *drv) | 311 | void ibmebus_unregister_driver(struct ibmebus_driver *drv) | 
| 317 | { | 312 | { | 
| 318 | driver_unregister(&drv->driver); | 313 | driver_unregister(&drv->driver); | 
| 319 | ibmebus_remove_devices_by_id(drv->id_table); | 314 | ibmebus_remove_devices_by_id(drv->id_table); | 
| 320 | } | 315 | } | 
| 321 | EXPORT_SYMBOL(ibmebus_unregister_driver); | 316 | EXPORT_SYMBOL(ibmebus_unregister_driver); | 
| 322 | 317 | ||
| 323 | int ibmebus_request_irq(struct ibmebus_dev *dev, | 318 | int ibmebus_request_irq(struct ibmebus_dev *dev, | 
| 324 | u32 ist, | 319 | u32 ist, | 
| 325 | irq_handler_t handler, | 320 | irq_handler_t handler, | 
| 326 | unsigned long irq_flags, const char * devname, | 321 | unsigned long irq_flags, const char * devname, | 
| 327 | void *dev_id) | 322 | void *dev_id) | 
| 328 | { | 323 | { | 
| 329 | unsigned int irq = irq_create_mapping(NULL, ist); | 324 | unsigned int irq = irq_create_mapping(NULL, ist); | 
| 330 | 325 | ||
| 331 | if (irq == NO_IRQ) | 326 | if (irq == NO_IRQ) | 
| 332 | return -EINVAL; | 327 | return -EINVAL; | 
| 333 | 328 | ||
| 334 | return request_irq(irq, handler, | 329 | return request_irq(irq, handler, | 
| 335 | irq_flags, devname, dev_id); | 330 | irq_flags, devname, dev_id); | 
| 336 | } | 331 | } | 
| @@ -339,56 +334,163 @@ EXPORT_SYMBOL(ibmebus_request_irq); | |||
| 339 | void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id) | 334 | void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id) | 
| 340 | { | 335 | { | 
| 341 | unsigned int irq = irq_find_mapping(NULL, ist); | 336 | unsigned int irq = irq_find_mapping(NULL, ist); | 
| 342 | 337 | ||
| 343 | free_irq(irq, dev_id); | 338 | free_irq(irq, dev_id); | 
| 344 | } | 339 | } | 
| 345 | EXPORT_SYMBOL(ibmebus_free_irq); | 340 | EXPORT_SYMBOL(ibmebus_free_irq); | 
| 346 | 341 | ||
| 347 | static int ibmebus_bus_match(struct device *dev, struct device_driver *drv) | 342 | static int ibmebus_bus_match(struct device *dev, struct device_driver *drv) | 
| 348 | { | 343 | { | 
| 349 | const struct ibmebus_dev *ebus_dev = to_ibmebus_dev(dev); | 344 | const struct ibmebus_dev *ebus_dev = to_ibmebus_dev(dev); | 
| 350 | struct ibmebus_driver *ebus_drv = to_ibmebus_driver(drv); | 345 | struct ibmebus_driver *ebus_drv = to_ibmebus_driver(drv); | 
| 351 | const struct of_device_id *ids = ebus_drv->id_table; | 346 | const struct of_device_id *ids = ebus_drv->id_table; | 
| 352 | const struct of_device_id *found_id; | 347 | const struct of_device_id *found_id; | 
| 353 | 348 | ||
| 354 | if (!ids) | 349 | if (!ids) | 
| 355 | return 0; | 350 | return 0; | 
| 356 | 351 | ||
| 357 | found_id = of_match_device(ids, &ebus_dev->ofdev); | 352 | found_id = of_match_device(ids, &ebus_dev->ofdev); | 
| 358 | if (found_id) | 353 | if (found_id) | 
| 359 | return 1; | 354 | return 1; | 
| 360 | 355 | ||
| 361 | return 0; | 356 | return 0; | 
| 362 | } | 357 | } | 
| 363 | 358 | ||
| 359 | static ssize_t name_show(struct device *dev, | ||
| 360 | struct device_attribute *attr, char *buf) | ||
| 361 | { | ||
| 362 | struct ibmebus_dev *ebus_dev = to_ibmebus_dev(dev); | ||
| 363 | const char *name = of_get_property(ebus_dev->ofdev.node, "name", NULL); | ||
| 364 | return sprintf(buf, "%s\n", name); | ||
| 365 | } | ||
| 366 | |||
| 367 | static struct device_attribute ibmebus_dev_attrs[] = { | ||
| 368 | __ATTR_RO(name), | ||
| 369 | __ATTR_NULL | ||
| 370 | }; | ||
| 371 | |||
| 372 | static int ibmebus_match_path(struct device *dev, void *data) | ||
| 373 | { | ||
| 374 | int rc; | ||
| 375 | struct device_node *dn = | ||
| 376 | of_node_get(to_ibmebus_dev(dev)->ofdev.node); | ||
| 377 | |||
| 378 | rc = (dn->full_name && (strcasecmp((char*)data, dn->full_name) == 0)); | ||
| 379 | |||
| 380 | of_node_put(dn); | ||
| 381 | return rc; | ||
| 382 | } | ||
| 383 | |||
| 384 | static char *ibmebus_chomp(const char *in, size_t count) | ||
| 385 | { | ||
| 386 | char *out = (char*)kmalloc(count + 1, GFP_KERNEL); | ||
| 387 | if (!out) | ||
| 388 | return NULL; | ||
| 389 | |||
| 390 | memcpy(out, in, count); | ||
| 391 | out[count] = '\0'; | ||
| 392 | if (out[count - 1] == '\n') | ||
| 393 | out[count - 1] = '\0'; | ||
| 394 | |||
| 395 | return out; | ||
| 396 | } | ||
| 397 | |||
| 398 | static ssize_t ibmebus_store_probe(struct bus_type *bus, | ||
| 399 | const char *buf, size_t count) | ||
| 400 | { | ||
| 401 | struct device_node *dn = NULL; | ||
| 402 | struct ibmebus_dev *dev; | ||
| 403 | char *path; | ||
| 404 | ssize_t rc; | ||
| 405 | |||
| 406 | path = ibmebus_chomp(buf, count); | ||
| 407 | if (!path) | ||
| 408 | return -ENOMEM; | ||
| 409 | |||
| 410 | if (bus_find_device(&ibmebus_bus_type, NULL, path, | ||
| 411 | ibmebus_match_path)) { | ||
| 412 | printk(KERN_WARNING "%s: %s has already been probed\n", | ||
| 413 | __FUNCTION__, path); | ||
| 414 | rc = -EINVAL; | ||
| 415 | goto out; | ||
| 416 | } | ||
| 417 | |||
| 418 | if ((dn = of_find_node_by_path(path))) { | ||
| 419 | dev = ibmebus_register_device_node(dn); | ||
| 420 | of_node_put(dn); | ||
| 421 | rc = IS_ERR(dev) ? PTR_ERR(dev) : count; | ||
| 422 | } else { | ||
| 423 | printk(KERN_WARNING "%s: no such device node: %s\n", | ||
| 424 | __FUNCTION__, path); | ||
| 425 | rc = -ENODEV; | ||
| 426 | } | ||
| 427 | |||
| 428 | out: | ||
| 429 | kfree(path); | ||
| 430 | return rc; | ||
| 431 | } | ||
| 432 | |||
| 433 | static ssize_t ibmebus_store_remove(struct bus_type *bus, | ||
| 434 | const char *buf, size_t count) | ||
| 435 | { | ||
| 436 | struct device *dev; | ||
| 437 | char *path; | ||
| 438 | |||
| 439 | path = ibmebus_chomp(buf, count); | ||
| 440 | if (!path) | ||
| 441 | return -ENOMEM; | ||
| 442 | |||
| 443 | if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path, | ||
| 444 | ibmebus_match_path))) { | ||
| 445 | ibmebus_unregister_device(dev); | ||
| 446 | |||
| 447 | kfree(path); | ||
| 448 | return count; | ||
| 449 | } else { | ||
| 450 | printk(KERN_WARNING "%s: %s not on the bus\n", | ||
| 451 | __FUNCTION__, path); | ||
| 452 | |||
| 453 | kfree(path); | ||
| 454 | return -ENODEV; | ||
| 455 | } | ||
| 456 | } | ||
| 457 | |||
| 458 | static struct bus_attribute ibmebus_bus_attrs[] = { | ||
| 459 | __ATTR(probe, S_IWUSR, NULL, ibmebus_store_probe), | ||
| 460 | __ATTR(remove, S_IWUSR, NULL, ibmebus_store_remove), | ||
| 461 | __ATTR_NULL | ||
| 462 | }; | ||
| 463 | |||
| 364 | struct bus_type ibmebus_bus_type = { | 464 | struct bus_type ibmebus_bus_type = { | 
| 365 | .name = "ibmebus", | 465 | .name = "ibmebus", | 
| 366 | .match = ibmebus_bus_match, | 466 | .match = ibmebus_bus_match, | 
| 467 | .dev_attrs = ibmebus_dev_attrs, | ||
| 468 | .bus_attrs = ibmebus_bus_attrs | ||
| 367 | }; | 469 | }; | 
| 368 | EXPORT_SYMBOL(ibmebus_bus_type); | 470 | EXPORT_SYMBOL(ibmebus_bus_type); | 
| 369 | 471 | ||
| 370 | static int __init ibmebus_bus_init(void) | 472 | static int __init ibmebus_bus_init(void) | 
| 371 | { | 473 | { | 
| 372 | int err; | 474 | int err; | 
| 373 | 475 | ||
| 374 | printk(KERN_INFO "IBM eBus Device Driver\n"); | 476 | printk(KERN_INFO "IBM eBus Device Driver\n"); | 
| 375 | 477 | ||
| 376 | err = bus_register(&ibmebus_bus_type); | 478 | err = bus_register(&ibmebus_bus_type); | 
| 377 | if (err) { | 479 | if (err) { | 
| 378 | printk(KERN_ERR ":%s: failed to register IBM eBus.\n", | 480 | printk(KERN_ERR ":%s: failed to register IBM eBus.\n", | 
| 379 | __FUNCTION__); | 481 | __FUNCTION__); | 
| 380 | return err; | 482 | return err; | 
| 381 | } | 483 | } | 
| 382 | 484 | ||
| 383 | err = device_register(&ibmebus_bus_device.ofdev.dev); | 485 | err = device_register(&ibmebus_bus_device); | 
| 384 | if (err) { | 486 | if (err) { | 
| 385 | printk(KERN_WARNING "%s: device_register returned %i\n", | 487 | printk(KERN_WARNING "%s: device_register returned %i\n", | 
| 386 | __FUNCTION__, err); | 488 | __FUNCTION__, err); | 
| 387 | bus_unregister(&ibmebus_bus_type); | 489 | bus_unregister(&ibmebus_bus_type); | 
| 388 | 490 | ||
| 389 | return err; | 491 | return err; | 
| 390 | } | 492 | } | 
| 391 | 493 | ||
| 392 | return 0; | 494 | return 0; | 
| 393 | } | 495 | } | 
| 394 | __initcall(ibmebus_bus_init); | 496 | __initcall(ibmebus_bus_init); | 
| diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 95edad4faf26..c08ceca6277d 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
| @@ -47,6 +47,8 @@ static int novmerge = 0; | |||
| 47 | static int novmerge = 1; | 47 | static int novmerge = 1; | 
| 48 | #endif | 48 | #endif | 
| 49 | 49 | ||
| 50 | static int protect4gb = 1; | ||
| 51 | |||
| 50 | static inline unsigned long iommu_num_pages(unsigned long vaddr, | 52 | static inline unsigned long iommu_num_pages(unsigned long vaddr, | 
| 51 | unsigned long slen) | 53 | unsigned long slen) | 
| 52 | { | 54 | { | 
| @@ -58,6 +60,16 @@ static inline unsigned long iommu_num_pages(unsigned long vaddr, | |||
| 58 | return npages; | 60 | return npages; | 
| 59 | } | 61 | } | 
| 60 | 62 | ||
| 63 | static int __init setup_protect4gb(char *str) | ||
| 64 | { | ||
| 65 | if (strcmp(str, "on") == 0) | ||
| 66 | protect4gb = 1; | ||
| 67 | else if (strcmp(str, "off") == 0) | ||
| 68 | protect4gb = 0; | ||
| 69 | |||
| 70 | return 1; | ||
| 71 | } | ||
| 72 | |||
| 61 | static int __init setup_iommu(char *str) | 73 | static int __init setup_iommu(char *str) | 
| 62 | { | 74 | { | 
| 63 | if (!strcmp(str, "novmerge")) | 75 | if (!strcmp(str, "novmerge")) | 
| @@ -67,6 +79,7 @@ static int __init setup_iommu(char *str) | |||
| 67 | return 1; | 79 | return 1; | 
| 68 | } | 80 | } | 
| 69 | 81 | ||
| 82 | __setup("protect4gb=", setup_protect4gb); | ||
| 70 | __setup("iommu=", setup_iommu); | 83 | __setup("iommu=", setup_iommu); | 
| 71 | 84 | ||
| 72 | static unsigned long iommu_range_alloc(struct iommu_table *tbl, | 85 | static unsigned long iommu_range_alloc(struct iommu_table *tbl, | 
| @@ -429,6 +442,9 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, | |||
| 429 | struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) | 442 | struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) | 
| 430 | { | 443 | { | 
| 431 | unsigned long sz; | 444 | unsigned long sz; | 
| 445 | unsigned long start_index, end_index; | ||
| 446 | unsigned long entries_per_4g; | ||
| 447 | unsigned long index; | ||
| 432 | static int welcomed = 0; | 448 | static int welcomed = 0; | 
| 433 | struct page *page; | 449 | struct page *page; | 
| 434 | 450 | ||
| @@ -450,7 +466,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) | |||
| 450 | 466 | ||
| 451 | #ifdef CONFIG_CRASH_DUMP | 467 | #ifdef CONFIG_CRASH_DUMP | 
| 452 | if (ppc_md.tce_get) { | 468 | if (ppc_md.tce_get) { | 
| 453 | unsigned long index, tceval; | 469 | unsigned long tceval; | 
| 454 | unsigned long tcecount = 0; | 470 | unsigned long tcecount = 0; | 
| 455 | 471 | ||
| 456 | /* | 472 | /* | 
| @@ -480,6 +496,23 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) | |||
| 480 | ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); | 496 | ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); | 
| 481 | #endif | 497 | #endif | 
| 482 | 498 | ||
| 499 | /* | ||
| 500 | * DMA cannot cross 4 GB boundary. Mark last entry of each 4 | ||
| 501 | * GB chunk as reserved. | ||
| 502 | */ | ||
| 503 | if (protect4gb) { | ||
| 504 | entries_per_4g = 0x100000000l >> IOMMU_PAGE_SHIFT; | ||
| 505 | |||
| 506 | /* Mark the last bit before a 4GB boundary as used */ | ||
| 507 | start_index = tbl->it_offset | (entries_per_4g - 1); | ||
| 508 | start_index -= tbl->it_offset; | ||
| 509 | |||
| 510 | end_index = tbl->it_size; | ||
| 511 | |||
| 512 | for (index = start_index; index < end_index - 1; index += entries_per_4g) | ||
| 513 | __set_bit(index, tbl->it_map); | ||
| 514 | } | ||
| 515 | |||
| 483 | if (!welcomed) { | 516 | if (!welcomed) { | 
| 484 | printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", | 517 | printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", | 
| 485 | novmerge ? "disabled" : "enabled"); | 518 | novmerge ? "disabled" : "enabled"); | 
| diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 100930826850..6c83fe229e60 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
| @@ -394,7 +394,7 @@ EXPORT_SYMBOL(do_softirq); | |||
| 394 | #ifdef CONFIG_PPC_MERGE | 394 | #ifdef CONFIG_PPC_MERGE | 
| 395 | 395 | ||
| 396 | static LIST_HEAD(irq_hosts); | 396 | static LIST_HEAD(irq_hosts); | 
| 397 | static spinlock_t irq_big_lock = SPIN_LOCK_UNLOCKED; | 397 | static DEFINE_SPINLOCK(irq_big_lock); | 
| 398 | static DEFINE_PER_CPU(unsigned int, irq_radix_reader); | 398 | static DEFINE_PER_CPU(unsigned int, irq_radix_reader); | 
| 399 | static unsigned int irq_radix_writer; | 399 | static unsigned int irq_radix_writer; | 
| 400 | struct irq_map_entry irq_map[NR_IRQS]; | 400 | struct irq_map_entry irq_map[NR_IRQS]; | 
| diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index dd2886f97e98..ef647e7a9dc3 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c | |||
| @@ -59,12 +59,14 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) | |||
| 59 | } | 59 | } | 
| 60 | 60 | ||
| 61 | if (!ret) { | 61 | if (!ret) { | 
| 62 | memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); | 62 | memcpy(p->ainsn.insn, p->addr, | 
| 63 | MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); | ||
| 63 | p->opcode = *p->addr; | 64 | p->opcode = *p->addr; | 
| 64 | flush_icache_range((unsigned long)p->ainsn.insn, | 65 | flush_icache_range((unsigned long)p->ainsn.insn, | 
| 65 | (unsigned long)p->ainsn.insn + sizeof(kprobe_opcode_t)); | 66 | (unsigned long)p->ainsn.insn + sizeof(kprobe_opcode_t)); | 
| 66 | } | 67 | } | 
| 67 | 68 | ||
| 69 | p->ainsn.boostable = 0; | ||
| 68 | return ret; | 70 | return ret; | 
| 69 | } | 71 | } | 
| 70 | 72 | ||
| @@ -232,6 +234,38 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
| 232 | return 1; | 234 | return 1; | 
| 233 | 235 | ||
| 234 | ss_probe: | 236 | ss_probe: | 
| 237 | if (p->ainsn.boostable >= 0) { | ||
| 238 | unsigned int insn = *p->ainsn.insn; | ||
| 239 | |||
| 240 | /* regs->nip is also adjusted if emulate_step returns 1 */ | ||
| 241 | ret = emulate_step(regs, insn); | ||
| 242 | if (ret > 0) { | ||
| 243 | /* | ||
| 244 | * Once this instruction has been boosted | ||
| 245 | * successfully, set the boostable flag | ||
| 246 | */ | ||
| 247 | if (unlikely(p->ainsn.boostable == 0)) | ||
| 248 | p->ainsn.boostable = 1; | ||
| 249 | |||
| 250 | if (p->post_handler) | ||
| 251 | p->post_handler(p, regs, 0); | ||
| 252 | |||
| 253 | kcb->kprobe_status = KPROBE_HIT_SSDONE; | ||
| 254 | reset_current_kprobe(); | ||
| 255 | preempt_enable_no_resched(); | ||
| 256 | return 1; | ||
| 257 | } else if (ret < 0) { | ||
| 258 | /* | ||
| 259 | * We don't allow kprobes on mtmsr(d)/rfi(d), etc. | ||
| 260 | * So, we should never get here... but, its still | ||
| 261 | * good to catch them, just in case... | ||
| 262 | */ | ||
| 263 | printk("Can't step on instruction %x\n", insn); | ||
| 264 | BUG(); | ||
| 265 | } else if (ret == 0) | ||
| 266 | /* This instruction can't be boosted */ | ||
| 267 | p->ainsn.boostable = -1; | ||
| 268 | } | ||
| 235 | prepare_singlestep(p, regs); | 269 | prepare_singlestep(p, regs); | 
| 236 | kcb->kprobe_status = KPROBE_HIT_SS; | 270 | kcb->kprobe_status = KPROBE_HIT_SS; | 
| 237 | return 1; | 271 | return 1; | 
| diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 325f490a10cc..63dd2c3ad95e 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c | |||
| @@ -44,12 +44,12 @@ static int __init add_legacy_port(struct device_node *np, int want_index, | |||
| 44 | int index; | 44 | int index; | 
| 45 | 45 | ||
| 46 | /* get clock freq. if present */ | 46 | /* get clock freq. if present */ | 
| 47 | clk = get_property(np, "clock-frequency", NULL); | 47 | clk = of_get_property(np, "clock-frequency", NULL); | 
| 48 | if (clk && *clk) | 48 | if (clk && *clk) | 
| 49 | clock = *clk; | 49 | clock = *clk; | 
| 50 | 50 | ||
| 51 | /* get default speed if present */ | 51 | /* get default speed if present */ | 
| 52 | spd = get_property(np, "current-speed", NULL); | 52 | spd = of_get_property(np, "current-speed", NULL); | 
| 53 | 53 | ||
| 54 | /* If we have a location index, then try to use it */ | 54 | /* If we have a location index, then try to use it */ | 
| 55 | if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS) | 55 | if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS) | 
| @@ -121,11 +121,11 @@ static int __init add_legacy_soc_port(struct device_node *np, | |||
| 121 | /* We only support ports that have a clock frequency properly | 121 | /* We only support ports that have a clock frequency properly | 
| 122 | * encoded in the device-tree. | 122 | * encoded in the device-tree. | 
| 123 | */ | 123 | */ | 
| 124 | if (get_property(np, "clock-frequency", NULL) == NULL) | 124 | if (of_get_property(np, "clock-frequency", NULL) == NULL) | 
| 125 | return -1; | 125 | return -1; | 
| 126 | 126 | ||
| 127 | /* if rtas uses this device, don't try to use it as well */ | 127 | /* if rtas uses this device, don't try to use it as well */ | 
| 128 | if (get_property(np, "used-by-rtas", NULL) != NULL) | 128 | if (of_get_property(np, "used-by-rtas", NULL) != NULL) | 
| 129 | return -1; | 129 | return -1; | 
| 130 | 130 | ||
| 131 | /* Get the address */ | 131 | /* Get the address */ | 
| @@ -157,7 +157,7 @@ static int __init add_legacy_isa_port(struct device_node *np, | |||
| 157 | DBG(" -> add_legacy_isa_port(%s)\n", np->full_name); | 157 | DBG(" -> add_legacy_isa_port(%s)\n", np->full_name); | 
| 158 | 158 | ||
| 159 | /* Get the ISA port number */ | 159 | /* Get the ISA port number */ | 
| 160 | reg = get_property(np, "reg", NULL); | 160 | reg = of_get_property(np, "reg", NULL); | 
| 161 | if (reg == NULL) | 161 | if (reg == NULL) | 
| 162 | return -1; | 162 | return -1; | 
| 163 | 163 | ||
| @@ -168,7 +168,7 @@ static int __init add_legacy_isa_port(struct device_node *np, | |||
| 168 | /* Now look for an "ibm,aix-loc" property that gives us ordering | 168 | /* Now look for an "ibm,aix-loc" property that gives us ordering | 
| 169 | * if any... | 169 | * if any... | 
| 170 | */ | 170 | */ | 
| 171 | typep = get_property(np, "ibm,aix-loc", NULL); | 171 | typep = of_get_property(np, "ibm,aix-loc", NULL); | 
| 172 | 172 | ||
| 173 | /* If we have a location index, then use it */ | 173 | /* If we have a location index, then use it */ | 
| 174 | if (typep && *typep == 'S') | 174 | if (typep && *typep == 'S') | 
| @@ -206,7 +206,7 @@ static int __init add_legacy_pci_port(struct device_node *np, | |||
| 206 | * compatible UARTs on PCI need all sort of quirks (port offsets | 206 | * compatible UARTs on PCI need all sort of quirks (port offsets | 
| 207 | * etc...) that this code doesn't know about | 207 | * etc...) that this code doesn't know about | 
| 208 | */ | 208 | */ | 
| 209 | if (get_property(np, "clock-frequency", NULL) == NULL) | 209 | if (of_get_property(np, "clock-frequency", NULL) == NULL) | 
| 210 | return -1; | 210 | return -1; | 
| 211 | 211 | ||
| 212 | /* Get the PCI address. Assume BAR 0 */ | 212 | /* Get the PCI address. Assume BAR 0 */ | 
| @@ -232,7 +232,7 @@ static int __init add_legacy_pci_port(struct device_node *np, | |||
| 232 | * we get to their "reg" property | 232 | * we get to their "reg" property | 
| 233 | */ | 233 | */ | 
| 234 | if (np != pci_dev) { | 234 | if (np != pci_dev) { | 
| 235 | const u32 *reg = get_property(np, "reg", NULL); | 235 | const u32 *reg = of_get_property(np, "reg", NULL); | 
| 236 | if (reg && (*reg < 4)) | 236 | if (reg && (*reg < 4)) | 
| 237 | index = lindex = *reg; | 237 | index = lindex = *reg; | 
| 238 | } | 238 | } | 
| @@ -296,7 +296,7 @@ void __init find_legacy_serial_ports(void) | |||
| 296 | DBG(" -> find_legacy_serial_port()\n"); | 296 | DBG(" -> find_legacy_serial_port()\n"); | 
| 297 | 297 | ||
| 298 | /* Now find out if one of these is out firmware console */ | 298 | /* Now find out if one of these is out firmware console */ | 
| 299 | path = get_property(of_chosen, "linux,stdout-path", NULL); | 299 | path = of_get_property(of_chosen, "linux,stdout-path", NULL); | 
| 300 | if (path != NULL) { | 300 | if (path != NULL) { | 
| 301 | stdout = of_find_node_by_path(path); | 301 | stdout = of_find_node_by_path(path); | 
| 302 | if (stdout) | 302 | if (stdout) | 
| @@ -529,7 +529,7 @@ static int __init check_legacy_serial_console(void) | |||
| 529 | } | 529 | } | 
| 530 | /* We are getting a weird phandle from OF ... */ | 530 | /* We are getting a weird phandle from OF ... */ | 
| 531 | /* ... So use the full path instead */ | 531 | /* ... So use the full path instead */ | 
| 532 | name = get_property(of_chosen, "linux,stdout-path", NULL); | 532 | name = of_get_property(of_chosen, "linux,stdout-path", NULL); | 
| 533 | if (name == NULL) { | 533 | if (name == NULL) { | 
| 534 | DBG(" no linux,stdout-path !\n"); | 534 | DBG(" no linux,stdout-path !\n"); | 
| 535 | return -ENODEV; | 535 | return -ENODEV; | 
| @@ -541,12 +541,12 @@ static int __init check_legacy_serial_console(void) | |||
| 541 | } | 541 | } | 
| 542 | DBG("stdout is %s\n", prom_stdout->full_name); | 542 | DBG("stdout is %s\n", prom_stdout->full_name); | 
| 543 | 543 | ||
| 544 | name = get_property(prom_stdout, "name", NULL); | 544 | name = of_get_property(prom_stdout, "name", NULL); | 
| 545 | if (!name) { | 545 | if (!name) { | 
| 546 | DBG(" stdout package has no name !\n"); | 546 | DBG(" stdout package has no name !\n"); | 
| 547 | goto not_found; | 547 | goto not_found; | 
| 548 | } | 548 | } | 
| 549 | spd = get_property(prom_stdout, "current-speed", NULL); | 549 | spd = of_get_property(prom_stdout, "current-speed", NULL); | 
| 550 | if (spd) | 550 | if (spd) | 
| 551 | speed = *spd; | 551 | speed = *spd; | 
| 552 | 552 | ||
| diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index 89486b631284..c492cee90e0f 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c | |||
| @@ -130,30 +130,31 @@ static int iseries_lparcfg_data(struct seq_file *m, void *v) | |||
| 130 | /* | 130 | /* | 
| 131 | * Methods used to fetch LPAR data when running on a pSeries platform. | 131 | * Methods used to fetch LPAR data when running on a pSeries platform. | 
| 132 | */ | 132 | */ | 
| 133 | /* find a better place for this function... */ | ||
| 134 | static void log_plpar_hcall_return(unsigned long rc, char *tag) | 133 | static void log_plpar_hcall_return(unsigned long rc, char *tag) | 
| 135 | { | 134 | { | 
| 136 | if (rc == 0) /* success, return */ | 135 | switch(rc) { | 
| 136 | case 0: | ||
| 137 | return; | 137 | return; | 
| 138 | /* check for null tag ? */ | 138 | case H_HARDWARE: | 
| 139 | if (rc == H_HARDWARE) | 139 | printk(KERN_INFO "plpar-hcall (%s) " | 
| 140 | printk(KERN_INFO | 140 | "Hardware fault\n", tag); | 
| 141 | "plpar-hcall (%s) failed with hardware fault\n", tag); | 141 | return; | 
| 142 | else if (rc == H_FUNCTION) | 142 | case H_FUNCTION: | 
| 143 | printk(KERN_INFO | 143 | printk(KERN_INFO "plpar-hcall (%s) " | 
| 144 | "plpar-hcall (%s) failed; function not allowed\n", tag); | 144 | "Function not allowed\n", tag); | 
| 145 | else if (rc == H_AUTHORITY) | 145 | return; | 
| 146 | printk(KERN_INFO | 146 | case H_AUTHORITY: | 
| 147 | "plpar-hcall (%s) failed; not authorized to this" | 147 | printk(KERN_INFO "plpar-hcall (%s) " | 
| 148 | " function\n", tag); | 148 | "Not authorized to this function\n", tag); | 
| 149 | else if (rc == H_PARAMETER) | 149 | return; | 
| 150 | printk(KERN_INFO "plpar-hcall (%s) failed; Bad parameter(s)\n", | 150 | case H_PARAMETER: | 
| 151 | tag); | 151 | printk(KERN_INFO "plpar-hcall (%s) " | 
| 152 | else | 152 | "Bad parameter(s)\n",tag); | 
| 153 | printk(KERN_INFO | 153 | return; | 
| 154 | "plpar-hcall (%s) failed with unexpected rc(0x%lx)\n", | 154 | default: | 
| 155 | tag, rc); | 155 | printk(KERN_INFO "plpar-hcall (%s) " | 
| 156 | 156 | "Unexpected rc(0x%lx)\n", tag, rc); | |
| 157 | } | ||
| 157 | } | 158 | } | 
| 158 | 159 | ||
| 159 | /* | 160 | /* | 
| @@ -321,15 +322,16 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v) | |||
| 321 | struct device_node *rtas_node; | 322 | struct device_node *rtas_node; | 
| 322 | const int *lrdrp = NULL; | 323 | const int *lrdrp = NULL; | 
| 323 | 324 | ||
| 324 | rtas_node = find_path_device("/rtas"); | 325 | rtas_node = of_find_node_by_path("/rtas"); | 
| 325 | if (rtas_node) | 326 | if (rtas_node) | 
| 326 | lrdrp = get_property(rtas_node, "ibm,lrdr-capacity", NULL); | 327 | lrdrp = of_get_property(rtas_node, "ibm,lrdr-capacity", NULL); | 
| 327 | 328 | ||
| 328 | if (lrdrp == NULL) { | 329 | if (lrdrp == NULL) { | 
| 329 | partition_potential_processors = vdso_data->processorCount; | 330 | partition_potential_processors = vdso_data->processorCount; | 
| 330 | } else { | 331 | } else { | 
| 331 | partition_potential_processors = *(lrdrp + 4); | 332 | partition_potential_processors = *(lrdrp + 4); | 
| 332 | } | 333 | } | 
| 334 | of_node_put(rtas_node); | ||
| 333 | 335 | ||
| 334 | partition_active_processors = lparcfg_count_active_processors(); | 336 | partition_active_processors = lparcfg_count_active_processors(); | 
| 335 | 337 | ||
| @@ -537,25 +539,27 @@ static int lparcfg_data(struct seq_file *m, void *v) | |||
| 537 | 539 | ||
| 538 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); | 540 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); | 
| 539 | 541 | ||
| 540 | rootdn = find_path_device("/"); | 542 | rootdn = of_find_node_by_path("/"); | 
| 541 | if (rootdn) { | 543 | if (rootdn) { | 
| 542 | tmp = get_property(rootdn, "model", NULL); | 544 | tmp = of_get_property(rootdn, "model", NULL); | 
| 543 | if (tmp) { | 545 | if (tmp) { | 
| 544 | model = tmp; | 546 | model = tmp; | 
| 545 | /* Skip "IBM," - see platforms/iseries/dt.c */ | 547 | /* Skip "IBM," - see platforms/iseries/dt.c */ | 
| 546 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | 548 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | 
| 547 | model += 4; | 549 | model += 4; | 
| 548 | } | 550 | } | 
| 549 | tmp = get_property(rootdn, "system-id", NULL); | 551 | tmp = of_get_property(rootdn, "system-id", NULL); | 
| 550 | if (tmp) { | 552 | if (tmp) { | 
| 551 | system_id = tmp; | 553 | system_id = tmp; | 
| 552 | /* Skip "IBM," - see platforms/iseries/dt.c */ | 554 | /* Skip "IBM," - see platforms/iseries/dt.c */ | 
| 553 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | 555 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | 
| 554 | system_id += 4; | 556 | system_id += 4; | 
| 555 | } | 557 | } | 
| 556 | lp_index_ptr = get_property(rootdn, "ibm,partition-no", NULL); | 558 | lp_index_ptr = of_get_property(rootdn, "ibm,partition-no", | 
| 559 | NULL); | ||
| 557 | if (lp_index_ptr) | 560 | if (lp_index_ptr) | 
| 558 | lp_index = *lp_index_ptr; | 561 | lp_index = *lp_index_ptr; | 
| 562 | of_node_put(rootdn); | ||
| 559 | } | 563 | } | 
| 560 | seq_printf(m, "serial_number=%s\n", system_id); | 564 | seq_printf(m, "serial_number=%s\n", system_id); | 
| 561 | seq_printf(m, "system_type=%s\n", model); | 565 | seq_printf(m, "system_type=%s\n", model); | 
| diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index a24b09c27718..704375bda73a 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
| @@ -72,8 +72,8 @@ int default_machine_kexec_prepare(struct kimage *image) | |||
| 72 | /* We also should not overwrite the tce tables */ | 72 | /* We also should not overwrite the tce tables */ | 
| 73 | for (node = of_find_node_by_type(NULL, "pci"); node != NULL; | 73 | for (node = of_find_node_by_type(NULL, "pci"); node != NULL; | 
| 74 | node = of_find_node_by_type(node, "pci")) { | 74 | node = of_find_node_by_type(node, "pci")) { | 
| 75 | basep = get_property(node, "linux,tce-base", NULL); | 75 | basep = of_get_property(node, "linux,tce-base", NULL); | 
| 76 | sizep = get_property(node, "linux,tce-size", NULL); | 76 | sizep = of_get_property(node, "linux,tce-size", NULL); | 
| 77 | if (basep == NULL || sizep == NULL) | 77 | if (basep == NULL || sizep == NULL) | 
| 78 | continue; | 78 | continue; | 
| 79 | 79 | ||
| @@ -294,19 +294,19 @@ static unsigned long htab_base, kernel_end; | |||
| 294 | static struct property htab_base_prop = { | 294 | static struct property htab_base_prop = { | 
| 295 | .name = "linux,htab-base", | 295 | .name = "linux,htab-base", | 
| 296 | .length = sizeof(unsigned long), | 296 | .length = sizeof(unsigned long), | 
| 297 | .value = (unsigned char *)&htab_base, | 297 | .value = &htab_base, | 
| 298 | }; | 298 | }; | 
| 299 | 299 | ||
| 300 | static struct property htab_size_prop = { | 300 | static struct property htab_size_prop = { | 
| 301 | .name = "linux,htab-size", | 301 | .name = "linux,htab-size", | 
| 302 | .length = sizeof(unsigned long), | 302 | .length = sizeof(unsigned long), | 
| 303 | .value = (unsigned char *)&htab_size_bytes, | 303 | .value = &htab_size_bytes, | 
| 304 | }; | 304 | }; | 
| 305 | 305 | ||
| 306 | static struct property kernel_end_prop = { | 306 | static struct property kernel_end_prop = { | 
| 307 | .name = "linux,kernel-end", | 307 | .name = "linux,kernel-end", | 
| 308 | .length = sizeof(unsigned long), | 308 | .length = sizeof(unsigned long), | 
| 309 | .value = (unsigned char *)&kernel_end, | 309 | .value = &kernel_end, | 
| 310 | }; | 310 | }; | 
| 311 | 311 | ||
| 312 | static void __init export_htab_values(void) | 312 | static void __init export_htab_values(void) | 
| @@ -335,7 +335,7 @@ static void __init export_htab_values(void) | |||
| 335 | static struct property crashk_base_prop = { | 335 | static struct property crashk_base_prop = { | 
| 336 | .name = "linux,crashkernel-base", | 336 | .name = "linux,crashkernel-base", | 
| 337 | .length = sizeof(unsigned long), | 337 | .length = sizeof(unsigned long), | 
| 338 | .value = (unsigned char *)&crashk_res.start, | 338 | .value = &crashk_res.start, | 
| 339 | }; | 339 | }; | 
| 340 | 340 | ||
| 341 | static unsigned long crashk_size; | 341 | static unsigned long crashk_size; | 
| @@ -343,7 +343,7 @@ static unsigned long crashk_size; | |||
| 343 | static struct property crashk_size_prop = { | 343 | static struct property crashk_size_prop = { | 
| 344 | .name = "linux,crashkernel-size", | 344 | .name = "linux,crashkernel-size", | 
| 345 | .length = sizeof(unsigned long), | 345 | .length = sizeof(unsigned long), | 
| 346 | .value = (unsigned char *)&crashk_size, | 346 | .value = &crashk_size, | 
| 347 | }; | 347 | }; | 
| 348 | 348 | ||
| 349 | static void __init export_crashk_values(void) | 349 | static void __init export_crashk_values(void) | 
| diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 412bea3cf813..98decf8ebff4 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
| @@ -734,10 +734,6 @@ _GLOBAL(abs) | |||
| 734 | sub r3,r3,r4 | 734 | sub r3,r3,r4 | 
| 735 | blr | 735 | blr | 
| 736 | 736 | ||
| 737 | _GLOBAL(_get_SP) | ||
| 738 | mr r3,r1 /* Close enough */ | ||
| 739 | blr | ||
| 740 | |||
| 741 | /* | 737 | /* | 
| 742 | * Create a kernel thread | 738 | * Create a kernel thread | 
| 743 | * kernel_thread(fn, arg, flags) | 739 | * kernel_thread(fn, arg, flags) | 
| diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index e921514e655b..0c8ea7659d92 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c | |||
| @@ -120,6 +120,117 @@ void of_device_unregister(struct of_device *ofdev) | |||
| 120 | } | 120 | } | 
| 121 | 121 | ||
| 122 | 122 | ||
| 123 | static ssize_t of_device_get_modalias(struct of_device *ofdev, | ||
| 124 | char *str, ssize_t len) | ||
| 125 | { | ||
| 126 | const char *compat; | ||
| 127 | int cplen, i; | ||
| 128 | ssize_t tsize, csize, repend; | ||
| 129 | |||
| 130 | /* Name & Type */ | ||
| 131 | csize = snprintf(str, len, "of:N%sT%s", | ||
| 132 | ofdev->node->name, ofdev->node->type); | ||
| 133 | |||
| 134 | /* Get compatible property if any */ | ||
| 135 | compat = of_get_property(ofdev->node, "compatible", &cplen); | ||
| 136 | if (!compat) | ||
| 137 | return csize; | ||
| 138 | |||
| 139 | /* Find true end (we tolerate multiple \0 at the end */ | ||
| 140 | for (i=(cplen-1); i>=0 && !compat[i]; i--) | ||
| 141 | cplen--; | ||
| 142 | if (!cplen) | ||
| 143 | return csize; | ||
| 144 | cplen++; | ||
| 145 | |||
| 146 | /* Check space (need cplen+1 chars including final \0) */ | ||
| 147 | tsize = csize + cplen; | ||
| 148 | repend = tsize; | ||
| 149 | |||
| 150 | if (csize>=len) /* @ the limit, all is already filled */ | ||
| 151 | return tsize; | ||
| 152 | |||
| 153 | if (tsize>=len) { /* limit compat list */ | ||
| 154 | cplen = len-csize-1; | ||
| 155 | repend = len; | ||
| 156 | } | ||
| 157 | |||
| 158 | /* Copy and do char replacement */ | ||
| 159 | memcpy(&str[csize+1], compat, cplen); | ||
| 160 | for (i=csize; i<repend; i++) { | ||
| 161 | char c = str[i]; | ||
| 162 | if (c=='\0') | ||
| 163 | str[i] = 'C'; | ||
| 164 | else if (c==' ') | ||
| 165 | str[i] = '_'; | ||
| 166 | } | ||
| 167 | |||
| 168 | return tsize; | ||
| 169 | } | ||
| 170 | |||
| 171 | int of_device_uevent(struct device *dev, | ||
| 172 | char **envp, int num_envp, char *buffer, int buffer_size) | ||
| 173 | { | ||
| 174 | struct of_device *ofdev; | ||
| 175 | const char *compat; | ||
| 176 | int i = 0, length = 0, seen = 0, cplen, sl; | ||
| 177 | |||
| 178 | if (!dev) | ||
| 179 | return -ENODEV; | ||
| 180 | |||
| 181 | ofdev = to_of_device(dev); | ||
| 182 | |||
| 183 | if (add_uevent_var(envp, num_envp, &i, | ||
| 184 | buffer, buffer_size, &length, | ||
| 185 | "OF_NAME=%s", ofdev->node->name)) | ||
| 186 | return -ENOMEM; | ||
| 187 | |||
| 188 | if (add_uevent_var(envp, num_envp, &i, | ||
| 189 | buffer, buffer_size, &length, | ||
| 190 | "OF_TYPE=%s", ofdev->node->type)) | ||
| 191 | return -ENOMEM; | ||
| 192 | |||
| 193 | /* Since the compatible field can contain pretty much anything | ||
| 194 | * it's not really legal to split it out with commas. We split it | ||
| 195 | * up using a number of environment variables instead. */ | ||
| 196 | |||
| 197 | compat = of_get_property(ofdev->node, "compatible", &cplen); | ||
| 198 | while (compat && *compat && cplen > 0) { | ||
| 199 | if (add_uevent_var(envp, num_envp, &i, | ||
| 200 | buffer, buffer_size, &length, | ||
| 201 | "OF_COMPATIBLE_%d=%s", seen, compat)) | ||
| 202 | return -ENOMEM; | ||
| 203 | |||
| 204 | sl = strlen (compat) + 1; | ||
| 205 | compat += sl; | ||
| 206 | cplen -= sl; | ||
| 207 | seen++; | ||
| 208 | } | ||
| 209 | |||
| 210 | if (add_uevent_var(envp, num_envp, &i, | ||
| 211 | buffer, buffer_size, &length, | ||
| 212 | "OF_COMPATIBLE_N=%d", seen)) | ||
| 213 | return -ENOMEM; | ||
| 214 | |||
| 215 | /* modalias is trickier, we add it in 2 steps */ | ||
| 216 | if (add_uevent_var(envp, num_envp, &i, | ||
| 217 | buffer, buffer_size, &length, | ||
| 218 | "MODALIAS=")) | ||
| 219 | return -ENOMEM; | ||
| 220 | |||
| 221 | sl = of_device_get_modalias(ofdev, &buffer[length-1], | ||
| 222 | buffer_size-length); | ||
| 223 | if (sl >= (buffer_size-length)) | ||
| 224 | return -ENOMEM; | ||
| 225 | |||
| 226 | length += sl; | ||
| 227 | |||
| 228 | envp[i] = NULL; | ||
| 229 | |||
| 230 | return 0; | ||
| 231 | } | ||
| 232 | |||
| 233 | |||
| 123 | EXPORT_SYMBOL(of_match_node); | 234 | EXPORT_SYMBOL(of_match_node); | 
| 124 | EXPORT_SYMBOL(of_match_device); | 235 | EXPORT_SYMBOL(of_match_device); | 
| 125 | EXPORT_SYMBOL(of_device_register); | 236 | EXPORT_SYMBOL(of_device_register); | 
| @@ -127,3 +238,4 @@ EXPORT_SYMBOL(of_device_unregister); | |||
| 127 | EXPORT_SYMBOL(of_dev_get); | 238 | EXPORT_SYMBOL(of_dev_get); | 
| 128 | EXPORT_SYMBOL(of_dev_put); | 239 | EXPORT_SYMBOL(of_dev_put); | 
| 129 | EXPORT_SYMBOL(of_release_dev); | 240 | EXPORT_SYMBOL(of_release_dev); | 
| 241 | EXPORT_SYMBOL(of_device_uevent); | ||
| diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 9e7a4d249f03..908ed7926db4 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c | |||
| @@ -133,6 +133,7 @@ static int of_platform_device_resume(struct device * dev) | |||
| 133 | struct bus_type of_platform_bus_type = { | 133 | struct bus_type of_platform_bus_type = { | 
| 134 | .name = "of_platform", | 134 | .name = "of_platform", | 
| 135 | .match = of_platform_bus_match, | 135 | .match = of_platform_bus_match, | 
| 136 | .uevent = of_device_uevent, | ||
| 136 | .probe = of_platform_device_probe, | 137 | .probe = of_platform_device_probe, | 
| 137 | .remove = of_platform_device_remove, | 138 | .remove = of_platform_device_remove, | 
| 138 | .suspend = of_platform_device_suspend, | 139 | .suspend = of_platform_device_suspend, | 
| @@ -177,7 +178,7 @@ static void of_platform_make_bus_id(struct of_device *dev) | |||
| 177 | * and 'D' for MMIO DCRs. | 178 | * and 'D' for MMIO DCRs. | 
| 178 | */ | 179 | */ | 
| 179 | #ifdef CONFIG_PPC_DCR | 180 | #ifdef CONFIG_PPC_DCR | 
| 180 | reg = get_property(node, "dcr-reg", NULL); | 181 | reg = of_get_property(node, "dcr-reg", NULL); | 
| 181 | if (reg) { | 182 | if (reg) { | 
| 182 | #ifdef CONFIG_PPC_DCR_NATIVE | 183 | #ifdef CONFIG_PPC_DCR_NATIVE | 
| 183 | snprintf(name, BUS_ID_SIZE, "d%x.%s", | 184 | snprintf(name, BUS_ID_SIZE, "d%x.%s", | 
| @@ -197,7 +198,7 @@ static void of_platform_make_bus_id(struct of_device *dev) | |||
| 197 | /* | 198 | /* | 
| 198 | * For MMIO, get the physical address | 199 | * For MMIO, get the physical address | 
| 199 | */ | 200 | */ | 
| 200 | reg = get_property(node, "reg", NULL); | 201 | reg = of_get_property(node, "reg", NULL); | 
| 201 | if (reg) { | 202 | if (reg) { | 
| 202 | addr = of_translate_address(node, reg); | 203 | addr = of_translate_address(node, reg); | 
| 203 | if (addr != OF_BAD_ADDR) { | 204 | if (addr != OF_BAD_ADDR) { | 
| diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index d8ef2e100505..f022862de344 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c | |||
| @@ -637,7 +637,7 @@ make_one_node_map(struct device_node* node, u8 pci_bus) | |||
| 637 | 637 | ||
| 638 | if (pci_bus >= pci_bus_count) | 638 | if (pci_bus >= pci_bus_count) | 
| 639 | return; | 639 | return; | 
| 640 | bus_range = get_property(node, "bus-range", &len); | 640 | bus_range = of_get_property(node, "bus-range", &len); | 
| 641 | if (bus_range == NULL || len < 2 * sizeof(int)) { | 641 | if (bus_range == NULL || len < 2 * sizeof(int)) { | 
| 642 | printk(KERN_WARNING "Can't get bus-range for %s, " | 642 | printk(KERN_WARNING "Can't get bus-range for %s, " | 
| 643 | "assuming it starts at 0\n", node->full_name); | 643 | "assuming it starts at 0\n", node->full_name); | 
| @@ -649,17 +649,20 @@ make_one_node_map(struct device_node* node, u8 pci_bus) | |||
| 649 | struct pci_dev* dev; | 649 | struct pci_dev* dev; | 
| 650 | const unsigned int *class_code, *reg; | 650 | const unsigned int *class_code, *reg; | 
| 651 | 651 | ||
| 652 | class_code = get_property(node, "class-code", NULL); | 652 | class_code = of_get_property(node, "class-code", NULL); | 
| 653 | if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && | 653 | if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && | 
| 654 | (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) | 654 | (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) | 
| 655 | continue; | 655 | continue; | 
| 656 | reg = get_property(node, "reg", NULL); | 656 | reg = of_get_property(node, "reg", NULL); | 
| 657 | if (!reg) | 657 | if (!reg) | 
| 658 | continue; | 658 | continue; | 
| 659 | dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff)); | 659 | dev = pci_get_bus_and_slot(pci_bus, ((reg[0] >> 8) & 0xff)); | 
| 660 | if (!dev || !dev->subordinate) | 660 | if (!dev || !dev->subordinate) { | 
| 661 | pci_dev_put(dev); | ||
| 661 | continue; | 662 | continue; | 
| 663 | } | ||
| 662 | make_one_node_map(node, dev->subordinate->number); | 664 | make_one_node_map(node, dev->subordinate->number); | 
| 665 | pci_dev_put(dev); | ||
| 663 | } | 666 | } | 
| 664 | } | 667 | } | 
| 665 | 668 | ||
| @@ -669,6 +672,7 @@ pcibios_make_OF_bus_map(void) | |||
| 669 | int i; | 672 | int i; | 
| 670 | struct pci_controller* hose; | 673 | struct pci_controller* hose; | 
| 671 | struct property *map_prop; | 674 | struct property *map_prop; | 
| 675 | struct device_node *dn; | ||
| 672 | 676 | ||
| 673 | pci_to_OF_bus_map = kmalloc(pci_bus_count, GFP_KERNEL); | 677 | pci_to_OF_bus_map = kmalloc(pci_bus_count, GFP_KERNEL); | 
| 674 | if (!pci_to_OF_bus_map) { | 678 | if (!pci_to_OF_bus_map) { | 
| @@ -690,12 +694,13 @@ pcibios_make_OF_bus_map(void) | |||
| 690 | continue; | 694 | continue; | 
| 691 | make_one_node_map(node, hose->first_busno); | 695 | make_one_node_map(node, hose->first_busno); | 
| 692 | } | 696 | } | 
| 693 | map_prop = of_find_property(find_path_device("/"), | 697 | dn = of_find_node_by_path("/"); | 
| 694 | "pci-OF-bus-map", NULL); | 698 | map_prop = of_find_property(dn, "pci-OF-bus-map", NULL); | 
| 695 | if (map_prop) { | 699 | if (map_prop) { | 
| 696 | BUG_ON(pci_bus_count > map_prop->length); | 700 | BUG_ON(pci_bus_count > map_prop->length); | 
| 697 | memcpy(map_prop->value, pci_to_OF_bus_map, pci_bus_count); | 701 | memcpy(map_prop->value, pci_to_OF_bus_map, pci_bus_count); | 
| 698 | } | 702 | } | 
| 703 | of_node_put(dn); | ||
| 699 | #ifdef DEBUG | 704 | #ifdef DEBUG | 
| 700 | printk("PCI->OF bus map:\n"); | 705 | printk("PCI->OF bus map:\n"); | 
| 701 | for (i=0; i<pci_bus_count; i++) { | 706 | for (i=0; i<pci_bus_count; i++) { | 
| @@ -724,7 +729,7 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* | |||
| 724 | * a fake root for all functions of a multi-function device, | 729 | * a fake root for all functions of a multi-function device, | 
| 725 | * we go down them as well. | 730 | * we go down them as well. | 
| 726 | */ | 731 | */ | 
| 727 | class_code = get_property(node, "class-code", NULL); | 732 | class_code = of_get_property(node, "class-code", NULL); | 
| 728 | if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && | 733 | if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && | 
| 729 | (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) && | 734 | (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) && | 
| 730 | strcmp(node->name, "multifunc-device")) | 735 | strcmp(node->name, "multifunc-device")) | 
| @@ -744,7 +749,7 @@ static struct device_node *scan_OF_for_pci_dev(struct device_node *parent, | |||
| 744 | unsigned int psize; | 749 | unsigned int psize; | 
| 745 | 750 | ||
| 746 | while ((np = of_get_next_child(parent, np)) != NULL) { | 751 | while ((np = of_get_next_child(parent, np)) != NULL) { | 
| 747 | reg = get_property(np, "reg", &psize); | 752 | reg = of_get_property(np, "reg", &psize); | 
| 748 | if (reg == NULL || psize < 4) | 753 | if (reg == NULL || psize < 4) | 
| 749 | continue; | 754 | continue; | 
| 750 | if (((reg[0] >> 8) & 0xff) == devfn) | 755 | if (((reg[0] >> 8) & 0xff) == devfn) | 
| @@ -859,7 +864,7 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) | |||
| 859 | if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child, | 864 | if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child, | 
| 860 | find_OF_pci_device_filter, (void *)node)) | 865 | find_OF_pci_device_filter, (void *)node)) | 
| 861 | return -ENODEV; | 866 | return -ENODEV; | 
| 862 | reg = get_property(node, "reg", NULL); | 867 | reg = of_get_property(node, "reg", NULL); | 
| 863 | if (!reg) | 868 | if (!reg) | 
| 864 | return -ENODEV; | 869 | return -ENODEV; | 
| 865 | *bus = (reg[0] >> 16) & 0xff; | 870 | *bus = (reg[0] >> 16) & 0xff; | 
| @@ -895,14 +900,14 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
| 895 | int rlen = 0, orig_rlen; | 900 | int rlen = 0, orig_rlen; | 
| 896 | int memno = 0; | 901 | int memno = 0; | 
| 897 | struct resource *res; | 902 | struct resource *res; | 
| 898 | int np, na = prom_n_addr_cells(dev); | 903 | int np, na = of_n_addr_cells(dev); | 
| 899 | np = na + 5; | 904 | np = na + 5; | 
| 900 | 905 | ||
| 901 | /* First we try to merge ranges to fix a problem with some pmacs | 906 | /* First we try to merge ranges to fix a problem with some pmacs | 
| 902 | * that can have more than 3 ranges, fortunately using contiguous | 907 | * that can have more than 3 ranges, fortunately using contiguous | 
| 903 | * addresses -- BenH | 908 | * addresses -- BenH | 
| 904 | */ | 909 | */ | 
| 905 | dt_ranges = get_property(dev, "ranges", &rlen); | 910 | dt_ranges = of_get_property(dev, "ranges", &rlen); | 
| 906 | if (!dt_ranges) | 911 | if (!dt_ranges) | 
| 907 | return; | 912 | return; | 
| 908 | /* Sanity check, though hopefully that never happens */ | 913 | /* Sanity check, though hopefully that never happens */ | 
| @@ -1006,14 +1011,19 @@ void __init | |||
| 1006 | pci_create_OF_bus_map(void) | 1011 | pci_create_OF_bus_map(void) | 
| 1007 | { | 1012 | { | 
| 1008 | struct property* of_prop; | 1013 | struct property* of_prop; | 
| 1009 | 1014 | struct device_node *dn; | |
| 1015 | |||
| 1010 | of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256); | 1016 | of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256); | 
| 1011 | if (of_prop && find_path_device("/")) { | 1017 | if (!of_prop) | 
| 1018 | return; | ||
| 1019 | dn = of_find_node_by_path("/"); | ||
| 1020 | if (dn) { | ||
| 1012 | memset(of_prop, -1, sizeof(struct property) + 256); | 1021 | memset(of_prop, -1, sizeof(struct property) + 256); | 
| 1013 | of_prop->name = "pci-OF-bus-map"; | 1022 | of_prop->name = "pci-OF-bus-map"; | 
| 1014 | of_prop->length = 256; | 1023 | of_prop->length = 256; | 
| 1015 | of_prop->value = (unsigned char *)&of_prop[1]; | 1024 | of_prop->value = &of_prop[1]; | 
| 1016 | prom_add_property(find_path_device("/"), of_prop); | 1025 | prom_add_property(dn, of_prop); | 
| 1026 | of_node_put(dn); | ||
| 1017 | } | 1027 | } | 
| 1018 | } | 1028 | } | 
| 1019 | 1029 | ||
| diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 7e97d71a5f8f..60d7d4baa227 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
| @@ -61,8 +61,7 @@ void iSeries_pcibios_init(void); | |||
| 61 | 61 | ||
| 62 | LIST_HEAD(hose_list); | 62 | LIST_HEAD(hose_list); | 
| 63 | 63 | ||
| 64 | struct dma_mapping_ops *pci_dma_ops; | 64 | static struct dma_mapping_ops *pci_dma_ops; | 
| 65 | EXPORT_SYMBOL(pci_dma_ops); | ||
| 66 | 65 | ||
| 67 | int global_phb_number; /* Global phb counter */ | 66 | int global_phb_number; /* Global phb counter */ | 
| 68 | 67 | ||
| @@ -70,6 +69,17 @@ int global_phb_number; /* Global phb counter */ | |||
| 70 | struct pci_dev *ppc64_isabridge_dev = NULL; | 69 | struct pci_dev *ppc64_isabridge_dev = NULL; | 
| 71 | EXPORT_SYMBOL_GPL(ppc64_isabridge_dev); | 70 | EXPORT_SYMBOL_GPL(ppc64_isabridge_dev); | 
| 72 | 71 | ||
| 72 | void set_pci_dma_ops(struct dma_mapping_ops *dma_ops) | ||
| 73 | { | ||
| 74 | pci_dma_ops = dma_ops; | ||
| 75 | } | ||
| 76 | |||
| 77 | struct dma_mapping_ops *get_pci_dma_ops(void) | ||
| 78 | { | ||
| 79 | return pci_dma_ops; | ||
| 80 | } | ||
| 81 | EXPORT_SYMBOL(get_pci_dma_ops); | ||
| 82 | |||
| 73 | static void fixup_broken_pcnet32(struct pci_dev* dev) | 83 | static void fixup_broken_pcnet32(struct pci_dev* dev) | 
| 74 | { | 84 | { | 
| 75 | if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { | 85 | if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { | 
| @@ -258,7 +268,7 @@ static u32 get_int_prop(struct device_node *np, const char *name, u32 def) | |||
| 258 | const u32 *prop; | 268 | const u32 *prop; | 
| 259 | int len; | 269 | int len; | 
| 260 | 270 | ||
| 261 | prop = get_property(np, name, &len); | 271 | prop = of_get_property(np, name, &len); | 
| 262 | if (prop && len >= 4) | 272 | if (prop && len >= 4) | 
| 263 | return *prop; | 273 | return *prop; | 
| 264 | return def; | 274 | return def; | 
| @@ -291,7 +301,7 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev) | |||
| 291 | u32 i; | 301 | u32 i; | 
| 292 | int proplen; | 302 | int proplen; | 
| 293 | 303 | ||
| 294 | addrs = get_property(node, "assigned-addresses", &proplen); | 304 | addrs = of_get_property(node, "assigned-addresses", &proplen); | 
| 295 | if (!addrs) | 305 | if (!addrs) | 
| 296 | return; | 306 | return; | 
| 297 | DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs); | 307 | DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs); | 
| @@ -333,7 +343,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, | |||
| 333 | dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); | 343 | dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); | 
| 334 | if (!dev) | 344 | if (!dev) | 
| 335 | return NULL; | 345 | return NULL; | 
| 336 | type = get_property(node, "device_type", NULL); | 346 | type = of_get_property(node, "device_type", NULL); | 
| 337 | if (type == NULL) | 347 | if (type == NULL) | 
| 338 | type = ""; | 348 | type = ""; | 
| 339 | 349 | ||
| @@ -397,7 +407,7 @@ void __devinit of_scan_bus(struct device_node *node, | |||
| 397 | 407 | ||
| 398 | while ((child = of_get_next_child(node, child)) != NULL) { | 408 | while ((child = of_get_next_child(node, child)) != NULL) { | 
| 399 | DBG(" * %s\n", child->full_name); | 409 | DBG(" * %s\n", child->full_name); | 
| 400 | reg = get_property(child, "reg", ®len); | 410 | reg = of_get_property(child, "reg", ®len); | 
| 401 | if (reg == NULL || reglen < 20) | 411 | if (reg == NULL || reglen < 20) | 
| 402 | continue; | 412 | continue; | 
| 403 | devfn = (reg[0] >> 8) & 0xff; | 413 | devfn = (reg[0] >> 8) & 0xff; | 
| @@ -430,13 +440,13 @@ void __devinit of_scan_pci_bridge(struct device_node *node, | |||
| 430 | DBG("of_scan_pci_bridge(%s)\n", node->full_name); | 440 | DBG("of_scan_pci_bridge(%s)\n", node->full_name); | 
| 431 | 441 | ||
| 432 | /* parse bus-range property */ | 442 | /* parse bus-range property */ | 
| 433 | busrange = get_property(node, "bus-range", &len); | 443 | busrange = of_get_property(node, "bus-range", &len); | 
| 434 | if (busrange == NULL || len != 8) { | 444 | if (busrange == NULL || len != 8) { | 
| 435 | printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n", | 445 | printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n", | 
| 436 | node->full_name); | 446 | node->full_name); | 
| 437 | return; | 447 | return; | 
| 438 | } | 448 | } | 
| 439 | ranges = get_property(node, "ranges", &len); | 449 | ranges = of_get_property(node, "ranges", &len); | 
| 440 | if (ranges == NULL) { | 450 | if (ranges == NULL) { | 
| 441 | printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", | 451 | printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", | 
| 442 | node->full_name); | 452 | node->full_name); | 
| @@ -900,7 +910,7 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node, | |||
| 900 | unsigned int size; | 910 | unsigned int size; | 
| 901 | int rlen = 0; | 911 | int rlen = 0; | 
| 902 | 912 | ||
| 903 | range = get_property(isa_node, "ranges", &rlen); | 913 | range = of_get_property(isa_node, "ranges", &rlen); | 
| 904 | if (range == NULL || (rlen < sizeof(struct isa_range))) { | 914 | if (range == NULL || (rlen < sizeof(struct isa_range))) { | 
| 905 | printk(KERN_ERR "no ISA ranges or unexpected isa range size," | 915 | printk(KERN_ERR "no ISA ranges or unexpected isa range size," | 
| 906 | "mapping 64k\n"); | 916 | "mapping 64k\n"); | 
| @@ -947,7 +957,7 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
| 947 | int rlen = 0; | 957 | int rlen = 0; | 
| 948 | int memno = 0; | 958 | int memno = 0; | 
| 949 | struct resource *res; | 959 | struct resource *res; | 
| 950 | int np, na = prom_n_addr_cells(dev); | 960 | int np, na = of_n_addr_cells(dev); | 
| 951 | unsigned long pci_addr, cpu_phys_addr; | 961 | unsigned long pci_addr, cpu_phys_addr; | 
| 952 | 962 | ||
| 953 | np = na + 5; | 963 | np = na + 5; | 
| @@ -960,7 +970,7 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
| 960 | * (size depending on dev->n_addr_cells) | 970 | * (size depending on dev->n_addr_cells) | 
| 961 | * cells 4+5 or 5+6: the size of the range | 971 | * cells 4+5 or 5+6: the size of the range | 
| 962 | */ | 972 | */ | 
| 963 | ranges = get_property(dev, "ranges", &rlen); | 973 | ranges = of_get_property(dev, "ranges", &rlen); | 
| 964 | if (ranges == NULL) | 974 | if (ranges == NULL) | 
| 965 | return; | 975 | return; | 
| 966 | hose->io_base_phys = 0; | 976 | hose->io_base_phys = 0; | 
| diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index 68df018dae0e..d7d36df9c053 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c | |||
| @@ -40,7 +40,8 @@ | |||
| 40 | static void * __devinit update_dn_pci_info(struct device_node *dn, void *data) | 40 | static void * __devinit update_dn_pci_info(struct device_node *dn, void *data) | 
| 41 | { | 41 | { | 
| 42 | struct pci_controller *phb = data; | 42 | struct pci_controller *phb = data; | 
| 43 | const int *type = get_property(dn, "ibm,pci-config-space-type", NULL); | 43 | const int *type = | 
| 44 | of_get_property(dn, "ibm,pci-config-space-type", NULL); | ||
| 44 | const u32 *regs; | 45 | const u32 *regs; | 
| 45 | struct pci_dn *pdn; | 46 | struct pci_dn *pdn; | 
| 46 | 47 | ||
| @@ -54,14 +55,14 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data) | |||
| 54 | dn->data = pdn; | 55 | dn->data = pdn; | 
| 55 | pdn->node = dn; | 56 | pdn->node = dn; | 
| 56 | pdn->phb = phb; | 57 | pdn->phb = phb; | 
| 57 | regs = get_property(dn, "reg", NULL); | 58 | regs = of_get_property(dn, "reg", NULL); | 
| 58 | if (regs) { | 59 | if (regs) { | 
| 59 | /* First register entry is addr (00BBSS00) */ | 60 | /* First register entry is addr (00BBSS00) */ | 
| 60 | pdn->busno = (regs[0] >> 16) & 0xff; | 61 | pdn->busno = (regs[0] >> 16) & 0xff; | 
| 61 | pdn->devfn = (regs[0] >> 8) & 0xff; | 62 | pdn->devfn = (regs[0] >> 8) & 0xff; | 
| 62 | } | 63 | } | 
| 63 | if (firmware_has_feature(FW_FEATURE_ISERIES)) { | 64 | if (firmware_has_feature(FW_FEATURE_ISERIES)) { | 
| 64 | const u32 *busp = get_property(dn, "linux,subbus", NULL); | 65 | const u32 *busp = of_get_property(dn, "linux,subbus", NULL); | 
| 65 | if (busp) | 66 | if (busp) | 
| 66 | pdn->bussubno = *busp; | 67 | pdn->bussubno = *busp; | 
| 67 | } | 68 | } | 
| @@ -100,7 +101,7 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre, | |||
| 100 | u32 class; | 101 | u32 class; | 
| 101 | 102 | ||
| 102 | nextdn = NULL; | 103 | nextdn = NULL; | 
| 103 | classp = get_property(dn, "class-code", NULL); | 104 | classp = of_get_property(dn, "class-code", NULL); | 
| 104 | class = classp ? *classp : 0; | 105 | class = classp ? *classp : 0; | 
| 105 | 106 | ||
| 106 | if (pre && ((ret = pre(dn, data)) != NULL)) | 107 | if (pre && ((ret = pre(dn, data)) != NULL)) | 
| diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 2f8e9c02c92a..ff252aaead12 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | #include <asm/processor.h> | 20 | #include <asm/processor.h> | 
| 21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> | 
| 22 | #include <asm/io.h> | 22 | #include <asm/io.h> | 
| 23 | #include <asm/ide.h> | ||
| 24 | #include <asm/atomic.h> | 23 | #include <asm/atomic.h> | 
| 25 | #include <asm/checksum.h> | 24 | #include <asm/checksum.h> | 
| 26 | #include <asm/pgtable.h> | 25 | #include <asm/pgtable.h> | 
| diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index e53b2988d1bf..e509aae2feb3 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
| @@ -305,9 +305,7 @@ struct task_struct *__switch_to(struct task_struct *prev, | |||
| 305 | set_dabr(new->thread.dabr); | 305 | set_dabr(new->thread.dabr); | 
| 306 | __get_cpu_var(current_dabr) = new->thread.dabr; | 306 | __get_cpu_var(current_dabr) = new->thread.dabr; | 
| 307 | } | 307 | } | 
| 308 | 308 | #endif /* CONFIG_PPC64 */ | |
| 309 | flush_tlb_pending(); | ||
| 310 | #endif | ||
| 311 | 309 | ||
| 312 | new_thread = &new->thread; | 310 | new_thread = &new->thread; | 
| 313 | old_thread = ¤t->thread; | 311 | old_thread = ¤t->thread; | 
| @@ -402,11 +400,11 @@ static void printbits(unsigned long val, struct regbit *bits) | |||
| 402 | } | 400 | } | 
| 403 | 401 | ||
| 404 | #ifdef CONFIG_PPC64 | 402 | #ifdef CONFIG_PPC64 | 
| 405 | #define REG "%016lX" | 403 | #define REG "%016lx" | 
| 406 | #define REGS_PER_LINE 4 | 404 | #define REGS_PER_LINE 4 | 
| 407 | #define LAST_VOLATILE 13 | 405 | #define LAST_VOLATILE 13 | 
| 408 | #else | 406 | #else | 
| 409 | #define REG "%08lX" | 407 | #define REG "%08lx" | 
| 410 | #define REGS_PER_LINE 8 | 408 | #define REGS_PER_LINE 8 | 
| 411 | #define LAST_VOLATILE 12 | 409 | #define LAST_VOLATILE 12 | 
| 412 | #endif | 410 | #endif | 
| @@ -421,7 +419,7 @@ void show_regs(struct pt_regs * regs) | |||
| 421 | regs, regs->trap, print_tainted(), init_utsname()->release); | 419 | regs, regs->trap, print_tainted(), init_utsname()->release); | 
| 422 | printk("MSR: "REG" ", regs->msr); | 420 | printk("MSR: "REG" ", regs->msr); | 
| 423 | printbits(regs->msr, msr_bits); | 421 | printbits(regs->msr, msr_bits); | 
| 424 | printk(" CR: %08lX XER: %08lX\n", regs->ccr, regs->xer); | 422 | printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); | 
| 425 | trap = TRAP(regs); | 423 | trap = TRAP(regs); | 
| 426 | if (trap == 0x300 || trap == 0x600) | 424 | if (trap == 0x300 || trap == 0x600) | 
| 427 | printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr); | 425 | printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr); | 
| @@ -572,7 +570,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, | |||
| 572 | kregs->nip = *((unsigned long *)ret_from_fork); | 570 | kregs->nip = *((unsigned long *)ret_from_fork); | 
| 573 | #else | 571 | #else | 
| 574 | kregs->nip = (unsigned long)ret_from_fork; | 572 | kregs->nip = (unsigned long)ret_from_fork; | 
| 575 | p->thread.last_syscall = -1; | ||
| 576 | #endif | 573 | #endif | 
| 577 | 574 | ||
| 578 | return 0; | 575 | return 0; | 
| @@ -823,6 +820,35 @@ out: | |||
| 823 | return error; | 820 | return error; | 
| 824 | } | 821 | } | 
| 825 | 822 | ||
| 823 | #ifdef CONFIG_IRQSTACKS | ||
| 824 | static inline int valid_irq_stack(unsigned long sp, struct task_struct *p, | ||
| 825 | unsigned long nbytes) | ||
| 826 | { | ||
| 827 | unsigned long stack_page; | ||
| 828 | unsigned long cpu = task_cpu(p); | ||
| 829 | |||
| 830 | /* | ||
| 831 | * Avoid crashing if the stack has overflowed and corrupted | ||
| 832 | * task_cpu(p), which is in the thread_info struct. | ||
| 833 | */ | ||
| 834 | if (cpu < NR_CPUS && cpu_possible(cpu)) { | ||
| 835 | stack_page = (unsigned long) hardirq_ctx[cpu]; | ||
| 836 | if (sp >= stack_page + sizeof(struct thread_struct) | ||
| 837 | && sp <= stack_page + THREAD_SIZE - nbytes) | ||
| 838 | return 1; | ||
| 839 | |||
| 840 | stack_page = (unsigned long) softirq_ctx[cpu]; | ||
| 841 | if (sp >= stack_page + sizeof(struct thread_struct) | ||
| 842 | && sp <= stack_page + THREAD_SIZE - nbytes) | ||
| 843 | return 1; | ||
| 844 | } | ||
| 845 | return 0; | ||
| 846 | } | ||
| 847 | |||
| 848 | #else | ||
| 849 | #define valid_irq_stack(sp, p, nb) 0 | ||
| 850 | #endif /* CONFIG_IRQSTACKS */ | ||
| 851 | |||
| 826 | int validate_sp(unsigned long sp, struct task_struct *p, | 852 | int validate_sp(unsigned long sp, struct task_struct *p, | 
| 827 | unsigned long nbytes) | 853 | unsigned long nbytes) | 
| 828 | { | 854 | { | 
| @@ -832,19 +858,7 @@ int validate_sp(unsigned long sp, struct task_struct *p, | |||
| 832 | && sp <= stack_page + THREAD_SIZE - nbytes) | 858 | && sp <= stack_page + THREAD_SIZE - nbytes) | 
| 833 | return 1; | 859 | return 1; | 
| 834 | 860 | ||
| 835 | #ifdef CONFIG_IRQSTACKS | 861 | return valid_irq_stack(sp, p, nbytes); | 
| 836 | stack_page = (unsigned long) hardirq_ctx[task_cpu(p)]; | ||
| 837 | if (sp >= stack_page + sizeof(struct thread_struct) | ||
| 838 | && sp <= stack_page + THREAD_SIZE - nbytes) | ||
| 839 | return 1; | ||
| 840 | |||
| 841 | stack_page = (unsigned long) softirq_ctx[task_cpu(p)]; | ||
| 842 | if (sp >= stack_page + sizeof(struct thread_struct) | ||
| 843 | && sp <= stack_page + THREAD_SIZE - nbytes) | ||
| 844 | return 1; | ||
| 845 | #endif | ||
| 846 | |||
| 847 | return 0; | ||
| 848 | } | 862 | } | 
| 849 | 863 | ||
| 850 | #ifdef CONFIG_PPC64 | 864 | #ifdef CONFIG_PPC64 | 
| diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 8d52b23348bd..caef555f2dc0 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
| @@ -390,18 +390,19 @@ static unsigned long __init unflatten_dt_node(unsigned long mem, | |||
| 390 | if (allnextpp) { | 390 | if (allnextpp) { | 
| 391 | pp->name = "name"; | 391 | pp->name = "name"; | 
| 392 | pp->length = sz; | 392 | pp->length = sz; | 
| 393 | pp->value = (unsigned char *)(pp + 1); | 393 | pp->value = pp + 1; | 
| 394 | *prev_pp = pp; | 394 | *prev_pp = pp; | 
| 395 | prev_pp = &pp->next; | 395 | prev_pp = &pp->next; | 
| 396 | memcpy(pp->value, ps, sz - 1); | 396 | memcpy(pp->value, ps, sz - 1); | 
| 397 | ((char *)pp->value)[sz - 1] = 0; | 397 | ((char *)pp->value)[sz - 1] = 0; | 
| 398 | DBG("fixed up name for %s -> %s\n", pathp, pp->value); | 398 | DBG("fixed up name for %s -> %s\n", pathp, | 
| 399 | (char *)pp->value); | ||
| 399 | } | 400 | } | 
| 400 | } | 401 | } | 
| 401 | if (allnextpp) { | 402 | if (allnextpp) { | 
| 402 | *prev_pp = NULL; | 403 | *prev_pp = NULL; | 
| 403 | np->name = get_property(np, "name", NULL); | 404 | np->name = of_get_property(np, "name", NULL); | 
| 404 | np->type = get_property(np, "device_type", NULL); | 405 | np->type = of_get_property(np, "device_type", NULL); | 
| 405 | 406 | ||
| 406 | if (!np->name) | 407 | if (!np->name) | 
| 407 | np->name = "<NULL>"; | 408 | np->name = "<NULL>"; | 
| @@ -719,6 +720,7 @@ static int __init early_init_dt_scan_chosen(unsigned long node, | |||
| 719 | const char *uname, int depth, void *data) | 720 | const char *uname, int depth, void *data) | 
| 720 | { | 721 | { | 
| 721 | unsigned long *lprop; | 722 | unsigned long *lprop; | 
| 723 | u32 *prop; | ||
| 722 | unsigned long l; | 724 | unsigned long l; | 
| 723 | char *p; | 725 | char *p; | 
| 724 | 726 | ||
| @@ -760,6 +762,22 @@ static int __init early_init_dt_scan_chosen(unsigned long node, | |||
| 760 | crashk_res.end = crashk_res.start + *lprop - 1; | 762 | crashk_res.end = crashk_res.start + *lprop - 1; | 
| 761 | #endif | 763 | #endif | 
| 762 | 764 | ||
| 765 | #ifdef CONFIG_BLK_DEV_INITRD | ||
| 766 | DBG("Looking for initrd properties... "); | ||
| 767 | prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l); | ||
| 768 | if (prop) { | ||
| 769 | initrd_start = (unsigned long)__va(of_read_ulong(prop, l/4)); | ||
| 770 | prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l); | ||
| 771 | if (prop) { | ||
| 772 | initrd_end = (unsigned long)__va(of_read_ulong(prop, l/4)); | ||
| 773 | initrd_below_start_ok = 1; | ||
| 774 | } else { | ||
| 775 | initrd_start = 0; | ||
| 776 | } | ||
| 777 | } | ||
| 778 | DBG("initrd_start=0x%lx initrd_end=0x%lx\n", initrd_start, initrd_end); | ||
| 779 | #endif /* CONFIG_BLK_DEV_INITRD */ | ||
| 780 | |||
| 763 | /* Retreive command line */ | 781 | /* Retreive command line */ | 
| 764 | p = of_get_flat_dt_prop(node, "bootargs", &l); | 782 | p = of_get_flat_dt_prop(node, "bootargs", &l); | 
| 765 | if (p != NULL && l > 0) | 783 | if (p != NULL && l > 0) | 
| @@ -926,6 +944,12 @@ static void __init early_reserve_mem(void) | |||
| 926 | self_size = initial_boot_params->totalsize; | 944 | self_size = initial_boot_params->totalsize; | 
| 927 | lmb_reserve(self_base, self_size); | 945 | lmb_reserve(self_base, self_size); | 
| 928 | 946 | ||
| 947 | #ifdef CONFIG_BLK_DEV_INITRD | ||
| 948 | /* then reserve the initrd, if any */ | ||
| 949 | if (initrd_start && (initrd_end > initrd_start)) | ||
| 950 | lmb_reserve(__pa(initrd_start), initrd_end - initrd_start); | ||
| 951 | #endif /* CONFIG_BLK_DEV_INITRD */ | ||
| 952 | |||
| 929 | #ifdef CONFIG_PPC32 | 953 | #ifdef CONFIG_PPC32 | 
| 930 | /* | 954 | /* | 
| 931 | * Handle the case where we might be booting from an old kexec | 955 | * Handle the case where we might be booting from an old kexec | 
| @@ -954,9 +978,6 @@ static void __init early_reserve_mem(void) | |||
| 954 | size = *(reserve_map++); | 978 | size = *(reserve_map++); | 
| 955 | if (size == 0) | 979 | if (size == 0) | 
| 956 | break; | 980 | break; | 
| 957 | /* skip if the reservation is for the blob */ | ||
| 958 | if (base == self_base && size == self_size) | ||
| 959 | continue; | ||
| 960 | DBG("reserving: %llx -> %llx\n", base, size); | 981 | DBG("reserving: %llx -> %llx\n", base, size); | 
| 961 | lmb_reserve(base, size); | 982 | lmb_reserve(base, size); | 
| 962 | } | 983 | } | 
| @@ -1021,102 +1042,46 @@ void __init early_init_devtree(void *params) | |||
| 1021 | 1042 | ||
| 1022 | #undef printk | 1043 | #undef printk | 
| 1023 | 1044 | ||
| 1024 | int | 1045 | int of_n_addr_cells(struct device_node* np) | 
| 1025 | prom_n_addr_cells(struct device_node* np) | ||
| 1026 | { | 1046 | { | 
| 1027 | const int *ip; | 1047 | const int *ip; | 
| 1028 | do { | 1048 | do { | 
| 1029 | if (np->parent) | 1049 | if (np->parent) | 
| 1030 | np = np->parent; | 1050 | np = np->parent; | 
| 1031 | ip = get_property(np, "#address-cells", NULL); | 1051 | ip = of_get_property(np, "#address-cells", NULL); | 
| 1032 | if (ip != NULL) | 1052 | if (ip != NULL) | 
| 1033 | return *ip; | 1053 | return *ip; | 
| 1034 | } while (np->parent); | 1054 | } while (np->parent); | 
| 1035 | /* No #address-cells property for the root node, default to 1 */ | 1055 | /* No #address-cells property for the root node, default to 1 */ | 
| 1036 | return 1; | 1056 | return 1; | 
| 1037 | } | 1057 | } | 
| 1038 | EXPORT_SYMBOL(prom_n_addr_cells); | 1058 | EXPORT_SYMBOL(of_n_addr_cells); | 
| 1039 | 1059 | ||
| 1040 | int | 1060 | int of_n_size_cells(struct device_node* np) | 
| 1041 | prom_n_size_cells(struct device_node* np) | ||
| 1042 | { | 1061 | { | 
| 1043 | const int* ip; | 1062 | const int* ip; | 
| 1044 | do { | 1063 | do { | 
| 1045 | if (np->parent) | 1064 | if (np->parent) | 
| 1046 | np = np->parent; | 1065 | np = np->parent; | 
| 1047 | ip = get_property(np, "#size-cells", NULL); | 1066 | ip = of_get_property(np, "#size-cells", NULL); | 
| 1048 | if (ip != NULL) | 1067 | if (ip != NULL) | 
| 1049 | return *ip; | 1068 | return *ip; | 
| 1050 | } while (np->parent); | 1069 | } while (np->parent); | 
| 1051 | /* No #size-cells property for the root node, default to 1 */ | 1070 | /* No #size-cells property for the root node, default to 1 */ | 
| 1052 | return 1; | 1071 | return 1; | 
| 1053 | } | 1072 | } | 
| 1054 | EXPORT_SYMBOL(prom_n_size_cells); | 1073 | EXPORT_SYMBOL(of_n_size_cells); | 
| 1055 | |||
| 1056 | /** | ||
| 1057 | * Construct and return a list of the device_nodes with a given name. | ||
| 1058 | */ | ||
| 1059 | struct device_node *find_devices(const char *name) | ||
| 1060 | { | ||
| 1061 | struct device_node *head, **prevp, *np; | ||
| 1062 | |||
| 1063 | prevp = &head; | ||
| 1064 | for (np = allnodes; np != 0; np = np->allnext) { | ||
| 1065 | if (np->name != 0 && strcasecmp(np->name, name) == 0) { | ||
| 1066 | *prevp = np; | ||
| 1067 | prevp = &np->next; | ||
| 1068 | } | ||
| 1069 | } | ||
| 1070 | *prevp = NULL; | ||
| 1071 | return head; | ||
| 1072 | } | ||
| 1073 | EXPORT_SYMBOL(find_devices); | ||
| 1074 | |||
| 1075 | /** | ||
| 1076 | * Construct and return a list of the device_nodes with a given type. | ||
| 1077 | */ | ||
| 1078 | struct device_node *find_type_devices(const char *type) | ||
| 1079 | { | ||
| 1080 | struct device_node *head, **prevp, *np; | ||
| 1081 | |||
| 1082 | prevp = &head; | ||
| 1083 | for (np = allnodes; np != 0; np = np->allnext) { | ||
| 1084 | if (np->type != 0 && strcasecmp(np->type, type) == 0) { | ||
| 1085 | *prevp = np; | ||
| 1086 | prevp = &np->next; | ||
| 1087 | } | ||
| 1088 | } | ||
| 1089 | *prevp = NULL; | ||
| 1090 | return head; | ||
| 1091 | } | ||
| 1092 | EXPORT_SYMBOL(find_type_devices); | ||
| 1093 | |||
| 1094 | /** | ||
| 1095 | * Returns all nodes linked together | ||
| 1096 | */ | ||
| 1097 | struct device_node *find_all_nodes(void) | ||
| 1098 | { | ||
| 1099 | struct device_node *head, **prevp, *np; | ||
| 1100 | |||
| 1101 | prevp = &head; | ||
| 1102 | for (np = allnodes; np != 0; np = np->allnext) { | ||
| 1103 | *prevp = np; | ||
| 1104 | prevp = &np->next; | ||
| 1105 | } | ||
| 1106 | *prevp = NULL; | ||
| 1107 | return head; | ||
| 1108 | } | ||
| 1109 | EXPORT_SYMBOL(find_all_nodes); | ||
| 1110 | 1074 | ||
| 1111 | /** Checks if the given "compat" string matches one of the strings in | 1075 | /** Checks if the given "compat" string matches one of the strings in | 
| 1112 | * the device's "compatible" property | 1076 | * the device's "compatible" property | 
| 1113 | */ | 1077 | */ | 
| 1114 | int device_is_compatible(const struct device_node *device, const char *compat) | 1078 | int of_device_is_compatible(const struct device_node *device, | 
| 1079 | const char *compat) | ||
| 1115 | { | 1080 | { | 
| 1116 | const char* cp; | 1081 | const char* cp; | 
| 1117 | int cplen, l; | 1082 | int cplen, l; | 
| 1118 | 1083 | ||
| 1119 | cp = get_property(device, "compatible", &cplen); | 1084 | cp = of_get_property(device, "compatible", &cplen); | 
| 1120 | if (cp == NULL) | 1085 | if (cp == NULL) | 
| 1121 | return 0; | 1086 | return 0; | 
| 1122 | while (cplen > 0) { | 1087 | while (cplen > 0) { | 
| @@ -1129,7 +1094,7 @@ int device_is_compatible(const struct device_node *device, const char *compat) | |||
| 1129 | 1094 | ||
| 1130 | return 0; | 1095 | return 0; | 
| 1131 | } | 1096 | } | 
| 1132 | EXPORT_SYMBOL(device_is_compatible); | 1097 | EXPORT_SYMBOL(of_device_is_compatible); | 
| 1133 | 1098 | ||
| 1134 | 1099 | ||
| 1135 | /** | 1100 | /** | 
| @@ -1143,51 +1108,13 @@ int machine_is_compatible(const char *compat) | |||
| 1143 | 1108 | ||
| 1144 | root = of_find_node_by_path("/"); | 1109 | root = of_find_node_by_path("/"); | 
| 1145 | if (root) { | 1110 | if (root) { | 
| 1146 | rc = device_is_compatible(root, compat); | 1111 | rc = of_device_is_compatible(root, compat); | 
| 1147 | of_node_put(root); | 1112 | of_node_put(root); | 
| 1148 | } | 1113 | } | 
| 1149 | return rc; | 1114 | return rc; | 
| 1150 | } | 1115 | } | 
| 1151 | EXPORT_SYMBOL(machine_is_compatible); | 1116 | EXPORT_SYMBOL(machine_is_compatible); | 
| 1152 | 1117 | ||
| 1153 | /** | ||
| 1154 | * Construct and return a list of the device_nodes with a given type | ||
| 1155 | * and compatible property. | ||
| 1156 | */ | ||
| 1157 | struct device_node *find_compatible_devices(const char *type, | ||
| 1158 | const char *compat) | ||
| 1159 | { | ||
| 1160 | struct device_node *head, **prevp, *np; | ||
| 1161 | |||
| 1162 | prevp = &head; | ||
| 1163 | for (np = allnodes; np != 0; np = np->allnext) { | ||
| 1164 | if (type != NULL | ||
| 1165 | && !(np->type != 0 && strcasecmp(np->type, type) == 0)) | ||
| 1166 | continue; | ||
| 1167 | if (device_is_compatible(np, compat)) { | ||
| 1168 | *prevp = np; | ||
| 1169 | prevp = &np->next; | ||
| 1170 | } | ||
| 1171 | } | ||
| 1172 | *prevp = NULL; | ||
| 1173 | return head; | ||
| 1174 | } | ||
| 1175 | EXPORT_SYMBOL(find_compatible_devices); | ||
| 1176 | |||
| 1177 | /** | ||
| 1178 | * Find the device_node with a given full_name. | ||
| 1179 | */ | ||
| 1180 | struct device_node *find_path_device(const char *path) | ||
| 1181 | { | ||
| 1182 | struct device_node *np; | ||
| 1183 | |||
| 1184 | for (np = allnodes; np != 0; np = np->allnext) | ||
| 1185 | if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0) | ||
| 1186 | return np; | ||
| 1187 | return NULL; | ||
| 1188 | } | ||
| 1189 | EXPORT_SYMBOL(find_path_device); | ||
| 1190 | |||
| 1191 | /******* | 1118 | /******* | 
| 1192 | * | 1119 | * | 
| 1193 | * New implementation of the OF "find" APIs, return a refcounted | 1120 | * New implementation of the OF "find" APIs, return a refcounted | 
| @@ -1280,7 +1207,7 @@ struct device_node *of_find_compatible_node(struct device_node *from, | |||
| 1280 | if (type != NULL | 1207 | if (type != NULL | 
| 1281 | && !(np->type != 0 && strcasecmp(np->type, type) == 0)) | 1208 | && !(np->type != 0 && strcasecmp(np->type, type) == 0)) | 
| 1282 | continue; | 1209 | continue; | 
| 1283 | if (device_is_compatible(np, compatible) && of_node_get(np)) | 1210 | if (of_device_is_compatible(np, compatible) && of_node_get(np)) | 
| 1284 | break; | 1211 | break; | 
| 1285 | } | 1212 | } | 
| 1286 | of_node_put(from); | 1213 | of_node_put(from); | 
| @@ -1527,8 +1454,8 @@ static int of_finish_dynamic_node(struct device_node *node) | |||
| 1527 | int err = 0; | 1454 | int err = 0; | 
| 1528 | const phandle *ibm_phandle; | 1455 | const phandle *ibm_phandle; | 
| 1529 | 1456 | ||
| 1530 | node->name = get_property(node, "name", NULL); | 1457 | node->name = of_get_property(node, "name", NULL); | 
| 1531 | node->type = get_property(node, "device_type", NULL); | 1458 | node->type = of_get_property(node, "device_type", NULL); | 
| 1532 | 1459 | ||
| 1533 | if (!parent) { | 1460 | if (!parent) { | 
| 1534 | err = -ENODEV; | 1461 | err = -ENODEV; | 
| @@ -1542,7 +1469,7 @@ static int of_finish_dynamic_node(struct device_node *node) | |||
| 1542 | return -ENODEV; | 1469 | return -ENODEV; | 
| 1543 | 1470 | ||
| 1544 | /* fix up new node's linux_phandle field */ | 1471 | /* fix up new node's linux_phandle field */ | 
| 1545 | if ((ibm_phandle = get_property(node, "ibm,phandle", NULL))) | 1472 | if ((ibm_phandle = of_get_property(node, "ibm,phandle", NULL))) | 
| 1546 | node->linux_phandle = *ibm_phandle; | 1473 | node->linux_phandle = *ibm_phandle; | 
| 1547 | 1474 | ||
| 1548 | out: | 1475 | out: | 
| @@ -1605,13 +1532,13 @@ EXPORT_SYMBOL(of_find_property); | |||
| 1605 | * Find a property with a given name for a given node | 1532 | * Find a property with a given name for a given node | 
| 1606 | * and return the value. | 1533 | * and return the value. | 
| 1607 | */ | 1534 | */ | 
| 1608 | const void *get_property(const struct device_node *np, const char *name, | 1535 | const void *of_get_property(const struct device_node *np, const char *name, | 
| 1609 | int *lenp) | 1536 | int *lenp) | 
| 1610 | { | 1537 | { | 
| 1611 | struct property *pp = of_find_property(np,name,lenp); | 1538 | struct property *pp = of_find_property(np,name,lenp); | 
| 1612 | return pp ? pp->value : NULL; | 1539 | return pp ? pp->value : NULL; | 
| 1613 | } | 1540 | } | 
| 1614 | EXPORT_SYMBOL(get_property); | 1541 | EXPORT_SYMBOL(of_get_property); | 
| 1615 | 1542 | ||
| 1616 | /* | 1543 | /* | 
| 1617 | * Add a property to a node | 1544 | * Add a property to a node | 
| @@ -1742,10 +1669,10 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) | |||
| 1742 | /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist | 1669 | /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist | 
| 1743 | * fallback to "reg" property and assume no threads | 1670 | * fallback to "reg" property and assume no threads | 
| 1744 | */ | 1671 | */ | 
| 1745 | intserv = get_property(np, "ibm,ppc-interrupt-server#s", | 1672 | intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", | 
| 1746 | &plen); | 1673 | &plen); | 
| 1747 | if (intserv == NULL) { | 1674 | if (intserv == NULL) { | 
| 1748 | const u32 *reg = get_property(np, "reg", NULL); | 1675 | const u32 *reg = of_get_property(np, "reg", NULL); | 
| 1749 | if (reg == NULL) | 1676 | if (reg == NULL) | 
| 1750 | continue; | 1677 | continue; | 
| 1751 | if (*reg == hardid) { | 1678 | if (*reg == hardid) { | 
| diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 4fb5938ce6d3..e27d9d1b6e67 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
| @@ -2035,39 +2035,50 @@ static void __init fixup_device_tree_maple(void) | |||
| 2035 | #endif | 2035 | #endif | 
| 2036 | 2036 | ||
| 2037 | #ifdef CONFIG_PPC_CHRP | 2037 | #ifdef CONFIG_PPC_CHRP | 
| 2038 | /* Pegasos and BriQ lacks the "ranges" property in the isa node */ | 2038 | /* | 
| 2039 | * Pegasos and BriQ lacks the "ranges" property in the isa node | ||
| 2040 | * Pegasos needs decimal IRQ 14/15, not hexadecimal | ||
| 2041 | */ | ||
| 2039 | static void __init fixup_device_tree_chrp(void) | 2042 | static void __init fixup_device_tree_chrp(void) | 
| 2040 | { | 2043 | { | 
| 2041 | phandle isa; | 2044 | phandle ph; | 
| 2042 | u32 isa_ranges[6]; | 2045 | u32 prop[6]; | 
| 2043 | u32 rloc = 0x01006000; /* IO space; PCI device = 12 */ | 2046 | u32 rloc = 0x01006000; /* IO space; PCI device = 12 */ | 
| 2044 | char *name; | 2047 | char *name; | 
| 2045 | int rc; | 2048 | int rc; | 
| 2046 | 2049 | ||
| 2047 | name = "/pci@80000000/isa@c"; | 2050 | name = "/pci@80000000/isa@c"; | 
| 2048 | isa = call_prom("finddevice", 1, 1, ADDR(name)); | 2051 | ph = call_prom("finddevice", 1, 1, ADDR(name)); | 
| 2049 | if (!PHANDLE_VALID(isa)) { | 2052 | if (!PHANDLE_VALID(ph)) { | 
| 2050 | name = "/pci@ff500000/isa@6"; | 2053 | name = "/pci@ff500000/isa@6"; | 
| 2051 | isa = call_prom("finddevice", 1, 1, ADDR(name)); | 2054 | ph = call_prom("finddevice", 1, 1, ADDR(name)); | 
| 2052 | rloc = 0x01003000; /* IO space; PCI device = 6 */ | 2055 | rloc = 0x01003000; /* IO space; PCI device = 6 */ | 
| 2053 | } | 2056 | } | 
| 2054 | if (!PHANDLE_VALID(isa)) | 2057 | if (PHANDLE_VALID(ph)) { | 
| 2055 | return; | 2058 | rc = prom_getproplen(ph, "ranges"); | 
| 2056 | 2059 | if (rc == 0 || rc == PROM_ERROR) { | |
| 2057 | rc = prom_getproplen(isa, "ranges"); | 2060 | prom_printf("Fixing up missing ISA range on Pegasos...\n"); | 
| 2058 | if (rc != 0 && rc != PROM_ERROR) | 2061 | |
| 2059 | return; | 2062 | prop[0] = 0x1; | 
| 2060 | 2063 | prop[1] = 0x0; | |
| 2061 | prom_printf("Fixing up missing ISA range on Pegasos...\n"); | 2064 | prop[2] = rloc; | 
| 2065 | prop[3] = 0x0; | ||
| 2066 | prop[4] = 0x0; | ||
| 2067 | prop[5] = 0x00010000; | ||
| 2068 | prom_setprop(ph, name, "ranges", prop, sizeof(prop)); | ||
| 2069 | } | ||
| 2070 | } | ||
| 2062 | 2071 | ||
| 2063 | isa_ranges[0] = 0x1; | 2072 | name = "/pci@80000000/ide@C,1"; | 
| 2064 | isa_ranges[1] = 0x0; | 2073 | ph = call_prom("finddevice", 1, 1, ADDR(name)); | 
| 2065 | isa_ranges[2] = rloc; | 2074 | if (PHANDLE_VALID(ph)) { | 
| 2066 | isa_ranges[3] = 0x0; | 2075 | prom_printf("Fixing up IDE interrupt on Pegasos...\n"); | 
| 2067 | isa_ranges[4] = 0x0; | 2076 | prop[0] = 14; | 
| 2068 | isa_ranges[5] = 0x00010000; | 2077 | prop[1] = 0x0; | 
| 2069 | prom_setprop(isa, name, "ranges", | 2078 | prop[2] = 15; | 
| 2070 | isa_ranges, sizeof(isa_ranges)); | 2079 | prop[3] = 0x0; | 
| 2080 | prom_setprop(ph, name, "interrupts", prop, 4*sizeof(u32)); | ||
| 2081 | } | ||
| 2071 | } | 2082 | } | 
| 2072 | #else | 2083 | #else | 
| 2073 | #define fixup_device_tree_chrp() | 2084 | #define fixup_device_tree_chrp() | 
| diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index 91b443c9a488..aa40a5307294 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c | |||
| @@ -68,9 +68,9 @@ static void of_bus_default_count_cells(struct device_node *dev, | |||
| 68 | int *addrc, int *sizec) | 68 | int *addrc, int *sizec) | 
| 69 | { | 69 | { | 
| 70 | if (addrc) | 70 | if (addrc) | 
| 71 | *addrc = prom_n_addr_cells(dev); | 71 | *addrc = of_n_addr_cells(dev); | 
| 72 | if (sizec) | 72 | if (sizec) | 
| 73 | *sizec = prom_n_size_cells(dev); | 73 | *sizec = of_n_size_cells(dev); | 
| 74 | } | 74 | } | 
| 75 | 75 | ||
| 76 | static u64 of_bus_default_map(u32 *addr, const u32 *range, | 76 | static u64 of_bus_default_map(u32 *addr, const u32 *range, | 
| @@ -196,7 +196,7 @@ const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, | |||
| 196 | return NULL; | 196 | return NULL; | 
| 197 | 197 | ||
| 198 | /* Get "reg" or "assigned-addresses" property */ | 198 | /* Get "reg" or "assigned-addresses" property */ | 
| 199 | prop = get_property(dev, bus->addresses, &psize); | 199 | prop = of_get_property(dev, bus->addresses, &psize); | 
| 200 | if (prop == NULL) | 200 | if (prop == NULL) | 
| 201 | return NULL; | 201 | return NULL; | 
| 202 | psize /= 4; | 202 | psize /= 4; | 
| @@ -438,7 +438,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, | |||
| 438 | * to translate addresses that aren't supposed to be translated in | 438 | * to translate addresses that aren't supposed to be translated in | 
| 439 | * the first place. --BenH. | 439 | * the first place. --BenH. | 
| 440 | */ | 440 | */ | 
| 441 | ranges = get_property(parent, "ranges", &rlen); | 441 | ranges = of_get_property(parent, "ranges", &rlen); | 
| 442 | if (ranges == NULL || rlen == 0) { | 442 | if (ranges == NULL || rlen == 0) { | 
| 443 | offset = of_read_number(addr, na); | 443 | offset = of_read_number(addr, na); | 
| 444 | memset(addr, 0, pna * 4); | 444 | memset(addr, 0, pna * 4); | 
| @@ -578,7 +578,7 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size, | |||
| 578 | return NULL; | 578 | return NULL; | 
| 579 | 579 | ||
| 580 | /* Get "reg" or "assigned-addresses" property */ | 580 | /* Get "reg" or "assigned-addresses" property */ | 
| 581 | prop = get_property(dev, bus->addresses, &psize); | 581 | prop = of_get_property(dev, bus->addresses, &psize); | 
| 582 | if (prop == NULL) | 582 | if (prop == NULL) | 
| 583 | return NULL; | 583 | return NULL; | 
| 584 | psize /= 4; | 584 | psize /= 4; | 
| @@ -650,17 +650,17 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, | |||
| 650 | /* busno is always one cell */ | 650 | /* busno is always one cell */ | 
| 651 | *busno = *(dma_window++); | 651 | *busno = *(dma_window++); | 
| 652 | 652 | ||
| 653 | prop = get_property(dn, "ibm,#dma-address-cells", NULL); | 653 | prop = of_get_property(dn, "ibm,#dma-address-cells", NULL); | 
| 654 | if (!prop) | 654 | if (!prop) | 
| 655 | prop = get_property(dn, "#address-cells", NULL); | 655 | prop = of_get_property(dn, "#address-cells", NULL); | 
| 656 | 656 | ||
| 657 | cells = prop ? *(u32 *)prop : prom_n_addr_cells(dn); | 657 | cells = prop ? *(u32 *)prop : of_n_addr_cells(dn); | 
| 658 | *phys = of_read_number(dma_window, cells); | 658 | *phys = of_read_number(dma_window, cells); | 
| 659 | 659 | ||
| 660 | dma_window += cells; | 660 | dma_window += cells; | 
| 661 | 661 | ||
| 662 | prop = get_property(dn, "ibm,#dma-size-cells", NULL); | 662 | prop = of_get_property(dn, "ibm,#dma-size-cells", NULL); | 
| 663 | cells = prop ? *(u32 *)prop : prom_n_size_cells(dn); | 663 | cells = prop ? *(u32 *)prop : of_n_size_cells(dn); | 
| 664 | *size = of_read_number(dma_window, cells); | 664 | *size = of_read_number(dma_window, cells); | 
| 665 | } | 665 | } | 
| 666 | 666 | ||
| @@ -680,7 +680,7 @@ static struct device_node *of_irq_find_parent(struct device_node *child) | |||
| 680 | return NULL; | 680 | return NULL; | 
| 681 | 681 | ||
| 682 | do { | 682 | do { | 
| 683 | parp = get_property(child, "interrupt-parent", NULL); | 683 | parp = of_get_property(child, "interrupt-parent", NULL); | 
| 684 | if (parp == NULL) | 684 | if (parp == NULL) | 
| 685 | p = of_get_parent(child); | 685 | p = of_get_parent(child); | 
| 686 | else { | 686 | else { | 
| @@ -691,7 +691,7 @@ static struct device_node *of_irq_find_parent(struct device_node *child) | |||
| 691 | } | 691 | } | 
| 692 | of_node_put(child); | 692 | of_node_put(child); | 
| 693 | child = p; | 693 | child = p; | 
| 694 | } while (p && get_property(p, "#interrupt-cells", NULL) == NULL); | 694 | } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); | 
| 695 | 695 | ||
| 696 | return p; | 696 | return p; | 
| 697 | } | 697 | } | 
| @@ -716,7 +716,7 @@ void of_irq_map_init(unsigned int flags) | |||
| 716 | struct device_node *np; | 716 | struct device_node *np; | 
| 717 | 717 | ||
| 718 | for(np = NULL; (np = of_find_all_nodes(np)) != NULL;) { | 718 | for(np = NULL; (np = of_find_all_nodes(np)) != NULL;) { | 
| 719 | if (get_property(np, "interrupt-controller", NULL) | 719 | if (of_get_property(np, "interrupt-controller", NULL) | 
| 720 | == NULL) | 720 | == NULL) | 
| 721 | continue; | 721 | continue; | 
| 722 | /* Skip /chosen/interrupt-controller */ | 722 | /* Skip /chosen/interrupt-controller */ | 
| @@ -755,7 +755,7 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, | |||
| 755 | * is none, we are nice and just walk up the tree | 755 | * is none, we are nice and just walk up the tree | 
| 756 | */ | 756 | */ | 
| 757 | do { | 757 | do { | 
| 758 | tmp = get_property(ipar, "#interrupt-cells", NULL); | 758 | tmp = of_get_property(ipar, "#interrupt-cells", NULL); | 
| 759 | if (tmp != NULL) { | 759 | if (tmp != NULL) { | 
| 760 | intsize = *tmp; | 760 | intsize = *tmp; | 
| 761 | break; | 761 | break; | 
| @@ -779,7 +779,7 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, | |||
| 779 | */ | 779 | */ | 
| 780 | old = of_node_get(ipar); | 780 | old = of_node_get(ipar); | 
| 781 | do { | 781 | do { | 
| 782 | tmp = get_property(old, "#address-cells", NULL); | 782 | tmp = of_get_property(old, "#address-cells", NULL); | 
| 783 | tnode = of_get_parent(old); | 783 | tnode = of_get_parent(old); | 
| 784 | of_node_put(old); | 784 | of_node_put(old); | 
| 785 | old = tnode; | 785 | old = tnode; | 
| @@ -795,7 +795,8 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, | |||
| 795 | /* Now check if cursor is an interrupt-controller and if it is | 795 | /* Now check if cursor is an interrupt-controller and if it is | 
| 796 | * then we are done | 796 | * then we are done | 
| 797 | */ | 797 | */ | 
| 798 | if (get_property(ipar, "interrupt-controller", NULL) != NULL) { | 798 | if (of_get_property(ipar, "interrupt-controller", NULL) != | 
| 799 | NULL) { | ||
| 799 | DBG(" -> got it !\n"); | 800 | DBG(" -> got it !\n"); | 
| 800 | memcpy(out_irq->specifier, intspec, | 801 | memcpy(out_irq->specifier, intspec, | 
| 801 | intsize * sizeof(u32)); | 802 | intsize * sizeof(u32)); | 
| @@ -806,7 +807,7 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, | |||
| 806 | } | 807 | } | 
| 807 | 808 | ||
| 808 | /* Now look for an interrupt-map */ | 809 | /* Now look for an interrupt-map */ | 
| 809 | imap = get_property(ipar, "interrupt-map", &imaplen); | 810 | imap = of_get_property(ipar, "interrupt-map", &imaplen); | 
| 810 | /* No interrupt map, check for an interrupt parent */ | 811 | /* No interrupt map, check for an interrupt parent */ | 
| 811 | if (imap == NULL) { | 812 | if (imap == NULL) { | 
| 812 | DBG(" -> no map, getting parent\n"); | 813 | DBG(" -> no map, getting parent\n"); | 
| @@ -816,7 +817,7 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, | |||
| 816 | imaplen /= sizeof(u32); | 817 | imaplen /= sizeof(u32); | 
| 817 | 818 | ||
| 818 | /* Look for a mask */ | 819 | /* Look for a mask */ | 
| 819 | imask = get_property(ipar, "interrupt-map-mask", NULL); | 820 | imask = of_get_property(ipar, "interrupt-map-mask", NULL); | 
| 820 | 821 | ||
| 821 | /* If we were passed no "reg" property and we attempt to parse | 822 | /* If we were passed no "reg" property and we attempt to parse | 
| 822 | * an interrupt-map, then #address-cells must be 0. | 823 | * an interrupt-map, then #address-cells must be 0. | 
| @@ -863,15 +864,13 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, | |||
| 863 | /* Get #interrupt-cells and #address-cells of new | 864 | /* Get #interrupt-cells and #address-cells of new | 
| 864 | * parent | 865 | * parent | 
| 865 | */ | 866 | */ | 
| 866 | tmp = get_property(newpar, "#interrupt-cells", | 867 | tmp = of_get_property(newpar, "#interrupt-cells", NULL); | 
| 867 | NULL); | ||
| 868 | if (tmp == NULL) { | 868 | if (tmp == NULL) { | 
| 869 | DBG(" -> parent lacks #interrupt-cells !\n"); | 869 | DBG(" -> parent lacks #interrupt-cells !\n"); | 
| 870 | goto fail; | 870 | goto fail; | 
| 871 | } | 871 | } | 
| 872 | newintsize = *tmp; | 872 | newintsize = *tmp; | 
| 873 | tmp = get_property(newpar, "#address-cells", | 873 | tmp = of_get_property(newpar, "#address-cells", NULL); | 
| 874 | NULL); | ||
| 875 | newaddrsize = (tmp == NULL) ? 0 : *tmp; | 874 | newaddrsize = (tmp == NULL) ? 0 : *tmp; | 
| 876 | 875 | ||
| 877 | DBG(" -> newintsize=%d, newaddrsize=%d\n", | 876 | DBG(" -> newintsize=%d, newaddrsize=%d\n", | 
| @@ -928,7 +927,7 @@ static int of_irq_map_oldworld(struct device_node *device, int index, | |||
| 928 | * everything together on these) | 927 | * everything together on these) | 
| 929 | */ | 928 | */ | 
| 930 | while (device) { | 929 | while (device) { | 
| 931 | ints = get_property(device, "AAPL,interrupts", &intlen); | 930 | ints = of_get_property(device, "AAPL,interrupts", &intlen); | 
| 932 | if (ints != NULL) | 931 | if (ints != NULL) | 
| 933 | break; | 932 | break; | 
| 934 | device = device->parent; | 933 | device = device->parent; | 
| @@ -970,13 +969,13 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq | |||
| 970 | return of_irq_map_oldworld(device, index, out_irq); | 969 | return of_irq_map_oldworld(device, index, out_irq); | 
| 971 | 970 | ||
| 972 | /* Get the interrupts property */ | 971 | /* Get the interrupts property */ | 
| 973 | intspec = get_property(device, "interrupts", &intlen); | 972 | intspec = of_get_property(device, "interrupts", &intlen); | 
| 974 | if (intspec == NULL) | 973 | if (intspec == NULL) | 
| 975 | return -EINVAL; | 974 | return -EINVAL; | 
| 976 | intlen /= sizeof(u32); | 975 | intlen /= sizeof(u32); | 
| 977 | 976 | ||
| 978 | /* Get the reg property (if any) */ | 977 | /* Get the reg property (if any) */ | 
| 979 | addr = get_property(device, "reg", NULL); | 978 | addr = of_get_property(device, "reg", NULL); | 
| 980 | 979 | ||
| 981 | /* Look for the interrupt parent. */ | 980 | /* Look for the interrupt parent. */ | 
| 982 | p = of_irq_find_parent(device); | 981 | p = of_irq_find_parent(device); | 
| @@ -984,7 +983,7 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq | |||
| 984 | return -EINVAL; | 983 | return -EINVAL; | 
| 985 | 984 | ||
| 986 | /* Get size of interrupt specifier */ | 985 | /* Get size of interrupt specifier */ | 
| 987 | tmp = get_property(p, "#interrupt-cells", NULL); | 986 | tmp = of_get_property(p, "#interrupt-cells", NULL); | 
| 988 | if (tmp == NULL) { | 987 | if (tmp == NULL) { | 
| 989 | of_node_put(p); | 988 | of_node_put(p); | 
| 990 | return -EINVAL; | 989 | return -EINVAL; | 
| diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c index 6cbf2ae5d7aa..190b7ed1dbfb 100644 --- a/arch/powerpc/kernel/rtas-proc.c +++ b/arch/powerpc/kernel/rtas-proc.c | |||
| @@ -450,7 +450,7 @@ static int ppc_rtas_sensors_show(struct seq_file *m, void *v) | |||
| 450 | int llen, offs; | 450 | int llen, offs; | 
| 451 | 451 | ||
| 452 | sprintf (rstr, SENSOR_PREFIX"%04d", p->token); | 452 | sprintf (rstr, SENSOR_PREFIX"%04d", p->token); | 
| 453 | loc = get_property(rtas_node, rstr, &llen); | 453 | loc = of_get_property(rtas_node, rstr, &llen); | 
| 454 | 454 | ||
| 455 | /* A sensor may have multiple instances */ | 455 | /* A sensor may have multiple instances */ | 
| 456 | for (j = 0, offs = 0; j <= p->quant; j++) { | 456 | for (j = 0, offs = 0; j <= p->quant; j++) { | 
| @@ -477,7 +477,7 @@ static int ppc_rtas_find_all_sensors(void) | |||
| 477 | const unsigned int *utmp; | 477 | const unsigned int *utmp; | 
| 478 | int len, i; | 478 | int len, i; | 
| 479 | 479 | ||
| 480 | utmp = get_property(rtas_node, "rtas-sensors", &len); | 480 | utmp = of_get_property(rtas_node, "rtas-sensors", &len); | 
| 481 | if (utmp == NULL) { | 481 | if (utmp == NULL) { | 
| 482 | printk (KERN_ERR "error: could not get rtas-sensors\n"); | 482 | printk (KERN_ERR "error: could not get rtas-sensors\n"); | 
| 483 | return 1; | 483 | return 1; | 
| diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 9d0735a54564..214780798289 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
| @@ -192,18 +192,19 @@ void rtas_progress(char *s, unsigned short hex) | |||
| 192 | 192 | ||
| 193 | if (display_width == 0) { | 193 | if (display_width == 0) { | 
| 194 | display_width = 0x10; | 194 | display_width = 0x10; | 
| 195 | if ((root = find_path_device("/rtas"))) { | 195 | if ((root = of_find_node_by_path("/rtas"))) { | 
| 196 | if ((p = get_property(root, | 196 | if ((p = of_get_property(root, | 
| 197 | "ibm,display-line-length", NULL))) | 197 | "ibm,display-line-length", NULL))) | 
| 198 | display_width = *p; | 198 | display_width = *p; | 
| 199 | if ((p = get_property(root, | 199 | if ((p = of_get_property(root, | 
| 200 | "ibm,form-feed", NULL))) | 200 | "ibm,form-feed", NULL))) | 
| 201 | form_feed = *p; | 201 | form_feed = *p; | 
| 202 | if ((p = get_property(root, | 202 | if ((p = of_get_property(root, | 
| 203 | "ibm,display-number-of-lines", NULL))) | 203 | "ibm,display-number-of-lines", NULL))) | 
| 204 | display_lines = *p; | 204 | display_lines = *p; | 
| 205 | row_width = get_property(root, | 205 | row_width = of_get_property(root, | 
| 206 | "ibm,display-truncation-length", NULL); | 206 | "ibm,display-truncation-length", NULL); | 
| 207 | of_node_put(root); | ||
| 207 | } | 208 | } | 
| 208 | display_character = rtas_token("display-character"); | 209 | display_character = rtas_token("display-character"); | 
| 209 | set_indicator = rtas_token("set-indicator"); | 210 | set_indicator = rtas_token("set-indicator"); | 
| @@ -298,7 +299,7 @@ int rtas_token(const char *service) | |||
| 298 | const int *tokp; | 299 | const int *tokp; | 
| 299 | if (rtas.dev == NULL) | 300 | if (rtas.dev == NULL) | 
| 300 | return RTAS_UNKNOWN_SERVICE; | 301 | return RTAS_UNKNOWN_SERVICE; | 
| 301 | tokp = get_property(rtas.dev, service, NULL); | 302 | tokp = of_get_property(rtas.dev, service, NULL); | 
| 302 | return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; | 303 | return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; | 
| 303 | } | 304 | } | 
| 304 | EXPORT_SYMBOL(rtas_token); | 305 | EXPORT_SYMBOL(rtas_token); | 
| @@ -832,12 +833,12 @@ void __init rtas_initialize(void) | |||
| 832 | if (rtas.dev) { | 833 | if (rtas.dev) { | 
| 833 | const u32 *basep, *entryp, *sizep; | 834 | const u32 *basep, *entryp, *sizep; | 
| 834 | 835 | ||
| 835 | basep = get_property(rtas.dev, "linux,rtas-base", NULL); | 836 | basep = of_get_property(rtas.dev, "linux,rtas-base", NULL); | 
| 836 | sizep = get_property(rtas.dev, "rtas-size", NULL); | 837 | sizep = of_get_property(rtas.dev, "rtas-size", NULL); | 
| 837 | if (basep != NULL && sizep != NULL) { | 838 | if (basep != NULL && sizep != NULL) { | 
| 838 | rtas.base = *basep; | 839 | rtas.base = *basep; | 
| 839 | rtas.size = *sizep; | 840 | rtas.size = *sizep; | 
| 840 | entryp = get_property(rtas.dev, | 841 | entryp = of_get_property(rtas.dev, | 
| 841 | "linux,rtas-entry", NULL); | 842 | "linux,rtas-entry", NULL); | 
| 842 | if (entryp == NULL) /* Ugh */ | 843 | if (entryp == NULL) /* Ugh */ | 
| 843 | rtas.entry = rtas.base; | 844 | rtas.entry = rtas.base; | 
| diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index ace9f4c86e67..f2286822be09 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c | |||
| @@ -60,7 +60,7 @@ static int of_device_available(struct device_node * dn) | |||
| 60 | { | 60 | { | 
| 61 | const char *status; | 61 | const char *status; | 
| 62 | 62 | ||
| 63 | status = get_property(dn, "status", NULL); | 63 | status = of_get_property(dn, "status", NULL); | 
| 64 | 64 | ||
| 65 | if (!status) | 65 | if (!status) | 
| 66 | return 1; | 66 | return 1; | 
| @@ -177,7 +177,7 @@ struct pci_ops rtas_pci_ops = { | |||
| 177 | 177 | ||
| 178 | int is_python(struct device_node *dev) | 178 | int is_python(struct device_node *dev) | 
| 179 | { | 179 | { | 
| 180 | const char *model = get_property(dev, "model", NULL); | 180 | const char *model = of_get_property(dev, "model", NULL); | 
| 181 | 181 | ||
| 182 | if (model && strstr(model, "Python")) | 182 | if (model && strstr(model, "Python")) | 
| 183 | return 1; | 183 | return 1; | 
| @@ -247,7 +247,7 @@ static int phb_set_bus_ranges(struct device_node *dev, | |||
| 247 | const int *bus_range; | 247 | const int *bus_range; | 
| 248 | unsigned int len; | 248 | unsigned int len; | 
| 249 | 249 | ||
| 250 | bus_range = get_property(dev, "bus-range", &len); | 250 | bus_range = of_get_property(dev, "bus-range", &len); | 
| 251 | if (bus_range == NULL || len < 2 * sizeof(int)) { | 251 | if (bus_range == NULL || len < 2 * sizeof(int)) { | 
| 252 | return 1; | 252 | return 1; | 
| 253 | } | 253 | } | 
| @@ -274,7 +274,7 @@ int __devinit rtas_setup_phb(struct pci_controller *phb) | |||
| 274 | return 0; | 274 | return 0; | 
| 275 | } | 275 | } | 
| 276 | 276 | ||
| 277 | unsigned long __init find_and_init_phbs(void) | 277 | void __init find_and_init_phbs(void) | 
| 278 | { | 278 | { | 
| 279 | struct device_node *node; | 279 | struct device_node *node; | 
| 280 | struct pci_controller *phb; | 280 | struct pci_controller *phb; | 
| @@ -309,18 +309,16 @@ unsigned long __init find_and_init_phbs(void) | |||
| 309 | if (of_chosen) { | 309 | if (of_chosen) { | 
| 310 | const int *prop; | 310 | const int *prop; | 
| 311 | 311 | ||
| 312 | prop = get_property(of_chosen, | 312 | prop = of_get_property(of_chosen, | 
| 313 | "linux,pci-probe-only", NULL); | 313 | "linux,pci-probe-only", NULL); | 
| 314 | if (prop) | 314 | if (prop) | 
| 315 | pci_probe_only = *prop; | 315 | pci_probe_only = *prop; | 
| 316 | 316 | ||
| 317 | prop = get_property(of_chosen, | 317 | prop = of_get_property(of_chosen, | 
| 318 | "linux,pci-assign-all-buses", NULL); | 318 | "linux,pci-assign-all-buses", NULL); | 
| 319 | if (prop) | 319 | if (prop) | 
| 320 | pci_assign_all_buses = *prop; | 320 | pci_assign_all_buses = *prop; | 
| 321 | } | 321 | } | 
| 322 | |||
| 323 | return 0; | ||
| 324 | } | 322 | } | 
| 325 | 323 | ||
| 326 | /* RPA-specific bits for removing PHBs */ | 324 | /* RPA-specific bits for removing PHBs */ | 
| diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 89cfaf49d3de..370803722e47 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> | 
| 22 | #include <linux/initrd.h> | 22 | #include <linux/initrd.h> | 
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> | 
| 24 | #include <linux/ide.h> | ||
| 25 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> | 
| 26 | #include <linux/ioport.h> | 25 | #include <linux/ioport.h> | 
| 27 | #include <linux/console.h> | 26 | #include <linux/console.h> | 
| @@ -304,26 +303,8 @@ struct seq_operations cpuinfo_op = { | |||
| 304 | void __init check_for_initrd(void) | 303 | void __init check_for_initrd(void) | 
| 305 | { | 304 | { | 
| 306 | #ifdef CONFIG_BLK_DEV_INITRD | 305 | #ifdef CONFIG_BLK_DEV_INITRD | 
| 307 | const unsigned int *prop; | 306 | DBG(" -> check_for_initrd() initrd_start=0x%lx initrd_end=0x%lx\n", | 
| 308 | int len; | 307 | initrd_start, initrd_end); | 
| 309 | |||
| 310 | DBG(" -> check_for_initrd()\n"); | ||
| 311 | |||
| 312 | if (of_chosen) { | ||
| 313 | prop = get_property(of_chosen, "linux,initrd-start", &len); | ||
| 314 | if (prop != NULL) { | ||
| 315 | initrd_start = (unsigned long) | ||
| 316 | __va(of_read_ulong(prop, len / 4)); | ||
| 317 | prop = get_property(of_chosen, | ||
| 318 | "linux,initrd-end", &len); | ||
| 319 | if (prop != NULL) { | ||
| 320 | initrd_end = (unsigned long) | ||
| 321 | __va(of_read_ulong(prop, len / 4)); | ||
| 322 | initrd_below_start_ok = 1; | ||
| 323 | } else | ||
| 324 | initrd_start = 0; | ||
| 325 | } | ||
| 326 | } | ||
| 327 | 308 | ||
| 328 | /* If we were passed an initrd, set the ROOT_DEV properly if the values | 309 | /* If we were passed an initrd, set the ROOT_DEV properly if the values | 
| 329 | * look sensible. If not, clear initrd reference. | 310 | * look sensible. If not, clear initrd reference. | 
| @@ -371,11 +352,12 @@ void __init smp_setup_cpu_maps(void) | |||
| 371 | const int *intserv; | 352 | const int *intserv; | 
| 372 | int j, len = sizeof(u32), nthreads = 1; | 353 | int j, len = sizeof(u32), nthreads = 1; | 
| 373 | 354 | ||
| 374 | intserv = get_property(dn, "ibm,ppc-interrupt-server#s", &len); | 355 | intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", | 
| 356 | &len); | ||
| 375 | if (intserv) | 357 | if (intserv) | 
| 376 | nthreads = len / sizeof(int); | 358 | nthreads = len / sizeof(int); | 
| 377 | else { | 359 | else { | 
| 378 | intserv = get_property(dn, "reg", NULL); | 360 | intserv = of_get_property(dn, "reg", NULL); | 
| 379 | if (!intserv) | 361 | if (!intserv) | 
| 380 | intserv = &cpu; /* assume logical == phys */ | 362 | intserv = &cpu; /* assume logical == phys */ | 
| 381 | } | 363 | } | 
| @@ -398,10 +380,10 @@ void __init smp_setup_cpu_maps(void) | |||
| 398 | int num_addr_cell, num_size_cell, maxcpus; | 380 | int num_addr_cell, num_size_cell, maxcpus; | 
| 399 | const unsigned int *ireg; | 381 | const unsigned int *ireg; | 
| 400 | 382 | ||
| 401 | num_addr_cell = prom_n_addr_cells(dn); | 383 | num_addr_cell = of_n_addr_cells(dn); | 
| 402 | num_size_cell = prom_n_size_cells(dn); | 384 | num_size_cell = of_n_size_cells(dn); | 
| 403 | 385 | ||
| 404 | ireg = get_property(dn, "ibm,lrdr-capacity", NULL); | 386 | ireg = of_get_property(dn, "ibm,lrdr-capacity", NULL); | 
| 405 | 387 | ||
| 406 | if (!ireg) | 388 | if (!ireg) | 
| 407 | goto out; | 389 | goto out; | 
| @@ -496,11 +478,39 @@ void probe_machine(void) | |||
| 496 | printk(KERN_INFO "Using %s machine description\n", ppc_md.name); | 478 | printk(KERN_INFO "Using %s machine description\n", ppc_md.name); | 
| 497 | } | 479 | } | 
| 498 | 480 | ||
| 481 | /* Match a class of boards, not a specific device configuration. */ | ||
| 499 | int check_legacy_ioport(unsigned long base_port) | 482 | int check_legacy_ioport(unsigned long base_port) | 
| 500 | { | 483 | { | 
| 501 | if (ppc_md.check_legacy_ioport == NULL) | 484 | struct device_node *parent, *np = NULL; | 
| 502 | return 0; | 485 | int ret = -ENODEV; | 
| 503 | return ppc_md.check_legacy_ioport(base_port); | 486 | |
| 487 | switch(base_port) { | ||
| 488 | case I8042_DATA_REG: | ||
| 489 | np = of_find_node_by_type(NULL, "8042"); | ||
| 490 | break; | ||
| 491 | case FDC_BASE: /* FDC1 */ | ||
| 492 | np = of_find_node_by_type(NULL, "fdc"); | ||
| 493 | break; | ||
| 494 | #ifdef CONFIG_PPC_PREP | ||
| 495 | case _PIDXR: | ||
| 496 | case _PNPWRP: | ||
| 497 | case PNPBIOS_BASE: | ||
| 498 | /* implement me */ | ||
| 499 | #endif | ||
| 500 | default: | ||
| 501 | /* ipmi is supposed to fail here */ | ||
| 502 | break; | ||
| 503 | } | ||
| 504 | if (!np) | ||
| 505 | return ret; | ||
| 506 | parent = of_get_parent(np); | ||
| 507 | if (parent) { | ||
| 508 | if (strcmp(parent->type, "isa") == 0) | ||
| 509 | ret = 0; | ||
| 510 | of_node_put(parent); | ||
| 511 | } | ||
| 512 | of_node_put(np); | ||
| 513 | return ret; | ||
| 504 | } | 514 | } | 
| 505 | EXPORT_SYMBOL(check_legacy_ioport); | 515 | EXPORT_SYMBOL(check_legacy_ioport); | 
| 506 | 516 | ||
| diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 44a6a3c47feb..35f8f443c14f 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
| @@ -92,7 +92,8 @@ unsigned long __init early_init(unsigned long dt_ptr) | |||
| 92 | 92 | ||
| 93 | /* First zero the BSS -- use memset_io, some platforms don't have | 93 | /* First zero the BSS -- use memset_io, some platforms don't have | 
| 94 | * caches on yet */ | 94 | * caches on yet */ | 
| 95 | memset_io((void __iomem *)PTRRELOC(&__bss_start), 0, _end - __bss_start); | 95 | memset_io((void __iomem *)PTRRELOC(&__bss_start), 0, | 
| 96 | __bss_stop - __bss_start); | ||
| 96 | 97 | ||
| 97 | /* | 98 | /* | 
| 98 | * Identify the CPU type and fix up code sections | 99 | * Identify the CPU type and fix up code sections | 
| @@ -195,18 +196,22 @@ EXPORT_SYMBOL(nvram_sync); | |||
| 195 | 196 | ||
| 196 | #endif /* CONFIG_NVRAM */ | 197 | #endif /* CONFIG_NVRAM */ | 
| 197 | 198 | ||
| 198 | static struct cpu cpu_devices[NR_CPUS]; | 199 | static DEFINE_PER_CPU(struct cpu, cpu_devices); | 
| 199 | 200 | ||
| 200 | int __init ppc_init(void) | 201 | int __init ppc_init(void) | 
| 201 | { | 202 | { | 
| 202 | int i; | 203 | int cpu; | 
| 203 | 204 | ||
| 204 | /* clear the progress line */ | 205 | /* clear the progress line */ | 
| 205 | if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); | 206 | if (ppc_md.progress) | 
| 207 | ppc_md.progress(" ", 0xffff); | ||
| 206 | 208 | ||
| 207 | /* register CPU devices */ | 209 | /* register CPU devices */ | 
| 208 | for_each_possible_cpu(i) | 210 | for_each_possible_cpu(cpu) { | 
| 209 | register_cpu(&cpu_devices[i], i); | 211 | struct cpu *c = &per_cpu(cpu_devices, cpu); | 
| 212 | c->hotpluggable = 1; | ||
| 213 | register_cpu(c, cpu); | ||
| 214 | } | ||
| 210 | 215 | ||
| 211 | /* call platform init */ | 216 | /* call platform init */ | 
| 212 | if (ppc_md.init != NULL) { | 217 | if (ppc_md.init != NULL) { | 
| diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 3733de30e84d..22083ce3cc30 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | #include <linux/reboot.h> | 20 | #include <linux/reboot.h> | 
| 21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> | 
| 22 | #include <linux/initrd.h> | 22 | #include <linux/initrd.h> | 
| 23 | #include <linux/ide.h> | ||
| 24 | #include <linux/seq_file.h> | 23 | #include <linux/seq_file.h> | 
| 25 | #include <linux/ioport.h> | 24 | #include <linux/ioport.h> | 
| 26 | #include <linux/console.h> | 25 | #include <linux/console.h> | 
| @@ -110,7 +109,7 @@ static void check_smt_enabled(void) | |||
| 110 | dn = of_find_node_by_path("/options"); | 109 | dn = of_find_node_by_path("/options"); | 
| 111 | 110 | ||
| 112 | if (dn) { | 111 | if (dn) { | 
| 113 | smt_option = get_property(dn, "ibm,smt-enabled", NULL); | 112 | smt_option = of_get_property(dn, "ibm,smt-enabled", NULL); | 
| 114 | 113 | ||
| 115 | if (smt_option) { | 114 | if (smt_option) { | 
| 116 | if (!strcmp(smt_option, "on")) | 115 | if (!strcmp(smt_option, "on")) | 
| @@ -305,10 +304,10 @@ static void __init initialize_cache_info(void) | |||
| 305 | 304 | ||
| 306 | size = 0; | 305 | size = 0; | 
| 307 | lsize = cur_cpu_spec->dcache_bsize; | 306 | lsize = cur_cpu_spec->dcache_bsize; | 
| 308 | sizep = get_property(np, "d-cache-size", NULL); | 307 | sizep = of_get_property(np, "d-cache-size", NULL); | 
| 309 | if (sizep != NULL) | 308 | if (sizep != NULL) | 
| 310 | size = *sizep; | 309 | size = *sizep; | 
| 311 | lsizep = get_property(np, dc, NULL); | 310 | lsizep = of_get_property(np, dc, NULL); | 
| 312 | if (lsizep != NULL) | 311 | if (lsizep != NULL) | 
| 313 | lsize = *lsizep; | 312 | lsize = *lsizep; | 
| 314 | if (sizep == 0 || lsizep == 0) | 313 | if (sizep == 0 || lsizep == 0) | 
| @@ -322,10 +321,10 @@ static void __init initialize_cache_info(void) | |||
| 322 | 321 | ||
| 323 | size = 0; | 322 | size = 0; | 
| 324 | lsize = cur_cpu_spec->icache_bsize; | 323 | lsize = cur_cpu_spec->icache_bsize; | 
| 325 | sizep = get_property(np, "i-cache-size", NULL); | 324 | sizep = of_get_property(np, "i-cache-size", NULL); | 
| 326 | if (sizep != NULL) | 325 | if (sizep != NULL) | 
| 327 | size = *sizep; | 326 | size = *sizep; | 
| 328 | lsizep = get_property(np, ic, NULL); | 327 | lsizep = of_get_property(np, ic, NULL); | 
| 329 | if (lsizep != NULL) | 328 | if (lsizep != NULL) | 
| 330 | lsize = *lsizep; | 329 | lsize = *lsizep; | 
| 331 | if (sizep == 0 || lsizep == 0) | 330 | if (sizep == 0 || lsizep == 0) | 
| diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 924d692bc8f9..d8e503b2e1af 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
| @@ -428,10 +428,6 @@ void generic_mach_cpu_die(void) | |||
| 428 | smp_wmb(); | 428 | smp_wmb(); | 
| 429 | while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) | 429 | while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) | 
| 430 | cpu_relax(); | 430 | cpu_relax(); | 
| 431 | |||
| 432 | #ifdef CONFIG_PPC64 | ||
| 433 | flush_tlb_pending(); | ||
| 434 | #endif | ||
| 435 | cpu_set(cpu, cpu_online_map); | 431 | cpu_set(cpu, cpu_online_map); | 
| 436 | local_irq_enable(); | 432 | local_irq_enable(); | 
| 437 | } | 433 | } | 
| diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 673e8d9df7f5..047246ad4f65 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
| @@ -53,10 +53,6 @@ | |||
| 53 | #include <asm/ppc-pci.h> | 53 | #include <asm/ppc-pci.h> | 
| 54 | #include <asm/syscalls.h> | 54 | #include <asm/syscalls.h> | 
| 55 | 55 | ||
| 56 | /* readdir & getdents */ | ||
| 57 | #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) | ||
| 58 | #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1)) | ||
| 59 | |||
| 60 | struct old_linux_dirent32 { | 56 | struct old_linux_dirent32 { | 
| 61 | u32 d_ino; | 57 | u32 d_ino; | 
| 62 | u32 d_offset; | 58 | u32 d_offset; | 
| diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index d57818aea081..933e214c33e8 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
| @@ -66,16 +66,17 @@ static int __init smt_setup(void) | |||
| 66 | if (!cpu_has_feature(CPU_FTR_SMT)) | 66 | if (!cpu_has_feature(CPU_FTR_SMT)) | 
| 67 | return -ENODEV; | 67 | return -ENODEV; | 
| 68 | 68 | ||
| 69 | options = find_path_device("/options"); | 69 | options = of_find_node_by_path("/options"); | 
| 70 | if (!options) | 70 | if (!options) | 
| 71 | return -ENODEV; | 71 | return -ENODEV; | 
| 72 | 72 | ||
| 73 | val = get_property(options, "ibm,smt-snooze-delay", NULL); | 73 | val = of_get_property(options, "ibm,smt-snooze-delay", NULL); | 
| 74 | if (!smt_snooze_cmdline && val) { | 74 | if (!smt_snooze_cmdline && val) { | 
| 75 | for_each_possible_cpu(cpu) | 75 | for_each_possible_cpu(cpu) | 
| 76 | per_cpu(smt_snooze_delay, cpu) = *val; | 76 | per_cpu(smt_snooze_delay, cpu) = *val; | 
| 77 | } | 77 | } | 
| 78 | 78 | ||
| 79 | of_node_put(options); | ||
| 79 | return 0; | 80 | return 0; | 
| 80 | } | 81 | } | 
| 81 | __initcall(smt_setup); | 82 | __initcall(smt_setup); | 
| @@ -189,12 +190,12 @@ SYSFS_PMCSETUP(purr, SPRN_PURR); | |||
| 189 | SYSFS_PMCSETUP(spurr, SPRN_SPURR); | 190 | SYSFS_PMCSETUP(spurr, SPRN_SPURR); | 
| 190 | SYSFS_PMCSETUP(dscr, SPRN_DSCR); | 191 | SYSFS_PMCSETUP(dscr, SPRN_DSCR); | 
| 191 | 192 | ||
| 192 | SYSFS_PMCSETUP(pa6t_pmc0, PA6T_SPRN_PMC0); | 193 | SYSFS_PMCSETUP(pa6t_pmc0, SPRN_PA6T_PMC0); | 
| 193 | SYSFS_PMCSETUP(pa6t_pmc1, PA6T_SPRN_PMC1); | 194 | SYSFS_PMCSETUP(pa6t_pmc1, SPRN_PA6T_PMC1); | 
| 194 | SYSFS_PMCSETUP(pa6t_pmc2, PA6T_SPRN_PMC2); | 195 | SYSFS_PMCSETUP(pa6t_pmc2, SPRN_PA6T_PMC2); | 
| 195 | SYSFS_PMCSETUP(pa6t_pmc3, PA6T_SPRN_PMC3); | 196 | SYSFS_PMCSETUP(pa6t_pmc3, SPRN_PA6T_PMC3); | 
| 196 | SYSFS_PMCSETUP(pa6t_pmc4, PA6T_SPRN_PMC4); | 197 | SYSFS_PMCSETUP(pa6t_pmc4, SPRN_PA6T_PMC4); | 
| 197 | SYSFS_PMCSETUP(pa6t_pmc5, PA6T_SPRN_PMC5); | 198 | SYSFS_PMCSETUP(pa6t_pmc5, SPRN_PA6T_PMC5); | 
| 198 | 199 | ||
| 199 | 200 | ||
| 200 | static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra); | 201 | static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra); | 
| diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index f6f0c6b07c4c..7cedef8f5f70 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
| @@ -834,7 +834,7 @@ static int __init get_freq(char *name, int cells, unsigned long *val) | |||
| 834 | cpu = of_find_node_by_type(NULL, "cpu"); | 834 | cpu = of_find_node_by_type(NULL, "cpu"); | 
| 835 | 835 | ||
| 836 | if (cpu) { | 836 | if (cpu) { | 
| 837 | fp = get_property(cpu, name, NULL); | 837 | fp = of_get_property(cpu, name, NULL); | 
| 838 | if (fp) { | 838 | if (fp) { | 
| 839 | found = 1; | 839 | found = 1; | 
| 840 | *val = of_read_ulong(fp, cells); | 840 | *val = of_read_ulong(fp, cells); | 
| diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 17724fb2067f..f7862224fe85 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
| @@ -90,21 +90,11 @@ EXPORT_SYMBOL(unregister_die_notifier); | |||
| 90 | * Trap & Exception support | 90 | * Trap & Exception support | 
| 91 | */ | 91 | */ | 
| 92 | 92 | ||
| 93 | static DEFINE_SPINLOCK(die_lock); | ||
| 94 | |||
| 95 | int die(const char *str, struct pt_regs *regs, long err) | ||
| 96 | { | ||
| 97 | static int die_counter; | ||
| 98 | |||
| 99 | if (debugger(regs)) | ||
| 100 | return 1; | ||
| 101 | |||
| 102 | console_verbose(); | ||
| 103 | spin_lock_irq(&die_lock); | ||
| 104 | bust_spinlocks(1); | ||
| 105 | #ifdef CONFIG_PMAC_BACKLIGHT | 93 | #ifdef CONFIG_PMAC_BACKLIGHT | 
| 94 | static void pmac_backlight_unblank(void) | ||
| 95 | { | ||
| 106 | mutex_lock(&pmac_backlight_mutex); | 96 | mutex_lock(&pmac_backlight_mutex); | 
| 107 | if (machine_is(powermac) && pmac_backlight) { | 97 | if (pmac_backlight) { | 
| 108 | struct backlight_properties *props; | 98 | struct backlight_properties *props; | 
| 109 | 99 | ||
| 110 | props = &pmac_backlight->props; | 100 | props = &pmac_backlight->props; | 
| @@ -113,26 +103,67 @@ int die(const char *str, struct pt_regs *regs, long err) | |||
| 113 | backlight_update_status(pmac_backlight); | 103 | backlight_update_status(pmac_backlight); | 
| 114 | } | 104 | } | 
| 115 | mutex_unlock(&pmac_backlight_mutex); | 105 | mutex_unlock(&pmac_backlight_mutex); | 
| 106 | } | ||
| 107 | #else | ||
| 108 | static inline void pmac_backlight_unblank(void) { } | ||
| 116 | #endif | 109 | #endif | 
| 117 | printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); | 110 | |
| 111 | int die(const char *str, struct pt_regs *regs, long err) | ||
| 112 | { | ||
| 113 | static struct { | ||
| 114 | spinlock_t lock; | ||
| 115 | u32 lock_owner; | ||
| 116 | int lock_owner_depth; | ||
| 117 | } die = { | ||
| 118 | .lock = __SPIN_LOCK_UNLOCKED(die.lock), | ||
| 119 | .lock_owner = -1, | ||
| 120 | .lock_owner_depth = 0 | ||
| 121 | }; | ||
| 122 | static int die_counter; | ||
| 123 | unsigned long flags; | ||
| 124 | |||
| 125 | if (debugger(regs)) | ||
| 126 | return 1; | ||
| 127 | |||
| 128 | oops_enter(); | ||
| 129 | |||
| 130 | if (die.lock_owner != raw_smp_processor_id()) { | ||
| 131 | console_verbose(); | ||
| 132 | spin_lock_irqsave(&die.lock, flags); | ||
| 133 | die.lock_owner = smp_processor_id(); | ||
| 134 | die.lock_owner_depth = 0; | ||
| 135 | bust_spinlocks(1); | ||
| 136 | if (machine_is(powermac)) | ||
| 137 | pmac_backlight_unblank(); | ||
| 138 | } else { | ||
| 139 | local_save_flags(flags); | ||
| 140 | } | ||
| 141 | |||
| 142 | if (++die.lock_owner_depth < 3) { | ||
| 143 | printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); | ||
| 118 | #ifdef CONFIG_PREEMPT | 144 | #ifdef CONFIG_PREEMPT | 
| 119 | printk("PREEMPT "); | 145 | printk("PREEMPT "); | 
| 120 | #endif | 146 | #endif | 
| 121 | #ifdef CONFIG_SMP | 147 | #ifdef CONFIG_SMP | 
| 122 | printk("SMP NR_CPUS=%d ", NR_CPUS); | 148 | printk("SMP NR_CPUS=%d ", NR_CPUS); | 
| 123 | #endif | 149 | #endif | 
| 124 | #ifdef CONFIG_DEBUG_PAGEALLOC | 150 | #ifdef CONFIG_DEBUG_PAGEALLOC | 
| 125 | printk("DEBUG_PAGEALLOC "); | 151 | printk("DEBUG_PAGEALLOC "); | 
| 126 | #endif | 152 | #endif | 
| 127 | #ifdef CONFIG_NUMA | 153 | #ifdef CONFIG_NUMA | 
| 128 | printk("NUMA "); | 154 | printk("NUMA "); | 
| 129 | #endif | 155 | #endif | 
| 130 | printk("%s\n", ppc_md.name ? "" : ppc_md.name); | 156 | printk("%s\n", ppc_md.name ? ppc_md.name : ""); | 
| 157 | |||
| 158 | print_modules(); | ||
| 159 | show_regs(regs); | ||
| 160 | } else { | ||
| 161 | printk("Recursive die() failure, output suppressed\n"); | ||
| 162 | } | ||
| 131 | 163 | ||
| 132 | print_modules(); | ||
| 133 | show_regs(regs); | ||
| 134 | bust_spinlocks(0); | 164 | bust_spinlocks(0); | 
| 135 | spin_unlock_irq(&die_lock); | 165 | die.lock_owner = -1; | 
| 166 | spin_unlock_irqrestore(&die.lock, flags); | ||
| 136 | 167 | ||
| 137 | if (kexec_should_crash(current) || | 168 | if (kexec_should_crash(current) || | 
| 138 | kexec_sr_activated(smp_processor_id())) | 169 | kexec_sr_activated(smp_processor_id())) | 
| @@ -145,6 +176,7 @@ int die(const char *str, struct pt_regs *regs, long err) | |||
| 145 | if (panic_on_oops) | 176 | if (panic_on_oops) | 
| 146 | panic("Fatal exception"); | 177 | panic("Fatal exception"); | 
| 147 | 178 | ||
| 179 | oops_exit(); | ||
| 148 | do_exit(err); | 180 | do_exit(err); | 
| 149 | 181 | ||
| 150 | return 0; | 182 | return 0; | 
| diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 2968ffeafdb6..9eaefac5053f 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
| @@ -81,7 +81,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) | |||
| 81 | struct iommu_table *tbl; | 81 | struct iommu_table *tbl; | 
| 82 | unsigned long offset, size; | 82 | unsigned long offset, size; | 
| 83 | 83 | ||
| 84 | dma_window = get_property(dev->dev.archdata.of_node, | 84 | dma_window = of_get_property(dev->dev.archdata.of_node, | 
| 85 | "ibm,my-dma-window", NULL); | 85 | "ibm,my-dma-window", NULL); | 
| 86 | if (!dma_window) | 86 | if (!dma_window) | 
| 87 | return NULL; | 87 | return NULL; | 
| @@ -226,7 +226,7 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) | |||
| 226 | return NULL; | 226 | return NULL; | 
| 227 | } | 227 | } | 
| 228 | 228 | ||
| 229 | unit_address = get_property(of_node, "reg", NULL); | 229 | unit_address = of_get_property(of_node, "reg", NULL); | 
| 230 | if (unit_address == NULL) { | 230 | if (unit_address == NULL) { | 
| 231 | printk(KERN_WARNING "%s: node %s missing 'reg'\n", | 231 | printk(KERN_WARNING "%s: node %s missing 'reg'\n", | 
| 232 | __FUNCTION__, | 232 | __FUNCTION__, | 
| @@ -246,7 +246,7 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) | |||
| 246 | viodev->type = of_node->type; | 246 | viodev->type = of_node->type; | 
| 247 | viodev->unit_address = *unit_address; | 247 | viodev->unit_address = *unit_address; | 
| 248 | if (firmware_has_feature(FW_FEATURE_ISERIES)) { | 248 | if (firmware_has_feature(FW_FEATURE_ISERIES)) { | 
| 249 | unit_address = get_property(of_node, | 249 | unit_address = of_get_property(of_node, | 
| 250 | "linux,unit_address", NULL); | 250 | "linux,unit_address", NULL); | 
| 251 | if (unit_address != NULL) | 251 | if (unit_address != NULL) | 
| 252 | viodev->unit_address = *unit_address; | 252 | viodev->unit_address = *unit_address; | 
| @@ -308,7 +308,7 @@ static int __init vio_bus_init(void) | |||
| 308 | return err; | 308 | return err; | 
| 309 | } | 309 | } | 
| 310 | 310 | ||
| 311 | node_vroot = find_devices("vdevice"); | 311 | node_vroot = of_find_node_by_name(NULL, "vdevice"); | 
| 312 | if (node_vroot) { | 312 | if (node_vroot) { | 
| 313 | struct device_node *of_node; | 313 | struct device_node *of_node; | 
| 314 | 314 | ||
| @@ -322,6 +322,7 @@ static int __init vio_bus_init(void) | |||
| 322 | __FUNCTION__, of_node); | 322 | __FUNCTION__, of_node); | 
| 323 | vio_register_device_node(of_node); | 323 | vio_register_device_node(of_node); | 
| 324 | } | 324 | } | 
| 325 | of_node_put(node_vroot); | ||
| 325 | } | 326 | } | 
| 326 | 327 | ||
| 327 | return 0; | 328 | return 0; | 
| @@ -377,7 +378,7 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp, | |||
| 377 | dn = dev->archdata.of_node; | 378 | dn = dev->archdata.of_node; | 
| 378 | if (!dn) | 379 | if (!dn) | 
| 379 | return -ENODEV; | 380 | return -ENODEV; | 
| 380 | cp = get_property(dn, "compatible", &length); | 381 | cp = of_get_property(dn, "compatible", &length); | 
| 381 | if (!cp) | 382 | if (!cp) | 
| 382 | return -ENODEV; | 383 | return -ENODEV; | 
| 383 | 384 | ||
| @@ -406,12 +407,12 @@ struct bus_type vio_bus_type = { | |||
| 406 | * @which: The property/attribute to be extracted. | 407 | * @which: The property/attribute to be extracted. | 
| 407 | * @length: Pointer to length of returned data size (unused if NULL). | 408 | * @length: Pointer to length of returned data size (unused if NULL). | 
| 408 | * | 409 | * | 
| 409 | * Calls prom.c's get_property() to return the value of the | 410 | * Calls prom.c's of_get_property() to return the value of the | 
| 410 | * attribute specified by @which | 411 | * attribute specified by @which | 
| 411 | */ | 412 | */ | 
| 412 | const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length) | 413 | const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length) | 
| 413 | { | 414 | { | 
| 414 | return get_property(vdev->dev.archdata.of_node, which, length); | 415 | return of_get_property(vdev->dev.archdata.of_node, which, length); | 
| 415 | } | 416 | } | 
| 416 | EXPORT_SYMBOL(vio_get_attribute); | 417 | EXPORT_SYMBOL(vio_get_attribute); | 
| 417 | 418 | ||
| @@ -443,7 +444,7 @@ struct vio_dev *vio_find_node(struct device_node *vnode) | |||
| 443 | char kobj_name[BUS_ID_SIZE]; | 444 | char kobj_name[BUS_ID_SIZE]; | 
| 444 | 445 | ||
| 445 | /* construct the kobject name from the device node */ | 446 | /* construct the kobject name from the device node */ | 
| 446 | unit_address = get_property(vnode, "reg", NULL); | 447 | unit_address = of_get_property(vnode, "reg", NULL); | 
| 447 | if (!unit_address) | 448 | if (!unit_address) | 
| 448 | return NULL; | 449 | return NULL; | 
| 449 | snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address); | 450 | snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address); | 
