lkml.org 
[lkml]   [2014]   [Jan]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[Patch v1 2/3] ACPI, PCI: reuse ACPI hotplug framework to support PCI host bridge hotplug
Date
Reuse ACPI hotplug framework to support PCI host bridge hotplug, this
makes PCI host bridge hotplug implementation simpler and more clear.

It also fixes a bug in support of PCI host bridge hot-addition.
Currently pci_root driver fails to install notification handler for
PCI host bridge absent at boot time because acpi_is_root_bridge()
returns false if no ACPI device created for handle. So PCI host
bridge hot-addition event will just be ignored by system.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
drivers/acpi/internal.h | 1 -
drivers/acpi/pci_root.c | 117 +++++++----------------------------------------
drivers/acpi/scan.c | 2 -
3 files changed, 17 insertions(+), 103 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index a29739c..03efa56 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -28,7 +28,6 @@ int init_acpi_device_notify(void);
int acpi_scan_init(void);
void acpi_pci_root_init(void);
void acpi_pci_link_init(void);
-void acpi_pci_root_hp_init(void);
void acpi_processor_init(void);
void acpi_platform_init(void);
int acpi_sysfs_init(void);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 20360e4..6f6e6c1 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -50,6 +50,7 @@ ACPI_MODULE_NAME("pci_root");
static int acpi_pci_root_add(struct acpi_device *device,
const struct acpi_device_id *not_used);
static void acpi_pci_root_remove(struct acpi_device *device);
+static int handle_hotplug_event_root(acpi_handle handle, u32 type, void *ctx);

#define ACPI_PCIE_REQ_SUPPORT (OSC_PCI_EXT_CONFIG_SUPPORT \
| OSC_PCI_ASPM_SUPPORT \
@@ -61,12 +62,14 @@ static const struct acpi_device_id root_device_ids[] = {
{"", 0},
};

+
static struct acpi_scan_handler pci_root_handler = {
.ids = root_device_ids,
+ .prepare = handle_hotplug_event_root,
.attach = acpi_pci_root_add,
.detach = acpi_pci_root_remove,
.hotplug = {
- .ignore = true,
+ .enabled = true,
},
};

@@ -627,113 +630,27 @@ void __init acpi_pci_root_init(void)

if (!acpi_pci_disabled) {
pci_acpi_crs_quirks();
- acpi_scan_add_handler(&pci_root_handler);
- }
-}
-/* Support root bridge hotplug */
-
-static void handle_root_bridge_insertion(acpi_handle handle)
-{
- struct acpi_device *device;
-
- if (!acpi_bus_get_device(handle, &device)) {
- dev_printk(KERN_DEBUG, &device->dev,
- "acpi device already exists; ignoring notify\n");
- return;
+ acpi_scan_add_handler_with_hotplug(&pci_root_handler,
+ "pci_hostbridge");
}
-
- if (acpi_bus_scan(handle))
- acpi_handle_err(handle, "cannot add bridge to acpi list\n");
}

-static void hotplug_event_root(void *data, u32 type)
+static int handle_hotplug_event_root(acpi_handle handle, u32 type, void *ctx)
{
- acpi_handle handle = data;
+ int ret = NOTIFY_OK;
struct acpi_pci_root *root;

- acpi_scan_lock_acquire();
-
- root = acpi_pci_find_root(handle);
-
- switch (type) {
- case ACPI_NOTIFY_BUS_CHECK:
- /* bus enumerate */
- acpi_handle_printk(KERN_DEBUG, handle,
- "Bus check notify on %s\n", __func__);
- if (root)
+ if (type == ACPI_NOTIFY_BUS_CHECK) {
+ acpi_scan_lock_acquire();
+ root = acpi_pci_find_root(handle);
+ if (root) {
+ acpi_handle_printk(KERN_DEBUG, handle,
+ "Bus check notify on %s\n", __func__);
acpiphp_check_host_bridge(handle);
- else
- handle_root_bridge_insertion(handle);
-
- break;
-
- case ACPI_NOTIFY_DEVICE_CHECK:
- /* device check */
- acpi_handle_printk(KERN_DEBUG, handle,
- "Device check notify on %s\n", __func__);
- if (!root)
- handle_root_bridge_insertion(handle);
- break;
-
- case ACPI_NOTIFY_EJECT_REQUEST:
- /* request device eject */
- acpi_handle_printk(KERN_DEBUG, handle,
- "Device eject notify on %s\n", __func__);
- if (!root)
- break;
-
- get_device(&root->device->dev);
-
+ ret = NOTIFY_STOP;
+ }
acpi_scan_lock_release();
-
- acpi_bus_device_eject(root->device, ACPI_NOTIFY_EJECT_REQUEST);
- return;
- default:
- acpi_handle_warn(handle,
- "notify_handler: unknown event type 0x%x\n",
- type);
- break;
}

- acpi_scan_lock_release();
-}
-
-static void handle_hotplug_event_root(acpi_handle handle, u32 type,
- void *context)
-{
- acpi_hotplug_execute(hotplug_event_root, handle, type);
-}
-
-static acpi_status __init
-find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
- acpi_status status;
- int *count = (int *)context;
-
- if (!acpi_is_root_bridge(handle))
- return AE_OK;
-
- (*count)++;
-
- status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
- handle_hotplug_event_root, NULL);
- if (ACPI_FAILURE(status))
- acpi_handle_printk(KERN_DEBUG, handle,
- "notify handler is not installed, exit status: %u\n",
- (unsigned int)status);
- else
- acpi_handle_printk(KERN_DEBUG, handle,
- "notify handler is installed\n");
-
- return AE_OK;
-}
-
-void __init acpi_pci_root_hp_init(void)
-{
- int num = 0;
-
- acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL);
-
- printk(KERN_DEBUG "Found %d acpi root devices\n", num);
+ return ret;
}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 6b0f419..d83e0ff 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2057,8 +2057,6 @@ int __init acpi_scan_init(void)

acpi_update_all_gpes();

- acpi_pci_root_hp_init();
-
out:
mutex_unlock(&acpi_scan_lock);
return result;
--
1.7.10.4


\
 
 \ /
  Last update: 2014-01-18 04:41    [W:0.667 / U:0.468 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site