}
 EXPORT_SYMBOL_GPL(acpi_root_bridge);
 
+
+static int is_ejectable(acpi_handle handle)
+{
+       acpi_status status;
+       acpi_handle tmp;
+       unsigned long long removable;
+       status = acpi_get_handle(handle, "_ADR", &tmp);
+       if (ACPI_FAILURE(status))
+               return 0;
+       status = acpi_get_handle(handle, "_EJ0", &tmp);
+       if (ACPI_SUCCESS(status))
+               return 1;
+       status = acpi_evaluate_integer(handle, "_RMV", NULL, &removable);
+       if (ACPI_SUCCESS(status) && removable)
+               return 1;
+       return 0;
+}
+
+/**
+ * acpi_pcihp_check_ejectable - check if handle is ejectable ACPI PCI slot
+ * @pbus: the PCI bus of the PCI slot corresponding to 'handle'
+ * @handle: ACPI handle to check
+ *
+ * Return 1 if handle is ejectable PCI slot, 0 otherwise.
+ */
+int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle)
+{
+       acpi_handle bridge_handle, parent_handle;
+
+       if (!(bridge_handle = acpi_pci_get_bridge_handle(pbus)))
+               return 0;
+       if ((ACPI_FAILURE(acpi_get_parent(handle, &parent_handle))))
+               return 0;
+       if (bridge_handle != parent_handle)
+               return 0;
+       return is_ejectable(handle);
+}
+EXPORT_SYMBOL_GPL(acpi_pci_check_ejectable);
+
+static acpi_status
+check_hotplug(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+       int *found = (int *)context;
+       if (is_ejectable(handle)) {
+               *found = 1;
+               return AE_CTRL_TERMINATE;
+       }
+       return AE_OK;
+}
+
+/**
+ * acpi_pci_detect_ejectable - check if the PCI bus has ejectable slots
+ * @pbus - PCI bus to scan
+ *
+ * Returns 1 if the PCI bus has ACPI based ejectable slots, 0 otherwise.
+ */
+int acpi_pci_detect_ejectable(struct pci_bus *pbus)
+{
+       acpi_handle handle;
+       int found = 0;
+
+       if (!(handle = acpi_pci_get_bridge_handle(pbus)))
+               return 0;
+       acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
+                           check_hotplug, (void *)&found, NULL);
+       return found;
+}
+EXPORT_SYMBOL_GPL(acpi_pci_detect_ejectable);
+
 module_param(debug_acpi, bool, 0644);
 MODULE_PARM_DESC(debug_acpi, "Debugging mode for ACPI enabled or not");
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
+#include <linux/pci-acpi.h>
 #include <linux/mutex.h>
 
 #include "../pci.h"
 static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus);
 static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context);
 
-
-/*
- * initialization & terminatation routines
- */
-
-/**
- * is_ejectable - determine if a slot is ejectable
- * @handle: handle to acpi namespace
- *
- * Ejectable slot should satisfy at least these conditions:
- *
- *  1. has _ADR method
- *  2. has _EJ0 method or _RMV method
- *
- * optionally
- *
- *  1. has _STA method
- *  2. has _PS0 method
- *  3. has _PS3 method
- *  4. ..
- */
-static int is_ejectable(acpi_handle handle)
-{
-       acpi_status status;
-       acpi_handle tmp;
-       unsigned long long removable;
-
-       status = acpi_get_handle(handle, "_ADR", &tmp);
-       if (ACPI_FAILURE(status))
-               return 0;
-
-       status = acpi_get_handle(handle, "_EJ0", &tmp);
-       if (ACPI_SUCCESS(status))
-               return 1;
-
-       status = acpi_get_handle(handle, "_RMV", &tmp);
-       if (ACPI_SUCCESS(status)) {
-               status = acpi_evaluate_integer(handle, "_RMV", NULL,
-                                              &removable);
-               if (ACPI_SUCCESS(status) && removable)
-                       return 1;
-       }
-
-       return 0;
-}
-
-
-/* callback routine to check for the existence of ejectable slots */
-static acpi_status
-is_ejectable_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-       int *count = (int *)context;
-
-       if (is_ejectable(handle)) {
-               (*count)++;
-               /* only one ejectable slot is enough */
-               return AE_CTRL_TERMINATE;
-       } else {
-               return AE_OK;
-       }
-}
-
 /* callback routine to check for the existence of a pci dock device */
 static acpi_status
 is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv)
        }
 }
 
-
-
-
 /*
  * the _DCK method can do funny things... and sometimes not
  * hah-hah funny.
        acpi_status status = AE_OK;
        unsigned long long adr, sun;
        int device, function, retval;
+       struct pci_bus *pbus = bridge->pci_bus;
 
-       if (!is_ejectable(handle) && !is_dock_device(handle))
+       if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle))
                return AE_OK;
 
        acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
                bridge->nr_slots++;
 
                dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n",
-                               slot->sun, pci_domain_nr(bridge->pci_bus),
-                               bridge->pci_bus->number, slot->device);
+                   slot->sun, pci_domain_nr(pbus), pbus->number, device);
                retval = acpiphp_register_hotplug_slot(slot);
                if (retval) {
                        if (retval == -EBUSY)
        list_add_tail(&newfunc->sibling, &slot->funcs);
 
        /* associate corresponding pci_dev */
