diff options
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); |