]> git.hungrycats.org Git - linux/commitdiff
[PATCH] add-pci_fixup_enable-pass.patch
authorAndrew Morton <akpm@osdl.org>
Wed, 6 Oct 2004 05:25:07 +0000 (22:25 -0700)
committerGreg Kroah-Hartman <greg@kroah.com>
Wed, 6 Oct 2004 05:25:07 +0000 (22:25 -0700)
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: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
drivers/pci/pci.c
drivers/pci/quirks.c
include/asm-generic/vmlinux.lds.h
include/linux/pci.h

index 46d56c8ccf100b80e280e8f53703e76ca1293a25..089eaa832c3792e75cf176bfdd3e2ab736384df7 100644 (file)
@@ -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;
 }
 
 /**
index 92067ac842c2da8199f1bc6e68ef34726e9b030f..49a9672c08010506c28f10e66caecab2cb551302 100644 (file)
@@ -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;
index bb340cb5cb03cfa74795c0f598c475f96c4ca278..da1b3ba89b3e19f4fb0f39055708d346935193b7 100644 (file)
@@ -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 */                       \
index 48d939c7625c40814e50e455279eef34495cfdcf..169badd4917ed3ebc519ac6407515bda828efa91 100644 (file)
@@ -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;