Merge branch 'linus' into x86/pci-ioapic-boot-irq-quirks
Conflicts: drivers/pci/quirks.c Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
@@ -1,5 +1,17 @@
|
||||
ifeq ($(CONFIG_X86_32),y)
|
||||
include ${srctree}/arch/x86/pci/Makefile_32
|
||||
else
|
||||
include ${srctree}/arch/x86/pci/Makefile_64
|
||||
endif
|
||||
obj-y := i386.o init.o
|
||||
|
||||
obj-$(CONFIG_PCI_BIOS) += pcbios.o
|
||||
obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_$(BITS).o direct.o mmconfig-shared.o
|
||||
obj-$(CONFIG_PCI_DIRECT) += direct.o
|
||||
obj-$(CONFIG_PCI_OLPC) += olpc.o
|
||||
|
||||
pci-y := fixup.o
|
||||
pci-$(CONFIG_ACPI) += acpi.o
|
||||
pci-y += legacy.o irq.o
|
||||
|
||||
pci-$(CONFIG_X86_VISWS) += visws.o
|
||||
|
||||
pci-$(CONFIG_X86_NUMAQ) += numa.o
|
||||
|
||||
obj-y += $(pci-y) common.o early.o
|
||||
obj-y += amd_bus.o
|
||||
|
@@ -1,26 +0,0 @@
|
||||
obj-y := i386.o init.o
|
||||
|
||||
obj-$(CONFIG_PCI_BIOS) += pcbios.o
|
||||
obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_32.o direct.o mmconfig-shared.o
|
||||
obj-$(CONFIG_PCI_DIRECT) += direct.o
|
||||
obj-$(CONFIG_PCI_OLPC) += olpc.o
|
||||
|
||||
pci-y := fixup.o
|
||||
|
||||
# Do not change the ordering here. There is a nasty init function
|
||||
# ordering dependency which breaks when you move acpi.o below
|
||||
# legacy/irq.o
|
||||
pci-$(CONFIG_ACPI) += acpi.o
|
||||
pci-y += legacy.o irq.o
|
||||
|
||||
# Careful: VISWS overrule the pci-y above. The colons are
|
||||
# therefor correct. This needs a proper fix by distangling the code.
|
||||
pci-$(CONFIG_X86_VISWS) := visws.o fixup.o
|
||||
|
||||
pci-$(CONFIG_X86_NUMAQ) += numa.o
|
||||
|
||||
# Necessary for NUMAQ as well
|
||||
pci-$(CONFIG_NUMA) += mp_bus_to_node.o
|
||||
|
||||
obj-y += $(pci-y) common.o early.o
|
||||
obj-y += amd_bus.o
|
@@ -1,17 +0,0 @@
|
||||
#
|
||||
# Makefile for X86_64 specific PCI routines
|
||||
#
|
||||
# Reuse the i386 PCI subsystem
|
||||
#
|
||||
EXTRA_CFLAGS += -Iarch/x86/pci
|
||||
|
||||
obj-y := i386.o
|
||||
obj-$(CONFIG_PCI_DIRECT)+= direct.o
|
||||
obj-y += fixup.o init.o
|
||||
obj-$(CONFIG_ACPI) += acpi.o
|
||||
obj-y += legacy.o irq.o common.o early.o
|
||||
# mmconfig has a 64bit special
|
||||
obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o
|
||||
|
||||
obj-y += amd_bus.o
|
||||
|
@@ -223,7 +223,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
|
||||
return bus;
|
||||
}
|
||||
|
||||
static int __init pci_acpi_init(void)
|
||||
int __init pci_acpi_init(void)
|
||||
{
|
||||
struct pci_dev *dev = NULL;
|
||||
|
||||
@@ -257,4 +257,3 @@ static int __init pci_acpi_init(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(pci_acpi_init);
|
||||
|
@@ -1,44 +1,25 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/topology.h>
|
||||
#include "pci.h"
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
|
||||
#include <asm/pci-direct.h>
|
||||
#include <asm/mpspec.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/topology.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This discovers the pcibus <-> node mapping on AMD K8.
|
||||
* also get peer root bus resource for io,mmio
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* sub bus (transparent) will use entres from 3 to store extra from root,
|
||||
* so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES?
|
||||
*/
|
||||
#define RES_NUM 16
|
||||
struct pci_root_info {
|
||||
char name[12];
|
||||
unsigned int res_num;
|
||||
struct resource res[RES_NUM];
|
||||
int bus_min;
|
||||
int bus_max;
|
||||
int node;
|
||||
int link;
|
||||
};
|
||||
|
||||
/* 4 at this time, it may become to 32 */
|
||||
#define PCI_ROOT_NR 4
|
||||
static int pci_root_num;
|
||||
static struct pci_root_info pci_root_info[PCI_ROOT_NR];
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
|
||||
#define BUS_NR 256
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
|
||||
static int mp_bus_to_node[BUS_NR];
|
||||
|
||||
void set_mp_bus_to_node(int busnum, int node)
|
||||
@@ -65,7 +46,52 @@ int get_mp_bus_to_node(int busnum)
|
||||
|
||||
return node;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* CONFIG_X86_32 */
|
||||
|
||||
static unsigned char mp_bus_to_node[BUS_NR];
|
||||
|
||||
void set_mp_bus_to_node(int busnum, int node)
|
||||
{
|
||||
if (busnum >= 0 && busnum < BUS_NR)
|
||||
mp_bus_to_node[busnum] = (unsigned char) node;
|
||||
}
|
||||
|
||||
int get_mp_bus_to_node(int busnum)
|
||||
{
|
||||
int node;
|
||||
|
||||
if (busnum < 0 || busnum > (BUS_NR - 1))
|
||||
return 0;
|
||||
node = mp_bus_to_node[busnum];
|
||||
return node;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_X86_32 */
|
||||
|
||||
#endif /* CONFIG_NUMA */
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
|
||||
/*
|
||||
* sub bus (transparent) will use entres from 3 to store extra from root,
|
||||
* so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES?
|
||||
*/
|
||||
#define RES_NUM 16
|
||||
struct pci_root_info {
|
||||
char name[12];
|
||||
unsigned int res_num;
|
||||
struct resource res[RES_NUM];
|
||||
int bus_min;
|
||||
int bus_max;
|
||||
int node;
|
||||
int link;
|
||||
};
|
||||
|
||||
/* 4 at this time, it may become to 32 */
|
||||
#define PCI_ROOT_NR 4
|
||||
static int pci_root_num;
|
||||
static struct pci_root_info pci_root_info[PCI_ROOT_NR];
|
||||
|
||||
void set_pci_bus_resources_arch_default(struct pci_bus *b)
|
||||
{
|
||||
@@ -552,7 +578,7 @@ static int __init enable_pci_io_ecs(void)
|
||||
/* assume all cpus from fam10h have IO ECS */
|
||||
if (boot_cpu_data.x86 < 0x10)
|
||||
return 0;
|
||||
on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1, 1);
|
||||
on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1);
|
||||
pci_probe |= PCI_HAS_IO_ECS;
|
||||
return 0;
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@
|
||||
unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
|
||||
PCI_PROBE_MMCONF;
|
||||
|
||||
unsigned int pci_early_dump_regs;
|
||||
static int pci_bf_sort;
|
||||
int pci_routeirq;
|
||||
int noioapicquirk;
|
||||
@@ -33,7 +34,7 @@ struct pci_raw_ops *raw_pci_ext_ops;
|
||||
int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
|
||||
int reg, int len, u32 *val)
|
||||
{
|
||||
if (reg < 256 && raw_pci_ops)
|
||||
if (domain == 0 && reg < 256 && raw_pci_ops)
|
||||
return raw_pci_ops->read(domain, bus, devfn, reg, len, val);
|
||||
if (raw_pci_ext_ops)
|
||||
return raw_pci_ext_ops->read(domain, bus, devfn, reg, len, val);
|
||||
@@ -43,7 +44,7 @@ int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
|
||||
int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
|
||||
int reg, int len, u32 val)
|
||||
{
|
||||
if (reg < 256 && raw_pci_ops)
|
||||
if (domain == 0 && reg < 256 && raw_pci_ops)
|
||||
return raw_pci_ops->write(domain, bus, devfn, reg, len, val);
|
||||
if (raw_pci_ext_ops)
|
||||
return raw_pci_ext_ops->write(domain, bus, devfn, reg, len, val);
|
||||
@@ -123,6 +124,21 @@ void __init dmi_check_skip_isa_align(void)
|
||||
dmi_check_system(can_skip_pciprobe_dmi_table);
|
||||
}
|
||||
|
||||
static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
|
||||
{
|
||||
struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
|
||||
|
||||
if (pci_probe & PCI_NOASSIGN_ROMS) {
|
||||
if (rom_r->parent)
|
||||
return;
|
||||
if (rom_r->start) {
|
||||
/* we deal with BIOS assigned ROM later */
|
||||
return;
|
||||
}
|
||||
rom_r->start = rom_r->end = rom_r->flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called after each bus is probed, but before its children
|
||||
* are examined.
|
||||
@@ -130,7 +146,11 @@ void __init dmi_check_skip_isa_align(void)
|
||||
|
||||
void __devinit pcibios_fixup_bus(struct pci_bus *b)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
|
||||
pci_read_bridge_bases(b);
|
||||
list_for_each_entry(dev, &b->devices, bus_list)
|
||||
pcibios_fixup_device_resources(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -386,7 +406,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
|
||||
|
||||
extern u8 pci_cache_line_size;
|
||||
|
||||
static int __init pcibios_init(void)
|
||||
int __init pcibios_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &boot_cpu_data;
|
||||
|
||||
@@ -413,8 +433,6 @@ static int __init pcibios_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(pcibios_init);
|
||||
|
||||
char * __devinit pcibios_setup(char *str)
|
||||
{
|
||||
if (!strcmp(str, "off")) {
|
||||
@@ -485,12 +503,18 @@ char * __devinit pcibios_setup(char *str)
|
||||
else if (!strcmp(str, "rom")) {
|
||||
pci_probe |= PCI_ASSIGN_ROMS;
|
||||
return NULL;
|
||||
} else if (!strcmp(str, "norom")) {
|
||||
pci_probe |= PCI_NOASSIGN_ROMS;
|
||||
return NULL;
|
||||
} else if (!strcmp(str, "assign-busses")) {
|
||||
pci_probe |= PCI_ASSIGN_ALL_BUSSES;
|
||||
return NULL;
|
||||
} else if (!strcmp(str, "use_crs")) {
|
||||
pci_probe |= PCI_USE__CRS;
|
||||
return NULL;
|
||||
} else if (!strcmp(str, "earlydump")) {
|
||||
pci_early_dump_regs = 1;
|
||||
return NULL;
|
||||
} else if (!strcmp(str, "routeirq")) {
|
||||
pci_routeirq = 1;
|
||||
return NULL;
|
||||
|
@@ -49,7 +49,14 @@ 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);
|
||||
outb(val, 0xcfc + (offset&3));
|
||||
}
|
||||
|
||||
void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val)
|
||||
{
|
||||
PDprintk("%x writing to %x: %x\n", slot, offset, val);
|
||||
outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
|
||||
outw(val, 0xcfc + (offset&2));
|
||||
}
|
||||
|
||||
int early_pci_allowed(void)
|
||||
@@ -57,3 +64,54 @@ int early_pci_allowed(void)
|
||||
return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) ==
|
||||
PCI_PROBE_CONF1;
|
||||
}
|
||||
|
||||
void early_dump_pci_device(u8 bus, u8 slot, u8 func)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
u32 val;
|
||||
|
||||
printk("PCI: %02x:%02x:%02x", bus, slot, func);
|
||||
|
||||
for (i = 0; i < 256; i += 4) {
|
||||
if (!(i & 0x0f))
|
||||
printk("\n%04x:",i);
|
||||
|
||||
val = read_pci_config(bus, slot, func, i);
|
||||
for (j = 0; j < 4; j++) {
|
||||
printk(" %02x", val & 0xff);
|
||||
val >>= 8;
|
||||
}
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
void early_dump_pci_devices(void)
|
||||
{
|
||||
unsigned bus, slot, func;
|
||||
|
||||
if (!early_pci_allowed())
|
||||
return;
|
||||
|
||||
for (bus = 0; bus < 256; bus++) {
|
||||
for (slot = 0; slot < 32; slot++) {
|
||||
for (func = 0; func < 8; func++) {
|
||||
u32 class;
|
||||
u8 type;
|
||||
class = read_pci_config(bus, slot, func,
|
||||
PCI_CLASS_REVISION);
|
||||
if (class == 0xffffffff)
|
||||
break;
|
||||
|
||||
early_dump_pci_device(bus, slot, func);
|
||||
|
||||
/* No multi-function device? */
|
||||
type = read_pci_config_byte(bus, slot, func,
|
||||
PCI_HEADER_TYPE);
|
||||
if (!(type & 0x80))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -334,7 +334,9 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
||||
flags = new_flags;
|
||||
}
|
||||
|
||||
if (vma->vm_pgoff <= max_pfn_mapped &&
|
||||
if (((vma->vm_pgoff < max_low_pfn_mapped) ||
|
||||
(vma->vm_pgoff >= (1UL<<(32 - PAGE_SHIFT)) &&
|
||||
vma->vm_pgoff < max_pfn_mapped)) &&
|
||||
ioremap_change_attr((unsigned long)__va(addr), len, flags)) {
|
||||
free_memtype(addr, addr + len);
|
||||
return -EINVAL;
|
||||
|
@@ -4,7 +4,7 @@
|
||||
|
||||
/* arch_initcall has too random ordering, so call the initializers
|
||||
in the right sequence from here. */
|
||||
static __init int pci_access_init(void)
|
||||
static __init int pci_arch_init(void)
|
||||
{
|
||||
#ifdef CONFIG_PCI_DIRECT
|
||||
int type = 0;
|
||||
@@ -40,4 +40,4 @@ static __init int pci_access_init(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(pci_access_init);
|
||||
arch_initcall(pci_arch_init);
|
||||
|
@@ -45,7 +45,8 @@ struct irq_router {
|
||||
char *name;
|
||||
u16 vendor, device;
|
||||
int (*get)(struct pci_dev *router, struct pci_dev *dev, int pirq);
|
||||
int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq, int new);
|
||||
int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq,
|
||||
int new);
|
||||
};
|
||||
|
||||
struct irq_router_handler {
|
||||
@@ -77,7 +78,8 @@ static inline struct irq_routing_table *pirq_check_routing_table(u8 *addr)
|
||||
for (i = 0; i < rt->size; i++)
|
||||
sum += addr[i];
|
||||
if (!sum) {
|
||||
DBG(KERN_DEBUG "PCI: Interrupt Routing Table found at 0x%p\n", rt);
|
||||
DBG(KERN_DEBUG "PCI: Interrupt Routing Table found at 0x%p\n",
|
||||
rt);
|
||||
return rt;
|
||||
}
|
||||
return NULL;
|
||||
@@ -183,7 +185,8 @@ static unsigned int read_config_nybble(struct pci_dev *router, unsigned offset,
|
||||
return (nr & 1) ? (x >> 4) : (x & 0xf);
|
||||
}
|
||||
|
||||
static void write_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr, unsigned int val)
|
||||
static void write_config_nybble(struct pci_dev *router, unsigned offset,
|
||||
unsigned nr, unsigned int val)
|
||||
{
|
||||
u8 x;
|
||||
unsigned reg = offset + (nr >> 1);
|
||||
@@ -467,7 +470,8 @@ static int pirq_serverworks_get(struct pci_dev *router, struct pci_dev *dev, int
|
||||
return inb(0xc01) & 0xf;
|
||||
}
|
||||
|
||||
static int pirq_serverworks_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
|
||||
static int pirq_serverworks_set(struct pci_dev *router, struct pci_dev *dev,
|
||||
int pirq, int irq)
|
||||
{
|
||||
outb(pirq, 0xc00);
|
||||
outb(irq, 0xc01);
|
||||
@@ -660,7 +664,8 @@ static __init int vlsi_router_probe(struct irq_router *r, struct pci_dev *router
|
||||
}
|
||||
|
||||
|
||||
static __init int serverworks_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
|
||||
static __init int serverworks_router_probe(struct irq_router *r,
|
||||
struct pci_dev *router, u16 device)
|
||||
{
|
||||
switch (device) {
|
||||
case PCI_DEVICE_ID_SERVERWORKS_OSB4:
|
||||
@@ -827,10 +832,12 @@ static void __init pirq_find_router(struct irq_router *r)
|
||||
|
||||
for (h = pirq_routers; h->vendor; h++) {
|
||||
/* First look for a router match */
|
||||
if (rt->rtr_vendor == h->vendor && h->probe(r, pirq_router_dev, rt->rtr_device))
|
||||
if (rt->rtr_vendor == h->vendor &&
|
||||
h->probe(r, pirq_router_dev, rt->rtr_device))
|
||||
break;
|
||||
/* Fall back to a device match */
|
||||
if (pirq_router_dev->vendor == h->vendor && h->probe(r, pirq_router_dev, pirq_router_dev->device))
|
||||
if (pirq_router_dev->vendor == h->vendor &&
|
||||
h->probe(r, pirq_router_dev, pirq_router_dev->device))
|
||||
break;
|
||||
}
|
||||
printk(KERN_INFO "PCI: Using IRQ router %s [%04x/%04x] at %s\n",
|
||||
@@ -845,11 +852,13 @@ static void __init pirq_find_router(struct irq_router *r)
|
||||
static struct irq_info *pirq_get_info(struct pci_dev *dev)
|
||||
{
|
||||
struct irq_routing_table *rt = pirq_table;
|
||||
int entries = (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
|
||||
int entries = (rt->size - sizeof(struct irq_routing_table)) /
|
||||
sizeof(struct irq_info);
|
||||
struct irq_info *info;
|
||||
|
||||
for (info = rt->slots; entries--; info++)
|
||||
if (info->bus == dev->bus->number && PCI_SLOT(info->devfn) == PCI_SLOT(dev->devfn))
|
||||
if (info->bus == dev->bus->number &&
|
||||
PCI_SLOT(info->devfn) == PCI_SLOT(dev->devfn))
|
||||
return info;
|
||||
return NULL;
|
||||
}
|
||||
@@ -890,7 +899,8 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
|
||||
DBG(" -> not routed\n" KERN_DEBUG);
|
||||
return 0;
|
||||
}
|
||||
DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs);
|
||||
DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask,
|
||||
pirq_table->exclusive_irqs);
|
||||
mask &= pcibios_irq_mask;
|
||||
|
||||
/* Work around broken HP Pavilion Notebooks which assign USB to
|
||||
@@ -903,7 +913,8 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
|
||||
}
|
||||
|
||||
/* same for Acer Travelmate 360, but with CB and irq 11 -> 10 */
|
||||
if (acer_tm360_irqrouting && dev->irq == 11 && dev->vendor == PCI_VENDOR_ID_O2) {
|
||||
if (acer_tm360_irqrouting && dev->irq == 11 &&
|
||||
dev->vendor == PCI_VENDOR_ID_O2) {
|
||||
pirq = 0x68;
|
||||
mask = 0x400;
|
||||
dev->irq = r->get(pirq_router_dev, dev, pirq);
|
||||
@@ -920,15 +931,16 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
|
||||
newirq = 0;
|
||||
else
|
||||
printk("\n" KERN_WARNING
|
||||
"PCI: IRQ %i for device %s doesn't match PIRQ mask "
|
||||
"- try pci=usepirqmask\n" KERN_DEBUG, newirq,
|
||||
pci_name(dev));
|
||||
"PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n"
|
||||
KERN_DEBUG, newirq,
|
||||
pci_name(dev));
|
||||
}
|
||||
if (!newirq && assign) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (!(mask & (1 << i)))
|
||||
continue;
|
||||
if (pirq_penalty[i] < pirq_penalty[newirq] && can_request_irq(i, IRQF_SHARED))
|
||||
if (pirq_penalty[i] < pirq_penalty[newirq] &&
|
||||
can_request_irq(i, IRQF_SHARED))
|
||||
newirq = i;
|
||||
}
|
||||
}
|
||||
@@ -944,7 +956,8 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
|
||||
DBG(" -> got IRQ %d\n", irq);
|
||||
msg = "Found";
|
||||
eisa_set_level_irq(irq);
|
||||
} else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
|
||||
} else if (newirq && r->set &&
|
||||
(dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
|
||||
DBG(" -> assigning IRQ %d", newirq);
|
||||
if (r->set(pirq_router_dev, dev, pirq, newirq)) {
|
||||
eisa_set_level_irq(newirq);
|
||||
@@ -962,7 +975,8 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, pci_name(dev));
|
||||
printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq,
|
||||
pci_name(dev));
|
||||
|
||||
/* Update IRQ for all devices with the same pirq value */
|
||||
while ((dev2 = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) {
|
||||
@@ -974,7 +988,10 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
|
||||
if (!info)
|
||||
continue;
|
||||
if (info->irq[pin].link == pirq) {
|
||||
/* We refuse to override the dev->irq information. Give a warning! */
|
||||
/*
|
||||
* We refuse to override the dev->irq
|
||||
* information. Give a warning!
|
||||
*/
|
||||
if (dev2->irq && dev2->irq != irq && \
|
||||
(!(pci_probe & PCI_USE_PIRQ_MASK) || \
|
||||
((1 << dev2->irq) & mask))) {
|
||||
@@ -987,7 +1004,9 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
|
||||
dev2->irq = irq;
|
||||
pirq_penalty[irq]++;
|
||||
if (dev != dev2)
|
||||
printk(KERN_INFO "PCI: Sharing IRQ %d with %s\n", irq, pci_name(dev2));
|
||||
printk(KERN_INFO
|
||||
"PCI: Sharing IRQ %d with %s\n",
|
||||
irq, pci_name(dev2));
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@@ -1001,15 +1020,21 @@ static void __init pcibios_fixup_irqs(void)
|
||||
DBG(KERN_DEBUG "PCI: IRQ fixup\n");
|
||||
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
|
||||
/*
|
||||
* If the BIOS has set an out of range IRQ number, just ignore it.
|
||||
* Also keep track of which IRQ's are already in use.
|
||||
* If the BIOS has set an out of range IRQ number, just
|
||||
* ignore it. Also keep track of which IRQ's are
|
||||
* already in use.
|
||||
*/
|
||||
if (dev->irq >= 16) {
|
||||
DBG(KERN_DEBUG "%s: ignoring bogus IRQ %d\n", pci_name(dev), dev->irq);
|
||||
DBG(KERN_DEBUG "%s: ignoring bogus IRQ %d\n",
|
||||
pci_name(dev), dev->irq);
|
||||
dev->irq = 0;
|
||||
}
|
||||
/* If the IRQ is already assigned to a PCI device, ignore its ISA use penalty */
|
||||
if (pirq_penalty[dev->irq] >= 100 && pirq_penalty[dev->irq] < 100000)
|
||||
/*
|
||||
* If the IRQ is already assigned to a PCI device,
|
||||
* ignore its ISA use penalty
|
||||
*/
|
||||
if (pirq_penalty[dev->irq] >= 100 &&
|
||||
pirq_penalty[dev->irq] < 100000)
|
||||
pirq_penalty[dev->irq] = 0;
|
||||
pirq_penalty[dev->irq]++;
|
||||
}
|
||||
@@ -1025,8 +1050,13 @@ static void __init pcibios_fixup_irqs(void)
|
||||
int irq;
|
||||
|
||||
if (pin) {
|
||||
pin--; /* interrupt pins are numbered starting from 1 */
|
||||
irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
|
||||
/*
|
||||
* interrupt pins are numbered starting
|
||||
* from 1
|
||||
*/
|
||||
pin--;
|
||||
irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
|
||||
PCI_SLOT(dev->devfn), pin);
|
||||
/*
|
||||
* Busses behind bridges are typically not listed in the MP-table.
|
||||
* In this case we have to look up the IRQ based on the parent bus,
|
||||
@@ -1067,7 +1097,8 @@ static int __init fix_broken_hp_bios_irq9(const struct dmi_system_id *d)
|
||||
{
|
||||
if (!broken_hp_bios_irq9) {
|
||||
broken_hp_bios_irq9 = 1;
|
||||
printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", d->ident);
|
||||
printk(KERN_INFO "%s detected - fixing broken IRQ routing\n",
|
||||
d->ident);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1080,7 +1111,8 @@ static int __init fix_acer_tm360_irqrouting(const struct dmi_system_id *d)
|
||||
{
|
||||
if (!acer_tm360_irqrouting) {
|
||||
acer_tm360_irqrouting = 1;
|
||||
printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", d->ident);
|
||||
printk(KERN_INFO "%s detected - fixing broken IRQ routing\n",
|
||||
d->ident);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1092,7 +1124,8 @@ static struct dmi_system_id __initdata pciirq_dmi_table[] = {
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "GE.M1.03"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION,
|
||||
"HP Pavilion Notebook Model GE"),
|
||||
DMI_MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736"),
|
||||
},
|
||||
},
|
||||
@@ -1107,7 +1140,7 @@ static struct dmi_system_id __initdata pciirq_dmi_table[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static int __init pcibios_irq_init(void)
|
||||
int __init pcibios_irq_init(void)
|
||||
{
|
||||
DBG(KERN_DEBUG "PCI: IRQ init\n");
|
||||
|
||||
@@ -1131,7 +1164,10 @@ static int __init pcibios_irq_init(void)
|
||||
if (!(pirq_table->exclusive_irqs & (1 << i)))
|
||||
pirq_penalty[i] += 100;
|
||||
}
|
||||
/* If we're using the I/O APIC, avoid using the PCI IRQ routing table */
|
||||
/*
|
||||
* If we're using the I/O APIC, avoid using the PCI IRQ
|
||||
* routing table
|
||||
*/
|
||||
if (io_apic_assign_pci_irqs)
|
||||
pirq_table = NULL;
|
||||
}
|
||||
@@ -1142,9 +1178,6 @@ static int __init pcibios_irq_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(pcibios_irq_init);
|
||||
|
||||
|
||||
static void pirq_penalize_isa_irq(int irq, int active)
|
||||
{
|
||||
/*
|
||||
@@ -1178,7 +1211,7 @@ static int pirq_enable_irq(struct pci_dev *dev)
|
||||
if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) {
|
||||
char *msg = "";
|
||||
|
||||
pin--; /* interrupt pins are numbered starting from 1 */
|
||||
pin--; /* interrupt pins are numbered starting from 1 */
|
||||
|
||||
if (io_apic_assign_pci_irqs) {
|
||||
int irq;
|
||||
@@ -1198,13 +1231,16 @@ static int pirq_enable_irq(struct pci_dev *dev)
|
||||
irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
|
||||
PCI_SLOT(bridge->devfn), pin);
|
||||
if (irq >= 0)
|
||||
printk(KERN_WARNING "PCI: using PPB %s[%c] to get irq %d\n",
|
||||
pci_name(bridge), 'A' + pin, irq);
|
||||
printk(KERN_WARNING
|
||||
"PCI: using PPB %s[%c] to get irq %d\n",
|
||||
pci_name(bridge),
|
||||
'A' + pin, irq);
|
||||
dev = bridge;
|
||||
}
|
||||
dev = temp_dev;
|
||||
if (irq >= 0) {
|
||||
printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n",
|
||||
printk(KERN_INFO
|
||||
"PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n",
|
||||
pci_name(dev), 'A' + pin, irq);
|
||||
dev->irq = irq;
|
||||
return 0;
|
||||
@@ -1215,12 +1251,17 @@ static int pirq_enable_irq(struct pci_dev *dev)
|
||||
else
|
||||
msg = " Please try using pci=biosirq.";
|
||||
|
||||
/* With IDE legacy devices the IRQ lookup failure is not a problem.. */
|
||||
if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE && !(dev->class & 0x5))
|
||||
/*
|
||||
* With IDE legacy devices the IRQ lookup failure is not
|
||||
* a problem..
|
||||
*/
|
||||
if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE &&
|
||||
!(dev->class & 0x5))
|
||||
return 0;
|
||||
|
||||
printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
|
||||
'A' + pin, pci_name(dev), msg);
|
||||
printk(KERN_WARNING
|
||||
"PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
|
||||
'A' + pin, pci_name(dev), msg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@@ -55,4 +55,18 @@ static int __init pci_legacy_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(pci_legacy_init);
|
||||
int __init pci_subsys_init(void)
|
||||
{
|
||||
#ifdef CONFIG_ACPI
|
||||
pci_acpi_init();
|
||||
#endif
|
||||
pci_legacy_init();
|
||||
pcibios_irq_init();
|
||||
#ifdef CONFIG_X86_NUMAQ
|
||||
pci_numa_init();
|
||||
#endif
|
||||
pcibios_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(pci_subsys_init);
|
||||
|
@@ -1,23 +0,0 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/topology.h>
|
||||
|
||||
#define BUS_NR 256
|
||||
|
||||
static unsigned char mp_bus_to_node[BUS_NR];
|
||||
|
||||
void set_mp_bus_to_node(int busnum, int node)
|
||||
{
|
||||
if (busnum >= 0 && busnum < BUS_NR)
|
||||
mp_bus_to_node[busnum] = (unsigned char) node;
|
||||
}
|
||||
|
||||
int get_mp_bus_to_node(int busnum)
|
||||
{
|
||||
int node;
|
||||
|
||||
if (busnum < 0 || busnum > (BUS_NR - 1))
|
||||
return 0;
|
||||
node = mp_bus_to_node[busnum];
|
||||
return node;
|
||||
}
|
@@ -151,7 +151,7 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d)
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx);
|
||||
|
||||
static int __init pci_numa_init(void)
|
||||
int __init pci_numa_init(void)
|
||||
{
|
||||
int quad;
|
||||
|
||||
@@ -176,5 +176,3 @@ static int __init pci_numa_init(void)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(pci_numa_init);
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#define PCI_USE__CRS 0x10000
|
||||
#define PCI_CHECK_ENABLE_AMD_MMCONF 0x20000
|
||||
#define PCI_HAS_IO_ECS 0x40000
|
||||
#define PCI_NOASSIGN_ROMS 0x80000
|
||||
|
||||
extern unsigned int pci_probe;
|
||||
extern unsigned long pirq_table_addr;
|
||||
@@ -39,9 +40,6 @@ enum pci_bf_sort_state {
|
||||
pci_dmi_bf,
|
||||
};
|
||||
|
||||
extern void __init dmi_check_pciprobe(void);
|
||||
extern void __init dmi_check_skip_isa_align(void);
|
||||
|
||||
/* pci-i386.c */
|
||||
|
||||
extern unsigned int pcibios_max_latency;
|
||||
@@ -99,10 +97,19 @@ extern struct pci_raw_ops *raw_pci_ext_ops;
|
||||
|
||||
extern struct pci_raw_ops pci_direct_conf1;
|
||||
|
||||
/* arch_initcall level */
|
||||
extern int pci_direct_probe(void);
|
||||
extern void pci_direct_init(int type);
|
||||
extern void pci_pcbios_init(void);
|
||||
extern int pci_olpc_init(void);
|
||||
extern void __init dmi_check_pciprobe(void);
|
||||
extern void __init dmi_check_skip_isa_align(void);
|
||||
|
||||
/* some common used subsys_initcalls */
|
||||
extern int __init pci_acpi_init(void);
|
||||
extern int __init pcibios_irq_init(void);
|
||||
extern int __init pci_numa_init(void);
|
||||
extern int __init pcibios_init(void);
|
||||
|
||||
/* pci-mmconfig.c */
|
||||
|
||||
|
@@ -8,18 +8,19 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include "cobalt.h"
|
||||
#include "lithium.h"
|
||||
#include <asm/setup.h>
|
||||
#include <asm/visws/cobalt.h>
|
||||
#include <asm/visws/lithium.h>
|
||||
|
||||
#include "pci.h"
|
||||
|
||||
static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; }
|
||||
static void pci_visws_disable_irq(struct pci_dev *dev) { }
|
||||
|
||||
int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq;
|
||||
void (*pcibios_disable_irq)(struct pci_dev *dev) = &pci_visws_disable_irq;
|
||||
/* int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq; */
|
||||
/* void (*pcibios_disable_irq)(struct pci_dev *dev) = &pci_visws_disable_irq; */
|
||||
|
||||
void __init pcibios_penalize_isa_irq(int irq, int active) {}
|
||||
/* void __init pcibios_penalize_isa_irq(int irq, int active) {} */
|
||||
|
||||
|
||||
unsigned int pci_bus0, pci_bus1;
|
||||
@@ -85,7 +86,7 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
}
|
||||
|
||||
static int __init pcibios_init(void)
|
||||
static int __init pci_visws_init(void)
|
||||
{
|
||||
/* The VISWS supports configuration access type 1 only */
|
||||
pci_probe = (pci_probe | PCI_PROBE_CONF1) &
|
||||
@@ -105,4 +106,17 @@ static int __init pcibios_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(pcibios_init);
|
||||
static __init int pci_subsys_init(void)
|
||||
{
|
||||
if (!is_visws_box())
|
||||
return -1;
|
||||
|
||||
pcibios_enable_irq = &pci_visws_enable_irq;
|
||||
pcibios_disable_irq = &pci_visws_disable_irq;
|
||||
|
||||
pci_visws_init();
|
||||
pcibios_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(pci_subsys_init);
|
||||
|
Reference in New Issue
Block a user