PCI: call final fixups hot-added devices

Final fixups are currently applied only at boot-time by
pci_apply_final_quirks(), which is an fs_initcall().  Hot-added devices
don't get these fixups, so they may not be completely initialized.

This patch makes us run final fixups for hot-added devices in
pci_bus_add_device() just before the new device becomes eligible for driver
binding.

This patch keeps the fs_initcall() for devices present at boot because we
do resource assignment between pci_bus_add_device and the fs_initcall(),
and we don't want to break any fixups that depend on that assignment.  This
is a design issue that may be addressed in the future -- any resource
assignment should be done *before* device_add().

[bhelgaas: changelog]
Signed-off-by: Myron Stowe <myron.stowe@redhat.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 4ce5ef2..b511bd4 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -164,6 +164,10 @@
 int pci_bus_add_device(struct pci_dev *dev)
 {
 	int retval;
+	extern bool pci_fixup_final_inited;
+
+	if (pci_fixup_final_inited)
+		pci_fixup_device(pci_fixup_final, dev);
 	retval = device_add(&dev->dev);
 	if (retval)
 		return retval;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 4565f4f..d8e9a0e 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3028,6 +3028,22 @@
 }
 EXPORT_SYMBOL(pci_fixup_device);
 
+
+/*
+ * The global variable 'pci_fixup_final_inited' is being used as a interim
+ * solution for calling the final quirks only during hot-plug events (not
+ * during boot processing).
+ *
+ * When the boot path's PCI device setup sequencing is addressed, we can
+ * remove the instance, and usages of, 'pci_fixup_final_inited' along with
+ * removing 'fs_initcall_sync(pci_apply_final_quirks);' and end up with a
+ * single, uniform, solution that satisfies both the boot path and the
+ * various hot-plug event paths.
+ *
+ * ToDo: Remove 'pci_fixup_final_inited'
+ */
+bool pci_fixup_final_inited;
+
 static int __init pci_apply_final_quirks(void)
 {
 	struct pci_dev *dev = NULL;
@@ -3058,6 +3074,8 @@
 			pci_cache_line_size = pci_dfl_cache_line_size;
 		}
 	}
+	pci_fixup_final_inited = 1;
+
 	if (!pci_cache_line_size) {
 		printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n",
 		       cls << 2, pci_dfl_cache_line_size << 2);