-       newfunc->pci_dev = pci_get_slot(bridge->pci_bus,
-                                        PCI_DEVFN(device, function));
+       newfunc->pci_dev = pci_get_slot(pbus, PCI_DEVFN(device, function));
        if (newfunc->pci_dev) {
                slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
        }
 
 
 /* see if it's worth looking at this bridge */
-static int detect_ejectable_slots(acpi_handle *bridge_handle)
+static int detect_ejectable_slots(struct pci_bus *pbus)
 {
-       acpi_status status;
-       int count;
-
-       count = 0;
-
-       /* only check slots defined directly below bridge object */
-       status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1,
-                                    is_ejectable_slot, (void *)&count, NULL);
-
-       /*
-        * we also need to add this bridge if there is a dock bridge or
-        * other pci device on a dock station (removable)
-        */
-       if (!count)
-               status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle,
-                               (u32)1, is_pci_dock_device, (void *)&count,
-                               NULL);
-
-       return count;
+       int found = acpi_pci_detect_ejectable(pbus);
+       if (!found) {
+               acpi_handle bridge_handle = acpi_pci_get_bridge_handle(pbus);
+               acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1,
+                                   is_pci_dock_device, (void *)&found, NULL);
+       }
+       return found;
 }
 
 
                goto out;
 
        /* check if this bridge has ejectable slots */
-       if ((detect_ejectable_slots(handle) > 0)) {
+       if ((detect_ejectable_slots(dev->subordinate) > 0)) {
                dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
                add_p2p_bridge(handle, dev);
        }
        }
 
        /* check if this bridge has ejectable slots */
-       if (detect_ejectable_slots(handle) > 0) {
+       if (detect_ejectable_slots(pci_bus) > 0) {
                dbg("found PCI host-bus bridge with hot-pluggable slots\n");
                add_host_bridge(handle, pci_bus);
        }
 
  */
 
 #include <linux/acpi.h>
+#include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include "pciehp.h"
 
 #define PCIEHP_DETECT_PCIE     (0)
         "  auto(default) - Auto select mode. Use acpi option if duplicate\n"
         "                  slot ids are found. Otherwise, use pcie option\n");
 
-static int is_ejectable(acpi_handle handle)
-{
-       acpi_status status;
-       acpi_handle tmp;
-       unsigned long long removable;
-       status = acpi_get_handle(handle, "_ADR", &tmp);
-       if (ACPI_FAILURE(status))
-               return 0;
-       status = acpi_get_handle(handle, "_EJ0", &tmp);
-       if (ACPI_SUCCESS(status))
-               return 1;
-       status = acpi_evaluate_integer(handle, "_RMV", NULL, &removable);
-       if (ACPI_SUCCESS(status) && removable)
-               return 1;
-       return 0;
-}
-
-static acpi_status
-check_hotplug(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-       int *found = (int *)context;
-       if (is_ejectable(handle)) {
-               *found = 1;
-               return AE_CTRL_TERMINATE;
-       }
-       return AE_OK;
-}
-
-static int pciehp_detect_acpi_slot(struct pci_bus *pbus)
-{
-       acpi_handle handle;
-       struct pci_dev *pdev = pbus->self;
-       int found = 0;
-
-       if (!pdev){
-               int seg = pci_domain_nr(pbus), busnr = pbus->number;
-               handle = acpi_get_pci_rootbridge_handle(seg, busnr);
-       } else
-               handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
-
-       if (!handle)
-               return 0;
-
-       acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-                           check_hotplug, (void *)&found, NULL);
-       return found;
-}
-
 int pciehp_acpi_slot_detection_check(struct pci_dev *dev)
 {
        if (slot_detection_mode != PCIEHP_DETECT_ACPI)
                return 0;
-       if (pciehp_detect_acpi_slot(dev->subordinate))
+       if (acpi_pci_detect_ejectable(dev->subordinate))
                return 0;
        return -ENODEV;
 }
        u32 slot_cap;
        struct slot *slot, *tmp;
        struct pci_dev *pdev = dev->port;
+       struct pci_bus *pbus = pdev->subordinate;
        if (!(slot = kzalloc(sizeof(*slot), GFP_KERNEL)))
                return -ENOMEM;
        /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */
                        dup_slot_id++;
        }
        list_add_tail(&slot->slot_list, &dummy_slots);
-       if (!acpi_slot_detected && pciehp_detect_acpi_slot(pdev->subordinate))
+       if (!acpi_slot_detected && acpi_pci_detect_ejectable(pbus))
                acpi_slot_detected = 1;
        return -ENODEV;         /* dummy driver always returns error */
 }
 
        return acpi_get_pci_rootbridge_handle(pci_domain_nr(pdev->bus),
                        pdev->bus->number);
 }
+
+static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus)
+{
+       int seg = pci_domain_nr(pbus), busnr = pbus->number;
+       struct pci_dev *bridge = pbus->self;
+       if (bridge)
+               return DEVICE_ACPI_HANDLE(&(bridge->dev));
+       return acpi_get_pci_rootbridge_handle(seg, busnr);
+}
 #else
 #if !defined(AE_ERROR)
 typedef u32            acpi_status;
 
                                struct hotplug_params *hpp);
 int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags);
 int acpi_root_bridge(acpi_handle handle);
+int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle);
+int acpi_pci_detect_ejectable(struct pci_bus *pbus);
 #endif
 #endif