* [PATCH -v3 02/47] PNPACPI: Fix device ref leaking in acpi_pnp_match
[not found] <1332135996-13860-1-git-send-email-yinghai@kernel.org>
@ 2012-03-19 5:45 ` Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 26/47] PCI, ACPI: Make acpi_pci_root_remove remove pci root bus too Yinghai Lu
` (7 subsequent siblings)
8 siblings, 0 replies; 9+ messages in thread
From: Yinghai Lu @ 2012-03-19 5:45 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] 9+ messages in thread
* [PATCH -v3 26/47] PCI, ACPI: Make acpi_pci_root_remove remove pci root bus too
[not found] <1332135996-13860-1-git-send-email-yinghai@kernel.org>
2012-03-19 5:45 ` [PATCH -v3 02/47] PNPACPI: Fix device ref leaking in acpi_pnp_match Yinghai Lu
@ 2012-03-19 5:46 ` Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 28/47] PCI, ACPI: Add pci_root_hp hot removal notification support Yinghai Lu
` (6 subsequent siblings)
8 siblings, 0 replies; 9+ messages in thread
From: Yinghai Lu @ 2012-03-19 5:46 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] 9+ messages in thread
* [PATCH -v3 28/47] PCI, ACPI: Add pci_root_hp hot removal notification support.
[not found] <1332135996-13860-1-git-send-email-yinghai@kernel.org>
2012-03-19 5:45 ` [PATCH -v3 02/47] PNPACPI: Fix device ref leaking in acpi_pnp_match Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 26/47] PCI, ACPI: Make acpi_pci_root_remove remove pci root bus too Yinghai Lu
@ 2012-03-19 5:46 ` Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 29/47] PCI, ACPI: Add alloc_acpi_hp_work() Yinghai Lu
` (5 subsequent siblings)
8 siblings, 0 replies; 9+ messages in thread
From: Yinghai Lu @ 2012-03-19 5:46 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 e07c31b..214adcb 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;
@@ -143,6 +149,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;
@@ -183,6 +238,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] 9+ messages in thread
* [PATCH -v3 29/47] PCI, ACPI: Add alloc_acpi_hp_work()
[not found] <1332135996-13860-1-git-send-email-yinghai@kernel.org>
` (2 preceding siblings ...)
2012-03-19 5:46 ` [PATCH -v3 28/47] PCI, ACPI: Add pci_root_hp hot removal notification support Yinghai Lu
@ 2012-03-19 5:46 ` Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 30/47] PCI, acpiphp: Use acpi_hp_work Yinghai Lu
` (4 subsequent siblings)
8 siblings, 0 replies; 9+ messages in thread
From: Yinghai Lu @ 2012-03-19 5:46 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] 9+ messages in thread
* [PATCH -v3 30/47] PCI, acpiphp: Use acpi_hp_work
[not found] <1332135996-13860-1-git-send-email-yinghai@kernel.org>
` (3 preceding siblings ...)
2012-03-19 5:46 ` [PATCH -v3 29/47] PCI, ACPI: Add alloc_acpi_hp_work() Yinghai Lu
@ 2012-03-19 5:46 ` Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 31/47] PCI, pci_root_hp: " Yinghai Lu
` (3 subsequent siblings)
8 siblings, 0 replies; 9+ messages in thread
From: Yinghai Lu @ 2012-03-19 5:46 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 ae78c3d..9d781a7 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1119,34 +1119,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;
@@ -1155,11 +1127,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;
@@ -1261,8 +1233,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)
@@ -1271,12 +1242,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;
@@ -1337,8 +1308,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] 9+ messages in thread
* [PATCH -v3 31/47] PCI, pci_root_hp: Use acpi_hp_work
[not found] <1332135996-13860-1-git-send-email-yinghai@kernel.org>
` (4 preceding siblings ...)
2012-03-19 5:46 ` [PATCH -v3 30/47] PCI, acpiphp: Use acpi_hp_work Yinghai Lu
@ 2012-03-19 5:46 ` Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 32/47] PCI, ACPI: Make kacpi_hotplug_wq static Yinghai Lu
` (2 subsequent siblings)
8 siblings, 0 replies; 9+ messages in thread
From: Yinghai Lu @ 2012-03-19 5:46 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 214adcb..d2ace81 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)
{
@@ -204,11 +176,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;
@@ -256,7 +228,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] 9+ messages in thread
* [PATCH -v3 32/47] PCI, ACPI: Make kacpi_hotplug_wq static
[not found] <1332135996-13860-1-git-send-email-yinghai@kernel.org>
` (5 preceding siblings ...)
2012-03-19 5:46 ` [PATCH -v3 31/47] PCI, pci_root_hp: " Yinghai Lu
@ 2012-03-19 5:46 ` Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 39/47] ACPI: Enable SCI_EMULATE to manually simulate physical hotplug testing Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 41/47] PCI, ACPI: Add acpi_pci_root_rescan() Yinghai Lu
8 siblings, 0 replies; 9+ messages in thread
From: Yinghai Lu @ 2012-03-19 5:46 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] 9+ messages in thread
* [PATCH -v3 39/47] ACPI: Enable SCI_EMULATE to manually simulate physical hotplug testing.
[not found] <1332135996-13860-1-git-send-email-yinghai@kernel.org>
` (6 preceding siblings ...)
2012-03-19 5:46 ` [PATCH -v3 32/47] PCI, ACPI: Make kacpi_hotplug_wq static Yinghai Lu
@ 2012-03-19 5:46 ` Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 41/47] PCI, ACPI: Add acpi_pci_root_rescan() Yinghai Lu
8 siblings, 0 replies; 9+ messages in thread
From: Yinghai Lu @ 2012-03-19 5:46 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] 9+ messages in thread
* [PATCH -v3 41/47] PCI, ACPI: Add acpi_pci_root_rescan()
[not found] <1332135996-13860-1-git-send-email-yinghai@kernel.org>
` (7 preceding siblings ...)
2012-03-19 5:46 ` [PATCH -v3 39/47] ACPI: Enable SCI_EMULATE to manually simulate physical hotplug testing Yinghai Lu
@ 2012-03-19 5:46 ` Yinghai Lu
8 siblings, 0 replies; 9+ messages in thread
From: Yinghai Lu @ 2012-03-19 5:46 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 d2ace81..e16b53d 100644
--- a/drivers/acpi/pci_root_hp.c
+++ b/drivers/acpi/pci_root_hp.c
@@ -269,3 +269,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] 9+ messages in thread
end of thread, other threads:[~2012-03-19 5:48 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1332135996-13860-1-git-send-email-yinghai@kernel.org>
2012-03-19 5:45 ` [PATCH -v3 02/47] PNPACPI: Fix device ref leaking in acpi_pnp_match Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 26/47] PCI, ACPI: Make acpi_pci_root_remove remove pci root bus too Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 28/47] PCI, ACPI: Add pci_root_hp hot removal notification support Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 29/47] PCI, ACPI: Add alloc_acpi_hp_work() Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 30/47] PCI, acpiphp: Use acpi_hp_work Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 31/47] PCI, pci_root_hp: " Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 32/47] PCI, ACPI: Make kacpi_hotplug_wq static Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 39/47] ACPI: Enable SCI_EMULATE to manually simulate physical hotplug testing Yinghai Lu
2012-03-19 5:46 ` [PATCH -v3 41/47] PCI, ACPI: Add acpi_pci_root_rescan() Yinghai Lu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox