aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Travis <travis@sgi.com>2009-12-28 16:28:25 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-30 15:25:26 -0500
commit9a7262a0563da6b91019156abf487bcdf1a41526 (patch)
tree909e69dbd2752b0a8e38872172d2b2f42820f8f4
parent66f0dc481e5b802ab363b979fc1753410c7d82b5 (diff)
x86_64 SGI UV: Fix writes to led registers on remote uv hubs.
The wrong address was being used to write the SCIR led regs on remote hubs. Also, there was an inconsistency between how BIOS and the kernel indexed these regs. Standardize on using the lower 6 bits of the APIC ID as the index. This patch fixes the problem of writing to an errant address to a cpu # >= 64. Signed-off-by: Mike Travis <travis@sgi.com> Reviewed-by: Jack Steiner <steiner@sgi.com> Cc: stable@kernel.org Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/x86/include/asm/uv/uv_hub.h20
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c12
2 files changed, 25 insertions, 7 deletions
diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
index 811bfabc80b7..bcdb708993d2 100644
--- a/arch/x86/include/asm/uv/uv_hub.h
+++ b/arch/x86/include/asm/uv/uv_hub.h
@@ -338,6 +338,18 @@ static inline unsigned long uv_global_gru_mmr_address(int pnode, unsigned long o
338 return UV_GLOBAL_GRU_MMR_BASE | offset | (pnode << uv_hub_info->m_val); 338 return UV_GLOBAL_GRU_MMR_BASE | offset | (pnode << uv_hub_info->m_val);
339} 339}
340 340
341static inline void uv_write_global_mmr8(int pnode, unsigned long offset,
342 unsigned char val)
343{
344 writeb(val, uv_global_mmr64_address(pnode, offset));
345}
346
347static inline unsigned char uv_read_global_mmr8(int pnode,
348 unsigned long offset)
349{
350 return readb(uv_global_mmr64_address(pnode, offset));
351}
352
341/* 353/*
342 * Access hub local MMRs. Faster than using global space but only local MMRs 354 * Access hub local MMRs. Faster than using global space but only local MMRs
343 * are accessible. 355 * are accessible.
@@ -457,11 +469,17 @@ static inline void uv_set_scir_bits(unsigned char value)
457 } 469 }
458} 470}
459 471
472static inline unsigned long uv_scir_offset(int apicid)
473{
474 return SCIR_LOCAL_MMR_BASE | (apicid & 0x3f);
475}
476
460static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value) 477static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value)
461{ 478{
462 if (uv_cpu_hub_info(cpu)->scir.state != value) { 479 if (uv_cpu_hub_info(cpu)->scir.state != value) {
480 uv_write_global_mmr8(uv_cpu_to_pnode(cpu),
481 uv_cpu_hub_info(cpu)->scir.offset, value);
463 uv_cpu_hub_info(cpu)->scir.state = value; 482 uv_cpu_hub_info(cpu)->scir.state = value;
464 uv_write_local_mmr8(uv_cpu_hub_info(cpu)->scir.offset, value);
465 } 483 }
466} 484}
467 485
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index d56b0efb2057..5f92494dab61 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -629,8 +629,10 @@ void __init uv_system_init(void)
629 uv_rtc_init(); 629 uv_rtc_init();
630 630
631 for_each_present_cpu(cpu) { 631 for_each_present_cpu(cpu) {
632 int apicid = per_cpu(x86_cpu_to_apicid, cpu);
633
632 nid = cpu_to_node(cpu); 634 nid = cpu_to_node(cpu);
633 pnode = uv_apicid_to_pnode(per_cpu(x86_cpu_to_apicid, cpu)); 635 pnode = uv_apicid_to_pnode(apicid);
634 blade = boot_pnode_to_blade(pnode); 636 blade = boot_pnode_to_blade(pnode);
635 lcpu = uv_blade_info[blade].nr_possible_cpus; 637 lcpu = uv_blade_info[blade].nr_possible_cpus;
636 uv_blade_info[blade].nr_possible_cpus++; 638 uv_blade_info[blade].nr_possible_cpus++;
@@ -651,15 +653,13 @@ void __init uv_system_init(void)
651 uv_cpu_hub_info(cpu)->gnode_extra = gnode_extra; 653 uv_cpu_hub_info(cpu)->gnode_extra = gnode_extra;
652 uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base; 654 uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
653 uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id; 655 uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id;
654 uv_cpu_hub_info(cpu)->scir.offset = SCIR_LOCAL_MMR_BASE + lcpu; 656 uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid);
655 uv_node_to_blade[nid] = blade; 657 uv_node_to_blade[nid] = blade;
656 uv_cpu_to_blade[cpu] = blade; 658 uv_cpu_to_blade[cpu] = blade;
657 max_pnode = max(pnode, max_pnode); 659 max_pnode = max(pnode, max_pnode);
658 660
659 printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, " 661 printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, lcpu %d, blade %d\n",
660 "lcpu %d, blade %d\n", 662 cpu, apicid, pnode, nid, lcpu, blade);
661 cpu, per_cpu(x86_cpu_to_apicid, cpu), pnode, nid,
662 lcpu, blade);
663 } 663 }
664 664
665 /* Add blade/pnode info for nodes without cpus */ 665 /* Add blade/pnode info for nodes without cpus */