![Siddha, Suresh B](/assets/img/avatar_default.png)
Mechanism of selecting physical mode in genapic when cpu hotplug is enabled on x86_64, broke the quirk(quirk_intel_irqbalance()) introduced for working around the transposing interrupt message errata in E7520/E7320/E7525 (revision ID 0x9 and below. errata #23 in http://download.intel.com/design/chipsets/specupdt/30304203.pdf). This errata requires the mode to be in logical flat, so that interrupts can be directed to more than one cpu(and thus use hardware IRQ balancing enabled by BIOS on these platforms). Following four patches fixes this by moving the quirk to early quirk and forcing the x86_64 genapic selection to logical flat on these platforms. Thanks to Shaohua for pointing out the breakage. This patch: Add write_pci_config_byte() to direct PCI access routines Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Andi Kleen <ak@suse.de> Cc: Andi Kleen <ak@suse.de> Cc: "Li, Shaohua" <shaohua.li@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org>
60 lines
1.5 KiB
C
60 lines
1.5 KiB
C
#include <linux/kernel.h>
|
|
#include <linux/pci.h>
|
|
#include <asm/pci-direct.h>
|
|
#include <asm/io.h>
|
|
#include "pci.h"
|
|
|
|
/* Direct PCI access. This is used for PCI accesses in early boot before
|
|
the PCI subsystem works. */
|
|
|
|
#define PDprintk(x...)
|
|
|
|
u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
|
|
{
|
|
u32 v;
|
|
outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
|
|
v = inl(0xcfc);
|
|
if (v != 0xffffffff)
|
|
PDprintk("%x reading 4 from %x: %x\n", slot, offset, v);
|
|
return v;
|
|
}
|
|
|
|
u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset)
|
|
{
|
|
u8 v;
|
|
outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
|
|
v = inb(0xcfc + (offset&3));
|
|
PDprintk("%x reading 1 from %x: %x\n", slot, offset, v);
|
|
return v;
|
|
}
|
|
|
|
u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset)
|
|
{
|
|
u16 v;
|
|
outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
|
|
v = inw(0xcfc + (offset&2));
|
|
PDprintk("%x reading 2 from %x: %x\n", slot, offset, v);
|
|
return v;
|
|
}
|
|
|
|
void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset,
|
|
u32 val)
|
|
{
|
|
PDprintk("%x writing to %x: %x\n", slot, offset, val);
|
|
outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
|
|
outl(val, 0xcfc);
|
|
}
|
|
|
|
void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val)
|
|
{
|
|
PDprintk("%x writing to %x: %x\n", slot, offset, val);
|
|
outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
|
|
outb(val, 0xcfc);
|
|
}
|
|
|
|
int early_pci_allowed(void)
|
|
{
|
|
return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) ==
|
|
PCI_PROBE_CONF1;
|
|
}
|