* [PATCH v2 02/37] PNPACPI: Fix device ref leaking in acpi_pnp_match
[not found] <1331362837-10740-1-git-send-email-yinghai@kernel.org>
@ 2012-03-10 7:00 ` Yinghai Lu
2012-03-13 2:40 ` Bjorn Helgaas
2012-03-10 7:00 ` [PATCH v2 21/37] PCI, ACPI: Make acpi_pci_root_remove remove pci root bus too Yinghai Lu
` (8 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Yinghai Lu @ 2012-03-10 7:00 UTC (permalink / raw)
To: Jesse Barnes, x86
Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
linux-pci, linux-kernel, Yinghai Lu, stable, Len Brown,
Adam Belay, linux-acpi
During testing pci root bus removal, found some root bus bridge is not freed.
If booting with pnpacpi=off, those hostbridge could be freed without problem.
It turns out that some devices reference are not released during acpi_pnp_match.
That match should not hold one device ref during every calling.
Add put_device calling before returning.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: stable@kernel.org
Cc: Len Brown <lenb@kernel.org>
Cc: Adam Belay <abelay@mit.edu>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: linux-acpi@vger.kernel.org
---
drivers/pnp/pnpacpi/core.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index b00c176..d21e8f5 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -321,9 +321,14 @@ static int __init acpi_pnp_match(struct device *dev, void *_pnp)
{
struct acpi_device *acpi = to_acpi_device(dev);
struct pnp_dev *pnp = _pnp;
+ struct device *physical_device;
+
+ physical_device = acpi_get_physical_device(acpi->handle);
+ if (physical_device)
+ put_device(physical_device);
/* true means it matched */
- return !acpi_get_physical_device(acpi->handle)
+ return !physical_device
&& compare_pnp_id(pnp->id, acpi_device_hid(acpi));
}
--
1.7.7
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 21/37] PCI, ACPI: Make acpi_pci_root_remove remove pci root bus too
[not found] <1331362837-10740-1-git-send-email-yinghai@kernel.org>
2012-03-10 7:00 ` [PATCH v2 02/37] PNPACPI: Fix device ref leaking in acpi_pnp_match Yinghai Lu
@ 2012-03-10 7:00 ` Yinghai Lu
2012-03-13 3:11 ` Bjorn Helgaas
2012-03-10 7:00 ` [PATCH v2 23/37] PCI, ACPI: Add pci_root_hp hot add hotplug notification Yinghai Lu
` (7 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Yinghai Lu @ 2012-03-10 7:00 UTC (permalink / raw)
To: Jesse Barnes, x86
Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
linux-pci, linux-kernel, Yinghai Lu, Len Brown, linux-acpi
It will call new added pci_stop_and_remove_bus() to stop/remove pci root bus.
Also checking if that pci_root_bus get removed already in bus remove in /sys
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org
---
drivers/acpi/pci_root.c | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 7aff631..b38e347 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -643,10 +643,24 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type)
{
struct acpi_pci_root *root = acpi_driver_data(device);
+ /* that root bus could be removed already */
+ if (!pci_find_bus(root->segment, root->secondary.start)) {
+ dev_printk(KERN_DEBUG, &device->dev,
+ "freeing acpi_pci_root, but pci root bus was removed before");
+ goto out;
+ }
+
device_set_run_wake(root->bus->bridge, false);
pci_acpi_remove_bus_pm_notifier(device);
+ dev_printk(KERN_DEBUG, &device->dev,
+ "freeing acpi_pci_root, will remove pci root bus at first");
+ pci_stop_and_remove_bus(root->bus);
+
+out:
+ list_del(&root->node);
kfree(root);
+
return 0;
}
--
1.7.7
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 23/37] PCI, ACPI: Add pci_root_hp hot add hotplug notification
[not found] <1331362837-10740-1-git-send-email-yinghai@kernel.org>
2012-03-10 7:00 ` [PATCH v2 02/37] PNPACPI: Fix device ref leaking in acpi_pnp_match Yinghai Lu
2012-03-10 7:00 ` [PATCH v2 21/37] PCI, ACPI: Make acpi_pci_root_remove remove pci root bus too Yinghai Lu
@ 2012-03-10 7:00 ` Yinghai Lu
2012-03-13 3:22 ` Bjorn Helgaas
2012-03-10 7:00 ` [PATCH v2 24/37] PCI, ACPI: Add pci_root_hp hot removal notification support Yinghai Lu
` (6 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Yinghai Lu @ 2012-03-10 7:00 UTC (permalink / raw)
To: Jesse Barnes, x86
Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
linux-pci, linux-kernel, Yinghai Lu, Len Brown, linux-acpi
It is from acpiphp_glue.c
How to use it?
Find out root bus number to acpi root name mapping from dmesg or /sys
echo "\_SB.PCIB 0" > /proc/acpi/sci/notify
to add it back
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org
---
drivers/acpi/Makefile | 1 +
drivers/acpi/pci_root_hp.c | 237 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 238 insertions(+), 0 deletions(-)
create mode 100644 drivers/acpi/pci_root_hp.c
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 1567028..bc6e53f 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -36,6 +36,7 @@ acpi-y += processor_core.o
acpi-y += ec.o
acpi-$(CONFIG_ACPI_DOCK) += dock.o
acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
+acpi-$(CONFIG_HOTPLUG) += pci_root_hp.o
acpi-y += power.o
acpi-y += event.o
acpi-y += sysfs.o
diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c
new file mode 100644
index 0000000..dc11e81
--- /dev/null
+++ b/drivers/acpi/pci_root_hp.c
@@ -0,0 +1,237 @@
+/*
+ * Separated from drivers/pci/hotplug/acpiphp_glue.c
+ * only support root bridge
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/acpi.h>
+
+static LIST_HEAD(acpi_root_bridge_list);
+struct acpi_root_bridge {
+ struct list_head list;
+ acpi_handle handle;
+ u32 flags;
+};
+
+/* bridge flags */
+#define ROOT_BRIDGE_HAS_EJ0 (0x00000002)
+#define ROOT_BRIDGE_HAS_PS3 (0x00000080)
+
+#define ACPI_STA_FUNCTIONING (0x00000008)
+
+static struct acpi_root_bridge *acpi_root_handle_to_bridge(acpi_handle handle)
+{
+ struct acpi_root_bridge *bridge;
+
+ list_for_each_entry(bridge, &acpi_root_bridge_list, list)
+ if (bridge->handle == handle)
+ return bridge;
+
+ return NULL;
+}
+
+/* allocate and initialize host bridge data structure */
+static void add_acpi_root_bridge(acpi_handle handle)
+{
+ struct acpi_root_bridge *bridge;
+ acpi_handle dummy_handle;
+ acpi_status status;
+
+ /* if the bridge doesn't have _STA, we assume it is always there */
+ status = acpi_get_handle(handle, "_STA", &dummy_handle);
+ if (ACPI_SUCCESS(status)) {
+ unsigned long long tmp;
+
+ status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_DEBUG "%s: _STA evaluation failure\n",
+ __func__);
+ return;
+ }
+ if ((tmp & ACPI_STA_FUNCTIONING) == 0)
+ /* don't register this object */
+ return;
+ }
+
+ bridge = kzalloc(sizeof(struct acpi_root_bridge), GFP_KERNEL);
+ if (!bridge)
+ return;
+
+ bridge->handle = handle;
+
+ if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &dummy_handle)))
+ bridge->flags |= ROOT_BRIDGE_HAS_EJ0;
+ if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &dummy_handle)))
+ bridge->flags |= ROOT_BRIDGE_HAS_PS3;
+
+ list_add(&bridge->list, &acpi_root_bridge_list);
+}
+
+struct acpi_root_hp_work {
+ struct work_struct work;
+ acpi_handle handle;
+ u32 type;
+ void *context;
+};
+
+static void alloc_acpi_root_hp_work(acpi_handle handle, u32 type,
+ void *context,
+ void (*func)(struct work_struct *work))
+{
+ struct acpi_root_hp_work *hp_work;
+ int ret;
+
+ hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL);
+ if (!hp_work)
+ return;
+
+ hp_work->handle = handle;
+ hp_work->type = type;
+ hp_work->context = context;
+
+ INIT_WORK(&hp_work->work, func);
+ ret = queue_work(kacpi_hotplug_wq, &hp_work->work);
+ if (!ret)
+ kfree(hp_work);
+}
+
+/* Program resources in newly inserted bridge */
+static void acpi_root_configure_bridge(acpi_handle handle)
+{
+ struct acpi_pci_root *root = acpi_pci_find_root(handle);
+
+ pci_assign_unassigned_bus_resources(root->bus);
+}
+
+static void handle_root_bridge_insertion(acpi_handle handle)
+{
+ struct acpi_device *device, *pdevice;
+ acpi_handle phandle;
+ int ret_val;
+
+ acpi_get_parent(handle, &phandle);
+ if (acpi_bus_get_device(phandle, &pdevice)) {
+ printk(KERN_DEBUG "no parent device, assuming NULL\n");
+ pdevice = NULL;
+ }
+ if (!acpi_bus_get_device(handle, &device)) {
+ /* check if pci root_bus is removed */
+ struct acpi_pci_root *root = acpi_driver_data(device);
+ if (pci_find_bus(root->segment, root->secondary.start))
+ return;
+
+ printk(KERN_DEBUG "bus exists... trim\n");
+ /* this shouldn't be in here, so remove
+ * the bus then re-add it...
+ */
+ ret_val = acpi_bus_trim(device, 1);
+ printk(KERN_DEBUG "acpi_bus_trim return %x\n", ret_val);
+ }
+ if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) {
+ printk(KERN_ERR "cannot add bridge to acpi list\n");
+ return;
+ }
+ acpi_root_configure_bridge(handle);
+ if (acpi_bus_start(device))
+ printk(KERN_ERR "cannot start bridge\n");
+}
+
+static void _handle_hotplug_event_root(struct work_struct *work)
+{
+ struct acpi_root_bridge *bridge;
+ char objname[64];
+ struct acpi_buffer buffer = { .length = sizeof(objname),
+ .pointer = objname };
+ struct acpi_root_hp_work *hp_work;
+ acpi_handle handle;
+ u32 type;
+
+ hp_work = container_of(work, struct acpi_root_hp_work, work);
+ handle = hp_work->handle;
+ type = hp_work->type;
+
+ bridge = acpi_root_handle_to_bridge(handle);
+
+ acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+
+ switch (type) {
+ case ACPI_NOTIFY_BUS_CHECK:
+ /* bus enumerate */
+ printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__,
+ objname);
+ if (!bridge) {
+ handle_root_bridge_insertion(handle);
+ add_acpi_root_bridge(handle);
+ }
+
+ break;
+
+ case ACPI_NOTIFY_DEVICE_CHECK:
+ /* device check */
+ printk(KERN_DEBUG "%s: Device check notify on %s\n", __func__,
+ objname);
+ if (!bridge) {
+ handle_root_bridge_insertion(handle);
+ add_acpi_root_bridge(handle);
+ }
+ break;
+
+ default:
+ printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n",
+ type, objname);
+ break;
+ }
+
+ kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
+}
+
+static void handle_hotplug_event_root(acpi_handle handle, u32 type,
+ void *context)
+{
+ alloc_acpi_root_hp_work(handle, type, context,
+ _handle_hotplug_event_root);
+}
+
+static acpi_status __init
+find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+ char objname[64];
+ struct acpi_buffer buffer = { .length = sizeof(objname),
+ .pointer = objname };
+ int *count = (int *)context;
+
+ if (!acpi_is_root_bridge(handle))
+ return AE_OK;
+
+ (*count)++;
+
+ acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+
+ acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+ handle_hotplug_event_root, NULL);
+ printk(KERN_DEBUG "acpi root: %s notify handler installed\n", objname);
+
+ add_acpi_root_bridge(handle);
+
+ return AE_OK;
+}
+
+static int __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 0;
+}
+
+subsys_initcall(acpi_pci_root_hp_init);
--
1.7.7
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 24/37] PCI, ACPI: Add pci_root_hp hot removal notification support.
[not found] <1331362837-10740-1-git-send-email-yinghai@kernel.org>
` (2 preceding siblings ...)
2012-03-10 7:00 ` [PATCH v2 23/37] PCI, ACPI: Add pci_root_hp hot add hotplug notification Yinghai Lu
@ 2012-03-10 7:00 ` Yinghai Lu
2012-03-13 3:25 ` Bjorn Helgaas
2012-03-10 7:00 ` [PATCH v2 25/37] PCI, ACPI: Add alloc_acpi_hp_work() Yinghai Lu
` (5 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Yinghai Lu @ 2012-03-10 7:00 UTC (permalink / raw)
To: Jesse Barnes, x86
Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
linux-pci, linux-kernel, Yinghai Lu, Len Brown, linux-acpi
Add missing hot_remove support for root device.
How to use it?
Find out root bus number to acpi root name mapping from dmesg or /sys
echo "\_SB.PCIB 3" > /proc/acpi/sci/notify
to remove root bus
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org
---
drivers/acpi/pci_root_hp.c | 61 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 61 insertions(+), 0 deletions(-)
diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c
index dc11e81..f5585f5 100644
--- a/drivers/acpi/pci_root_hp.c
+++ b/drivers/acpi/pci_root_hp.c
@@ -73,6 +73,12 @@ static void add_acpi_root_bridge(acpi_handle handle)
list_add(&bridge->list, &acpi_root_bridge_list);
}
+static void remove_acpi_root_bridge(struct acpi_root_bridge *bridge)
+{
+ list_del(&bridge->list);
+ kfree(bridge);
+}
+
struct acpi_root_hp_work {
struct work_struct work;
acpi_handle handle;
@@ -142,6 +148,55 @@ static void handle_root_bridge_insertion(acpi_handle handle)
printk(KERN_ERR "cannot start bridge\n");
}
+static int acpi_root_evaluate_object(acpi_handle handle, char *cmd, int val)
+{
+ acpi_status status;
+ struct acpi_object_list arg_list;
+ union acpi_object arg;
+
+ arg_list.count = 1;
+ arg_list.pointer = &arg;
+ arg.type = ACPI_TYPE_INTEGER;
+ arg.integer.value = val;
+
+ status = acpi_evaluate_object(handle, cmd, &arg_list, NULL);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_WARNING "%s: %s to %d failed\n",
+ __func__, cmd, val);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void handle_root_bridge_removal(acpi_handle handle,
+ struct acpi_root_bridge *bridge)
+{
+ u32 flags = 0;
+ struct acpi_device *device;
+
+ if (bridge) {
+ flags = bridge->flags;
+ remove_acpi_root_bridge(bridge);
+ }
+
+ if (!acpi_bus_get_device(handle, &device)) {
+ int ret_val = acpi_bus_trim(device, 1);
+
+ printk(KERN_DEBUG "acpi_bus_trim return %x\n", ret_val);
+ }
+
+ if (flags & ROOT_BRIDGE_HAS_PS3) {
+ acpi_status status;
+
+ status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
+ if (ACPI_FAILURE(status))
+ printk(KERN_WARNING "%s: _PS3 failed\n", __func__);
+ }
+ if (flags & ROOT_BRIDGE_HAS_EJ0)
+ acpi_root_evaluate_object(handle, "_EJ0", 1);
+}
+
static void _handle_hotplug_event_root(struct work_struct *work)
{
struct acpi_root_bridge *bridge;
@@ -182,6 +237,12 @@ static void _handle_hotplug_event_root(struct work_struct *work)
}
break;
+ case ACPI_NOTIFY_EJECT_REQUEST:
+ /* request device eject */
+ printk(KERN_DEBUG "%s: Device eject notify on %s\n", __func__,
+ objname);
+ handle_root_bridge_removal(handle, bridge);
+ break;
default:
printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n",
type, objname);
--
1.7.7
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 25/37] PCI, ACPI: Add alloc_acpi_hp_work()
[not found] <1331362837-10740-1-git-send-email-yinghai@kernel.org>
` (3 preceding siblings ...)
2012-03-10 7:00 ` [PATCH v2 24/37] PCI, ACPI: Add pci_root_hp hot removal notification support Yinghai Lu
@ 2012-03-10 7:00 ` Yinghai Lu
2012-03-10 7:00 ` [PATCH v2 26/37] PCI, acpiphp: Use acpi_hp_work Yinghai Lu
` (4 subsequent siblings)
9 siblings, 0 replies; 21+ messages in thread
From: Yinghai Lu @ 2012-03-10 7:00 UTC (permalink / raw)
To: Jesse Barnes, x86
Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
linux-pci, linux-kernel, Yinghai Lu, Len Brown, linux-acpi
Will use it with acpiphp and pci_root_hp events handling
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org
---
drivers/acpi/osl.c | 21 +++++++++++++++++++++
include/acpi/acpiosxf.h | 9 +++++++++
2 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 412a1e0..fdcf4a5 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1641,3 +1641,24 @@ acpi_status acpi_os_terminate(void)
return AE_OK;
}
+
+void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context,
+ void (*func)(struct work_struct *work))
+{
+ struct acpi_hp_work *hp_work;
+ int ret;
+
+ hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL);
+ if (!hp_work)
+ return;
+
+ hp_work->handle = handle;
+ hp_work->type = type;
+ hp_work->context = context;
+
+ INIT_WORK(&hp_work->work, func);
+ ret = queue_work(kacpi_hotplug_wq, &hp_work->work);
+ if (!ret)
+ kfree(hp_work);
+}
+EXPORT_SYMBOL(alloc_acpi_hp_work);
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index 7c9aebe..62326ae 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -191,6 +191,15 @@ void acpi_os_fixed_event_count(u32 fixed_event_number);
*/
extern struct workqueue_struct *kacpi_hotplug_wq;
+struct acpi_hp_work {
+ struct work_struct work;
+ acpi_handle handle;
+ u32 type;
+ void *context;
+};
+void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context,
+ void (*func)(struct work_struct *work));
+
acpi_thread_id acpi_os_get_thread_id(void);
acpi_status
--
1.7.7
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 26/37] PCI, acpiphp: Use acpi_hp_work
[not found] <1331362837-10740-1-git-send-email-yinghai@kernel.org>
` (4 preceding siblings ...)
2012-03-10 7:00 ` [PATCH v2 25/37] PCI, ACPI: Add alloc_acpi_hp_work() Yinghai Lu
@ 2012-03-10 7:00 ` Yinghai Lu
2012-03-10 7:00 ` [PATCH v2 27/37] PCI, pci_root_hp: " Yinghai Lu
` (3 subsequent siblings)
9 siblings, 0 replies; 21+ messages in thread
From: Yinghai Lu @ 2012-03-10 7:00 UTC (permalink / raw)
To: Jesse Barnes, x86
Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
linux-pci, linux-kernel, Yinghai Lu, Len Brown, linux-acpi
Remove local defined acpiphp_hp_work.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org
---
drivers/pci/hotplug/acpiphp_glue.c | 42 +++++------------------------------
1 files changed, 6 insertions(+), 36 deletions(-)
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 1ca82ae..9f1a195 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1118,34 +1118,6 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
return AE_OK ;
}
-struct acpiphp_hp_work {
- struct work_struct work;
- acpi_handle handle;
- u32 type;
- void *context;
-};
-
-static void alloc_acpiphp_hp_work(acpi_handle handle, u32 type,
- void *context,
- void (*func)(struct work_struct *work))
-{
- struct acpiphp_hp_work *hp_work;
- int ret;
-
- hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL);
- if (!hp_work)
- return;
-
- hp_work->handle = handle;
- hp_work->type = type;
- hp_work->context = context;
-
- INIT_WORK(&hp_work->work, func);
- ret = queue_work(kacpi_hotplug_wq, &hp_work->work);
- if (!ret)
- kfree(hp_work);
-}
-
static void _handle_hotplug_event_bridge(struct work_struct *work)
{
struct acpiphp_bridge *bridge;
@@ -1154,11 +1126,11 @@ static void _handle_hotplug_event_bridge(struct work_struct *work)
.pointer = objname };
struct acpi_device *device;
int num_sub_bridges = 0;
- struct acpiphp_hp_work *hp_work;
+ struct acpi_hp_work *hp_work;
acpi_handle handle;
u32 type;
- hp_work = container_of(work, struct acpiphp_hp_work, work);
+ hp_work = container_of(work, struct acpi_hp_work, work);
handle = hp_work->handle;
type = hp_work->type;
@@ -1260,8 +1232,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type,
* For now just re-add this work to the kacpi_hotplug_wq so we
* don't deadlock on hotplug actions.
*/
- alloc_acpiphp_hp_work(handle, type, context,
- _handle_hotplug_event_bridge);
+ alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge);
}
static void _handle_hotplug_event_func(struct work_struct *work)
@@ -1270,12 +1241,12 @@ static void _handle_hotplug_event_func(struct work_struct *work)
char objname[64];
struct acpi_buffer buffer = { .length = sizeof(objname),
.pointer = objname };
- struct acpiphp_hp_work *hp_work;
+ struct acpi_hp_work *hp_work;
acpi_handle handle;
u32 type;
void *context;
- hp_work = container_of(work, struct acpiphp_hp_work, work);
+ hp_work = container_of(work, struct acpi_hp_work, work);
handle = hp_work->handle;
type = hp_work->type;
context = hp_work->context;
@@ -1336,8 +1307,7 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type,
* For now just re-add this work to the kacpi_hotplug_wq so we
* don't deadlock on hotplug actions.
*/
- alloc_acpiphp_hp_work(handle, type, context,
- _handle_hotplug_event_func);
+ alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func);
}
static struct acpi_pci_driver acpi_pci_hp_driver = {
--
1.7.7
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 27/37] PCI, pci_root_hp: Use acpi_hp_work
[not found] <1331362837-10740-1-git-send-email-yinghai@kernel.org>
` (5 preceding siblings ...)
2012-03-10 7:00 ` [PATCH v2 26/37] PCI, acpiphp: Use acpi_hp_work Yinghai Lu
@ 2012-03-10 7:00 ` Yinghai Lu
2012-03-10 7:00 ` [PATCH v2 28/37] PCI, ACPI: Make kacpi_hotplug_wq static Yinghai Lu
` (2 subsequent siblings)
9 siblings, 0 replies; 21+ messages in thread
From: Yinghai Lu @ 2012-03-10 7:00 UTC (permalink / raw)
To: Jesse Barnes, x86
Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
linux-pci, linux-kernel, Yinghai Lu, Len Brown, linux-acpi
Remove local copy: acpi_root_hp_work
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org
---
drivers/acpi/pci_root_hp.c | 34 +++-------------------------------
1 files changed, 3 insertions(+), 31 deletions(-)
diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c
index f5585f5..b453181 100644
--- a/drivers/acpi/pci_root_hp.c
+++ b/drivers/acpi/pci_root_hp.c
@@ -79,34 +79,6 @@ static void remove_acpi_root_bridge(struct acpi_root_bridge *bridge)
kfree(bridge);
}
-struct acpi_root_hp_work {
- struct work_struct work;
- acpi_handle handle;
- u32 type;
- void *context;
-};
-
-static void alloc_acpi_root_hp_work(acpi_handle handle, u32 type,
- void *context,
- void (*func)(struct work_struct *work))
-{
- struct acpi_root_hp_work *hp_work;
- int ret;
-
- hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL);
- if (!hp_work)
- return;
-
- hp_work->handle = handle;
- hp_work->type = type;
- hp_work->context = context;
-
- INIT_WORK(&hp_work->work, func);
- ret = queue_work(kacpi_hotplug_wq, &hp_work->work);
- if (!ret)
- kfree(hp_work);
-}
-
/* Program resources in newly inserted bridge */
static void acpi_root_configure_bridge(acpi_handle handle)
{
@@ -203,11 +175,11 @@ static void _handle_hotplug_event_root(struct work_struct *work)
char objname[64];
struct acpi_buffer buffer = { .length = sizeof(objname),
.pointer = objname };
- struct acpi_root_hp_work *hp_work;
+ struct acpi_hp_work *hp_work;
acpi_handle handle;
u32 type;
- hp_work = container_of(work, struct acpi_root_hp_work, work);
+ hp_work = container_of(work, struct acpi_hp_work, work);
handle = hp_work->handle;
type = hp_work->type;
@@ -255,7 +227,7 @@ static void _handle_hotplug_event_root(struct work_struct *work)
static void handle_hotplug_event_root(acpi_handle handle, u32 type,
void *context)
{
- alloc_acpi_root_hp_work(handle, type, context,
+ alloc_acpi_hp_work(handle, type, context,
_handle_hotplug_event_root);
}
--
1.7.7
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 28/37] PCI, ACPI: Make kacpi_hotplug_wq static
[not found] <1331362837-10740-1-git-send-email-yinghai@kernel.org>
` (6 preceding siblings ...)
2012-03-10 7:00 ` [PATCH v2 27/37] PCI, pci_root_hp: " Yinghai Lu
@ 2012-03-10 7:00 ` Yinghai Lu
2012-03-10 7:00 ` [PATCH v2 29/37] PCI, ACPI: Add acpi_pci_root_rescan() Yinghai Lu
2012-03-10 7:00 ` [PATCH v2 36/37] ACPI: Enable SCI_EMULATE to manually simulate physical hotplug testing Yinghai Lu
9 siblings, 0 replies; 21+ messages in thread
From: Yinghai Lu @ 2012-03-10 7:00 UTC (permalink / raw)
To: Jesse Barnes, x86
Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
linux-pci, linux-kernel, Yinghai Lu, Len Brown, linux-acpi
No external user anymore.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org
---
drivers/acpi/osl.c | 3 +--
include/acpi/acpiosxf.h | 2 --
2 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index fdcf4a5..09be602 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -81,8 +81,7 @@ static acpi_osd_handler acpi_irq_handler;
static void *acpi_irq_context;
static struct workqueue_struct *kacpid_wq;
static struct workqueue_struct *kacpi_notify_wq;
-struct workqueue_struct *kacpi_hotplug_wq;
-EXPORT_SYMBOL(kacpi_hotplug_wq);
+static struct workqueue_struct *kacpi_hotplug_wq;
/*
* This list of permanent mappings is for memory that may be accessed from
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index 62326ae..2326622 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -189,8 +189,6 @@ void acpi_os_fixed_event_count(u32 fixed_event_number);
/*
* Threads and Scheduling
*/
-extern struct workqueue_struct *kacpi_hotplug_wq;
-
struct acpi_hp_work {
struct work_struct work;
acpi_handle handle;
--
1.7.7
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 29/37] PCI, ACPI: Add acpi_pci_root_rescan()
[not found] <1331362837-10740-1-git-send-email-yinghai@kernel.org>
` (7 preceding siblings ...)
2012-03-10 7:00 ` [PATCH v2 28/37] PCI, ACPI: Make kacpi_hotplug_wq static Yinghai Lu
@ 2012-03-10 7:00 ` Yinghai Lu
2012-03-13 3:33 ` Bjorn Helgaas
2012-03-10 7:00 ` [PATCH v2 36/37] ACPI: Enable SCI_EMULATE to manually simulate physical hotplug testing Yinghai Lu
9 siblings, 1 reply; 21+ messages in thread
From: Yinghai Lu @ 2012-03-10 7:00 UTC (permalink / raw)
To: Jesse Barnes, x86
Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
linux-pci, linux-kernel, Yinghai Lu, Len Brown, linux-acpi
It will rescan all acpi pci root if related pci root bus get removed before.
Signed-off-by: Yinghai <yinghai@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org
---
drivers/acpi/pci_root_hp.c | 17 +++++++++++++++++
include/linux/pci-acpi.h | 7 +++++++
2 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c
index b453181..ca73d51 100644
--- a/drivers/acpi/pci_root_hp.c
+++ b/drivers/acpi/pci_root_hp.c
@@ -268,3 +268,20 @@ static int __init acpi_pci_root_hp_init(void)
}
subsys_initcall(acpi_pci_root_hp_init);
+
+static acpi_status
+rescan_root_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+ if (!acpi_is_root_bridge(handle))
+ return AE_OK;
+
+ handle_root_bridge_insertion(handle);
+
+ return AE_OK;
+}
+
+void acpi_pci_root_rescan(void)
+{
+ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, rescan_root_bridge, NULL, NULL, NULL);
+}
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 4462350..ac93634 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -35,6 +35,13 @@ static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus)
return acpi_get_pci_rootbridge_handle(pci_domain_nr(pbus),
pbus->number);
}
+
+void acpi_pci_root_rescan(void);
+
+#else
+
+static inline void acpi_pci_root_rescan(void) { }
+
#endif
#ifdef CONFIG_ACPI_APEI
--
1.7.7
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 36/37] ACPI: Enable SCI_EMULATE to manually simulate physical hotplug testing.
[not found] <1331362837-10740-1-git-send-email-yinghai@kernel.org>
` (8 preceding siblings ...)
2012-03-10 7:00 ` [PATCH v2 29/37] PCI, ACPI: Add acpi_pci_root_rescan() Yinghai Lu
@ 2012-03-10 7:00 ` Yinghai Lu
9 siblings, 0 replies; 21+ messages in thread
From: Yinghai Lu @ 2012-03-10 7:00 UTC (permalink / raw)
To: Jesse Barnes, x86
Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
linux-pci, linux-kernel, Ashok Raj, Yinghai Lu, Len Brown,
linux-acpi
From: Ashok Raj <ashok.raj@intel.com>
Emulate an ACPI SCI interrupt to emulate a hot-plug event. Useful
for testing ACPI based hot-plug on systems that don't have the
necessary firmware support.
Enable CONFIG_ACPI_SCI_EMULATE on kernel compile.
Now you will notice /proc/acpi/sci/notify when new kernel is booted.
echo "\_SB.CPU4 1" > /proc/acpi/sci/notify to trigger a hot-add of CPU4.
You will now notice an entry /sys/firmware/acpi/namespace/ACPI/_SB/CPU4
if the namespace had an entry CPU4 under _SB scope. If the entry had a
_EJ0 method, you will also notice a file "eject" under the CPU4 directory.
-v2: Update to current upstream, and remove not related stuff.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org
===================================================================
---
drivers/acpi/Kconfig | 10 +++
drivers/acpi/Makefile | 1 +
drivers/acpi/bus.c | 2 +
drivers/acpi/internal.h | 6 ++
drivers/acpi/sci_emu.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 160 insertions(+), 0 deletions(-)
create mode 100644 drivers/acpi/sci_emu.c
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 7556913..b7b8541 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -272,6 +272,16 @@ config ACPI_BLACKLIST_YEAR
Enter 0 to disable this mechanism and allow ACPI to
run by default no matter what the year. (default)
+config ACPI_SCI_EMULATE
+ bool "ACPI SCI Event Emulation Support"
+ depends on ACPI
+ default n
+ help
+ This will enable your system to emulate sci hotplug event
+ notification through proc file system. For example user needs to
+ echo "XXX 0" > /proc/acpi/sci/notify (where, XXX is a target ACPI
+ device object name present under \_SB scope).
+
config ACPI_DEBUG
bool "Debug Statements"
default n
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index bc6e53f..3580f04 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -31,6 +31,7 @@ acpi-$(CONFIG_ACPI_SLEEP) += proc.o
# ACPI Bus and Device Drivers
#
acpi-y += bus.o glue.o
+acpi-$(CONFIG_ACPI_SCI_EMULATE) += sci_emu.o
acpi-y += scan.o
acpi-y += processor_core.o
acpi-y += ec.o
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 9ecec98..512235e 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1001,6 +1001,8 @@ static int __init acpi_bus_init(void)
*/
acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
+ acpi_init_sci_emulate();
+
return 0;
/* Mimic structured exception handling */
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index ca75b9c..5b22cd2 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -34,6 +34,12 @@ int acpi_debugfs_init(void);
static inline void acpi_debugfs_init(void) { return; }
#endif
+#ifdef CONFIG_ACPI_SCI_EMULATE
+int acpi_init_sci_emulate(void);
+#else
+static inline int acpi_init_sci_emulate(void) { return 0; }
+#endif
+
/* --------------------------------------------------------------------------
Power Resource
-------------------------------------------------------------------------- */
diff --git a/drivers/acpi/sci_emu.c b/drivers/acpi/sci_emu.c
new file mode 100644
index 0000000..d972436
--- /dev/null
+++ b/drivers/acpi/sci_emu.c
@@ -0,0 +1,141 @@
+/*
+ * Code to emulate SCI interrupt for Hotplug node insertion/removal
+ */
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/acpi.h>
+
+#include "internal.h"
+
+#include "acpica/accommon.h"
+#include "acpica/acnamesp.h"
+#include "acpica/acevents.h"
+
+#define _COMPONENT ACPI_SYSTEM_COMPONENT
+ACPI_MODULE_NAME("sci_emu");
+
+static void acpi_sci_notify_client(char *acpi_name, u32 event);
+static int acpi_sci_notify_write_proc(struct file *file, const char *buffer, \
+ unsigned long count, void *data);
+struct proc_dir_entry *acpi_sci_dir;
+
+static int acpi_sci_notify_write_proc(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ u32 event;
+ char *name1 = NULL;
+ char *name2 = NULL;
+ char *end_name = NULL;
+ const char *delim = " ";
+ char *temp_buf = NULL;
+ char *temp_buf_addr = NULL;
+
+ temp_buf = kmalloc(count+1, GFP_ATOMIC);
+ if (!temp_buf) {
+ printk(KERN_WARNING PREFIX
+ "acpi_sci_notify_wire_proc: Memory allocation failed\n");
+ return count;
+ }
+ temp_buf[count] = '\0';
+ temp_buf_addr = temp_buf;
+ memcpy(temp_buf, buffer, count);
+ name1 = strsep(&temp_buf, delim);
+ name2 = strsep(&temp_buf, delim);
+
+ if (name1 && name2)
+ event = simple_strtoul(name2, &end_name, 10);
+ else {
+ printk(KERN_WARNING PREFIX "unknown device\n");
+ kfree(temp_buf_addr);
+ return count;
+ }
+
+ printk(KERN_INFO PREFIX
+ "ACPI device name is <%s>, event code is <%d>\n",
+ name1, event);
+
+ acpi_sci_notify_client(name1, event);
+
+ kfree(temp_buf_addr);
+
+ return count;
+}
+
+static void acpi_sci_notify_client(char *acpi_name, u32 event)
+{
+ struct acpi_namespace_node *node;
+ acpi_status status, status1;
+ acpi_handle hlsb, hsb;
+ union acpi_operand_object *obj_desc;
+
+ status = acpi_get_handle(NULL, "\\_SB", &hsb);
+ status1 = acpi_get_handle(hsb, acpi_name, &hlsb);
+ if (ACPI_FAILURE(status) || ACPI_FAILURE(status1)) {
+ printk(KERN_ERR PREFIX
+ "acpi getting handle to <\\_SB.%s> failed inside notify_client\n",
+ acpi_name);
+ return;
+ }
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR PREFIX "Acquiring acpi namespace mutext failed\n");
+ return;
+ }
+
+ node = acpi_ns_validate_handle(hlsb);
+ if (!node) {
+ acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ printk(KERN_ERR PREFIX "Mapping handle to node failed\n");
+ return;
+ }
+
+ /*
+ * Check for internal object and make sure there is a handler
+ * registered for this object
+ */
+ obj_desc = acpi_ns_get_attached_object(node);
+ if (obj_desc) {
+ if (obj_desc->common_notify.system_notify) {
+ /*
+ * Release the lock and queue the item for later
+ * exectuion
+ */
+ acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ status = acpi_ev_queue_notify_request(node, event);
+ if (ACPI_FAILURE(status))
+ printk(KERN_ERR PREFIX "acpi_ev_queue_notify_request failed\n");
+ else
+ printk(KERN_INFO PREFIX "Notify event is queued\n");
+ return;
+ }
+ } else {
+ printk(KERN_INFO PREFIX "Notify handler not registered for this device\n");
+ }
+
+ acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+ return;
+}
+
+int __init acpi_init_sci_emulate(void)
+{
+ struct proc_dir_entry *notify_entry = NULL;
+
+ ACPI_FUNCTION_TRACE("acpi_init_sci_emulate");
+
+ acpi_sci_dir = proc_mkdir("sci", acpi_root_dir);
+ if (!acpi_sci_dir)
+ return_VALUE(-ENODEV);
+
+ notify_entry = create_proc_entry("notify", \
+ S_IWUGO|S_IRUGO, acpi_sci_dir);
+ if (!notify_entry) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INIT,
+ "Unable to create '%s' fs entry\n", "notify"));
+ } else {
+ notify_entry->write_proc = acpi_sci_notify_write_proc;
+ notify_entry->data = NULL;
+ }
+
+ return_VALUE(0);
+}
--
1.7.7
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v2 02/37] PNPACPI: Fix device ref leaking in acpi_pnp_match
2012-03-10 7:00 ` [PATCH v2 02/37] PNPACPI: Fix device ref leaking in acpi_pnp_match Yinghai Lu
@ 2012-03-13 2:40 ` Bjorn Helgaas
0 siblings, 0 replies; 21+ messages in thread
From: Bjorn Helgaas @ 2012-03-13 2:40 UTC (permalink / raw)
To: Yinghai Lu
Cc: Jesse Barnes, x86, Andrew Morton, Linus Torvalds,
Greg Kroah-Hartman, linux-pci, linux-kernel, stable, Len Brown,
Adam Belay, linux-acpi
On Sat, Mar 10, 2012 at 12:00 AM, Yinghai Lu <yinghai@kernel.org> wrote:
> During testing pci root bus removal, found some root bus bridge is not freed.
>
> If booting with pnpacpi=off, those hostbridge could be freed without problem.
>
> It turns out that some devices reference are not released during acpi_pnp_match.
>
> That match should not hold one device ref during every calling.
>
> Add put_device calling before returning.
Changelog doesn't fit in 80 columns when using "git log". I mentioned
this before; please try it yourself.
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Cc: stable@kernel.org
> Cc: Len Brown <lenb@kernel.org>
> Cc: Adam Belay <abelay@mit.edu>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: linux-acpi@vger.kernel.org
> ---
> drivers/pnp/pnpacpi/core.c | 7 ++++++-
> 1 files changed, 6 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
> index b00c176..d21e8f5 100644
> --- a/drivers/pnp/pnpacpi/core.c
> +++ b/drivers/pnp/pnpacpi/core.c
> @@ -321,9 +321,14 @@ static int __init acpi_pnp_match(struct device *dev, void *_pnp)
> {
> struct acpi_device *acpi = to_acpi_device(dev);
> struct pnp_dev *pnp = _pnp;
> + struct device *physical_device;
> +
> + physical_device = acpi_get_physical_device(acpi->handle);
> + if (physical_device)
> + put_device(physical_device);
>
> /* true means it matched */
> - return !acpi_get_physical_device(acpi->handle)
> + return !physical_device
> && compare_pnp_id(pnp->id, acpi_device_hid(acpi));
> }
>
> --
> 1.7.7
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 21/37] PCI, ACPI: Make acpi_pci_root_remove remove pci root bus too
2012-03-10 7:00 ` [PATCH v2 21/37] PCI, ACPI: Make acpi_pci_root_remove remove pci root bus too Yinghai Lu
@ 2012-03-13 3:11 ` Bjorn Helgaas
0 siblings, 0 replies; 21+ messages in thread
From: Bjorn Helgaas @ 2012-03-13 3:11 UTC (permalink / raw)
To: Yinghai Lu
Cc: Jesse Barnes, x86, Andrew Morton, Linus Torvalds,
Greg Kroah-Hartman, linux-pci, linux-kernel, Len Brown,
linux-acpi
On Sat, Mar 10, 2012 at 12:00 AM, Yinghai Lu <yinghai@kernel.org> wrote:
> It will call new added pci_stop_and_remove_bus() to stop/remove pci root bus.
>
> Also checking if that pci_root_bus get removed already in bus remove in /sys
>
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Cc: Len Brown <lenb@kernel.org>
> Cc: linux-acpi@vger.kernel.org
> ---
> drivers/acpi/pci_root.c | 14 ++++++++++++++
> 1 files changed, 14 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> index 7aff631..b38e347 100644
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -643,10 +643,24 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type)
> {
> struct acpi_pci_root *root = acpi_driver_data(device);
>
> + /* that root bus could be removed already */
> + if (!pci_find_bus(root->segment, root->secondary.start)) {
> + dev_printk(KERN_DEBUG, &device->dev,
> + "freeing acpi_pci_root, but pci root bus was removed before");
> + goto out;
I don't think we should handle the root bus separately from the host
bridge, as I mentioned before. If we handle them together, checks
like this won't be needed.
> + }
> +
> device_set_run_wake(root->bus->bridge, false);
> pci_acpi_remove_bus_pm_notifier(device);
>
> + dev_printk(KERN_DEBUG, &device->dev,
> + "freeing acpi_pci_root, will remove pci root bus at first");
> + pci_stop_and_remove_bus(root->bus);
> +
> +out:
> + list_del(&root->node);
> kfree(root);
> +
> return 0;
> }
>
> --
> 1.7.7
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 23/37] PCI, ACPI: Add pci_root_hp hot add hotplug notification
2012-03-10 7:00 ` [PATCH v2 23/37] PCI, ACPI: Add pci_root_hp hot add hotplug notification Yinghai Lu
@ 2012-03-13 3:22 ` Bjorn Helgaas
2012-03-13 6:03 ` Yinghai Lu
0 siblings, 1 reply; 21+ messages in thread
From: Bjorn Helgaas @ 2012-03-13 3:22 UTC (permalink / raw)
To: Yinghai Lu
Cc: Jesse Barnes, x86, Andrew Morton, Linus Torvalds,
Greg Kroah-Hartman, linux-pci, linux-kernel, Len Brown,
linux-acpi
On Sat, Mar 10, 2012 at 12:00 AM, Yinghai Lu <yinghai@kernel.org> wrote:
> It is from acpiphp_glue.c
>
> How to use it?
> Find out root bus number to acpi root name mapping from dmesg or /sys
>
> echo "\_SB.PCIB 0" > /proc/acpi/sci/notify
> to add it back
Nope. That might be a way to exercise this for debug purposes (and it
only works when /proc/acpi/sci/notify is compiled in), but we
definitely don't want normal users to deal with ACPI pathnames like
this.
Most of this functionality belongs in the ACPI core, not here. The
core should be handling these notify events and turning them into
.add() and .remove() calls to the driver.
But since the ACPI core doesn't do that yet, we have to do it in the
driver, like we do for CPU, memory, etc. That part is fine. But I
think it at least belongs *in* the driver, i.e., in pci_root.c, not in
a new pci_root_hp.c file.
There definitely should not be another acpi_walk_namespace() and
another list of ACPI host bridges. The core *does* already walk the
namespace and call acpi_pci_root_add() for us. And the driver already
has a list of host bridges (acpi_pci_roots).
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Cc: Len Brown <lenb@kernel.org>
> Cc: linux-acpi@vger.kernel.org
> ---
> drivers/acpi/Makefile | 1 +
> drivers/acpi/pci_root_hp.c | 237 ++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 238 insertions(+), 0 deletions(-)
> create mode 100644 drivers/acpi/pci_root_hp.c
>
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 1567028..bc6e53f 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -36,6 +36,7 @@ acpi-y += processor_core.o
> acpi-y += ec.o
> acpi-$(CONFIG_ACPI_DOCK) += dock.o
> acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
> +acpi-$(CONFIG_HOTPLUG) += pci_root_hp.o
> acpi-y += power.o
> acpi-y += event.o
> acpi-y += sysfs.o
> diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c
> new file mode 100644
> index 0000000..dc11e81
> --- /dev/null
> +++ b/drivers/acpi/pci_root_hp.c
> @@ -0,0 +1,237 @@
> +/*
> + * Separated from drivers/pci/hotplug/acpiphp_glue.c
> + * only support root bridge
> + */
> +
> +#include <linux/init.h>
> +#include <linux/module.h>
> +
> +#include <linux/kernel.h>
> +#include <linux/pci.h>
> +#include <linux/mutex.h>
> +#include <linux/slab.h>
> +#include <linux/acpi.h>
> +
> +static LIST_HEAD(acpi_root_bridge_list);
> +struct acpi_root_bridge {
> + struct list_head list;
> + acpi_handle handle;
> + u32 flags;
> +};
> +
> +/* bridge flags */
> +#define ROOT_BRIDGE_HAS_EJ0 (0x00000002)
> +#define ROOT_BRIDGE_HAS_PS3 (0x00000080)
> +
> +#define ACPI_STA_FUNCTIONING (0x00000008)
> +
> +static struct acpi_root_bridge *acpi_root_handle_to_bridge(acpi_handle handle)
> +{
> + struct acpi_root_bridge *bridge;
> +
> + list_for_each_entry(bridge, &acpi_root_bridge_list, list)
> + if (bridge->handle == handle)
> + return bridge;
> +
> + return NULL;
> +}
> +
> +/* allocate and initialize host bridge data structure */
> +static void add_acpi_root_bridge(acpi_handle handle)
> +{
> + struct acpi_root_bridge *bridge;
> + acpi_handle dummy_handle;
> + acpi_status status;
> +
> + /* if the bridge doesn't have _STA, we assume it is always there */
> + status = acpi_get_handle(handle, "_STA", &dummy_handle);
> + if (ACPI_SUCCESS(status)) {
> + unsigned long long tmp;
> +
> + status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp);
> + if (ACPI_FAILURE(status)) {
> + printk(KERN_DEBUG "%s: _STA evaluation failure\n",
> + __func__);
> + return;
> + }
> + if ((tmp & ACPI_STA_FUNCTIONING) == 0)
> + /* don't register this object */
> + return;
> + }
> +
> + bridge = kzalloc(sizeof(struct acpi_root_bridge), GFP_KERNEL);
> + if (!bridge)
> + return;
> +
> + bridge->handle = handle;
> +
> + if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &dummy_handle)))
> + bridge->flags |= ROOT_BRIDGE_HAS_EJ0;
> + if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &dummy_handle)))
> + bridge->flags |= ROOT_BRIDGE_HAS_PS3;
> +
> + list_add(&bridge->list, &acpi_root_bridge_list);
> +}
> +
> +struct acpi_root_hp_work {
> + struct work_struct work;
> + acpi_handle handle;
> + u32 type;
> + void *context;
> +};
> +
> +static void alloc_acpi_root_hp_work(acpi_handle handle, u32 type,
> + void *context,
> + void (*func)(struct work_struct *work))
> +{
> + struct acpi_root_hp_work *hp_work;
> + int ret;
> +
> + hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL);
> + if (!hp_work)
> + return;
> +
> + hp_work->handle = handle;
> + hp_work->type = type;
> + hp_work->context = context;
> +
> + INIT_WORK(&hp_work->work, func);
> + ret = queue_work(kacpi_hotplug_wq, &hp_work->work);
> + if (!ret)
> + kfree(hp_work);
> +}
> +
> +/* Program resources in newly inserted bridge */
> +static void acpi_root_configure_bridge(acpi_handle handle)
> +{
> + struct acpi_pci_root *root = acpi_pci_find_root(handle);
> +
> + pci_assign_unassigned_bus_resources(root->bus);
> +}
> +
> +static void handle_root_bridge_insertion(acpi_handle handle)
> +{
> + struct acpi_device *device, *pdevice;
> + acpi_handle phandle;
> + int ret_val;
> +
> + acpi_get_parent(handle, &phandle);
> + if (acpi_bus_get_device(phandle, &pdevice)) {
> + printk(KERN_DEBUG "no parent device, assuming NULL\n");
> + pdevice = NULL;
> + }
> + if (!acpi_bus_get_device(handle, &device)) {
> + /* check if pci root_bus is removed */
> + struct acpi_pci_root *root = acpi_driver_data(device);
> + if (pci_find_bus(root->segment, root->secondary.start))
> + return;
> +
> + printk(KERN_DEBUG "bus exists... trim\n");
> + /* this shouldn't be in here, so remove
> + * the bus then re-add it...
> + */
> + ret_val = acpi_bus_trim(device, 1);
> + printk(KERN_DEBUG "acpi_bus_trim return %x\n", ret_val);
> + }
> + if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) {
> + printk(KERN_ERR "cannot add bridge to acpi list\n");
> + return;
> + }
> + acpi_root_configure_bridge(handle);
> + if (acpi_bus_start(device))
> + printk(KERN_ERR "cannot start bridge\n");
> +}
> +
> +static void _handle_hotplug_event_root(struct work_struct *work)
> +{
> + struct acpi_root_bridge *bridge;
> + char objname[64];
> + struct acpi_buffer buffer = { .length = sizeof(objname),
> + .pointer = objname };
> + struct acpi_root_hp_work *hp_work;
> + acpi_handle handle;
> + u32 type;
> +
> + hp_work = container_of(work, struct acpi_root_hp_work, work);
> + handle = hp_work->handle;
> + type = hp_work->type;
> +
> + bridge = acpi_root_handle_to_bridge(handle);
> +
> + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
> +
> + switch (type) {
> + case ACPI_NOTIFY_BUS_CHECK:
> + /* bus enumerate */
> + printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__,
> + objname);
> + if (!bridge) {
> + handle_root_bridge_insertion(handle);
> + add_acpi_root_bridge(handle);
> + }
> +
> + break;
> +
> + case ACPI_NOTIFY_DEVICE_CHECK:
> + /* device check */
> + printk(KERN_DEBUG "%s: Device check notify on %s\n", __func__,
> + objname);
> + if (!bridge) {
> + handle_root_bridge_insertion(handle);
> + add_acpi_root_bridge(handle);
> + }
> + break;
> +
> + default:
> + printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n",
> + type, objname);
> + break;
> + }
> +
> + kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
> +}
> +
> +static void handle_hotplug_event_root(acpi_handle handle, u32 type,
> + void *context)
> +{
> + alloc_acpi_root_hp_work(handle, type, context,
> + _handle_hotplug_event_root);
> +}
> +
> +static acpi_status __init
> +find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
> +{
> + char objname[64];
> + struct acpi_buffer buffer = { .length = sizeof(objname),
> + .pointer = objname };
> + int *count = (int *)context;
> +
> + if (!acpi_is_root_bridge(handle))
> + return AE_OK;
> +
> + (*count)++;
> +
> + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
> +
> + acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
> + handle_hotplug_event_root, NULL);
> + printk(KERN_DEBUG "acpi root: %s notify handler installed\n", objname);
> +
> + add_acpi_root_bridge(handle);
> +
> + return AE_OK;
> +}
> +
> +static int __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 0;
> +}
> +
> +subsys_initcall(acpi_pci_root_hp_init);
> --
> 1.7.7
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 24/37] PCI, ACPI: Add pci_root_hp hot removal notification support.
2012-03-10 7:00 ` [PATCH v2 24/37] PCI, ACPI: Add pci_root_hp hot removal notification support Yinghai Lu
@ 2012-03-13 3:25 ` Bjorn Helgaas
2012-03-13 6:06 ` Yinghai Lu
0 siblings, 1 reply; 21+ messages in thread
From: Bjorn Helgaas @ 2012-03-13 3:25 UTC (permalink / raw)
To: Yinghai Lu
Cc: Jesse Barnes, x86, Andrew Morton, Linus Torvalds,
Greg Kroah-Hartman, linux-pci, linux-kernel, Len Brown,
linux-acpi
On Sat, Mar 10, 2012 at 12:00 AM, Yinghai Lu <yinghai@kernel.org> wrote:
> Add missing hot_remove support for root device.
>
> How to use it?
> Find out root bus number to acpi root name mapping from dmesg or /sys
>
> echo "\_SB.PCIB 3" > /proc/acpi/sci/notify
> to remove root bus
Same comments as before: this is definitely NOT the way users should
use this. If you want to do that for debugging the ACPI notification
path, fine, but the normal way is for the platform to generate this
notification. I think the normal way for users to manually remove an
ACPI device should be something like:
echo 1 > /sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/remove
just like we do for PCI devices.
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Cc: Len Brown <lenb@kernel.org>
> Cc: linux-acpi@vger.kernel.org
> ---
> drivers/acpi/pci_root_hp.c | 61 ++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 61 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c
> index dc11e81..f5585f5 100644
> --- a/drivers/acpi/pci_root_hp.c
> +++ b/drivers/acpi/pci_root_hp.c
> @@ -73,6 +73,12 @@ static void add_acpi_root_bridge(acpi_handle handle)
> list_add(&bridge->list, &acpi_root_bridge_list);
> }
>
> +static void remove_acpi_root_bridge(struct acpi_root_bridge *bridge)
> +{
> + list_del(&bridge->list);
> + kfree(bridge);
> +}
> +
> struct acpi_root_hp_work {
> struct work_struct work;
> acpi_handle handle;
> @@ -142,6 +148,55 @@ static void handle_root_bridge_insertion(acpi_handle handle)
> printk(KERN_ERR "cannot start bridge\n");
> }
>
> +static int acpi_root_evaluate_object(acpi_handle handle, char *cmd, int val)
> +{
> + acpi_status status;
> + struct acpi_object_list arg_list;
> + union acpi_object arg;
> +
> + arg_list.count = 1;
> + arg_list.pointer = &arg;
> + arg.type = ACPI_TYPE_INTEGER;
> + arg.integer.value = val;
> +
> + status = acpi_evaluate_object(handle, cmd, &arg_list, NULL);
> + if (ACPI_FAILURE(status)) {
> + printk(KERN_WARNING "%s: %s to %d failed\n",
> + __func__, cmd, val);
> + return -1;
> + }
> +
> + return 0;
This function really has nothing to do with host bridges. Are you
sure there's no generic function you can use instead?
> +}
> +
> +static void handle_root_bridge_removal(acpi_handle handle,
> + struct acpi_root_bridge *bridge)
> +{
> + u32 flags = 0;
> + struct acpi_device *device;
> +
> + if (bridge) {
> + flags = bridge->flags;
> + remove_acpi_root_bridge(bridge);
> + }
> +
> + if (!acpi_bus_get_device(handle, &device)) {
> + int ret_val = acpi_bus_trim(device, 1);
> +
> + printk(KERN_DEBUG "acpi_bus_trim return %x\n", ret_val);
> + }
> +
> + if (flags & ROOT_BRIDGE_HAS_PS3) {
> + acpi_status status;
> +
> + status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
> + if (ACPI_FAILURE(status))
> + printk(KERN_WARNING "%s: _PS3 failed\n", __func__);
> + }
> + if (flags & ROOT_BRIDGE_HAS_EJ0)
> + acpi_root_evaluate_object(handle, "_EJ0", 1);
> +}
> +
> static void _handle_hotplug_event_root(struct work_struct *work)
> {
> struct acpi_root_bridge *bridge;
> @@ -182,6 +237,12 @@ static void _handle_hotplug_event_root(struct work_struct *work)
> }
> break;
>
> + case ACPI_NOTIFY_EJECT_REQUEST:
> + /* request device eject */
> + printk(KERN_DEBUG "%s: Device eject notify on %s\n", __func__,
> + objname);
> + handle_root_bridge_removal(handle, bridge);
> + break;
> default:
> printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n",
> type, objname);
> --
> 1.7.7
>
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 29/37] PCI, ACPI: Add acpi_pci_root_rescan()
2012-03-10 7:00 ` [PATCH v2 29/37] PCI, ACPI: Add acpi_pci_root_rescan() Yinghai Lu
@ 2012-03-13 3:33 ` Bjorn Helgaas
0 siblings, 0 replies; 21+ messages in thread
From: Bjorn Helgaas @ 2012-03-13 3:33 UTC (permalink / raw)
To: Yinghai Lu
Cc: Jesse Barnes, x86, Andrew Morton, Linus Torvalds,
Greg Kroah-Hartman, linux-pci, linux-kernel, Len Brown,
linux-acpi
On Sat, Mar 10, 2012 at 12:00 AM, Yinghai Lu <yinghai@kernel.org> wrote:
> It will rescan all acpi pci root if related pci root bus get removed before.
I think this is a bad idea. The ACPI core already walks the entire
ACPI namespace, finding devices and binding drivers to them.
Walking the whole thing again looking for "hotplug" things we can do
is just a hack. Maybe you want it for debugging, but I don't want it
in Linux.
> Signed-off-by: Yinghai <yinghai@kernel.org>
> Cc: Len Brown <lenb@kernel.org>
> Cc: linux-acpi@vger.kernel.org
> ---
> drivers/acpi/pci_root_hp.c | 17 +++++++++++++++++
> include/linux/pci-acpi.h | 7 +++++++
> 2 files changed, 24 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c
> index b453181..ca73d51 100644
> --- a/drivers/acpi/pci_root_hp.c
> +++ b/drivers/acpi/pci_root_hp.c
> @@ -268,3 +268,20 @@ static int __init acpi_pci_root_hp_init(void)
> }
>
> subsys_initcall(acpi_pci_root_hp_init);
> +
> +static acpi_status
> +rescan_root_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
> +{
> + if (!acpi_is_root_bridge(handle))
> + return AE_OK;
> +
> + handle_root_bridge_insertion(handle);
> +
> + return AE_OK;
> +}
> +
> +void acpi_pci_root_rescan(void)
> +{
> + acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
> + ACPI_UINT32_MAX, rescan_root_bridge, NULL, NULL, NULL);
> +}
> diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
> index 4462350..ac93634 100644
> --- a/include/linux/pci-acpi.h
> +++ b/include/linux/pci-acpi.h
> @@ -35,6 +35,13 @@ static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus)
> return acpi_get_pci_rootbridge_handle(pci_domain_nr(pbus),
> pbus->number);
> }
> +
> +void acpi_pci_root_rescan(void);
> +
> +#else
> +
> +static inline void acpi_pci_root_rescan(void) { }
> +
> #endif
>
> #ifdef CONFIG_ACPI_APEI
> --
> 1.7.7
>
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 23/37] PCI, ACPI: Add pci_root_hp hot add hotplug notification
2012-03-13 3:22 ` Bjorn Helgaas
@ 2012-03-13 6:03 ` Yinghai Lu
2012-03-15 17:47 ` Bjorn Helgaas
0 siblings, 1 reply; 21+ messages in thread
From: Yinghai Lu @ 2012-03-13 6:03 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Jesse Barnes, x86, Andrew Morton, Linus Torvalds,
Greg Kroah-Hartman, linux-pci, linux-kernel, Len Brown,
linux-acpi
On Mon, Mar 12, 2012 at 8:22 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Sat, Mar 10, 2012 at 12:00 AM, Yinghai Lu <yinghai@kernel.org> wrote:
>> It is from acpiphp_glue.c
>>
>> How to use it?
>> Find out root bus number to acpi root name mapping from dmesg or /sys
>>
>> echo "\_SB.PCIB 0" > /proc/acpi/sci/notify
>> to add it back
>
> Nope. That might be a way to exercise this for debug purposes (and it
> only works when /proc/acpi/sci/notify is compiled in), but we
> definitely don't want normal users to deal with ACPI pathnames like
> this.
before this patch set, only way is: Users really put one root bus in
and press buton etc to trigger notification
to get it work.
>
> Most of this functionality belongs in the ACPI core, not here. The
> core should be handling these notify events and turning them into
> .add() and .remove() calls to the driver.
>
> But since the ACPI core doesn't do that yet, we have to do it in the
> driver, like we do for CPU, memory, etc. That part is fine. But I
> think it at least belongs *in* the driver, i.e., in pci_root.c, not in
> a new pci_root_hp.c file.
don't want to pollute pci_root.c.
in separated file, we can use CONFIG_HOTPLUG in Makefile instead of pci_root.c
>
> There definitely should not be another acpi_walk_namespace() and
> another list of ACPI host bridges. The core *does* already walk the
> namespace and call acpi_pci_root_add() for us. And the driver already
> has a list of host bridges (acpi_pci_roots).
no, we may not have acpi_pci_root there.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 24/37] PCI, ACPI: Add pci_root_hp hot removal notification support.
2012-03-13 3:25 ` Bjorn Helgaas
@ 2012-03-13 6:06 ` Yinghai Lu
2012-03-15 17:53 ` Bjorn Helgaas
0 siblings, 1 reply; 21+ messages in thread
From: Yinghai Lu @ 2012-03-13 6:06 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Jesse Barnes, x86, Andrew Morton, Linus Torvalds,
Greg Kroah-Hartman, linux-pci, linux-kernel, Len Brown,
linux-acpi
On Mon, Mar 12, 2012 at 8:25 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Sat, Mar 10, 2012 at 12:00 AM, Yinghai Lu <yinghai@kernel.org> wrote:
>> Add missing hot_remove support for root device.
>>
>> How to use it?
>> Find out root bus number to acpi root name mapping from dmesg or /sys
>>
>> echo "\_SB.PCIB 3" > /proc/acpi/sci/notify
>> to remove root bus
>
> Same comments as before: this is definitely NOT the way users should
> use this. If you want to do that for debugging the ACPI notification
> path, fine, but the normal way is for the platform to generate this
> notification. I think the normal way for users to manually remove an
> ACPI device should be something like:
>
> echo 1 > /sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/remove
>
> just like we do for PCI devices.
notify way looks more like really physical hotadd/remove.
pci bus/remove and other is not really, because when you are using
/sys, you may still need to hold
one reference to bus or device.
>
>> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>> Cc: Len Brown <lenb@kernel.org>
>> Cc: linux-acpi@vger.kernel.org
>> ---
>> drivers/acpi/pci_root_hp.c | 61 ++++++++++++++++++++++++++++++++++++++++++++
>> 1 files changed, 61 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c
>> index dc11e81..f5585f5 100644
>> --- a/drivers/acpi/pci_root_hp.c
>> +++ b/drivers/acpi/pci_root_hp.c
>> @@ -73,6 +73,12 @@ static void add_acpi_root_bridge(acpi_handle handle)
>> list_add(&bridge->list, &acpi_root_bridge_list);
>> }
>>
>> +static void remove_acpi_root_bridge(struct acpi_root_bridge *bridge)
>> +{
>> + list_del(&bridge->list);
>> + kfree(bridge);
>> +}
>> +
>> struct acpi_root_hp_work {
>> struct work_struct work;
>> acpi_handle handle;
>> @@ -142,6 +148,55 @@ static void handle_root_bridge_insertion(acpi_handle handle)
>> printk(KERN_ERR "cannot start bridge\n");
>> }
>>
>> +static int acpi_root_evaluate_object(acpi_handle handle, char *cmd, int val)
>> +{
>> + acpi_status status;
>> + struct acpi_object_list arg_list;
>> + union acpi_object arg;
>> +
>> + arg_list.count = 1;
>> + arg_list.pointer = &arg;
>> + arg.type = ACPI_TYPE_INTEGER;
>> + arg.integer.value = val;
>> +
>> + status = acpi_evaluate_object(handle, cmd, &arg_list, NULL);
>> + if (ACPI_FAILURE(status)) {
>> + printk(KERN_WARNING "%s: %s to %d failed\n",
>> + __func__, cmd, val);
>> + return -1;
>> + }
>> +
>> + return 0;
>
> This function really has nothing to do with host bridges. Are you
> sure there's no generic function you can use instead?
seems not.
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 23/37] PCI, ACPI: Add pci_root_hp hot add hotplug notification
2012-03-13 6:03 ` Yinghai Lu
@ 2012-03-15 17:47 ` Bjorn Helgaas
0 siblings, 0 replies; 21+ messages in thread
From: Bjorn Helgaas @ 2012-03-15 17:47 UTC (permalink / raw)
To: Yinghai Lu
Cc: Jesse Barnes, x86, Andrew Morton, Linus Torvalds,
Greg Kroah-Hartman, linux-pci, linux-kernel, Len Brown,
linux-acpi
On Tue, Mar 13, 2012 at 12:03 AM, Yinghai Lu <yinghai@kernel.org> wrote:
> On Mon, Mar 12, 2012 at 8:22 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> On Sat, Mar 10, 2012 at 12:00 AM, Yinghai Lu <yinghai@kernel.org> wrote:
>>> It is from acpiphp_glue.c
>>>
>>> How to use it?
>>> Find out root bus number to acpi root name mapping from dmesg or /sys
>>>
>>> echo "\_SB.PCIB 0" > /proc/acpi/sci/notify
>>> to add it back
>>
>> Nope. That might be a way to exercise this for debug purposes (and it
>> only works when /proc/acpi/sci/notify is compiled in), but we
>> definitely don't want normal users to deal with ACPI pathnames like
>> this.
>
> before this patch set, only way is: Users really put one root bus in
> and press buton etc to trigger notification
> to get it work.
>
>>
>> Most of this functionality belongs in the ACPI core, not here. The
>> core should be handling these notify events and turning them into
>> .add() and .remove() calls to the driver.
>>
>> But since the ACPI core doesn't do that yet, we have to do it in the
>> driver, like we do for CPU, memory, etc. That part is fine. But I
>> think it at least belongs *in* the driver, i.e., in pci_root.c, not in
>> a new pci_root_hp.c file.
>
> don't want to pollute pci_root.c.
>
> in separated file, we can use CONFIG_HOTPLUG in Makefile instead of pci_root.c
I don't buy this argument. Most of this functionality should someday
be in the ACPI core. Until then, it is intimately connected to the
stuff in pci_root.c. It is not "pollution."
>> There definitely should not be another acpi_walk_namespace() and
>> another list of ACPI host bridges. The core *does* already walk the
>> namespace and call acpi_pci_root_add() for us. And the driver already
>> has a list of host bridges (acpi_pci_roots).
>
> no, we may not have acpi_pci_root there.
I don't understand what you're saying here. I think you should be
basically implementing the "turn notify events into add/remove calls"
functionality. This is what *should* be in the ACPI core, but isn't
yet. If you put this in the driver, and hopefully follow the style
already used by the processor/memory/etc. drivers, it will be easier
to someday move it into the ACPI core.
Bjorn
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 24/37] PCI, ACPI: Add pci_root_hp hot removal notification support.
2012-03-13 6:06 ` Yinghai Lu
@ 2012-03-15 17:53 ` Bjorn Helgaas
2012-03-15 18:01 ` Yinghai Lu
0 siblings, 1 reply; 21+ messages in thread
From: Bjorn Helgaas @ 2012-03-15 17:53 UTC (permalink / raw)
To: Yinghai Lu
Cc: Jesse Barnes, x86, Andrew Morton, Linus Torvalds,
Greg Kroah-Hartman, linux-pci, linux-kernel, Len Brown,
linux-acpi
On Tue, Mar 13, 2012 at 12:06 AM, Yinghai Lu <yinghai@kernel.org> wrote:
> On Mon, Mar 12, 2012 at 8:25 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> On Sat, Mar 10, 2012 at 12:00 AM, Yinghai Lu <yinghai@kernel.org> wrote:
>>> Add missing hot_remove support for root device.
>>>
>>> How to use it?
>>> Find out root bus number to acpi root name mapping from dmesg or /sys
>>>
>>> echo "\_SB.PCIB 3" > /proc/acpi/sci/notify
>>> to remove root bus
>>
>> Same comments as before: this is definitely NOT the way users should
>> use this. If you want to do that for debugging the ACPI notification
>> path, fine, but the normal way is for the platform to generate this
>> notification. I think the normal way for users to manually remove an
>> ACPI device should be something like:
>>
>> echo 1 > /sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/remove
>>
>> just like we do for PCI devices.
>
> notify way looks more like really physical hotadd/remove.
Sure, the 'echo "\_SB.PCIB 3" > /proc/acpi/sci/notify' way looks more
like physical hotadd/remove because it is basically injecting the
notify event that the hardware/BIOS should be generating itself. But
it is platform-specific and therefore unacceptable as a general user
interface.
Using /sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/remove would be a
more generic way. The PNP0A08:00/remove implementation would
basically turn into an acpi_pci_root_remove() call, just like the
'echo "\_SB.PCIB 3" > /proc/acpi/sci/notify' does.
Both ways should exercise the same code path. The only difference is
that using /proc/acpi/sci/notify should go through a little more of
the ACPI notify path before reaching acpi_pci_root_remove().
> pci bus/remove and other is not really, because when you are using
> /sys, you may still need to hold
> one reference to bus or device.
>
>>
>>> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>>> Cc: Len Brown <lenb@kernel.org>
>>> Cc: linux-acpi@vger.kernel.org
>>> ---
>>> drivers/acpi/pci_root_hp.c | 61 ++++++++++++++++++++++++++++++++++++++++++++
>>> 1 files changed, 61 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c
>>> index dc11e81..f5585f5 100644
>>> --- a/drivers/acpi/pci_root_hp.c
>>> +++ b/drivers/acpi/pci_root_hp.c
>>> @@ -73,6 +73,12 @@ static void add_acpi_root_bridge(acpi_handle handle)
>>> list_add(&bridge->list, &acpi_root_bridge_list);
>>> }
>>>
>>> +static void remove_acpi_root_bridge(struct acpi_root_bridge *bridge)
>>> +{
>>> + list_del(&bridge->list);
>>> + kfree(bridge);
>>> +}
>>> +
>>> struct acpi_root_hp_work {
>>> struct work_struct work;
>>> acpi_handle handle;
>>> @@ -142,6 +148,55 @@ static void handle_root_bridge_insertion(acpi_handle handle)
>>> printk(KERN_ERR "cannot start bridge\n");
>>> }
>>>
>>> +static int acpi_root_evaluate_object(acpi_handle handle, char *cmd, int val)
>>> +{
>>> + acpi_status status;
>>> + struct acpi_object_list arg_list;
>>> + union acpi_object arg;
>>> +
>>> + arg_list.count = 1;
>>> + arg_list.pointer = &arg;
>>> + arg.type = ACPI_TYPE_INTEGER;
>>> + arg.integer.value = val;
>>> +
>>> + status = acpi_evaluate_object(handle, cmd, &arg_list, NULL);
>>> + if (ACPI_FAILURE(status)) {
>>> + printk(KERN_WARNING "%s: %s to %d failed\n",
>>> + __func__, cmd, val);
>>> + return -1;
>>> + }
>>> +
>>> + return 0;
>>
>> This function really has nothing to do with host bridges. Are you
>> sure there's no generic function you can use instead?
>
> seems not.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 24/37] PCI, ACPI: Add pci_root_hp hot removal notification support.
2012-03-15 17:53 ` Bjorn Helgaas
@ 2012-03-15 18:01 ` Yinghai Lu
2012-03-15 18:09 ` Bjorn Helgaas
0 siblings, 1 reply; 21+ messages in thread
From: Yinghai Lu @ 2012-03-15 18:01 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Jesse Barnes, x86, Andrew Morton, Linus Torvalds,
Greg Kroah-Hartman, linux-pci, linux-kernel, Len Brown,
linux-acpi
On Thu, Mar 15, 2012 at 10:53 AM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> Sure, the 'echo "\_SB.PCIB 3" > /proc/acpi/sci/notify' way looks more
> like physical hotadd/remove because it is basically injecting the
> notify event that the hardware/BIOS should be generating itself. But
> it is platform-specific and therefore unacceptable as a general user
> interface.
>
> Using /sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/remove would be a
> more generic way. The PNP0A08:00/remove implementation would
> basically turn into an acpi_pci_root_remove() call, just like the
> 'echo "\_SB.PCIB 3" > /proc/acpi/sci/notify' does.
if the users can not find _SB.PCIB etc, they may not find
LNXSYSTM:00/device:00/PNP0A08:00.
so /sys/class/pci_bus/0000:80/remove is more easy for them?
Yinghai
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 24/37] PCI, ACPI: Add pci_root_hp hot removal notification support.
2012-03-15 18:01 ` Yinghai Lu
@ 2012-03-15 18:09 ` Bjorn Helgaas
0 siblings, 0 replies; 21+ messages in thread
From: Bjorn Helgaas @ 2012-03-15 18:09 UTC (permalink / raw)
To: Yinghai Lu
Cc: Jesse Barnes, x86, Andrew Morton, Linus Torvalds,
Greg Kroah-Hartman, linux-pci, linux-kernel, Len Brown,
linux-acpi
On Thu, Mar 15, 2012 at 12:01 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> On Thu, Mar 15, 2012 at 10:53 AM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> Sure, the 'echo "\_SB.PCIB 3" > /proc/acpi/sci/notify' way looks more
>> like physical hotadd/remove because it is basically injecting the
>> notify event that the hardware/BIOS should be generating itself. But
>> it is platform-specific and therefore unacceptable as a general user
>> interface.
>>
>> Using /sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/remove would be a
>> more generic way. The PNP0A08:00/remove implementation would
>> basically turn into an acpi_pci_root_remove() call, just like the
>> 'echo "\_SB.PCIB 3" > /proc/acpi/sci/notify' does.
>
> if the users can not find _SB.PCIB etc, they may not find
> LNXSYSTM:00/device:00/PNP0A08:00.
>
> so /sys/class/pci_bus/0000:80/remove is more easy for them?
I don't think so. LNXSYSTM:00/... is the canonical machine
description on x86. I think there should probably be a link from the
PCI device to the upstream bridge. The upstream bridge could be
either a P2P bridge or a host bridge.
Bjorn
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2012-03-15 18:09 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1331362837-10740-1-git-send-email-yinghai@kernel.org>
2012-03-10 7:00 ` [PATCH v2 02/37] PNPACPI: Fix device ref leaking in acpi_pnp_match Yinghai Lu
2012-03-13 2:40 ` Bjorn Helgaas
2012-03-10 7:00 ` [PATCH v2 21/37] PCI, ACPI: Make acpi_pci_root_remove remove pci root bus too Yinghai Lu
2012-03-13 3:11 ` Bjorn Helgaas
2012-03-10 7:00 ` [PATCH v2 23/37] PCI, ACPI: Add pci_root_hp hot add hotplug notification Yinghai Lu
2012-03-13 3:22 ` Bjorn Helgaas
2012-03-13 6:03 ` Yinghai Lu
2012-03-15 17:47 ` Bjorn Helgaas
2012-03-10 7:00 ` [PATCH v2 24/37] PCI, ACPI: Add pci_root_hp hot removal notification support Yinghai Lu
2012-03-13 3:25 ` Bjorn Helgaas
2012-03-13 6:06 ` Yinghai Lu
2012-03-15 17:53 ` Bjorn Helgaas
2012-03-15 18:01 ` Yinghai Lu
2012-03-15 18:09 ` Bjorn Helgaas
2012-03-10 7:00 ` [PATCH v2 25/37] PCI, ACPI: Add alloc_acpi_hp_work() Yinghai Lu
2012-03-10 7:00 ` [PATCH v2 26/37] PCI, acpiphp: Use acpi_hp_work Yinghai Lu
2012-03-10 7:00 ` [PATCH v2 27/37] PCI, pci_root_hp: " Yinghai Lu
2012-03-10 7:00 ` [PATCH v2 28/37] PCI, ACPI: Make kacpi_hotplug_wq static Yinghai Lu
2012-03-10 7:00 ` [PATCH v2 29/37] PCI, ACPI: Add acpi_pci_root_rescan() Yinghai Lu
2012-03-13 3:33 ` Bjorn Helgaas
2012-03-10 7:00 ` [PATCH v2 36/37] ACPI: Enable SCI_EMULATE to manually simulate physical hotplug testing Yinghai Lu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).