Commit 005fefbc authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleed-2.6

into kroah.com:/home/greg/linux/BK/pci-2.6
parents e47c11be fb729e28
......@@ -921,6 +921,10 @@ running once the system is up.
enabled.
noacpi [IA-32] Do not use ACPI for IRQ routing
or for PCI scanning.
routeirq Do IRQ routing for all PCI devices.
This is normally done in pci_enable_device(),
so this option is a temporary workaround
for broken drivers that don't call it.
firmware [ARM] Do not re-enumerate the bus but
instead just use the configuration
......
......@@ -457,17 +457,11 @@ unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
* Make sure all (legacy) PCI IRQs are set as level-triggered.
*/
if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
static u16 irq_mask;
extern void eisa_set_level_irq(unsigned int irq);
if (edge_level == ACPI_LEVEL_SENSITIVE) {
if ((gsi < 16) && !((1 << gsi) & irq_mask)) {
Dprintk(KERN_DEBUG PREFIX "Setting GSI %u as level-triggered\n", gsi);
irq_mask |= (1 << gsi);
if (edge_level == ACPI_LEVEL_SENSITIVE)
eisa_set_level_irq(gsi);
}
}
}
#endif
#ifdef CONFIG_X86_IO_APIC
......
......@@ -15,6 +15,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
return pcibios_scan_root(busnum);
}
extern int pci_routeirq;
static int __init pci_acpi_init(void)
{
struct pci_dev *dev = NULL;
......@@ -30,14 +31,27 @@ static int __init pci_acpi_init(void)
pcibios_scanned++;
pcibios_enable_irq = acpi_pci_irq_enable;
if (pci_routeirq) {
/*
* PCI IRQ routing is set up by pci_enable_device(), but we
* also do it here in case there are still broken drivers that
* don't use pci_enable_device().
*/
while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
printk(KERN_INFO "** Routing PCI interrupts for all devices because \"pci=routeirq\"\n");
printk(KERN_INFO "** was specified. If this was required to make a driver work,\n");
printk(KERN_INFO "** please email the output of \"lspci\" to bjorn.helgaas@hp.com\n");
printk(KERN_INFO "** so I can fix the driver.\n");
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
acpi_pci_irq_enable(dev);
} else {
printk(KERN_INFO "** PCI interrupts are no longer routed automatically. If this\n");
printk(KERN_INFO "** causes a device to stop working, it is probably because the\n");
printk(KERN_INFO "** driver failed to call pci_enable_device(). As a temporary\n");
printk(KERN_INFO "** workaround, the \"pci=routeirq\" argument restores the old\n");
printk(KERN_INFO "** behavior. If this argument makes the device work again,\n");
printk(KERN_INFO "** please email the output of \"lspci\" to bjorn.helgaas@hp.com\n");
printk(KERN_INFO "** so I can fix the driver.\n");
}
#ifdef CONFIG_X86_IO_APIC
if (acpi_ioapic)
print_IO_APIC();
......
......@@ -23,6 +23,7 @@ extern void pcibios_sort(void);
unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
PCI_PROBE_MMCONF;
int pci_routeirq;
int pcibios_last_bus = -1;
struct pci_bus *pci_root_bus = NULL;
struct pci_raw_ops *raw_pci_ops;
......@@ -227,6 +228,9 @@ char * __devinit pcibios_setup(char *str)
} else if (!strcmp(str, "assign-busses")) {
pci_probe |= PCI_ASSIGN_ALL_BUSSES;
return NULL;
} else if (!strcmp(str, "routeirq")) {
pci_routeirq = 1;
return NULL;
}
return str;
}
......
......@@ -127,8 +127,15 @@ void eisa_set_level_irq(unsigned int irq)
{
unsigned char mask = 1 << (irq & 7);
unsigned int port = 0x4d0 + (irq >> 3);
unsigned char val = inb(port);
unsigned char val;
static u16 eisa_irq_mask;
if (irq >= 16 || (1 << irq) & eisa_irq_mask)
return;
eisa_irq_mask |= (1 << irq);
printk("PCI: setting IRQ %u as level-triggered\n", irq);
val = inb(port);
if (!(val & mask)) {
DBG(" -> edge");
outb(val | mask, port);
......@@ -452,21 +459,17 @@ static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq,
#endif
static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
{
struct pci_dev *dev1, *dev2;
static struct pci_device_id pirq_440gx[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
{ },
};
/* 440GX has a proprietary PIRQ router -- don't use it */
dev1 = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82443GX_0, NULL);
dev2 = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82443GX_2, NULL);
if ((dev1 != NULL) || (dev2 != NULL)) {
pci_dev_put(dev1);
pci_dev_put(dev2);
if (pci_dev_present(pirq_440gx))
return 0;
}
switch(device)
{
......
......@@ -46,6 +46,8 @@
#define DBG(x...)
#endif
static int pci_routeirq;
/*
* Low-level SAL-based PCI configuration access functions. Note that SAL
* calls are already serialized (via sal_lock), so we don't need another
......@@ -141,13 +143,28 @@ extern acpi_status acpi_map_iosapic (acpi_handle, u32, void*, void**);
acpi_get_devices(NULL, acpi_map_iosapic, NULL, NULL);
#endif
if (pci_routeirq) {
/*
* PCI IRQ routing is set up by pci_enable_device(), but we
* also do it here in case there are still broken drivers that
* don't use pci_enable_device().
*/
printk(KERN_INFO "** Routing PCI interrupts for all devices because \"pci=routeirq\"\n");
printk(KERN_INFO "** was specified. If this was required to make a driver work,\n");
printk(KERN_INFO "** please email the output of \"lspci\" to bjorn.helgaas@hp.com\n");
printk(KERN_INFO "** so I can fix the driver.\n");
while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
acpi_pci_irq_enable(dev);
} else {
printk(KERN_INFO "** PCI interrupts are no longer routed automatically. If this\n");
printk(KERN_INFO "** causes a device to stop working, it is probably because the\n");
printk(KERN_INFO "** driver failed to call pci_enable_device(). As a temporary\n");
printk(KERN_INFO "** workaround, the \"pci=routeirq\" argument restores the old\n");
printk(KERN_INFO "** behavior. If this argument makes the device work again,\n");
printk(KERN_INFO "** please email the output of \"lspci\" to bjorn.helgaas@hp.com\n");
printk(KERN_INFO "** so I can fix the driver.\n");
}
return 0;
}
......@@ -443,6 +460,8 @@ pcibios_align_resource (void *data, struct resource *res,
char * __init
pcibios_setup (char *str)
{
if (!strcmp(str, "routeirq"))
pci_routeirq = 1;
return NULL;
}
......
......@@ -3685,9 +3685,9 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id)
int i, err;
if (pci_enable_device(pcidev)) {
if ((err = pci_enable_device(pcidev))) {
printk("idt77252: can't enable PCI device at %s\n", pci_name(pcidev));
return -ENODEV;
return err;
}
if (pci_read_config_word(pcidev, PCI_REVISION_ID, &revision)) {
......
......@@ -88,10 +88,10 @@ static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id
tpam_card *card, *c;
int i, err;
if (pci_enable_device(dev)) {
if ((err = pci_enable_device(dev))) {
printk(KERN_ERR "TurboPAM: can't enable PCI device at %s\n",
pci_name(dev));
return -ENODEV;
return err;
}
/* allocate memory for the board structure */
......
......@@ -59,13 +59,13 @@
static int __init ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
int result = -ENOMEM;
int err, result = -ENOMEM;
struct service_processor *sp;
if (pci_enable_device(pdev)) {
if ((err = pci_enable_device(pdev))) {
printk(KERN_ERR "%s: can't enable PCI device at %s\n",
DRIVER_NAME, pci_name(pdev));
return -ENODEV;
return err;
}
sp = kmalloc(sizeof(struct service_processor), GFP_KERNEL);
......
......@@ -2242,8 +2242,8 @@ static int __devinit de4x5_pci_probe (struct pci_dev *pdev,
return -ENODEV;
/* Ok, the device seems to be for us. */
if (pci_enable_device (pdev))
return -ENODEV;
if ((error = pci_enable_device (pdev)))
return error;
if (!(dev = alloc_etherdev (sizeof (struct de4x5_private)))) {
error = -ENOMEM;
......
......@@ -374,6 +374,16 @@ pci_enable_device(struct pci_dev *dev)
return 0;
}
/**
* pcibios_disable_device - disable arch specific PCI resources for device dev
* @dev: the PCI device to disable
*
* Disables architecture specific PCI resources for the device. This
* is the default implementation. Architecture implementations can
* override this.
*/
void __attribute__ ((weak)) pcibios_disable_device (struct pci_dev *dev) {}
/**
* pci_disable_device - Disable PCI device after use
* @dev: PCI device to be disabled
......@@ -394,6 +404,8 @@ pci_disable_device(struct pci_dev *dev)
pci_command &= ~PCI_COMMAND_MASTER;
pci_write_config_word(dev, PCI_COMMAND, pci_command);
}
pcibios_disable_device(dev);
}
/**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment