mirror of https://gitee.com/openkylin/linux.git
x86: 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: Robin Holt <holt@sgi.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: stable@kernel.org LKML-Reference: <4B3922F9.3060905@sgi.com> [ v2: fix a number of annoying checkpatch artifacts and whitespace noise ] Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
c0ca9da442
commit
39d3077099
|
@ -287,21 +287,18 @@ static inline int uv_apicid_to_pnode(int apicid)
|
|||
* Access global MMRs using the low memory MMR32 space. This region supports
|
||||
* faster MMR access but not all MMRs are accessible in this space.
|
||||
*/
|
||||
static inline unsigned long *uv_global_mmr32_address(int pnode,
|
||||
unsigned long offset)
|
||||
static inline unsigned long *uv_global_mmr32_address(int pnode, unsigned long offset)
|
||||
{
|
||||
return __va(UV_GLOBAL_MMR32_BASE |
|
||||
UV_GLOBAL_MMR32_PNODE_BITS(pnode) | offset);
|
||||
}
|
||||
|
||||
static inline void uv_write_global_mmr32(int pnode, unsigned long offset,
|
||||
unsigned long val)
|
||||
static inline void uv_write_global_mmr32(int pnode, unsigned long offset, unsigned long val)
|
||||
{
|
||||
writeq(val, uv_global_mmr32_address(pnode, offset));
|
||||
}
|
||||
|
||||
static inline unsigned long uv_read_global_mmr32(int pnode,
|
||||
unsigned long offset)
|
||||
static inline unsigned long uv_read_global_mmr32(int pnode, unsigned long offset)
|
||||
{
|
||||
return readq(uv_global_mmr32_address(pnode, offset));
|
||||
}
|
||||
|
@ -310,21 +307,18 @@ static inline unsigned long uv_read_global_mmr32(int pnode,
|
|||
* Access Global MMR space using the MMR space located at the top of physical
|
||||
* memory.
|
||||
*/
|
||||
static inline unsigned long *uv_global_mmr64_address(int pnode,
|
||||
unsigned long offset)
|
||||
static inline unsigned long *uv_global_mmr64_address(int pnode, unsigned long offset)
|
||||
{
|
||||
return __va(UV_GLOBAL_MMR64_BASE |
|
||||
UV_GLOBAL_MMR64_PNODE_BITS(pnode) | offset);
|
||||
}
|
||||
|
||||
static inline void uv_write_global_mmr64(int pnode, unsigned long offset,
|
||||
unsigned long val)
|
||||
static inline void uv_write_global_mmr64(int pnode, unsigned long offset, unsigned long val)
|
||||
{
|
||||
writeq(val, uv_global_mmr64_address(pnode, offset));
|
||||
}
|
||||
|
||||
static inline unsigned long uv_read_global_mmr64(int pnode,
|
||||
unsigned long offset)
|
||||
static inline unsigned long uv_read_global_mmr64(int pnode, unsigned long offset)
|
||||
{
|
||||
return readq(uv_global_mmr64_address(pnode, offset));
|
||||
}
|
||||
|
@ -338,6 +332,16 @@ static inline unsigned long uv_global_gru_mmr_address(int pnode, unsigned long o
|
|||
return UV_GLOBAL_GRU_MMR_BASE | offset | (pnode << uv_hub_info->m_val);
|
||||
}
|
||||
|
||||
static inline void uv_write_global_mmr8(int pnode, unsigned long offset, unsigned char val)
|
||||
{
|
||||
writeb(val, uv_global_mmr64_address(pnode, offset));
|
||||
}
|
||||
|
||||
static inline unsigned char uv_read_global_mmr8(int pnode, unsigned long offset)
|
||||
{
|
||||
return readb(uv_global_mmr64_address(pnode, offset));
|
||||
}
|
||||
|
||||
/*
|
||||
* Access hub local MMRs. Faster than using global space but only local MMRs
|
||||
* are accessible.
|
||||
|
@ -457,11 +461,17 @@ static inline void uv_set_scir_bits(unsigned char value)
|
|||
}
|
||||
}
|
||||
|
||||
static inline unsigned long uv_scir_offset(int apicid)
|
||||
{
|
||||
return SCIR_LOCAL_MMR_BASE | (apicid & 0x3f);
|
||||
}
|
||||
|
||||
static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value)
|
||||
{
|
||||
if (uv_cpu_hub_info(cpu)->scir.state != value) {
|
||||
uv_write_global_mmr8(uv_cpu_to_pnode(cpu),
|
||||
uv_cpu_hub_info(cpu)->scir.offset, value);
|
||||
uv_cpu_hub_info(cpu)->scir.state = value;
|
||||
uv_write_local_mmr8(uv_cpu_hub_info(cpu)->scir.offset, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -629,8 +629,10 @@ void __init uv_system_init(void)
|
|||
uv_rtc_init();
|
||||
|
||||
for_each_present_cpu(cpu) {
|
||||
int apicid = per_cpu(x86_cpu_to_apicid, cpu);
|
||||
|
||||
nid = cpu_to_node(cpu);
|
||||
pnode = uv_apicid_to_pnode(per_cpu(x86_cpu_to_apicid, cpu));
|
||||
pnode = uv_apicid_to_pnode(apicid);
|
||||
blade = boot_pnode_to_blade(pnode);
|
||||
lcpu = uv_blade_info[blade].nr_possible_cpus;
|
||||
uv_blade_info[blade].nr_possible_cpus++;
|
||||
|
@ -651,15 +653,13 @@ void __init uv_system_init(void)
|
|||
uv_cpu_hub_info(cpu)->gnode_extra = gnode_extra;
|
||||
uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
|
||||
uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id;
|
||||
uv_cpu_hub_info(cpu)->scir.offset = SCIR_LOCAL_MMR_BASE + lcpu;
|
||||
uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid);
|
||||
uv_node_to_blade[nid] = blade;
|
||||
uv_cpu_to_blade[cpu] = blade;
|
||||
max_pnode = max(pnode, max_pnode);
|
||||
|
||||
printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, "
|
||||
"lcpu %d, blade %d\n",
|
||||
cpu, per_cpu(x86_cpu_to_apicid, cpu), pnode, nid,
|
||||
lcpu, blade);
|
||||
printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, lcpu %d, blade %d\n",
|
||||
cpu, apicid, pnode, nid, lcpu, blade);
|
||||
}
|
||||
|
||||
/* Add blade/pnode info for nodes without cpus */
|
||||
|
|
Loading…
Reference in New Issue