]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/pci/hotplug/shpchp_pci.c
[PATCH] pciehp: request control of each hotplug controller individually
[linux-2.6-omap-h63xx.git] / drivers / pci / hotplug / shpchp_pci.c
index f51a97d7611fd58b3f0826e99fb19154b994cbb3..b8e95acea3b6abfe36527f4aca6ba2c9d0611ca1 100644 (file)
  *
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/proc_fs.h>
 #include <linux/pci.h>
 #include "../pci.h"
 #include "shpchp.h"
@@ -148,20 +144,33 @@ int shpchp_configure_device(struct slot *p_slot)
        return 0;
 }
 
-int shpchp_unconfigure_device(struct pci_func* func) 
+int shpchp_unconfigure_device(struct slot *p_slot)
 {
        int rc = 0;
        int j;
+       u8 bctl = 0;
        
-       dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus,
-                               func->device, func->function);
+       dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, p_slot->device);
 
        for (j=0; j<8 ; j++) {
-               struct pci_dev* temp = pci_find_slot(func->bus,
-                               (func->device << 3) | j);
-               if (temp) {
-                       pci_remove_bus_device(temp);
+               struct pci_dev* temp = pci_find_slot(p_slot->bus,
+                               (p_slot->device << 3) | j);
+               if (!temp)
+                       continue;
+               if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
+                       err("Cannot remove display device %s\n",
+                                       pci_name(temp));
+                       continue;
+               }
+               if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+                       pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
+                       if (bctl & PCI_BRIDGE_CTL_VGA) {
+                               err("Cannot remove display device %s\n",
+                                               pci_name(temp));
+                               continue;
+                       }
                }
+               pci_remove_bus_device(temp);
        }
        return rc;
 }