Commit 7bfaf2ed authored by Andrew Morton's avatar Andrew Morton Committed by Greg Kroah-Hartman

[PATCH] add-pci_fixup_enable-pass.patch

From: Bjorn Helgaas <bjorn.helgaas@hp.com>

Nick Piggin's USB driver stopped working when I removed the unconditional
PCI ACPI IRQ routing stuff.  He has verified that the attached patch fixes
it.  I sort of hate to add another pass of PCI fixups, so I'm open to
alternate solutions if anybody suggests one.

Add a "pci_fixup_enable" pass of PCI fixups.  These are run at the end of
pci_enable_device() to fix up things like IRQs that are not set up until
then.  Some VIA boards require a fixup after the IRQ is set up.  Found by
Nick Piggin, initial patch by Bjorn Helgaas, reworked to fit into current
-mm by Nick.
Signed-off-by: default avatarNick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: default avatarBjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 3322aa43
......@@ -382,8 +382,13 @@ pci_enable_device_bars(struct pci_dev *dev, int bars)
int
pci_enable_device(struct pci_dev *dev)
{
int err;
dev->is_enabled = 1;
return pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
if ((err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1)))
return err;
pci_fixup_device(pci_fixup_enable, dev);
return 0;
}
/**
......
......@@ -491,9 +491,9 @@ static void __devinit quirk_via_irqpic(struct pci_dev *dev)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irqpic );
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irqpic );
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_6, quirk_via_irqpic );
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irqpic );
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irqpic );
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_6, quirk_via_irqpic );
/*
......@@ -1003,6 +1003,9 @@ extern struct pci_fixup __start_pci_fixups_header[];
extern struct pci_fixup __end_pci_fixups_header[];
extern struct pci_fixup __start_pci_fixups_final[];
extern struct pci_fixup __end_pci_fixups_final[];
extern struct pci_fixup __start_pci_fixups_enable[];
extern struct pci_fixup __end_pci_fixups_enable[];
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
{
......@@ -1018,6 +1021,12 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
start = __start_pci_fixups_final;
end = __end_pci_fixups_final;
break;
case pci_fixup_enable:
start = __start_pci_fixups_enable;
end = __end_pci_fixups_enable;
break;
default:
/* stupid compiler warning, you would think with an enum... */
return;
......
......@@ -24,6 +24,9 @@
VMLINUX_SYMBOL(__start_pci_fixups_final) = .; \
*(.pci_fixup_final) \
VMLINUX_SYMBOL(__end_pci_fixups_final) = .; \
VMLINUX_SYMBOL(__start_pci_fixups_enable) = .; \
*(.pci_fixup_enable) \
VMLINUX_SYMBOL(__end_pci_fixups_enable) = .; \
} \
\
/* Kernel symbol table: Normal symbols */ \
......
......@@ -1001,6 +1001,7 @@ struct pci_fixup {
enum pci_fixup_pass {
pci_fixup_header, /* Called immediately after reading configuration header */
pci_fixup_final, /* Final phase of device fixups */
pci_fixup_enable, /* pci_enable_device() time */
};
/* Anonymous variables would be nice... */
......@@ -1014,6 +1015,12 @@ enum pci_fixup_pass {
__attribute__((__section__(".pci_fixup_final"))) = { \
vendor, device, hook };
#define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook) \
static struct pci_fixup __pci_fixup_##vendor##device##hook __attribute_used__ \
__attribute__((__section__(".pci_fixup_enable"))) = { \
vendor, device, hook };
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
extern int pci_pci_problems;
......
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