Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee13...
[pandora-kernel.git] / arch / i386 / pci / common.c
index f6bc48d..68bce19 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/pci.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
+#include <linux/dmi.h>
 
 #include <asm/acpi.h>
 #include <asm/segment.h>
 
 #include "pci.h"
 
-#ifdef CONFIG_PCI_BIOS
-extern  void pcibios_sort(void);
-#endif
-
 unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
                                PCI_PROBE_MMCONF;
 
@@ -120,11 +117,42 @@ void __devinit  pcibios_fixup_bus(struct pci_bus *b)
        pci_read_bridge_bases(b);
 }
 
+/*
+ * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus)
+ */
+#ifdef __i386__
+static int __devinit assign_all_busses(struct dmi_system_id *d)
+{
+       pci_probe |= PCI_ASSIGN_ALL_BUSSES;
+       printk(KERN_INFO "%s detected: enabling PCI bus# renumbering"
+                       " (pci=assign-busses)\n", d->ident);
+       return 0;
+}
+#endif
+
+/*
+ * Laptops which need pci=assign-busses to see Cardbus cards
+ */
+static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
+#ifdef __i386__
+       {
+               .callback = assign_all_busses,
+               .ident = "Samsung X20 Laptop",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "SX20S"),
+               },
+       },
+#endif         /* __i386__ */
+       {}
+};
 
 struct pci_bus * __devinit pcibios_scan_root(int busnum)
 {
        struct pci_bus *bus = NULL;
 
+       dmi_check_system(pciprobe_dmi_table);
+
        while ((bus = pci_find_next_bus(bus)) != NULL) {
                if (bus->number == busnum) {
                        /* Already scanned */
@@ -214,6 +242,10 @@ char * __devinit  pcibios_setup(char *str)
                acpi_noirq_set();
                return NULL;
        }
+       else if (!strcmp(str, "noearly")) {
+               pci_probe |= PCI_PROBE_NOEARLY;
+               return NULL;
+       }
 #ifndef CONFIG_X86_VISWS
        else if (!strcmp(str, "usepirqmask")) {
                pci_probe |= PCI_USE_PIRQ_MASK;
@@ -256,6 +288,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 
 void pcibios_disable_device (struct pci_dev *dev)
 {
+       pcibios_disable_resources(dev);
        if (pcibios_disable_irq)
                pcibios_disable_irq(dev);
 }