linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver
@ 2013-01-11 22:40 Yinghai Lu
  2013-01-11 22:40 ` [PATCH v8 01/22] PCI, acpiphp: Add is_hotplug_bridge detection Yinghai Lu
                   ` (22 more replies)
  0 siblings, 23 replies; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

It includes
1. preparing patches for pci root bus hotadd/hotremove support
2. move root bus hotadd from acpiphp to pci_root.c
3. add hot-remove support
4. clean up hotadd/remove with common functions
5. add acpi_hp_work to be shared with acpiphp and root-bus hotplug
6. add match_driver to add pci device to device tree early but
   not attach driver for hotplug path.

based on pci/next

could get from
        git://git.kernel.org/pub/scm/linux/kernel/git/yinghai/linux-yinghai.git for-pci-root-bus-hotplug

After this patchset, will send out
	 for_each_host_bridge support
	 for_each_dev_addon_res

Jiang Liu (4):
  PCI: Fix a device reference count leakage issue in pci_dev_present()
  PCI: make PCI device create/destroy logic symmetric
  PCI: split registration of PCI bus devices into two stages
  PCI: correctly detect ACPI PCI host bridge objects

Tang Chen (2):
  ACPI: Introduce a new acpi handle to determine HID match.
  PCI, ACPI: debug print for installation of acpi root bridge's notifier

Yinghai Lu (16):
  PCI, acpiphp: Add is_hotplug_bridge detection
  PCI: Add root bus children dev's res to fail list
  PCI: Set dev_node early for pci_dev
  ACPI: Separate acpi_bus_trim to support two steps.
  PCI, acpiphp: Separate out hot-add support of pci host bridge
  PCI, ACPI: Add pci_root_hp hot removal notification support.
  PCI, ACPI: remove acpi_root_bridge in pci_root_hp
  ACPI: update ej_event interface to take acpi_device
  ACPI, PCI: Simplify handle_root_bridge_removal()
  PCI, acpiphp: Don't bailout even no slots found yet.
  PCI, ACPI: Add alloc_acpi_hp_work()
  PCI, acpiphp: Use acpi_hp_work
  PCI, pci_root_hp: Use acpi_hp_work
  PCI, ACPI: Make kacpi_hotplug_wq static
  PCI: add match_driver in struct pci_dev
  PCI: move device_add out of pci_bus_add_device()

 drivers/acpi/acpi_memhotplug.c     |    2 +-
 drivers/acpi/osl.c                 |   24 ++++-
 drivers/acpi/pci_root.c            |  180 ++++++++++++++++++++++++++++++++++++
 drivers/acpi/processor_driver.c    |    2 +-
 drivers/acpi/scan.c                |   52 ++++++++---
 drivers/pci/bus.c                  |   57 +++---------
 drivers/pci/hotplug/acpiphp.h      |    1 -
 drivers/pci/hotplug/acpiphp_core.c |   23 +----
 drivers/pci/hotplug/acpiphp_glue.c |  150 ++++++++++--------------------
 drivers/pci/iov.c                  |    7 --
 drivers/pci/pci-driver.c           |    6 +-
 drivers/pci/probe.c                |   40 ++++++--
 drivers/pci/remove.c               |   14 +--
 drivers/pci/search.c               |   10 +-
 drivers/pci/setup-bus.c            |    2 +-
 include/acpi/acpi_bus.h            |    4 +-
 include/acpi/acpiosxf.h            |    9 +-
 include/linux/pci.h                |    1 +
 18 files changed, 365 insertions(+), 219 deletions(-)

-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 78+ messages in thread

* [PATCH v8 01/22] PCI, acpiphp: Add is_hotplug_bridge detection
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 21:35   ` Rafael J. Wysocki
  2013-01-15  6:45   ` Yijing Wang
  2013-01-11 22:40 ` [PATCH v8 02/22] PCI: Add root bus children dev's res to fail list Yinghai Lu
                   ` (21 subsequent siblings)
  22 siblings, 2 replies; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

When system support hotplug bridge with children hotplug slots, we need
to make sure that parent bridge get preallocated resource so later when
device is plugged into children slot, those children devices will get
resource allocated.

We do not meet this problem, because for pcie hotplug card, when acpiphp
is used, pci_scan_bridge will set that for us when detect hotplug bit in
slot cap.

Reported-and-tested-by: Jason Baron <jbaron@redhat.com>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Jason Baron <jbaron@redhat.com>
---
 drivers/pci/hotplug/acpiphp_glue.c |   27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 91b5ad8..1e5c5df 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -797,6 +797,29 @@ static void acpiphp_set_acpi_region(struct acpiphp_slot *slot)
 	}
 }
 
+static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev)
+{
+	struct acpiphp_func *func;
+
+	if (!dev->subordinate)
+		return;
+
+	/* quirk, or pcie could set it already */
+	if (dev->is_hotplug_bridge)
+		return;
+
+	if (PCI_SLOT(dev->devfn) != slot->device)
+		return;
+
+	list_for_each_entry(func, &slot->funcs, sibling) {
+		if (PCI_FUNC(dev->devfn) == func->function) {
+			/* check if this bridge has ejectable slots */
+			if ((detect_ejectable_slots(func->handle) > 0))
+				dev->is_hotplug_bridge = 1;
+			break;
+		}
+	}
+}
 /**
  * enable_device - enable, configure a slot
  * @slot: slot to be enabled
@@ -831,8 +854,10 @@ static int __ref enable_device(struct acpiphp_slot *slot)
 			if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
 			    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
 				max = pci_scan_bridge(bus, dev, max, pass);
-				if (pass && dev->subordinate)
+				if (pass && dev->subordinate) {
+					check_hotplug_bridge(slot, dev);
 					pci_bus_size_bridges(dev->subordinate);
+				}
 			}
 		}
 	}
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 02/22] PCI: Add root bus children dev's res to fail list
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
  2013-01-11 22:40 ` [PATCH v8 01/22] PCI, acpiphp: Add is_hotplug_bridge detection Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 21:37   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 03/22] PCI: Set dev_node early for pci_dev Yinghai Lu
                   ` (20 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

We can stop trying according to try number now and do not need to use
root_bus checking as stop sign anymore.

In extreme case we could need to reallocate resource for device just
under root bus.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/setup-bus.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 6d3591d..7e8739e 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -283,7 +283,7 @@ static void assign_requested_resources_sorted(struct list_head *head,
 		idx = res - &dev_res->dev->resource[0];
 		if (resource_size(res) &&
 		    pci_assign_resource(dev_res->dev, idx)) {
-			if (fail_head && !pci_is_root_bus(dev_res->dev->bus)) {
+			if (fail_head) {
 				/*
 				 * if the failed res is for ROM BAR, and it will
 				 * be enabled later, don't add it to the list
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 03/22] PCI: Set dev_node early for pci_dev
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
  2013-01-11 22:40 ` [PATCH v8 01/22] PCI, acpiphp: Add is_hotplug_bridge detection Yinghai Lu
  2013-01-11 22:40 ` [PATCH v8 02/22] PCI: Add root bus children dev's res to fail list Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 21:38   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 04/22] PCI: Fix a device reference count leakage issue in pci_dev_present() Yinghai Lu
                   ` (19 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

Otherwise irq_desc for pci bridge with hot-added ioapic can not be on
local node.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/probe.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 2dcd22d..b97dea5 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1300,6 +1300,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 	dev->dev.release = pci_release_dev;
 	pci_dev_get(dev);
 
+	set_dev_node(&dev->dev, pcibus_to_node(bus));
 	dev->dev.dma_mask = &dev->dma_mask;
 	dev->dev.dma_parms = &dev->dma_parms;
 	dev->dev.coherent_dma_mask = 0xffffffffull;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 04/22] PCI: Fix a device reference count leakage issue in pci_dev_present()
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (2 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 03/22] PCI: Set dev_node early for pci_dev Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 21:39   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 05/22] PCI: make PCI device create/destroy logic symmetric Yinghai Lu
                   ` (18 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi

From: Jiang Liu <jiang.liu@huawei.com>

Function pci_get_dev_by_id() will hold a reference count on the pci device
returned, so pci_dev_present() should release the corresponding reference
count to avoid memory leakage.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
 drivers/pci/search.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index bf969ba..d0627fa 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -319,13 +319,13 @@ int pci_dev_present(const struct pci_device_id *ids)
 	WARN_ON(in_interrupt());
 	while (ids->vendor || ids->subvendor || ids->class_mask) {
 		found = pci_get_dev_by_id(ids, NULL);
-		if (found)
-			goto exit;
+		if (found) {
+			pci_dev_put(found);
+			return 1;
+		}
 		ids++;
 	}
-exit:
-	if (found)
-		return 1;
+
 	return 0;
 }
 EXPORT_SYMBOL(pci_dev_present);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 05/22] PCI: make PCI device create/destroy logic symmetric
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (3 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 04/22] PCI: Fix a device reference count leakage issue in pci_dev_present() Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 21:40   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 06/22] PCI: split registration of PCI bus devices into two stages Yinghai Lu
                   ` (17 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi

From: Jiang Liu <jiang.liu@huawei.com>

According to device model documentation, the way to create/destroy PCI
devices should be symmetric.

/**
 * device_del - delete device from system.
 * @dev: device.
 *
 * This is the first part of the device unregistration
 * sequence. This removes the device from the lists we control
 * from here, has it removed from the other driver model
 * subsystems it was added to in device_add(), and removes it
 * from the kobject hierarchy.
 *
 * NOTE: this should be called manually _iff_ device_add() was
 * also called manually.
 */

The rule is to either use
1) device_register()/device_unregister()
or
2) device_initialize()/device_add()/device_del()/put_device().

So change PCI core logic to follow the rule and get rid of the redundant
pci_dev_get()/pci_dev_put() pair.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/probe.c  |    1 -
 drivers/pci/remove.c |    4 ++--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index b97dea5..48b35e1 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1298,7 +1298,6 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 {
 	device_initialize(&dev->dev);
 	dev->dev.release = pci_release_dev;
-	pci_dev_get(dev);
 
 	set_dev_node(&dev->dev, pcibus_to_node(bus));
 	dev->dev.dma_mask = &dev->dma_mask;
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 7c0fd92..fc38c48 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -22,7 +22,7 @@ static void pci_stop_dev(struct pci_dev *dev)
 	if (dev->is_added) {
 		pci_proc_detach_device(dev);
 		pci_remove_sysfs_dev_files(dev);
-		device_unregister(&dev->dev);
+		device_del(&dev->dev);
 		dev->is_added = 0;
 	}
 
@@ -37,7 +37,7 @@ static void pci_destroy_dev(struct pci_dev *dev)
 	up_write(&pci_bus_sem);
 
 	pci_free_resources(dev);
-	pci_dev_put(dev);
+	put_device(&dev->dev);
 }
 
 void pci_remove_bus(struct pci_bus *bus)
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 06/22] PCI: split registration of PCI bus devices into two stages
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (4 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 05/22] PCI: make PCI device create/destroy logic symmetric Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 22:34   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 07/22] ACPI: Separate acpi_bus_trim to support two steps Yinghai Lu
                   ` (16 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

From: Jiang Liu <jiang.liu@huawei.com>

When handling BUS_NOTIFY_ADD_DEVICE event for a PCI bridge device,
the notification handler can't hold reference count to the new PCI bus
because the device object for the new bus (pci_dev->subordinate->dev)
hasn't been initialized yet.

Split the registration of PCI bus device into two stages as below,
so that the event handler could hold reference count to the new PCI bus
when handling BUS_NOTIFY_ADD_DEVICE event.

1) device_initialize(&pci_dev->dev)
2) device_initialize(&pci_dev->subordinate->dev)
3) notify BUS_NOTIFY_ADD_DEVICE event for pci_dev
4) device_add(&pci_dev->dev)
5) device_add(&pci_dev->subordinate->dev)

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/bus.c    |    2 +-
 drivers/pci/probe.c  |    4 +++-
 drivers/pci/remove.c |   10 +++++-----
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 847f3ca..5f9c728 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -200,7 +200,7 @@ int pci_bus_add_child(struct pci_bus *bus)
 	if (bus->bridge)
 		bus->dev.parent = bus->bridge;
 
-	retval = device_register(&bus->dev);
+	retval = device_add(&bus->dev);
 	if (retval)
 		return retval;
 
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 48b35e1..dc4fde3 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -642,6 +642,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
 	 */
 	child->dev.class = &pcibus_class;
 	dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr);
+	device_initialize(&child->dev);
 
 	/*
 	 * Set up the primary, secondary and subordinate
@@ -1678,7 +1679,8 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	b->dev.class = &pcibus_class;
 	b->dev.parent = b->bridge;
 	dev_set_name(&b->dev, "%04x:%02x", pci_domain_nr(b), bus);
-	error = device_register(&b->dev);
+	device_initialize(&b->dev);
+	error = device_add(&b->dev);
 	if (error)
 		goto class_dev_reg_err;
 
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index fc38c48..a1fdd0f 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -48,11 +48,11 @@ void pci_remove_bus(struct pci_bus *bus)
 	list_del(&bus->node);
 	pci_bus_release_busn_res(bus);
 	up_write(&pci_bus_sem);
-	if (!bus->is_added)
-		return;
-
-	pci_remove_legacy_files(bus);
-	device_unregister(&bus->dev);
+	if (bus->is_added) {
+		pci_remove_legacy_files(bus);
+		device_del(&bus->dev);
+	}
+	put_device(&bus->dev);
 }
 EXPORT_SYMBOL(pci_remove_bus);
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 07/22] ACPI: Separate acpi_bus_trim to support two steps.
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (5 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 06/22] PCI: split registration of PCI bus devices into two stages Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 22:40   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 08/22] PCI, acpiphp: Separate out hot-add support of pci host bridge Yinghai Lu
                   ` (15 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

Current all acpi_bus_trim callers have rmdevice to 1.
that means it will remove all acpi devices.

When 0, is passed, it will keep the parent.

For root bus hotremove support, we need to have pci device to be
removed before acpi devices.

So try to keep all acpi devices, and only stop drivers with them.

This change should be safe because all current callers all have 1 passed.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org
---
 drivers/acpi/scan.c |    5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e380345..db7664e 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1669,10 +1669,7 @@ int acpi_bus_trim(struct acpi_device *start, int rmdevice)
 			child = parent;
 			parent = parent->parent;
 
-			if (level == 0)
-				err = acpi_bus_remove(child, rmdevice);
-			else
-				err = acpi_bus_remove(child, 1);
+			err = acpi_bus_remove(child, rmdevice);
 
 			continue;
 		}
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 08/22] PCI, acpiphp: Separate out hot-add support of pci host bridge
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (6 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 07/22] ACPI: Separate acpi_bus_trim to support two steps Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 23:18   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 09/22] PCI, ACPI: Add pci_root_hp hot removal notification support Yinghai Lu
                   ` (14 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

It causes confusion.

We may only need acpi hp for pci host bridge.

Split host bridge hot-add support to pci_root_hp, and keep acpiphp simple.

-v2: put back pci_root_hp change in one patch
-v3: add pcibios_resource_survey_bus() calling
-v4: remove not needed code with remove_bridge
-v5: put back support for acpiphp support for slots just on root bus.
-v6: change some functions to *_p2p_* to make it more clean.
-v7: split hot_added change out.
-v8: Move to pci_root.c instead of adding another file requested by Bjorn.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/acpi/pci_root.c            |  220 ++++++++++++++++++++++++++++++++++++
 drivers/pci/hotplug/acpiphp_glue.c |   59 +++-------
 2 files changed, 235 insertions(+), 44 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 471b2dc..5c1f462c 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -673,3 +673,223 @@ int __init acpi_pci_root_init(void)
 
 	return 0;
 }
+
+/*
+ * Separated from drivers/pci/hotplug/acpiphp_glue.c
+ *	only support root bridge
+ */
+
+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);
+}
+
+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...
+		 */
+		/* remove pci devices at first */
+		ret_val = acpi_bus_trim(device, 0);
+		printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
+		/* remove acpi devices */
+		ret_val = acpi_bus_trim(device, 1);
+		printk(KERN_DEBUG "acpi_bus_trim remove return %x\n", ret_val);
+	}
+	if (acpi_bus_add(handle))
+		printk(KERN_ERR "cannot add bridge to acpi list\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);
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 1e5c5df..02c41ab 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -543,10 +543,13 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
 	acpi_status status;
 	acpi_handle handle = bridge->handle;
 
-	status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+	if (bridge->type != BRIDGE_TYPE_HOST) {
+		status = acpi_remove_notify_handler(handle,
+					    ACPI_SYSTEM_NOTIFY,
 					    handle_hotplug_event_bridge);
-	if (ACPI_FAILURE(status))
-		err("failed to remove notify handler\n");
+		if (ACPI_FAILURE(status))
+			err("failed to remove notify handler\n");
+	}
 
 	if ((bridge->type != BRIDGE_TYPE_HOST) &&
 	    ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func)) {
@@ -630,9 +633,6 @@ static void remove_bridge(struct acpi_pci_root *root)
 	bridge = acpiphp_handle_to_bridge(handle);
 	if (bridge)
 		cleanup_bridge(bridge);
-	else
-		acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
-					   handle_hotplug_event_bridge);
 }
 
 static int power_on_slot(struct acpiphp_slot *slot)
@@ -1123,18 +1123,12 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus)
 }
 
 /* Program resources in newly inserted bridge */
-static int acpiphp_configure_bridge (acpi_handle handle)
+static int acpiphp_configure_p2p_bridge(acpi_handle handle)
 {
-	struct pci_bus *bus;
+	struct pci_dev *pdev = acpi_get_pci_dev(handle);
+	struct pci_bus *bus = pdev->subordinate;
 
-	if (acpi_is_root_bridge(handle)) {
-		struct acpi_pci_root *root = acpi_pci_find_root(handle);
-		bus = root->bus;
-	} else {
-		struct pci_dev *pdev = acpi_get_pci_dev(handle);
-		bus = pdev->subordinate;
-		pci_dev_put(pdev);
-	}
+	pci_dev_put(pdev);
 
 	pci_bus_size_bridges(bus);
 	pci_bus_assign_resources(bus);
@@ -1144,7 +1138,7 @@ static int acpiphp_configure_bridge (acpi_handle handle)
 	return 0;
 }
 
-static void handle_bridge_insertion(acpi_handle handle, u32 type)
+static void handle_p2p_bridge_insertion(acpi_handle handle, u32 type)
 {
 	struct acpi_device *device;
 
@@ -1162,8 +1156,8 @@ static void handle_bridge_insertion(acpi_handle handle, u32 type)
 		err("ACPI device object missing\n");
 		return;
 	}
-	if (!acpiphp_configure_bridge(handle))
-		add_bridge(handle);
+	if (!acpiphp_configure_p2p_bridge(handle))
+		add_p2p_bridge(handle);
 	else
 		err("cannot configure and start bridge\n");
 
@@ -1249,7 +1243,7 @@ static void _handle_hotplug_event_bridge(struct work_struct *work)
 
 	if (acpi_bus_get_device(handle, &device)) {
 		/* This bridge must have just been physically inserted */
-		handle_bridge_insertion(handle, type);
+		handle_p2p_bridge_insertion(handle, type);
 		goto out;
 	}
 
@@ -1426,21 +1420,6 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type,
 			      _handle_hotplug_event_func);
 }
 
-static acpi_status
-find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-	int *count = (int *)context;
-
-	if (!acpi_is_root_bridge(handle))
-		return AE_OK;
-
-	(*count)++;
-	acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
-				    handle_hotplug_event_bridge, NULL);
-
-	return AE_OK ;
-}
-
 static struct acpi_pci_driver acpi_pci_hp_driver = {
 	.add =		add_bridge,
 	.remove =	remove_bridge,
@@ -1451,15 +1430,7 @@ static struct acpi_pci_driver acpi_pci_hp_driver = {
  */
 int __init acpiphp_glue_init(void)
 {
-	int num = 0;
-
-	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-			ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL);
-
-	if (num <= 0)
-		return -1;
-	else
-		acpi_pci_register_driver(&acpi_pci_hp_driver);
+	acpi_pci_register_driver(&acpi_pci_hp_driver);
 
 	return 0;
 }
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 09/22] PCI, ACPI: Add pci_root_hp hot removal notification support.
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (7 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 08/22] PCI, acpiphp: Separate out hot-add support of pci host bridge Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 23:26   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 10/22] ACPI: Introduce a new acpi handle to determine HID match Yinghai Lu
                   ` (13 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

Add missing hot_remove support for root device.

How to test it?
Find out root bus number to acpi root name mapping from dmesg or /sys

  echo "\_SB.PCIB 3" > /sys/kernel/debug/acpi/sci_notify
to remove root bus

-v2: separate stop and remove, so it will be safe for comingi
	acpi_pci_bind_notify() changes.

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 |   67 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 5c1f462c..5ae36d8 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -740,6 +740,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;
@@ -800,6 +806,61 @@ static void handle_root_bridge_insertion(acpi_handle handle)
 		printk(KERN_ERR "cannot add bridge to acpi list\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)) {
+		pr_warn("%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;
+
+		/* remove pci devices at first */
+		ret_val = acpi_bus_trim(device, 0);
+		printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
+
+		/* remove acpi devices */
+		ret_val = acpi_bus_trim(device, 1);
+		printk(KERN_DEBUG "acpi_bus_trim remove 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))
+			pr_warn("%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;
@@ -840,6 +901,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.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 10/22] ACPI: Introduce a new acpi handle to determine HID match.
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (8 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 09/22] PCI, ACPI: Add pci_root_hp hot removal notification support Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 23:27   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 11/22] PCI: correctly detect ACPI PCI host bridge objects Yinghai Lu
                   ` (12 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Tang Chen, Yinghai Lu

From: Tang Chen <tangchen@cn.fujitsu.com>

We need to find out if one handle is for root bridge, and install notify
handler for it to handle pci root bus hot add.
At that time, root bridge acpi device is not created yet.

So acpi_match_device_ids() will not work.

This patch add a function to check if new acpi handle's HID matches a list
of IDs.  The new api use acpi_device_info instead acpi_device.

-v2: updated changelog, also check length for string info...
     change checking sequence by moving string comaring close to for loop.
					- Yinghai
-v3: change to _GPL according to Rafael

Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org
---
 drivers/acpi/scan.c     |   33 +++++++++++++++++++++++++++++++++
 include/acpi/acpi_bus.h |    2 ++
 2 files changed, 35 insertions(+)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index db7664e..8883539 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -470,6 +470,39 @@ int acpi_match_device_ids(struct acpi_device *device,
 }
 EXPORT_SYMBOL(acpi_match_device_ids);
 
+int acpi_match_object_info_ids(struct acpi_device_info *info,
+			       const struct acpi_device_id *ids)
+{
+	const struct acpi_device_id *id;
+	char *str;
+	u32 len;
+	int i;
+
+	len = info->hardware_id.length;
+	if (len) {
+		str = info->hardware_id.string;
+		if (str)
+			for (id = ids; id->id[0]; id++)
+				if (!strcmp((char *)id->id, str))
+					return 0;
+	}
+
+	for (i = 0; i < info->compatible_id_list.count; i++) {
+		len = info->compatible_id_list.ids[i].length;
+		if (!len)
+			continue;
+		str = info->compatible_id_list.ids[i].string;
+		if (!str)
+			continue;
+		for (id = ids; id->id[0]; id++)
+			if (!strcmp((char *)id->id, str))
+				return 0;
+	}
+
+	return -ENOENT;
+}
+EXPORT_SYMBOL_GPL(acpi_match_object_info_ids);
+
 static void acpi_free_ids(struct acpi_device *device)
 {
 	struct acpi_hardware_id *id, *tmp;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index a9e1421..2246ba9 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -355,6 +355,8 @@ int acpi_bus_trim(struct acpi_device *start, int rmdevice);
 acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
 int acpi_match_device_ids(struct acpi_device *device,
 			  const struct acpi_device_id *ids);
+int acpi_match_object_info_ids(struct acpi_device_info *info,
+			       const struct acpi_device_id *ids);
 int acpi_create_dir(struct acpi_device *);
 void acpi_remove_dir(struct acpi_device *);
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 11/22] PCI: correctly detect ACPI PCI host bridge objects
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (9 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 10/22] ACPI: Introduce a new acpi handle to determine HID match Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 23:34   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 12/22] PCI, ACPI: debug print for installation of acpi root bridge's notifier Yinghai Lu
                   ` (11 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

From: Jiang Liu <jiang.liu@huawei.com>

The code in pci_root_hp.c depends on function acpi_is_root_bridge()
to check whether an ACPI object is a PCI host bridge or not.
If an ACPI device hasn't been created for the ACPI object yet,
function acpi_is_root_bridge() will return false even if the object
is a PCI host bridge object. That behavior will cause two issues:
1) No ACPI notification handler installed for PCI host bridges absent
   at startup, so hotplug events for those bridges won't be handled.
2) rescan_root_bridge() can't reenumerate offlined PCI host bridges
   because the ACPI devices have been already destroyed.

So use acpi_match_object_info_ids() to correctly detect PCI host bridges.

-v2: update to use acpi_match_object_info_ids() from Tang Chen  - Yinghai
-v3: drop the PNP0A008, according to Bjorn.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
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 |   19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 5ae36d8..d30fb94 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -923,6 +923,23 @@ static void handle_hotplug_event_root(acpi_handle handle, u32 type,
 				_handle_hotplug_event_root);
 }
 
+static bool acpi_is_root_bridge_object(acpi_handle handle)
+{
+	struct acpi_device_info *info = NULL;
+	acpi_status status;
+	bool ret;
+
+	status = acpi_get_object_info(handle, &info);
+	if (ACPI_FAILURE(status))
+		return false;
+
+	ret = !acpi_match_object_info_ids(info, root_device_ids);
+
+	kfree(info);
+
+	return ret;
+}
+
 static acpi_status __init
 find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
@@ -931,7 +948,7 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
 				      .pointer = objname };
 	int *count = (int *)context;
 
-	if (!acpi_is_root_bridge(handle))
+	if (!acpi_is_root_bridge_object(handle))
 		return AE_OK;
 
 	(*count)++;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 12/22] PCI, ACPI: debug print for installation of acpi root bridge's notifier
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (10 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 11/22] PCI: correctly detect ACPI PCI host bridge objects Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 23:37   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 13/22] PCI, ACPI: remove acpi_root_bridge in pci_root_hp Yinghai Lu
                   ` (10 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Tang Chen, Yinghai Lu

From: Tang Chen <tangchen@cn.fujitsu.com>

acpi_install_notify_handler() could fail. So check the exit status
and give a better debug info.

Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/acpi/pci_root.c |   12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index d30fb94..862abcc 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -943,6 +943,7 @@ static bool acpi_is_root_bridge_object(acpi_handle handle)
 static acpi_status __init
 find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
+	acpi_status status;
 	char objname[64];
 	struct acpi_buffer buffer = { .length = sizeof(objname),
 				      .pointer = objname };
@@ -955,9 +956,14 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
 
 	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);
+	status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+					handle_hotplug_event_root, NULL);
+	if (ACPI_FAILURE(status))
+		printk(KERN_DEBUG "acpi root: %s notify handler is not installed, exit status: %u\n",
+				  objname, (unsigned int)status);
+	else
+		printk(KERN_DEBUG "acpi root: %s notify handler is installed\n",
+				 objname);
 
 	add_acpi_root_bridge(handle);
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 13/22] PCI, ACPI: remove acpi_root_bridge in pci_root_hp
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (11 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 12/22] PCI, ACPI: debug print for installation of acpi root bridge's notifier Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 23:39   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 14/22] ACPI: update ej_event interface to take acpi_device Yinghai Lu
                   ` (9 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

Tang noticed that hotplug through container will not update acpi_root_bridge
list.

After closely checking, we don't need that for struct for tracking and
could use acpi_pci_root directly.

Reported-by: Tang Chen <tangchen@cn.fujitsu.com>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/acpi/pci_root.c |  109 +++++++++--------------------------------------
 1 file changed, 20 insertions(+), 89 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 862abcc..697ec65 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -679,73 +679,12 @@ int __init acpi_pci_root_init(void)
  *	only support root bridge
  */
 
-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);
-}
-
-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;
@@ -827,28 +766,25 @@ static int acpi_root_evaluate_object(acpi_handle handle, char *cmd, int val)
 	return 0;
 }
 
-static void handle_root_bridge_removal(acpi_handle handle,
-		 struct acpi_root_bridge *bridge)
+static void handle_root_bridge_removal(struct acpi_device *device)
 {
+	int ret_val;
 	u32 flags = 0;
-	struct acpi_device *device;
+	acpi_handle dummy_handle;
+	acpi_handle handle = device->handle;
 
-	if (bridge) {
-		flags = bridge->flags;
-		remove_acpi_root_bridge(bridge);
-	}
+	if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &dummy_handle)))
+		flags |= ROOT_BRIDGE_HAS_EJ0;
+	if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &dummy_handle)))
+		flags |= ROOT_BRIDGE_HAS_PS3;
 
-	if (!acpi_bus_get_device(handle, &device)) {
-		int ret_val;
+	/* remove pci devices at first */
+	ret_val = acpi_bus_trim(device, 0);
+	printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
 
-		/* remove pci devices at first */
-		ret_val = acpi_bus_trim(device, 0);
-		printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
-
-		/* remove acpi devices */
-		ret_val = acpi_bus_trim(device, 1);
-		printk(KERN_DEBUG "acpi_bus_trim remove return %x\n", ret_val);
-	}
+	/* remove acpi devices */
+	ret_val = acpi_bus_trim(device, 1);
+	printk(KERN_DEBUG "acpi_bus_trim remove return %x\n", ret_val);
 
 	if (flags & ROOT_BRIDGE_HAS_PS3) {
 		acpi_status status;
@@ -863,7 +799,7 @@ static void handle_root_bridge_removal(acpi_handle handle,
 
 static void _handle_hotplug_event_root(struct work_struct *work)
 {
-	struct acpi_root_bridge *bridge;
+	struct acpi_pci_root *root;
 	char objname[64];
 	struct acpi_buffer buffer = { .length = sizeof(objname),
 				      .pointer = objname };
@@ -875,7 +811,7 @@ static void _handle_hotplug_event_root(struct work_struct *work)
 	handle = hp_work->handle;
 	type = hp_work->type;
 
-	bridge = acpi_root_handle_to_bridge(handle);
+	root = acpi_pci_find_root(handle);
 
 	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 
@@ -884,10 +820,8 @@ static void _handle_hotplug_event_root(struct work_struct *work)
 		/* bus enumerate */
 		printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__,
 				 objname);
-		if (!bridge) {
+		if (!root)
 			handle_root_bridge_insertion(handle);
-			add_acpi_root_bridge(handle);
-		}
 
 		break;
 
@@ -895,17 +829,16 @@ static void _handle_hotplug_event_root(struct work_struct *work)
 		/* device check */
 		printk(KERN_DEBUG "%s: Device check notify on %s\n", __func__,
 				 objname);
-		if (!bridge) {
+		if (!root)
 			handle_root_bridge_insertion(handle);
-			add_acpi_root_bridge(handle);
-		}
 		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);
+		if (root)
+			handle_root_bridge_removal(root->device);
 		break;
 	default:
 		printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n",
@@ -965,8 +898,6 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
 		printk(KERN_DEBUG "acpi root: %s notify handler is installed\n",
 				 objname);
 
-	add_acpi_root_bridge(handle);
-
 	return AE_OK;
 }
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 14/22] ACPI: update ej_event interface to take acpi_device
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (12 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 13/22] PCI, ACPI: remove acpi_root_bridge in pci_root_hp Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 23:40   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 15/22] ACPI, PCI: Simplify handle_root_bridge_removal() Yinghai Lu
                   ` (8 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

Should use acpi_device pointer directly instead of use handle and
get the device pointer again later.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/acpi/acpi_memhotplug.c  |    2 +-
 drivers/acpi/processor_driver.c |    2 +-
 drivers/acpi/scan.c             |   14 ++++----------
 include/acpi/acpi_bus.h         |    2 +-
 4 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 327ab44..eaddb7a 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -361,7 +361,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
 			break;
 		}
 
-		ej_event->handle = handle;
+		ej_event->device = device;
 		ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
 		acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
 					(void *)ej_event);
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 0777663..a24ee43 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -733,7 +733,7 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
 			break;
 		}
 
-		ej_event->handle = handle;
+		ej_event->device = device;
 		ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
 		acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
 					(void *)ej_event);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 8883539..f4c6305 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -116,20 +116,14 @@ static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
 void acpi_bus_hot_remove_device(void *context)
 {
 	struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context;
-	struct acpi_device *device;
-	acpi_handle handle = ej_event->handle;
+	struct acpi_device *device = ej_event->device;
+	acpi_handle handle = device->handle;
 	acpi_handle temp;
 	struct acpi_object_list arg_list;
 	union acpi_object arg;
 	acpi_status status = AE_OK;
 	u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
 
-	if (acpi_bus_get_device(handle, &device))
-		goto err_out;
-
-	if (!device)
-		goto err_out;
-
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 		"Hot-removing device %s...\n", dev_name(&device->dev)));
 
@@ -215,7 +209,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
 		goto err;
 	}
 
-	ej_event->handle = acpi_device->handle;
+	ej_event->device = acpi_device;
 	if (acpi_device->flags.eject_pending) {
 		/* event originated from ACPI eject notification */
 		ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
@@ -223,7 +217,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
 	} else {
 		/* event originated from user */
 		ej_event->event = ACPI_OST_EC_OSPM_EJECT;
-		(void) acpi_evaluate_hotplug_ost(ej_event->handle,
+		(void) acpi_evaluate_hotplug_ost(acpi_device->handle,
 			ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
 	}
 
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 2246ba9..181ff2d 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -309,7 +309,7 @@ struct acpi_bus_event {
 };
 
 struct acpi_eject_event {
-	acpi_handle	handle;
+	struct acpi_device	*device;
 	u32		event;
 };
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 15/22] ACPI, PCI: Simplify handle_root_bridge_removal()
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (13 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 14/22] ACPI: update ej_event interface to take acpi_device Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 23:42   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 16/22] PCI, acpiphp: Don't bailout even no slots found yet Yinghai Lu
                   ` (7 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

Tang Chen found handle_root_bridge_removal is very similiar to
acpi_bus_hot_remove_device().
Only difference is that it call trim two times.

Change to handle_root_bridge_removal to call trim one time and then
use acpi_bus_hot_remove_device.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/acpi/pci_root.c |   49 ++++++++---------------------------------------
 1 file changed, 8 insertions(+), 41 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 697ec65..8a0e2e2 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -745,56 +745,23 @@ static void handle_root_bridge_insertion(acpi_handle handle)
 		printk(KERN_ERR "cannot add bridge to acpi list\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)) {
-		pr_warn("%s: %s to %d failed\n",
-				 __func__, cmd, val);
-		return -1;
-	}
-
-	return 0;
-}
-
 static void handle_root_bridge_removal(struct acpi_device *device)
 {
 	int ret_val;
-	u32 flags = 0;
-	acpi_handle dummy_handle;
-	acpi_handle handle = device->handle;
+	struct acpi_eject_event *ej_event;
+
+	ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
+	if (!ej_event)
+		return;
 
-	if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &dummy_handle)))
-		flags |= ROOT_BRIDGE_HAS_EJ0;
-	if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &dummy_handle)))
-		flags |= ROOT_BRIDGE_HAS_PS3;
+	ej_event->device = device;
+	ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
 
 	/* remove pci devices at first */
 	ret_val = acpi_bus_trim(device, 0);
 	printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
 
-	/* remove acpi devices */
-	ret_val = acpi_bus_trim(device, 1);
-	printk(KERN_DEBUG "acpi_bus_trim remove 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))
-			pr_warn("%s: _PS3 failed\n", __func__);
-	}
-	if (flags & ROOT_BRIDGE_HAS_EJ0)
-		acpi_root_evaluate_object(handle, "_EJ0", 1);
+	acpi_bus_hot_remove_device(ej_event);
 }
 
 static void _handle_hotplug_event_root(struct work_struct *work)
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 16/22] PCI, acpiphp: Don't bailout even no slots found yet.
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (14 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 15/22] ACPI, PCI: Simplify handle_root_bridge_removal() Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 23:43   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 17/22] PCI, ACPI: Add alloc_acpi_hp_work() Yinghai Lu
                   ` (6 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

Could have root bus hot addde later and there may be slots that need acpiphp.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/hotplug/acpiphp.h      |    1 -
 drivers/pci/hotplug/acpiphp_core.c |   23 ++---------------------
 drivers/pci/hotplug/acpiphp_glue.c |   22 ----------------------
 3 files changed, 2 insertions(+), 44 deletions(-)

diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index a1afb5b..b3ead7a 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -193,7 +193,6 @@ extern void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot);
 /* acpiphp_glue.c */
 extern int acpiphp_glue_init (void);
 extern void acpiphp_glue_exit (void);
-extern int acpiphp_get_num_slots (void);
 typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
 
 extern int acpiphp_enable_slot (struct acpiphp_slot *slot);
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index 96316b7..c2fd309 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -50,7 +50,6 @@
 bool acpiphp_debug;
 
 /* local variables */
-static int num_slots;
 static struct acpiphp_attention_info *attention_info;
 
 #define DRIVER_VERSION	"0.5"
@@ -272,25 +271,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
 	return 0;
 }
 
-static int __init init_acpi(void)
-{
-	int retval;
-
-	/* initialize internal data structure etc. */
-	retval = acpiphp_glue_init();
-
-	/* read initial number of slots */
-	if (!retval) {
-		num_slots = acpiphp_get_num_slots();
-		if (num_slots == 0) {
-			acpiphp_glue_exit();
-			retval = -ENODEV;
-		}
-	}
-
-	return retval;
-}
-
 /**
  * release_slot - free up the memory used by a slot
  * @hotplug_slot: slot to free
@@ -379,7 +359,8 @@ static int __init acpiphp_init(void)
 		return 0;
 
 	/* read all the ACPI info from the system */
-	return init_acpi();
+	/* initialize internal data structure etc. */
+	return acpiphp_glue_init();
 }
 
 
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 02c41ab..30467ec 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1446,28 +1446,6 @@ void  acpiphp_glue_exit(void)
 	acpi_pci_unregister_driver(&acpi_pci_hp_driver);
 }
 
-
-/**
- * acpiphp_get_num_slots - count number of slots in a system
- */
-int __init acpiphp_get_num_slots(void)
-{
-	struct acpiphp_bridge *bridge;
-	int num_slots = 0;
-
-	list_for_each_entry(bridge, &bridge_list, list) {
-		dbg("Bus %04x:%02x has %d slot%s\n",
-				pci_domain_nr(bridge->pci_bus),
-				bridge->pci_bus->number, bridge->nr_slots,
-				bridge->nr_slots == 1 ? "" : "s");
-		num_slots += bridge->nr_slots;
-	}
-
-	dbg("Total %d slots\n", num_slots);
-	return num_slots;
-}
-
-
 /**
  * acpiphp_enable_slot - power on slot
  * @slot: ACPI PHP slot
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 17/22] PCI, ACPI: Add alloc_acpi_hp_work()
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (15 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 16/22] PCI, acpiphp: Don't bailout even no slots found yet Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 23:45   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 18/22] PCI, acpiphp: Use acpi_hp_work Yinghai Lu
                   ` (5 subsequent siblings)
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

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(+)

diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 3ff2678..e6539a3 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1778,3 +1778,24 @@ void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
 {
 	__acpi_os_prepare_sleep = func;
 }
+
+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 4315274..2a64da5 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -195,6 +195,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.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 18/22] PCI, acpiphp: Use acpi_hp_work
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (16 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 17/22] PCI, ACPI: Add alloc_acpi_hp_work() Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-11 22:40 ` [PATCH v8 19/22] PCI, pci_root_hp: " Yinghai Lu
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

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 file changed, 6 insertions(+), 36 deletions(-)

diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 30467ec..82e8883 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1197,34 +1197,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;
@@ -1233,11 +1205,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;
 
@@ -1340,8 +1312,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)
@@ -1350,12 +1321,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;
@@ -1416,8 +1387,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.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 19/22] PCI, pci_root_hp: Use acpi_hp_work
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (17 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 18/22] PCI, acpiphp: Use acpi_hp_work Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-11 22:40 ` [PATCH v8 20/22] PCI, ACPI: Make kacpi_hotplug_wq static Yinghai Lu
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

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.c |   34 +++-------------------------------
 1 file changed, 3 insertions(+), 31 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 8a0e2e2..e3774b2 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -685,34 +685,6 @@ int __init acpi_pci_root_init(void)
 
 #define ACPI_STA_FUNCTIONING	(0x00000008)
 
-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);
-}
-
 static void handle_root_bridge_insertion(acpi_handle handle)
 {
 	struct acpi_device *device, *pdevice;
@@ -770,11 +742,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;
 
@@ -819,7 +791,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.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 20/22] PCI, ACPI: Make kacpi_hotplug_wq static
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (18 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 19/22] PCI, pci_root_hp: " Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-11 22:40 ` [PATCH v8 21/22] PCI: add match_driver in struct pci_dev Yinghai Lu
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

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 insertion(+), 4 deletions(-)

diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index e6539a3..afcce46 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -84,8 +84,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 2a64da5..adab63c 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -193,8 +193,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.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 21/22] PCI: add match_driver in struct pci_dev
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (19 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 20/22] PCI, ACPI: Make kacpi_hotplug_wq static Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 23:49   ` Rafael J. Wysocki
  2013-01-11 22:40 ` [PATCH v8 22/22] PCI: move device_add out of pci_bus_add_device() Yinghai Lu
  2013-01-12 21:35 ` [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Rafael J. Wysocki
  22 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

with that we could move out attaching driver for pci device,
out of device_add for pci hot add path.

pci_bus_attach_device() will attach driver to pci device.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/bus.c        |   10 ++++++++++
 drivers/pci/pci-driver.c |    6 +++++-
 include/linux/pci.h      |    1 +
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 5f9c728..1f5916a 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -160,6 +160,15 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
 
 void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { }
 
+static void pci_bus_attach_device(struct pci_dev *dev)
+{
+	int ret;
+
+	dev->match_driver = true;
+	ret = device_attach(&dev->dev);
+	WARN_ON(ret < 0);
+}
+
 /**
  * pci_bus_add_device - add a single device
  * @dev: device to add
@@ -181,6 +190,7 @@ int pci_bus_add_device(struct pci_dev *dev)
 	if (retval)
 		return retval;
 
+	pci_bus_attach_device(dev);
 	dev->is_added = 1;
 	pci_proc_attach_device(dev);
 	pci_create_sysfs_dev_files(dev);
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index f79cbcd..acdcc3c 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -1186,9 +1186,13 @@ pci_dev_driver(const struct pci_dev *dev)
 static int pci_bus_match(struct device *dev, struct device_driver *drv)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct pci_driver *pci_drv = to_pci_driver(drv);
+	struct pci_driver *pci_drv;
 	const struct pci_device_id *found_id;
 
+	if (!pci_dev->match_driver)
+		return 0;
+
+	pci_drv = to_pci_driver(drv);
 	found_id = pci_match_device(pci_drv, pci_dev);
 	if (found_id)
 		return 1;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 907b455..d73af08 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -286,6 +286,7 @@ struct pci_dev {
 	unsigned int	irq;
 	struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
 
+	bool match_driver;
 	/* These fields are used by common fixups */
 	unsigned int	transparent:1;	/* Transparent PCI bridge */
 	unsigned int	multifunction:1;/* Part of multi-function device */
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v8 22/22] PCI: move device_add out of pci_bus_add_device()
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (20 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 21/22] PCI: add match_driver in struct pci_dev Yinghai Lu
@ 2013-01-11 22:40 ` Yinghai Lu
  2013-01-12 23:54   ` Rafael J. Wysocki
  2013-01-16  2:29   ` Yijing Wang
  2013-01-12 21:35 ` [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Rafael J. Wysocki
  22 siblings, 2 replies; 78+ messages in thread
From: Yinghai Lu @ 2013-01-11 22:40 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi, Jiang Liu
  Cc: linux-pci, linux-kernel, linux-acpi, Yinghai Lu

Move out device registering out of pci_bus_add_devices, so we could
put new created pci devices in device tree early.

new pci_bus_add_devices will do the device_attach work to load pci drivers
instead.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/bus.c   |   47 +++--------------------------------------------
 drivers/pci/iov.c   |    7 -------
 drivers/pci/probe.c |   34 +++++++++++++++++++++++++++-------
 3 files changed, 30 insertions(+), 58 deletions(-)

diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 1f5916a..0a55845 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -178,22 +178,9 @@ static void pci_bus_attach_device(struct pci_dev *dev)
  */
 int pci_bus_add_device(struct pci_dev *dev)
 {
-	int retval;
-
-	pci_fixup_device(pci_fixup_final, dev);
-
-	retval = pcibios_add_device(dev);
-	if (retval)
-		return retval;
-
-	retval = device_add(&dev->dev);
-	if (retval)
-		return retval;
-
 	pci_bus_attach_device(dev);
 	dev->is_added = 1;
-	pci_proc_attach_device(dev);
-	pci_create_sysfs_dev_files(dev);
+
 	return 0;
 }
 
@@ -205,21 +192,9 @@ int pci_bus_add_device(struct pci_dev *dev)
  */
 int pci_bus_add_child(struct pci_bus *bus)
 {
-	int retval;
-
-	if (bus->bridge)
-		bus->dev.parent = bus->bridge;
-
-	retval = device_add(&bus->dev);
-	if (retval)
-		return retval;
-
 	bus->is_added = 1;
 
-	/* Create legacy_io and legacy_mem files for this bus */
-	pci_create_legacy_files(bus);
-
-	return retval;
+	return 0;
 }
 
 /**
@@ -245,36 +220,20 @@ void pci_bus_add_devices(const struct pci_bus *bus)
 		if (dev->is_added)
 			continue;
 		retval = pci_bus_add_device(dev);
-		if (retval)
-			dev_err(&dev->dev, "Error adding device, continuing\n");
 	}
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		BUG_ON(!dev->is_added);
 
 		child = dev->subordinate;
-		/*
-		 * If there is an unattached subordinate bus, attach
-		 * it and then scan for unattached PCI devices.
-		 */
+
 		if (!child)
 			continue;
-		if (list_empty(&child->node)) {
-			down_write(&pci_bus_sem);
-			list_add_tail(&child->node, &dev->bus->children);
-			up_write(&pci_bus_sem);
-		}
 		pci_bus_add_devices(child);
 
-		/*
-		 * register the bus with sysfs as the parent is now
-		 * properly registered.
-		 */
 		if (child->is_added)
 			continue;
 		retval = pci_bus_add_child(child);
-		if (retval)
-			dev_err(&dev->dev, "Error adding bus, continuing\n");
 	}
 }
 
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index bafd2bb..dbad72e 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -48,12 +48,7 @@ static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
 		return NULL;
 
 	pci_bus_insert_busn_res(child, busnr, busnr);
-	child->dev.parent = bus->bridge;
 	rc = pci_bus_add_child(child);
-	if (rc) {
-		pci_remove_bus(child);
-		return NULL;
-	}
 
 	return child;
 }
@@ -123,8 +118,6 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
 	virtfn->is_virtfn = 1;
 
 	rc = pci_bus_add_device(virtfn);
-	if (rc)
-		goto failed1;
 	sprintf(buf, "virtfn%u", id);
 	rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
 	if (rc)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index dc4fde3..84c92a0 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -623,6 +623,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
 {
 	struct pci_bus *child;
 	int i;
+	int ret;
 
 	/*
 	 * Allocate a new bus, and inherit stuff from the parent..
@@ -637,8 +638,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
 	child->bus_flags = parent->bus_flags;
 
 	/* initialize some portions of the bus device, but don't register it
-	 * now as the parent is not properly set up yet.  This device will get
-	 * registered later in pci_bus_add_devices()
+	 * now as the parent is not properly set up yet.
 	 */
 	child->dev.class = &pcibus_class;
 	dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr);
@@ -652,11 +652,14 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
 	child->primary = parent->busn_res.start;
 	child->busn_res.end = 0xff;
 
-	if (!bridge)
-		return child;
+	if (!bridge) {
+		child->dev.parent = parent->bridge;
+		goto add_dev;
+	}
 
 	child->self = bridge;
 	child->bridge = get_device(&bridge->dev);
+	child->dev.parent = child->bridge;
 	pci_set_bus_of_node(child);
 	pci_set_bus_speed(child);
 
@@ -667,6 +670,13 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
 	}
 	bridge->subordinate = child;
 
+add_dev:
+	ret = device_add(&child->dev);
+	WARN_ON(ret < 0);
+
+	/* Create legacy_io and legacy_mem files for this bus */
+	pci_create_legacy_files(child);
+
 	return child;
 }
 
@@ -1297,6 +1307,8 @@ static void pci_init_capabilities(struct pci_dev *dev)
 
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 {
+	int ret;
+
 	device_initialize(&dev->dev);
 	dev->dev.release = pci_release_dev;
 
@@ -1327,6 +1339,16 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 	down_write(&pci_bus_sem);
 	list_add_tail(&dev->bus_list, &bus->devices);
 	up_write(&pci_bus_sem);
+
+	pci_fixup_device(pci_fixup_final, dev);
+        ret = pcibios_add_device(dev);
+	WARN_ON(ret < 0);
+	/* notifier could use pci capabilities */
+	ret = device_add(&dev->dev);
+	WARN_ON(ret < 0);
+
+	pci_proc_attach_device(dev);
+	pci_create_sysfs_dev_files(dev);
 }
 
 struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn)
@@ -1645,13 +1667,13 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	char bus_addr[64];
 	char *fmt;
 
-
 	b = pci_alloc_bus();
 	if (!b)
 		return NULL;
 
 	b->sysdata = sysdata;
 	b->ops = ops;
+	b->number = b->busn_res.start = bus;
 	b2 = pci_find_bus(pci_domain_nr(b), bus);
 	if (b2) {
 		/* If we already got to this bus through a different bridge, ignore it */
@@ -1687,8 +1709,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	/* Create legacy_io and legacy_mem files for this bus */
 	pci_create_legacy_files(b);
 
-	b->number = b->busn_res.start = bus;
-
 	if (parent)
 		dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
 	else
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver
  2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
                   ` (21 preceding siblings ...)
  2013-01-11 22:40 ` [PATCH v8 22/22] PCI: move device_add out of pci_bus_add_device() Yinghai Lu
@ 2013-01-12 21:35 ` Rafael J. Wysocki
  22 siblings, 0 replies; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 21:35 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:27 PM Yinghai Lu wrote:
> It includes
> 1. preparing patches for pci root bus hotadd/hotremove support
> 2. move root bus hotadd from acpiphp to pci_root.c
> 3. add hot-remove support
> 4. clean up hotadd/remove with common functions
> 5. add acpi_hp_work to be shared with acpiphp and root-bus hotplug
> 6. add match_driver to add pci device to device tree early but
>    not attach driver for hotplug path.
> 
> based on pci/next
> 
> could get from
>         git://git.kernel.org/pub/scm/linux/kernel/git/yinghai/linux-yinghai.git for-pci-root-bus-hotplug
> 
> After this patchset, will send out
> 	 for_each_host_bridge support
> 	 for_each_dev_addon_res
> 
> Jiang Liu (4):
>   PCI: Fix a device reference count leakage issue in pci_dev_present()
>   PCI: make PCI device create/destroy logic symmetric
>   PCI: split registration of PCI bus devices into two stages
>   PCI: correctly detect ACPI PCI host bridge objects
> 
> Tang Chen (2):
>   ACPI: Introduce a new acpi handle to determine HID match.
>   PCI, ACPI: debug print for installation of acpi root bridge's notifier
> 
> Yinghai Lu (16):
>   PCI, acpiphp: Add is_hotplug_bridge detection
>   PCI: Add root bus children dev's res to fail list
>   PCI: Set dev_node early for pci_dev
>   ACPI: Separate acpi_bus_trim to support two steps.
>   PCI, acpiphp: Separate out hot-add support of pci host bridge
>   PCI, ACPI: Add pci_root_hp hot removal notification support.
>   PCI, ACPI: remove acpi_root_bridge in pci_root_hp
>   ACPI: update ej_event interface to take acpi_device
>   ACPI, PCI: Simplify handle_root_bridge_removal()
>   PCI, acpiphp: Don't bailout even no slots found yet.
>   PCI, ACPI: Add alloc_acpi_hp_work()
>   PCI, acpiphp: Use acpi_hp_work
>   PCI, pci_root_hp: Use acpi_hp_work
>   PCI, ACPI: Make kacpi_hotplug_wq static
>   PCI: add match_driver in struct pci_dev
>   PCI: move device_add out of pci_bus_add_device()

It looks good overall, but I have a few questions and comments.

I'll reply to the individual patches where applicable.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 01/22] PCI, acpiphp: Add is_hotplug_bridge detection
  2013-01-11 22:40 ` [PATCH v8 01/22] PCI, acpiphp: Add is_hotplug_bridge detection Yinghai Lu
@ 2013-01-12 21:35   ` Rafael J. Wysocki
  2013-01-15  6:45   ` Yijing Wang
  1 sibling, 0 replies; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 21:35 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:28 PM Yinghai Lu wrote:
> When system support hotplug bridge with children hotplug slots, we need
> to make sure that parent bridge get preallocated resource so later when
> device is plugged into children slot, those children devices will get
> resource allocated.
> 
> We do not meet this problem, because for pcie hotplug card, when acpiphp
> is used, pci_scan_bridge will set that for us when detect hotplug bit in
> slot cap.
> 
> Reported-and-tested-by: Jason Baron <jbaron@redhat.com>
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Acked-by: Jason Baron <jbaron@redhat.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/pci/hotplug/acpiphp_glue.c |   27 ++++++++++++++++++++++++++-
>  1 file changed, 26 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
> index 91b5ad8..1e5c5df 100644
> --- a/drivers/pci/hotplug/acpiphp_glue.c
> +++ b/drivers/pci/hotplug/acpiphp_glue.c
> @@ -797,6 +797,29 @@ static void acpiphp_set_acpi_region(struct acpiphp_slot *slot)
>  	}
>  }
>  
> +static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev)
> +{
> +	struct acpiphp_func *func;
> +
> +	if (!dev->subordinate)
> +		return;
> +
> +	/* quirk, or pcie could set it already */
> +	if (dev->is_hotplug_bridge)
> +		return;
> +
> +	if (PCI_SLOT(dev->devfn) != slot->device)
> +		return;
> +
> +	list_for_each_entry(func, &slot->funcs, sibling) {
> +		if (PCI_FUNC(dev->devfn) == func->function) {
> +			/* check if this bridge has ejectable slots */
> +			if ((detect_ejectable_slots(func->handle) > 0))
> +				dev->is_hotplug_bridge = 1;
> +			break;
> +		}
> +	}
> +}
>  /**
>   * enable_device - enable, configure a slot
>   * @slot: slot to be enabled
> @@ -831,8 +854,10 @@ static int __ref enable_device(struct acpiphp_slot *slot)
>  			if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
>  			    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
>  				max = pci_scan_bridge(bus, dev, max, pass);
> -				if (pass && dev->subordinate)
> +				if (pass && dev->subordinate) {
> +					check_hotplug_bridge(slot, dev);
>  					pci_bus_size_bridges(dev->subordinate);
> +				}
>  			}
>  		}
>  	}
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 02/22] PCI: Add root bus children dev's res to fail list
  2013-01-11 22:40 ` [PATCH v8 02/22] PCI: Add root bus children dev's res to fail list Yinghai Lu
@ 2013-01-12 21:37   ` Rafael J. Wysocki
  2013-01-15  6:23     ` Yinghai Lu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 21:37 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:29 PM Yinghai Lu wrote:
> We can stop trying according to try number now and do not need to use
> root_bus checking as stop sign anymore.
> 
> In extreme case we could need to reallocate resource for device just
> under root bus.

Well, the above says that we _can_ do the change, but it doesn't explain why it
is needed.  So what's the reason why we need to do that?

Rafael


> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/pci/setup-bus.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
> index 6d3591d..7e8739e 100644
> --- a/drivers/pci/setup-bus.c
> +++ b/drivers/pci/setup-bus.c
> @@ -283,7 +283,7 @@ static void assign_requested_resources_sorted(struct list_head *head,
>  		idx = res - &dev_res->dev->resource[0];
>  		if (resource_size(res) &&
>  		    pci_assign_resource(dev_res->dev, idx)) {
> -			if (fail_head && !pci_is_root_bus(dev_res->dev->bus)) {
> +			if (fail_head) {
>  				/*
>  				 * if the failed res is for ROM BAR, and it will
>  				 * be enabled later, don't add it to the list
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 03/22] PCI: Set dev_node early for pci_dev
  2013-01-11 22:40 ` [PATCH v8 03/22] PCI: Set dev_node early for pci_dev Yinghai Lu
@ 2013-01-12 21:38   ` Rafael J. Wysocki
  0 siblings, 0 replies; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 21:38 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:30 PM Yinghai Lu wrote:
> Otherwise irq_desc for pci bridge with hot-added ioapic can not be on
> local node.
> 
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/pci/probe.c |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 2dcd22d..b97dea5 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1300,6 +1300,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>  	dev->dev.release = pci_release_dev;
>  	pci_dev_get(dev);
>  
> +	set_dev_node(&dev->dev, pcibus_to_node(bus));
>  	dev->dev.dma_mask = &dev->dma_mask;
>  	dev->dev.dma_parms = &dev->dma_parms;
>  	dev->dev.coherent_dma_mask = 0xffffffffull;
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 04/22] PCI: Fix a device reference count leakage issue in pci_dev_present()
  2013-01-11 22:40 ` [PATCH v8 04/22] PCI: Fix a device reference count leakage issue in pci_dev_present() Yinghai Lu
@ 2013-01-12 21:39   ` Rafael J. Wysocki
  0 siblings, 0 replies; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 21:39 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:31 PM Yinghai Lu wrote:
> From: Jiang Liu <jiang.liu@huawei.com>
> 
> Function pci_get_dev_by_id() will hold a reference count on the pci device
> returned, so pci_dev_present() should release the corresponding reference
> count to avoid memory leakage.
> 
> Signed-off-by: Jiang Liu <jiang.liu@huawei.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/pci/search.c |   10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pci/search.c b/drivers/pci/search.c
> index bf969ba..d0627fa 100644
> --- a/drivers/pci/search.c
> +++ b/drivers/pci/search.c
> @@ -319,13 +319,13 @@ int pci_dev_present(const struct pci_device_id *ids)
>  	WARN_ON(in_interrupt());
>  	while (ids->vendor || ids->subvendor || ids->class_mask) {
>  		found = pci_get_dev_by_id(ids, NULL);
> -		if (found)
> -			goto exit;
> +		if (found) {
> +			pci_dev_put(found);
> +			return 1;
> +		}
>  		ids++;
>  	}
> -exit:
> -	if (found)
> -		return 1;
> +
>  	return 0;
>  }
>  EXPORT_SYMBOL(pci_dev_present);
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 05/22] PCI: make PCI device create/destroy logic symmetric
  2013-01-11 22:40 ` [PATCH v8 05/22] PCI: make PCI device create/destroy logic symmetric Yinghai Lu
@ 2013-01-12 21:40   ` Rafael J. Wysocki
  0 siblings, 0 replies; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 21:40 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:32 PM Yinghai Lu wrote:
> From: Jiang Liu <jiang.liu@huawei.com>
> 
> According to device model documentation, the way to create/destroy PCI
> devices should be symmetric.
> 
> /**
>  * device_del - delete device from system.
>  * @dev: device.
>  *
>  * This is the first part of the device unregistration
>  * sequence. This removes the device from the lists we control
>  * from here, has it removed from the other driver model
>  * subsystems it was added to in device_add(), and removes it
>  * from the kobject hierarchy.
>  *
>  * NOTE: this should be called manually _iff_ device_add() was
>  * also called manually.
>  */
> 
> The rule is to either use
> 1) device_register()/device_unregister()
> or
> 2) device_initialize()/device_add()/device_del()/put_device().
> 
> So change PCI core logic to follow the rule and get rid of the redundant
> pci_dev_get()/pci_dev_put() pair.
> 
> Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
> Acked-by: Bjorn Helgaas <bhelgaas@google.com>
> Signed-by: Yinghai Lu <yinghai@kernel.org>

Signed-off-by I suppose?

Apart from this:

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/pci/probe.c  |    1 -
>  drivers/pci/remove.c |    4 ++--
>  2 files changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index b97dea5..48b35e1 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1298,7 +1298,6 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>  {
>  	device_initialize(&dev->dev);
>  	dev->dev.release = pci_release_dev;
> -	pci_dev_get(dev);
>  
>  	set_dev_node(&dev->dev, pcibus_to_node(bus));
>  	dev->dev.dma_mask = &dev->dma_mask;
> diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
> index 7c0fd92..fc38c48 100644
> --- a/drivers/pci/remove.c
> +++ b/drivers/pci/remove.c
> @@ -22,7 +22,7 @@ static void pci_stop_dev(struct pci_dev *dev)
>  	if (dev->is_added) {
>  		pci_proc_detach_device(dev);
>  		pci_remove_sysfs_dev_files(dev);
> -		device_unregister(&dev->dev);
> +		device_del(&dev->dev);
>  		dev->is_added = 0;
>  	}
>  
> @@ -37,7 +37,7 @@ static void pci_destroy_dev(struct pci_dev *dev)
>  	up_write(&pci_bus_sem);
>  
>  	pci_free_resources(dev);
> -	pci_dev_put(dev);
> +	put_device(&dev->dev);
>  }
>  
>  void pci_remove_bus(struct pci_bus *bus)
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 06/22] PCI: split registration of PCI bus devices into two stages
  2013-01-11 22:40 ` [PATCH v8 06/22] PCI: split registration of PCI bus devices into two stages Yinghai Lu
@ 2013-01-12 22:34   ` Rafael J. Wysocki
  2013-01-13 15:25     ` Jiang Liu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 22:34 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:33 PM Yinghai Lu wrote:
> From: Jiang Liu <jiang.liu@huawei.com>
> 
> When handling BUS_NOTIFY_ADD_DEVICE event for a PCI bridge device,
> the notification handler can't hold reference count to the new PCI bus
> because the device object for the new bus (pci_dev->subordinate->dev)
> hasn't been initialized yet.

It doesn't look like BUS_NOTIFY_ADD_DEVICE is used by the PCI bus type
in the mainline.

Is it in linux-next?

If not, then I don't see why we need this patch.

Thanks,
Rafael


> Split the registration of PCI bus device into two stages as below,
> so that the event handler could hold reference count to the new PCI bus
> when handling BUS_NOTIFY_ADD_DEVICE event.
> 
> 1) device_initialize(&pci_dev->dev)
> 2) device_initialize(&pci_dev->subordinate->dev)
> 3) notify BUS_NOTIFY_ADD_DEVICE event for pci_dev
> 4) device_add(&pci_dev->dev)
> 5) device_add(&pci_dev->subordinate->dev)
> 
> Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/pci/bus.c    |    2 +-
>  drivers/pci/probe.c  |    4 +++-
>  drivers/pci/remove.c |   10 +++++-----
>  3 files changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
> index 847f3ca..5f9c728 100644
> --- a/drivers/pci/bus.c
> +++ b/drivers/pci/bus.c
> @@ -200,7 +200,7 @@ int pci_bus_add_child(struct pci_bus *bus)
>  	if (bus->bridge)
>  		bus->dev.parent = bus->bridge;
>  
> -	retval = device_register(&bus->dev);
> +	retval = device_add(&bus->dev);
>  	if (retval)
>  		return retval;
>  
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 48b35e1..dc4fde3 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -642,6 +642,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
>  	 */
>  	child->dev.class = &pcibus_class;
>  	dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr);
> +	device_initialize(&child->dev);
>  
>  	/*
>  	 * Set up the primary, secondary and subordinate
> @@ -1678,7 +1679,8 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>  	b->dev.class = &pcibus_class;
>  	b->dev.parent = b->bridge;
>  	dev_set_name(&b->dev, "%04x:%02x", pci_domain_nr(b), bus);
> -	error = device_register(&b->dev);
> +	device_initialize(&b->dev);
> +	error = device_add(&b->dev);
>  	if (error)
>  		goto class_dev_reg_err;
>  
> diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
> index fc38c48..a1fdd0f 100644
> --- a/drivers/pci/remove.c
> +++ b/drivers/pci/remove.c
> @@ -48,11 +48,11 @@ void pci_remove_bus(struct pci_bus *bus)
>  	list_del(&bus->node);
>  	pci_bus_release_busn_res(bus);
>  	up_write(&pci_bus_sem);
> -	if (!bus->is_added)
> -		return;
> -
> -	pci_remove_legacy_files(bus);
> -	device_unregister(&bus->dev);
> +	if (bus->is_added) {
> +		pci_remove_legacy_files(bus);
> +		device_del(&bus->dev);
> +	}
> +	put_device(&bus->dev);
>  }
>  EXPORT_SYMBOL(pci_remove_bus);
>  
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 07/22] ACPI: Separate acpi_bus_trim to support two steps.
  2013-01-11 22:40 ` [PATCH v8 07/22] ACPI: Separate acpi_bus_trim to support two steps Yinghai Lu
@ 2013-01-12 22:40   ` Rafael J. Wysocki
  2013-01-15  6:31     ` Yinghai Lu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 22:40 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:34 PM Yinghai Lu wrote:
> Current all acpi_bus_trim callers have rmdevice to 1.
> that means it will remove all acpi devices.
> 
> When 0, is passed, it will keep the parent.
> 
> For root bus hotremove support, we need to have pci device to be
> removed before acpi devices.
> 
> So try to keep all acpi devices, and only stop drivers with them.
> 
> This change should be safe because all current callers all have 1 passed.

I'm not sure how the chanelog is related to the patch itself.

The patch modifies the behavior of acpi_bus_trim() to avoid removing all
devices (not just the start point) for rmdevice==0, which doesn't really change
the functionality, because all callers pass rmdevice=1 anyway.

Yes, we can make this change, but why is it necessary?

And why don't we remove the rmdevice argument from acpi_bus_trim() altogether?

Rafael


> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Cc: Len Brown <lenb@kernel.org>
> Cc: linux-acpi@vger.kernel.org
> ---
>  drivers/acpi/scan.c |    5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index e380345..db7664e 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1669,10 +1669,7 @@ int acpi_bus_trim(struct acpi_device *start, int rmdevice)
>  			child = parent;
>  			parent = parent->parent;
>  
> -			if (level == 0)
> -				err = acpi_bus_remove(child, rmdevice);
> -			else
> -				err = acpi_bus_remove(child, 1);
> +			err = acpi_bus_remove(child, rmdevice);
>  
>  			continue;
>  		}
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 08/22] PCI, acpiphp: Separate out hot-add support of pci host bridge
  2013-01-11 22:40 ` [PATCH v8 08/22] PCI, acpiphp: Separate out hot-add support of pci host bridge Yinghai Lu
@ 2013-01-12 23:18   ` Rafael J. Wysocki
  2013-01-15  6:44     ` Yinghai Lu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 23:18 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:35 PM Yinghai Lu wrote:
> It causes confusion.
> 
> We may only need acpi hp for pci host bridge.

What does this mean?

> Split host bridge hot-add support to pci_root_hp, and keep acpiphp simple.

s/Split/Move/ I suppose?

In any case that's not telling the whole story, because the patch doesn't just
move code from one file to another.

> -v2: put back pci_root_hp change in one patch
> -v3: add pcibios_resource_survey_bus() calling
> -v4: remove not needed code with remove_bridge
> -v5: put back support for acpiphp support for slots just on root bus.
> -v6: change some functions to *_p2p_* to make it more clean.
> -v7: split hot_added change out.
> -v8: Move to pci_root.c instead of adding another file requested by Bjorn.
> 
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/acpi/pci_root.c            |  220 ++++++++++++++++++++++++++++++++++++
>  drivers/pci/hotplug/acpiphp_glue.c |   59 +++-------
>  2 files changed, 235 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> index 471b2dc..5c1f462c 100644
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -673,3 +673,223 @@ int __init acpi_pci_root_init(void)
>  
>  	return 0;
>  }
> +
> +/*
> + * Separated from drivers/pci/hotplug/acpiphp_glue.c
> + *	only support root bridge
> + */

This comment will be useless after applying the patch.

> +
> +static LIST_HEAD(acpi_root_bridge_list);
> +struct acpi_root_bridge {
> +	struct list_head list;
> +	acpi_handle handle;
> +	u32 flags;
> +};

We have struct acpi_pci_root already.  Why do we need this in addition?

Also, we have acpi_pci_roots, so why do we need another list of root bridges?

> +
> +/* bridge flags */
> +#define ROOT_BRIDGE_HAS_EJ0	(0x00000002)
> +#define ROOT_BRIDGE_HAS_PS3	(0x00000080)

What is that needed for?

> +
> +#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;
> +

Why do we need to evaluate all of the methods directly here?

Don't we have a struct acpi_device for handle already?

> +	/* 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;

All of this attempts to duplicate the scanning code from scan.c in a very
incomplete and questionable way.

For example, what if the root bridge has _PR0?

> +
> +	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);
> +}

The function above is called only once and used by __init stuff only.
Why don't we move it to the caller and mark that caller as __init too?

> +
> +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...
> +		 */

Why?  Shouldn't we just bail out here?

> +		/* remove pci devices at first */
> +		ret_val = acpi_bus_trim(device, 0);
> +		printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
> +		/* remove acpi devices */
> +		ret_val = acpi_bus_trim(device, 1);

Oh, I see why you need the second argument of acpi_bus_trim() now.

Do I think correctly that you want acpi_pci_root_remove() to be executed before
all of the struct acpi_device objects are removed?  In which case why don't we
call acpi_pci_root_remove() directly before doing the acpi_bus_trim(device, 1)
instead of making the code next to impossible to understand?

> +		printk(KERN_DEBUG "acpi_bus_trim remove return %x\n", ret_val);
> +	}
> +	if (acpi_bus_add(handle))
> +		printk(KERN_ERR "cannot add bridge to acpi list\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);

I don't think we should call add_acpi_root_bridge() for handle if the above
fails.  So probably handle_root_bridge_insertion() should return error codes?

> +			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;
> +}

Why do we need to do that from an initcall?  Couldn't we simply hook up
that code to acpi_pci_root_add() somewhere?

And even if not, why don't we call acpi_pci_root_hp_init() from
acpi_pci_root_init()?

All of the changes in acpiphp_glue.c look reasonable to me.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 09/22] PCI, ACPI: Add pci_root_hp hot removal notification support.
  2013-01-11 22:40 ` [PATCH v8 09/22] PCI, ACPI: Add pci_root_hp hot removal notification support Yinghai Lu
@ 2013-01-12 23:26   ` Rafael J. Wysocki
  2013-01-15  6:45     ` Yinghai Lu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 23:26 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:36 PM Yinghai Lu wrote:
> Add missing hot_remove support for root device.
> 
> How to test it?
> Find out root bus number to acpi root name mapping from dmesg or /sys
> 
>   echo "\_SB.PCIB 3" > /sys/kernel/debug/acpi/sci_notify
> to remove root bus
> 
> -v2: separate stop and remove, so it will be safe for comingi
> 	acpi_pci_bind_notify() changes.
> 
> 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 |   67 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 67 insertions(+)
> 
> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> index 5c1f462c..5ae36d8 100644
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -740,6 +740,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;
> @@ -800,6 +806,61 @@ static void handle_root_bridge_insertion(acpi_handle handle)
>  		printk(KERN_ERR "cannot add bridge to acpi list\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)) {
> +		pr_warn("%s: %s to %d failed\n",
> +				 __func__, cmd, val);
> +		return -1;

Please use a meaningful error code.

> +	}
> +
> +	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;
> +
> +		/* remove pci devices at first */
> +		ret_val = acpi_bus_trim(device, 0);
> +		printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
> +
> +		/* remove acpi devices */
> +		ret_val = acpi_bus_trim(device, 1);
> +		printk(KERN_DEBUG "acpi_bus_trim remove return %x\n", ret_val);

First of all, I don't agree with the way acpi_bus_trim() is used here, as
I said in the previous message.

Second, this code duplicates the code you're adding on [08/22] almost exactly.
Please put it into a one separate function instead of duplicating it like this.

> +	}
> +
> +	if (flags & ROOT_BRIDGE_HAS_PS3) {
> +		acpi_status status;
> +
> +		status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
> +		if (ACPI_FAILURE(status))
> +			pr_warn("%s: _PS3 failed\n", __func__);

No, please.  acpi_device_set_power() is for that.

> +	}
> +	if (flags & ROOT_BRIDGE_HAS_EJ0)
> +		acpi_root_evaluate_object(handle, "_EJ0", 1);

That seems to duplicate some code from scan.c.

> +}
> +
>  static void _handle_hotplug_event_root(struct work_struct *work)
>  {
>  	struct acpi_root_bridge *bridge;
> @@ -840,6 +901,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);
> 

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 10/22] ACPI: Introduce a new acpi handle to determine HID match.
  2013-01-11 22:40 ` [PATCH v8 10/22] ACPI: Introduce a new acpi handle to determine HID match Yinghai Lu
@ 2013-01-12 23:27   ` Rafael J. Wysocki
  0 siblings, 0 replies; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 23:27 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi, Tang Chen

On Friday, January 11, 2013 02:40:37 PM Yinghai Lu wrote:
> From: Tang Chen <tangchen@cn.fujitsu.com>
> 
> We need to find out if one handle is for root bridge, and install notify
> handler for it to handle pci root bus hot add.
> At that time, root bridge acpi device is not created yet.
> 
> So acpi_match_device_ids() will not work.
> 
> This patch add a function to check if new acpi handle's HID matches a list
> of IDs.  The new api use acpi_device_info instead acpi_device.
> 
> -v2: updated changelog, also check length for string info...
>      change checking sequence by moving string comaring close to for loop.
> 					- Yinghai
> -v3: change to _GPL according to Rafael

Please fold this into [11/22].  Otherwise one has to look at these two patches
at the same time to understand how the code is supposed to work, which is less
than useful.

Thanks,
Rafael


> Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Cc: Len Brown <lenb@kernel.org>
> Cc: linux-acpi@vger.kernel.org
> ---
>  drivers/acpi/scan.c     |   33 +++++++++++++++++++++++++++++++++
>  include/acpi/acpi_bus.h |    2 ++
>  2 files changed, 35 insertions(+)
> 
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index db7664e..8883539 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -470,6 +470,39 @@ int acpi_match_device_ids(struct acpi_device *device,
>  }
>  EXPORT_SYMBOL(acpi_match_device_ids);
>  
> +int acpi_match_object_info_ids(struct acpi_device_info *info,
> +			       const struct acpi_device_id *ids)
> +{
> +	const struct acpi_device_id *id;
> +	char *str;
> +	u32 len;
> +	int i;
> +
> +	len = info->hardware_id.length;
> +	if (len) {
> +		str = info->hardware_id.string;
> +		if (str)
> +			for (id = ids; id->id[0]; id++)
> +				if (!strcmp((char *)id->id, str))
> +					return 0;
> +	}
> +
> +	for (i = 0; i < info->compatible_id_list.count; i++) {
> +		len = info->compatible_id_list.ids[i].length;
> +		if (!len)
> +			continue;
> +		str = info->compatible_id_list.ids[i].string;
> +		if (!str)
> +			continue;
> +		for (id = ids; id->id[0]; id++)
> +			if (!strcmp((char *)id->id, str))
> +				return 0;
> +	}
> +
> +	return -ENOENT;
> +}
> +EXPORT_SYMBOL_GPL(acpi_match_object_info_ids);
> +
>  static void acpi_free_ids(struct acpi_device *device)
>  {
>  	struct acpi_hardware_id *id, *tmp;
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index a9e1421..2246ba9 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -355,6 +355,8 @@ int acpi_bus_trim(struct acpi_device *start, int rmdevice);
>  acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
>  int acpi_match_device_ids(struct acpi_device *device,
>  			  const struct acpi_device_id *ids);
> +int acpi_match_object_info_ids(struct acpi_device_info *info,
> +			       const struct acpi_device_id *ids);
>  int acpi_create_dir(struct acpi_device *);
>  void acpi_remove_dir(struct acpi_device *);
>  
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 11/22] PCI: correctly detect ACPI PCI host bridge objects
  2013-01-11 22:40 ` [PATCH v8 11/22] PCI: correctly detect ACPI PCI host bridge objects Yinghai Lu
@ 2013-01-12 23:34   ` Rafael J. Wysocki
  2013-01-13 15:32     ` Jiang Liu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 23:34 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:38 PM Yinghai Lu wrote:
> From: Jiang Liu <jiang.liu@huawei.com>
> 
> The code in pci_root_hp.c depends on function acpi_is_root_bridge()
> to check whether an ACPI object is a PCI host bridge or not.
> If an ACPI device hasn't been created for the ACPI object yet,
> function acpi_is_root_bridge() will return false even if the object
> is a PCI host bridge object. That behavior will cause two issues:
> 1) No ACPI notification handler installed for PCI host bridges absent
>    at startup, so hotplug events for those bridges won't be handled.
> 2) rescan_root_bridge() can't reenumerate offlined PCI host bridges
>    because the ACPI devices have been already destroyed.
> 
> So use acpi_match_object_info_ids() to correctly detect PCI host bridges.
> 
> -v2: update to use acpi_match_object_info_ids() from Tang Chen  - Yinghai
> -v3: drop the PNP0A008, according to Bjorn.
> 
> Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
> 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 |   19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> index 5ae36d8..d30fb94 100644
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -923,6 +923,23 @@ static void handle_hotplug_event_root(acpi_handle handle, u32 type,
>  				_handle_hotplug_event_root);
>  }
>  
> +static bool acpi_is_root_bridge_object(acpi_handle handle)
> +{
> +	struct acpi_device_info *info = NULL;
> +	acpi_status status;
> +	bool ret;
> +
> +	status = acpi_get_object_info(handle, &info);
> +	if (ACPI_FAILURE(status))
> +		return false;
> +
> +	ret = !acpi_match_object_info_ids(info, root_device_ids);
> +

Well, I kind of don't understand why don't we check info->flags
against ACPI_PCI_ROOT_BRIDGE that acpi_get_object_info() sets for us if it
finds a PCI root bridge?

> +	kfree(info);
> +
> +	return ret;
> +}
> +
>  static acpi_status __init
>  find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
>  {
> @@ -931,7 +948,7 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
>  				      .pointer = objname };
>  	int *count = (int *)context;
>  
> -	if (!acpi_is_root_bridge(handle))
> +	if (!acpi_is_root_bridge_object(handle))
>  		return AE_OK;
>  
>  	(*count)++;
> 

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 12/22] PCI, ACPI: debug print for installation of acpi root bridge's notifier
  2013-01-11 22:40 ` [PATCH v8 12/22] PCI, ACPI: debug print for installation of acpi root bridge's notifier Yinghai Lu
@ 2013-01-12 23:37   ` Rafael J. Wysocki
  0 siblings, 0 replies; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 23:37 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi, Tang Chen

On Friday, January 11, 2013 02:40:39 PM Yinghai Lu wrote:
> From: Tang Chen <tangchen@cn.fujitsu.com>
> 
> acpi_install_notify_handler() could fail. So check the exit status
> and give a better debug info.
> 
> Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/acpi/pci_root.c |   12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> index d30fb94..862abcc 100644
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -943,6 +943,7 @@ static bool acpi_is_root_bridge_object(acpi_handle handle)
>  static acpi_status __init
>  find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
>  {
> +	acpi_status status;
>  	char objname[64];
>  	struct acpi_buffer buffer = { .length = sizeof(objname),
>  				      .pointer = objname };
> @@ -955,9 +956,14 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
>  
>  	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);
> +	status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
> +					handle_hotplug_event_root, NULL);
> +	if (ACPI_FAILURE(status))
> +		printk(KERN_DEBUG "acpi root: %s notify handler is not installed, exit status: %u\n",
> +				  objname, (unsigned int)status);

If we print a message on failure, I don't think we need one on success.

Besides, please use pr_debug().

> +	else
> +		printk(KERN_DEBUG "acpi root: %s notify handler is installed\n",
> +				 objname);
>  
>  	add_acpi_root_bridge(handle);

And I wonder what sens does this make to call add_acpi_root_bridge() here if we
haven't installed the notify handler for handle?

Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 13/22] PCI, ACPI: remove acpi_root_bridge in pci_root_hp
  2013-01-11 22:40 ` [PATCH v8 13/22] PCI, ACPI: remove acpi_root_bridge in pci_root_hp Yinghai Lu
@ 2013-01-12 23:39   ` Rafael J. Wysocki
  0 siblings, 0 replies; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 23:39 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:40 PM Yinghai Lu wrote:
> Tang noticed that hotplug through container will not update acpi_root_bridge
> list.
> 
> After closely checking, we don't need that for struct for tracking and
> could use acpi_pci_root directly.

Well, precisely, so please modify your patches [08-09/22] accordingly instead
of adding this one.

Thanks,
Rafael


> Reported-by: Tang Chen <tangchen@cn.fujitsu.com>
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/acpi/pci_root.c |  109 +++++++++--------------------------------------
>  1 file changed, 20 insertions(+), 89 deletions(-)
> 
> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> index 862abcc..697ec65 100644
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -679,73 +679,12 @@ int __init acpi_pci_root_init(void)
>   *	only support root bridge
>   */
>  
> -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);
> -}
> -
> -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;
> @@ -827,28 +766,25 @@ static int acpi_root_evaluate_object(acpi_handle handle, char *cmd, int val)
>  	return 0;
>  }
>  
> -static void handle_root_bridge_removal(acpi_handle handle,
> -		 struct acpi_root_bridge *bridge)
> +static void handle_root_bridge_removal(struct acpi_device *device)
>  {
> +	int ret_val;
>  	u32 flags = 0;
> -	struct acpi_device *device;
> +	acpi_handle dummy_handle;
> +	acpi_handle handle = device->handle;
>  
> -	if (bridge) {
> -		flags = bridge->flags;
> -		remove_acpi_root_bridge(bridge);
> -	}
> +	if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &dummy_handle)))
> +		flags |= ROOT_BRIDGE_HAS_EJ0;
> +	if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &dummy_handle)))
> +		flags |= ROOT_BRIDGE_HAS_PS3;
>  
> -	if (!acpi_bus_get_device(handle, &device)) {
> -		int ret_val;
> +	/* remove pci devices at first */
> +	ret_val = acpi_bus_trim(device, 0);
> +	printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
>  
> -		/* remove pci devices at first */
> -		ret_val = acpi_bus_trim(device, 0);
> -		printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
> -
> -		/* remove acpi devices */
> -		ret_val = acpi_bus_trim(device, 1);
> -		printk(KERN_DEBUG "acpi_bus_trim remove return %x\n", ret_val);
> -	}
> +	/* remove acpi devices */
> +	ret_val = acpi_bus_trim(device, 1);
> +	printk(KERN_DEBUG "acpi_bus_trim remove return %x\n", ret_val);
>  
>  	if (flags & ROOT_BRIDGE_HAS_PS3) {
>  		acpi_status status;
> @@ -863,7 +799,7 @@ static void handle_root_bridge_removal(acpi_handle handle,
>  
>  static void _handle_hotplug_event_root(struct work_struct *work)
>  {
> -	struct acpi_root_bridge *bridge;
> +	struct acpi_pci_root *root;
>  	char objname[64];
>  	struct acpi_buffer buffer = { .length = sizeof(objname),
>  				      .pointer = objname };
> @@ -875,7 +811,7 @@ static void _handle_hotplug_event_root(struct work_struct *work)
>  	handle = hp_work->handle;
>  	type = hp_work->type;
>  
> -	bridge = acpi_root_handle_to_bridge(handle);
> +	root = acpi_pci_find_root(handle);
>  
>  	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
>  
> @@ -884,10 +820,8 @@ static void _handle_hotplug_event_root(struct work_struct *work)
>  		/* bus enumerate */
>  		printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__,
>  				 objname);
> -		if (!bridge) {
> +		if (!root)
>  			handle_root_bridge_insertion(handle);
> -			add_acpi_root_bridge(handle);
> -		}
>  
>  		break;
>  
> @@ -895,17 +829,16 @@ static void _handle_hotplug_event_root(struct work_struct *work)
>  		/* device check */
>  		printk(KERN_DEBUG "%s: Device check notify on %s\n", __func__,
>  				 objname);
> -		if (!bridge) {
> +		if (!root)
>  			handle_root_bridge_insertion(handle);
> -			add_acpi_root_bridge(handle);
> -		}
>  		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);
> +		if (root)
> +			handle_root_bridge_removal(root->device);
>  		break;
>  	default:
>  		printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n",
> @@ -965,8 +898,6 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
>  		printk(KERN_DEBUG "acpi root: %s notify handler is installed\n",
>  				 objname);
>  
> -	add_acpi_root_bridge(handle);
> -
>  	return AE_OK;
>  }
>  
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 14/22] ACPI: update ej_event interface to take acpi_device
  2013-01-11 22:40 ` [PATCH v8 14/22] ACPI: update ej_event interface to take acpi_device Yinghai Lu
@ 2013-01-12 23:40   ` Rafael J. Wysocki
  2013-01-15  6:55     ` Yinghai Lu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 23:40 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:41 PM Yinghai Lu wrote:
> Should use acpi_device pointer directly instead of use handle and
> get the device pointer again later.

Looks good.

I can take this one right now if you want.

Thanks,
Rafael


> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/acpi/acpi_memhotplug.c  |    2 +-
>  drivers/acpi/processor_driver.c |    2 +-
>  drivers/acpi/scan.c             |   14 ++++----------
>  include/acpi/acpi_bus.h         |    2 +-
>  4 files changed, 7 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
> index 327ab44..eaddb7a 100644
> --- a/drivers/acpi/acpi_memhotplug.c
> +++ b/drivers/acpi/acpi_memhotplug.c
> @@ -361,7 +361,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
>  			break;
>  		}
>  
> -		ej_event->handle = handle;
> +		ej_event->device = device;
>  		ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
>  		acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
>  					(void *)ej_event);
> diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
> index 0777663..a24ee43 100644
> --- a/drivers/acpi/processor_driver.c
> +++ b/drivers/acpi/processor_driver.c
> @@ -733,7 +733,7 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
>  			break;
>  		}
>  
> -		ej_event->handle = handle;
> +		ej_event->device = device;
>  		ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
>  		acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
>  					(void *)ej_event);
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index 8883539..f4c6305 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -116,20 +116,14 @@ static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
>  void acpi_bus_hot_remove_device(void *context)
>  {
>  	struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context;
> -	struct acpi_device *device;
> -	acpi_handle handle = ej_event->handle;
> +	struct acpi_device *device = ej_event->device;
> +	acpi_handle handle = device->handle;
>  	acpi_handle temp;
>  	struct acpi_object_list arg_list;
>  	union acpi_object arg;
>  	acpi_status status = AE_OK;
>  	u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
>  
> -	if (acpi_bus_get_device(handle, &device))
> -		goto err_out;
> -
> -	if (!device)
> -		goto err_out;
> -
>  	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
>  		"Hot-removing device %s...\n", dev_name(&device->dev)));
>  
> @@ -215,7 +209,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
>  		goto err;
>  	}
>  
> -	ej_event->handle = acpi_device->handle;
> +	ej_event->device = acpi_device;
>  	if (acpi_device->flags.eject_pending) {
>  		/* event originated from ACPI eject notification */
>  		ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
> @@ -223,7 +217,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
>  	} else {
>  		/* event originated from user */
>  		ej_event->event = ACPI_OST_EC_OSPM_EJECT;
> -		(void) acpi_evaluate_hotplug_ost(ej_event->handle,
> +		(void) acpi_evaluate_hotplug_ost(acpi_device->handle,
>  			ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
>  	}
>  
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index 2246ba9..181ff2d 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -309,7 +309,7 @@ struct acpi_bus_event {
>  };
>  
>  struct acpi_eject_event {
> -	acpi_handle	handle;
> +	struct acpi_device	*device;
>  	u32		event;
>  };
>  
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 15/22] ACPI, PCI: Simplify handle_root_bridge_removal()
  2013-01-11 22:40 ` [PATCH v8 15/22] ACPI, PCI: Simplify handle_root_bridge_removal() Yinghai Lu
@ 2013-01-12 23:42   ` Rafael J. Wysocki
  0 siblings, 0 replies; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 23:42 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:42 PM Yinghai Lu wrote:
> Tang Chen found handle_root_bridge_removal is very similiar to
> acpi_bus_hot_remove_device().
> Only difference is that it call trim two times.
> 
> Change to handle_root_bridge_removal to call trim one time and then
> use acpi_bus_hot_remove_device.

Please fold these changes into your previous patches instead of adding a new
one to modify them.

Thanks,
Rafael


> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/acpi/pci_root.c |   49 ++++++++---------------------------------------
>  1 file changed, 8 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> index 697ec65..8a0e2e2 100644
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -745,56 +745,23 @@ static void handle_root_bridge_insertion(acpi_handle handle)
>  		printk(KERN_ERR "cannot add bridge to acpi list\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)) {
> -		pr_warn("%s: %s to %d failed\n",
> -				 __func__, cmd, val);
> -		return -1;
> -	}
> -
> -	return 0;
> -}
> -
>  static void handle_root_bridge_removal(struct acpi_device *device)
>  {
>  	int ret_val;
> -	u32 flags = 0;
> -	acpi_handle dummy_handle;
> -	acpi_handle handle = device->handle;
> +	struct acpi_eject_event *ej_event;
> +
> +	ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
> +	if (!ej_event)
> +		return;
>  
> -	if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &dummy_handle)))
> -		flags |= ROOT_BRIDGE_HAS_EJ0;
> -	if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &dummy_handle)))
> -		flags |= ROOT_BRIDGE_HAS_PS3;
> +	ej_event->device = device;
> +	ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
>  
>  	/* remove pci devices at first */
>  	ret_val = acpi_bus_trim(device, 0);
>  	printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
>  
> -	/* remove acpi devices */
> -	ret_val = acpi_bus_trim(device, 1);
> -	printk(KERN_DEBUG "acpi_bus_trim remove 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))
> -			pr_warn("%s: _PS3 failed\n", __func__);
> -	}
> -	if (flags & ROOT_BRIDGE_HAS_EJ0)
> -		acpi_root_evaluate_object(handle, "_EJ0", 1);
> +	acpi_bus_hot_remove_device(ej_event);
>  }
>  
>  static void _handle_hotplug_event_root(struct work_struct *work)
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 16/22] PCI, acpiphp: Don't bailout even no slots found yet.
  2013-01-11 22:40 ` [PATCH v8 16/22] PCI, acpiphp: Don't bailout even no slots found yet Yinghai Lu
@ 2013-01-12 23:43   ` Rafael J. Wysocki
  0 siblings, 0 replies; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 23:43 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:43 PM Yinghai Lu wrote:
> Could have root bus hot addde later and there may be slots that need acpiphp.

s/addde/added/

The changes look reasonable to me, but I'm not very familiar with the code in
question.

Thanks,
Rafael


> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/pci/hotplug/acpiphp.h      |    1 -
>  drivers/pci/hotplug/acpiphp_core.c |   23 ++---------------------
>  drivers/pci/hotplug/acpiphp_glue.c |   22 ----------------------
>  3 files changed, 2 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
> index a1afb5b..b3ead7a 100644
> --- a/drivers/pci/hotplug/acpiphp.h
> +++ b/drivers/pci/hotplug/acpiphp.h
> @@ -193,7 +193,6 @@ extern void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot);
>  /* acpiphp_glue.c */
>  extern int acpiphp_glue_init (void);
>  extern void acpiphp_glue_exit (void);
> -extern int acpiphp_get_num_slots (void);
>  typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
>  
>  extern int acpiphp_enable_slot (struct acpiphp_slot *slot);
> diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
> index 96316b7..c2fd309 100644
> --- a/drivers/pci/hotplug/acpiphp_core.c
> +++ b/drivers/pci/hotplug/acpiphp_core.c
> @@ -50,7 +50,6 @@
>  bool acpiphp_debug;
>  
>  /* local variables */
> -static int num_slots;
>  static struct acpiphp_attention_info *attention_info;
>  
>  #define DRIVER_VERSION	"0.5"
> @@ -272,25 +271,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
>  	return 0;
>  }
>  
> -static int __init init_acpi(void)
> -{
> -	int retval;
> -
> -	/* initialize internal data structure etc. */
> -	retval = acpiphp_glue_init();
> -
> -	/* read initial number of slots */
> -	if (!retval) {
> -		num_slots = acpiphp_get_num_slots();
> -		if (num_slots == 0) {
> -			acpiphp_glue_exit();
> -			retval = -ENODEV;
> -		}
> -	}
> -
> -	return retval;
> -}
> -
>  /**
>   * release_slot - free up the memory used by a slot
>   * @hotplug_slot: slot to free
> @@ -379,7 +359,8 @@ static int __init acpiphp_init(void)
>  		return 0;
>  
>  	/* read all the ACPI info from the system */
> -	return init_acpi();
> +	/* initialize internal data structure etc. */
> +	return acpiphp_glue_init();
>  }
>  
>  
> diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
> index 02c41ab..30467ec 100644
> --- a/drivers/pci/hotplug/acpiphp_glue.c
> +++ b/drivers/pci/hotplug/acpiphp_glue.c
> @@ -1446,28 +1446,6 @@ void  acpiphp_glue_exit(void)
>  	acpi_pci_unregister_driver(&acpi_pci_hp_driver);
>  }
>  
> -
> -/**
> - * acpiphp_get_num_slots - count number of slots in a system
> - */
> -int __init acpiphp_get_num_slots(void)
> -{
> -	struct acpiphp_bridge *bridge;
> -	int num_slots = 0;
> -
> -	list_for_each_entry(bridge, &bridge_list, list) {
> -		dbg("Bus %04x:%02x has %d slot%s\n",
> -				pci_domain_nr(bridge->pci_bus),
> -				bridge->pci_bus->number, bridge->nr_slots,
> -				bridge->nr_slots == 1 ? "" : "s");
> -		num_slots += bridge->nr_slots;
> -	}
> -
> -	dbg("Total %d slots\n", num_slots);
> -	return num_slots;
> -}
> -
> -
>  /**
>   * acpiphp_enable_slot - power on slot
>   * @slot: ACPI PHP slot
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 17/22] PCI, ACPI: Add alloc_acpi_hp_work()
  2013-01-11 22:40 ` [PATCH v8 17/22] PCI, ACPI: Add alloc_acpi_hp_work() Yinghai Lu
@ 2013-01-12 23:45   ` Rafael J. Wysocki
  2013-01-15  6:59     ` Yinghai Lu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 23:45 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:44 PM Yinghai Lu wrote:
> Will use it with acpiphp and pci_root_hp events handling

I think it would be better if you folded patches [17-20/22] together.

Thanks,
Rafael


> 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(+)
> 
> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> index 3ff2678..e6539a3 100644
> --- a/drivers/acpi/osl.c
> +++ b/drivers/acpi/osl.c
> @@ -1778,3 +1778,24 @@ void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
>  {
>  	__acpi_os_prepare_sleep = func;
>  }
> +
> +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 4315274..2a64da5 100644
> --- a/include/acpi/acpiosxf.h
> +++ b/include/acpi/acpiosxf.h
> @@ -195,6 +195,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
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 21/22] PCI: add match_driver in struct pci_dev
  2013-01-11 22:40 ` [PATCH v8 21/22] PCI: add match_driver in struct pci_dev Yinghai Lu
@ 2013-01-12 23:49   ` Rafael J. Wysocki
  2013-01-13 15:40     ` Jiang Liu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 23:49 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:48 PM Yinghai Lu wrote:
> with that we could move out attaching driver for pci device,
> out of device_add for pci hot add path.
> 
> pci_bus_attach_device() will attach driver to pci device.

Clever, but I wonder why exactly we need to do that?

Rafael


> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/pci/bus.c        |   10 ++++++++++
>  drivers/pci/pci-driver.c |    6 +++++-
>  include/linux/pci.h      |    1 +
>  3 files changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
> index 5f9c728..1f5916a 100644
> --- a/drivers/pci/bus.c
> +++ b/drivers/pci/bus.c
> @@ -160,6 +160,15 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
>  
>  void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { }
>  
> +static void pci_bus_attach_device(struct pci_dev *dev)
> +{
> +	int ret;
> +
> +	dev->match_driver = true;
> +	ret = device_attach(&dev->dev);
> +	WARN_ON(ret < 0);
> +}
> +
>  /**
>   * pci_bus_add_device - add a single device
>   * @dev: device to add
> @@ -181,6 +190,7 @@ int pci_bus_add_device(struct pci_dev *dev)
>  	if (retval)
>  		return retval;
>  
> +	pci_bus_attach_device(dev);
>  	dev->is_added = 1;
>  	pci_proc_attach_device(dev);
>  	pci_create_sysfs_dev_files(dev);
> diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
> index f79cbcd..acdcc3c 100644
> --- a/drivers/pci/pci-driver.c
> +++ b/drivers/pci/pci-driver.c
> @@ -1186,9 +1186,13 @@ pci_dev_driver(const struct pci_dev *dev)
>  static int pci_bus_match(struct device *dev, struct device_driver *drv)
>  {
>  	struct pci_dev *pci_dev = to_pci_dev(dev);
> -	struct pci_driver *pci_drv = to_pci_driver(drv);
> +	struct pci_driver *pci_drv;
>  	const struct pci_device_id *found_id;
>  
> +	if (!pci_dev->match_driver)
> +		return 0;
> +
> +	pci_drv = to_pci_driver(drv);
>  	found_id = pci_match_device(pci_drv, pci_dev);
>  	if (found_id)
>  		return 1;
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 907b455..d73af08 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -286,6 +286,7 @@ struct pci_dev {
>  	unsigned int	irq;
>  	struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
>  
> +	bool match_driver;
>  	/* These fields are used by common fixups */
>  	unsigned int	transparent:1;	/* Transparent PCI bridge */
>  	unsigned int	multifunction:1;/* Part of multi-function device */
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 22/22] PCI: move device_add out of pci_bus_add_device()
  2013-01-11 22:40 ` [PATCH v8 22/22] PCI: move device_add out of pci_bus_add_device() Yinghai Lu
@ 2013-01-12 23:54   ` Rafael J. Wysocki
  2013-01-15  7:10     ` Yinghai Lu
  2013-01-16  2:29   ` Yijing Wang
  1 sibling, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-12 23:54 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Friday, January 11, 2013 02:40:49 PM Yinghai Lu wrote:
> Move out device registering out of pci_bus_add_devices, so we could
> put new created pci devices in device tree early.
> 
> new pci_bus_add_devices will do the device_attach work to load pci drivers
> instead.

I wonder what problem it solves?

> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/pci/bus.c   |   47 +++--------------------------------------------
>  drivers/pci/iov.c   |    7 -------
>  drivers/pci/probe.c |   34 +++++++++++++++++++++++++++-------
>  3 files changed, 30 insertions(+), 58 deletions(-)
> 
> diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
> index 1f5916a..0a55845 100644
> --- a/drivers/pci/bus.c
> +++ b/drivers/pci/bus.c
> @@ -178,22 +178,9 @@ static void pci_bus_attach_device(struct pci_dev *dev)
>   */
>  int pci_bus_add_device(struct pci_dev *dev)
>  {
> -	int retval;
> -
> -	pci_fixup_device(pci_fixup_final, dev);
> -
> -	retval = pcibios_add_device(dev);
> -	if (retval)
> -		return retval;
> -
> -	retval = device_add(&dev->dev);
> -	if (retval)
> -		return retval;
> -
>  	pci_bus_attach_device(dev);
>  	dev->is_added = 1;
> -	pci_proc_attach_device(dev);
> -	pci_create_sysfs_dev_files(dev);
> +
>  	return 0;
>  }
>  
> @@ -205,21 +192,9 @@ int pci_bus_add_device(struct pci_dev *dev)
>   */
>  int pci_bus_add_child(struct pci_bus *bus)
>  {
> -	int retval;
> -
> -	if (bus->bridge)
> -		bus->dev.parent = bus->bridge;
> -
> -	retval = device_add(&bus->dev);
> -	if (retval)
> -		return retval;
> -
>  	bus->is_added = 1;
>  
> -	/* Create legacy_io and legacy_mem files for this bus */
> -	pci_create_legacy_files(bus);
> -
> -	return retval;
> +	return 0;
>  }
>  
>  /**
> @@ -245,36 +220,20 @@ void pci_bus_add_devices(const struct pci_bus *bus)
>  		if (dev->is_added)
>  			continue;
>  		retval = pci_bus_add_device(dev);
> -		if (retval)
> -			dev_err(&dev->dev, "Error adding device, continuing\n");
>  	}
>  
>  	list_for_each_entry(dev, &bus->devices, bus_list) {
>  		BUG_ON(!dev->is_added);
>  
>  		child = dev->subordinate;
> -		/*
> -		 * If there is an unattached subordinate bus, attach
> -		 * it and then scan for unattached PCI devices.
> -		 */
> +
>  		if (!child)
>  			continue;
> -		if (list_empty(&child->node)) {
> -			down_write(&pci_bus_sem);
> -			list_add_tail(&child->node, &dev->bus->children);
> -			up_write(&pci_bus_sem);
> -		}
>  		pci_bus_add_devices(child);
>  
> -		/*
> -		 * register the bus with sysfs as the parent is now
> -		 * properly registered.
> -		 */
>  		if (child->is_added)
>  			continue;
>  		retval = pci_bus_add_child(child);
> -		if (retval)
> -			dev_err(&dev->dev, "Error adding bus, continuing\n");
>  	}
>  }
>  
> diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
> index bafd2bb..dbad72e 100644
> --- a/drivers/pci/iov.c
> +++ b/drivers/pci/iov.c
> @@ -48,12 +48,7 @@ static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
>  		return NULL;
>  
>  	pci_bus_insert_busn_res(child, busnr, busnr);
> -	child->dev.parent = bus->bridge;
>  	rc = pci_bus_add_child(child);
> -	if (rc) {
> -		pci_remove_bus(child);
> -		return NULL;
> -	}
>  
>  	return child;
>  }
> @@ -123,8 +118,6 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
>  	virtfn->is_virtfn = 1;
>  
>  	rc = pci_bus_add_device(virtfn);
> -	if (rc)
> -		goto failed1;
>  	sprintf(buf, "virtfn%u", id);
>  	rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
>  	if (rc)
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index dc4fde3..84c92a0 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -623,6 +623,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
>  {
>  	struct pci_bus *child;
>  	int i;
> +	int ret;
>  
>  	/*
>  	 * Allocate a new bus, and inherit stuff from the parent..
> @@ -637,8 +638,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
>  	child->bus_flags = parent->bus_flags;
>  
>  	/* initialize some portions of the bus device, but don't register it
> -	 * now as the parent is not properly set up yet.  This device will get
> -	 * registered later in pci_bus_add_devices()
> +	 * now as the parent is not properly set up yet.
>  	 */
>  	child->dev.class = &pcibus_class;
>  	dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr);
> @@ -652,11 +652,14 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
>  	child->primary = parent->busn_res.start;
>  	child->busn_res.end = 0xff;
>  
> -	if (!bridge)
> -		return child;
> +	if (!bridge) {
> +		child->dev.parent = parent->bridge;
> +		goto add_dev;
> +	}
>  
>  	child->self = bridge;
>  	child->bridge = get_device(&bridge->dev);
> +	child->dev.parent = child->bridge;
>  	pci_set_bus_of_node(child);
>  	pci_set_bus_speed(child);
>  
> @@ -667,6 +670,13 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
>  	}
>  	bridge->subordinate = child;
>  
> +add_dev:
> +	ret = device_add(&child->dev);
> +	WARN_ON(ret < 0);
> +
> +	/* Create legacy_io and legacy_mem files for this bus */
> +	pci_create_legacy_files(child);
> +
>  	return child;
>  }
>  
> @@ -1297,6 +1307,8 @@ static void pci_init_capabilities(struct pci_dev *dev)
>  
>  void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>  {
> +	int ret;
> +
>  	device_initialize(&dev->dev);
>  	dev->dev.release = pci_release_dev;
>  
> @@ -1327,6 +1339,16 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>  	down_write(&pci_bus_sem);
>  	list_add_tail(&dev->bus_list, &bus->devices);
>  	up_write(&pci_bus_sem);
> +
> +	pci_fixup_device(pci_fixup_final, dev);
> +        ret = pcibios_add_device(dev);

Broken whitespace?

> +	WARN_ON(ret < 0);
> +	/* notifier could use pci capabilities */
> +	ret = device_add(&dev->dev);
> +	WARN_ON(ret < 0);

These WARN_ON() things make me kind of nervous.

> +
> +	pci_proc_attach_device(dev);
> +	pci_create_sysfs_dev_files(dev);
>  }
>  
>  struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn)
> @@ -1645,13 +1667,13 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>  	char bus_addr[64];
>  	char *fmt;
>  
> -
>  	b = pci_alloc_bus();
>  	if (!b)
>  		return NULL;
>  
>  	b->sysdata = sysdata;
>  	b->ops = ops;
> +	b->number = b->busn_res.start = bus;
>  	b2 = pci_find_bus(pci_domain_nr(b), bus);
>  	if (b2) {
>  		/* If we already got to this bus through a different bridge, ignore it */
> @@ -1687,8 +1709,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>  	/* Create legacy_io and legacy_mem files for this bus */
>  	pci_create_legacy_files(b);
>  
> -	b->number = b->busn_res.start = bus;
> -
>  	if (parent)
>  		dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
>  	else
> 

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 06/22] PCI: split registration of PCI bus devices into two stages
  2013-01-12 22:34   ` Rafael J. Wysocki
@ 2013-01-13 15:25     ` Jiang Liu
  2013-01-15  6:29       ` Yinghai Lu
  0 siblings, 1 reply; 78+ messages in thread
From: Jiang Liu @ 2013-01-13 15:25 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Yinghai Lu, Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu,
	linux-pci, linux-kernel, linux-acpi

On 01/13/2013 06:34 AM, Rafael J. Wysocki wrote:
> On Friday, January 11, 2013 02:40:33 PM Yinghai Lu wrote:
>> From: Jiang Liu <jiang.liu@huawei.com>
>>
>> When handling BUS_NOTIFY_ADD_DEVICE event for a PCI bridge device,
>> the notification handler can't hold reference count to the new PCI bus
>> because the device object for the new bus (pci_dev->subordinate->dev)
>> hasn't been initialized yet.
> 
> It doesn't look like BUS_NOTIFY_ADD_DEVICE is used by the PCI bus type
> in the mainline.
> 
> Is it in linux-next?
> 
> If not, then I don't see why we need this patch.
Hi Rafael,
	Originally it's a preparation patch for pci_slot/acpiphp/pci_bind
related fixups. With recent work from you to remove bind/unbind from struct
acpi_bus_type, we have no dependency on this patch anymore.
Regards!
Gerry

> 
> Thanks,
> Rafael
> 
> 
>> Split the registration of PCI bus device into two stages as below,
>> so that the event handler could hold reference count to the new PCI bus
>> when handling BUS_NOTIFY_ADD_DEVICE event.
>>
>> 1) device_initialize(&pci_dev->dev)
>> 2) device_initialize(&pci_dev->subordinate->dev)
>> 3) notify BUS_NOTIFY_ADD_DEVICE event for pci_dev
>> 4) device_add(&pci_dev->dev)
>> 5) device_add(&pci_dev->subordinate->dev)
>>
>> Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
>> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>> ---
>>  drivers/pci/bus.c    |    2 +-
>>  drivers/pci/probe.c  |    4 +++-
>>  drivers/pci/remove.c |   10 +++++-----
>>  3 files changed, 9 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
>> index 847f3ca..5f9c728 100644
>> --- a/drivers/pci/bus.c
>> +++ b/drivers/pci/bus.c
>> @@ -200,7 +200,7 @@ int pci_bus_add_child(struct pci_bus *bus)
>>  	if (bus->bridge)
>>  		bus->dev.parent = bus->bridge;
>>  
>> -	retval = device_register(&bus->dev);
>> +	retval = device_add(&bus->dev);
>>  	if (retval)
>>  		return retval;
>>  
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index 48b35e1..dc4fde3 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -642,6 +642,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
>>  	 */
>>  	child->dev.class = &pcibus_class;
>>  	dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr);
>> +	device_initialize(&child->dev);
>>  
>>  	/*
>>  	 * Set up the primary, secondary and subordinate
>> @@ -1678,7 +1679,8 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>>  	b->dev.class = &pcibus_class;
>>  	b->dev.parent = b->bridge;
>>  	dev_set_name(&b->dev, "%04x:%02x", pci_domain_nr(b), bus);
>> -	error = device_register(&b->dev);
>> +	device_initialize(&b->dev);
>> +	error = device_add(&b->dev);
>>  	if (error)
>>  		goto class_dev_reg_err;
>>  
>> diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
>> index fc38c48..a1fdd0f 100644
>> --- a/drivers/pci/remove.c
>> +++ b/drivers/pci/remove.c
>> @@ -48,11 +48,11 @@ void pci_remove_bus(struct pci_bus *bus)
>>  	list_del(&bus->node);
>>  	pci_bus_release_busn_res(bus);
>>  	up_write(&pci_bus_sem);
>> -	if (!bus->is_added)
>> -		return;
>> -
>> -	pci_remove_legacy_files(bus);
>> -	device_unregister(&bus->dev);
>> +	if (bus->is_added) {
>> +		pci_remove_legacy_files(bus);
>> +		device_del(&bus->dev);
>> +	}
>> +	put_device(&bus->dev);
>>  }
>>  EXPORT_SYMBOL(pci_remove_bus);
>>  
>>


^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 11/22] PCI: correctly detect ACPI PCI host bridge objects
  2013-01-12 23:34   ` Rafael J. Wysocki
@ 2013-01-13 15:32     ` Jiang Liu
  0 siblings, 0 replies; 78+ messages in thread
From: Jiang Liu @ 2013-01-13 15:32 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Yinghai Lu, Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu,
	linux-pci, linux-kernel, linux-acpi

On 01/13/2013 07:34 AM, Rafael J. Wysocki wrote:
> On Friday, January 11, 2013 02:40:38 PM Yinghai Lu wrote:
>> From: Jiang Liu <jiang.liu@huawei.com>
>>
>> The code in pci_root_hp.c depends on function acpi_is_root_bridge()
>> to check whether an ACPI object is a PCI host bridge or not.
>> If an ACPI device hasn't been created for the ACPI object yet,
>> function acpi_is_root_bridge() will return false even if the object
>> is a PCI host bridge object. That behavior will cause two issues:
>> 1) No ACPI notification handler installed for PCI host bridges absent
>>    at startup, so hotplug events for those bridges won't be handled.
>> 2) rescan_root_bridge() can't reenumerate offlined PCI host bridges
>>    because the ACPI devices have been already destroyed.
>>
>> So use acpi_match_object_info_ids() to correctly detect PCI host bridges.
>>
>> -v2: update to use acpi_match_object_info_ids() from Tang Chen  - Yinghai
>> -v3: drop the PNP0A008, according to Bjorn.
>>
>> Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
>> 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 |   19 ++++++++++++++++++-
>>  1 file changed, 18 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
>> index 5ae36d8..d30fb94 100644
>> --- a/drivers/acpi/pci_root.c
>> +++ b/drivers/acpi/pci_root.c
>> @@ -923,6 +923,23 @@ static void handle_hotplug_event_root(acpi_handle handle, u32 type,
>>  				_handle_hotplug_event_root);
>>  }
>>  
>> +static bool acpi_is_root_bridge_object(acpi_handle handle)
>> +{
>> +	struct acpi_device_info *info = NULL;
>> +	acpi_status status;
>> +	bool ret;
>> +
>> +	status = acpi_get_object_info(handle, &info);
>> +	if (ACPI_FAILURE(status))
>> +		return false;
>> +
>> +	ret = !acpi_match_object_info_ids(info, root_device_ids);
>> +
> 
> Well, I kind of don't understand why don't we check info->flags
> against ACPI_PCI_ROOT_BRIDGE that acpi_get_object_info() sets for us if it
> finds a PCI root bridge?
Hi Rafael,
	Thanks for reminder, we should test ACPI_PCI_ROOT_BRIDGE flag
instead of a redundant calling to acpi_match_object_info_ids(). To be honest,
I don't know the existence of ACPI_PCI_ROOT_BRIDGE flag before:(

> 
>> +	kfree(info);
>> +
>> +	return ret;
>> +}
>> +
>>  static acpi_status __init
>>  find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
>>  {
>> @@ -931,7 +948,7 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
>>  				      .pointer = objname };
>>  	int *count = (int *)context;
>>  
>> -	if (!acpi_is_root_bridge(handle))
>> +	if (!acpi_is_root_bridge_object(handle))
>>  		return AE_OK;
>>  
>>  	(*count)++;
>>
> 
> Thanks,
> Rafael
> 
> 


^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 21/22] PCI: add match_driver in struct pci_dev
  2013-01-12 23:49   ` Rafael J. Wysocki
@ 2013-01-13 15:40     ` Jiang Liu
  2013-01-13 20:01       ` Rafael J. Wysocki
  0 siblings, 1 reply; 78+ messages in thread
From: Jiang Liu @ 2013-01-13 15:40 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Yinghai Lu, Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu,
	linux-pci, linux-kernel, linux-acpi

On 01/13/2013 07:49 AM, Rafael J. Wysocki wrote:
> On Friday, January 11, 2013 02:40:48 PM Yinghai Lu wrote:
>> with that we could move out attaching driver for pci device,
>> out of device_add for pci hot add path.
>>
>> pci_bus_attach_device() will attach driver to pci device.
> 
> Clever, but I wonder why exactly we need to do that?
Hi Rafael,
	To make following sequence possible,
1) Create PCI device objects for hot-added PCI host bridge
2) Create IOMMU devices for DMAR units belong to the hot-added PCI host bridge
3) Bind and start all PCI devices connected to the PCI host bridge.

Regards!
Gerry

> 
> Rafael
> 
> 
>> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>> ---
>>  drivers/pci/bus.c        |   10 ++++++++++
>>  drivers/pci/pci-driver.c |    6 +++++-
>>  include/linux/pci.h      |    1 +
>>  3 files changed, 16 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
>> index 5f9c728..1f5916a 100644
>> --- a/drivers/pci/bus.c
>> +++ b/drivers/pci/bus.c
>> @@ -160,6 +160,15 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
>>  
>>  void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { }
>>  
>> +static void pci_bus_attach_device(struct pci_dev *dev)
>> +{
>> +	int ret;
>> +
>> +	dev->match_driver = true;
>> +	ret = device_attach(&dev->dev);
>> +	WARN_ON(ret < 0);
>> +}
>> +
>>  /**
>>   * pci_bus_add_device - add a single device
>>   * @dev: device to add
>> @@ -181,6 +190,7 @@ int pci_bus_add_device(struct pci_dev *dev)
>>  	if (retval)
>>  		return retval;
>>  
>> +	pci_bus_attach_device(dev);
>>  	dev->is_added = 1;
>>  	pci_proc_attach_device(dev);
>>  	pci_create_sysfs_dev_files(dev);
>> diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
>> index f79cbcd..acdcc3c 100644
>> --- a/drivers/pci/pci-driver.c
>> +++ b/drivers/pci/pci-driver.c
>> @@ -1186,9 +1186,13 @@ pci_dev_driver(const struct pci_dev *dev)
>>  static int pci_bus_match(struct device *dev, struct device_driver *drv)
>>  {
>>  	struct pci_dev *pci_dev = to_pci_dev(dev);
>> -	struct pci_driver *pci_drv = to_pci_driver(drv);
>> +	struct pci_driver *pci_drv;
>>  	const struct pci_device_id *found_id;
>>  
>> +	if (!pci_dev->match_driver)
>> +		return 0;
>> +
>> +	pci_drv = to_pci_driver(drv);
>>  	found_id = pci_match_device(pci_drv, pci_dev);
>>  	if (found_id)
>>  		return 1;
>> diff --git a/include/linux/pci.h b/include/linux/pci.h
>> index 907b455..d73af08 100644
>> --- a/include/linux/pci.h
>> +++ b/include/linux/pci.h
>> @@ -286,6 +286,7 @@ struct pci_dev {
>>  	unsigned int	irq;
>>  	struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
>>  
>> +	bool match_driver;
>>  	/* These fields are used by common fixups */
>>  	unsigned int	transparent:1;	/* Transparent PCI bridge */
>>  	unsigned int	multifunction:1;/* Part of multi-function device */
>>


^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 21/22] PCI: add match_driver in struct pci_dev
  2013-01-13 15:40     ` Jiang Liu
@ 2013-01-13 20:01       ` Rafael J. Wysocki
  0 siblings, 0 replies; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-13 20:01 UTC (permalink / raw)
  To: Jiang Liu
  Cc: Yinghai Lu, Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu,
	linux-pci, linux-kernel, linux-acpi

On Sunday, January 13, 2013 11:40:12 PM Jiang Liu wrote:
> On 01/13/2013 07:49 AM, Rafael J. Wysocki wrote:
> > On Friday, January 11, 2013 02:40:48 PM Yinghai Lu wrote:
> >> with that we could move out attaching driver for pci device,
> >> out of device_add for pci hot add path.
> >>
> >> pci_bus_attach_device() will attach driver to pci device.
> > 
> > Clever, but I wonder why exactly we need to do that?
> Hi Rafael,
> 	To make following sequence possible,
> 1) Create PCI device objects for hot-added PCI host bridge
> 2) Create IOMMU devices for DMAR units belong to the hot-added PCI host bridge
> 3) Bind and start all PCI devices connected to the PCI host bridge.

OK, but why exactly isn't it possible without that change?

Rafael


> >> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> >> ---
> >>  drivers/pci/bus.c        |   10 ++++++++++
> >>  drivers/pci/pci-driver.c |    6 +++++-
> >>  include/linux/pci.h      |    1 +
> >>  3 files changed, 16 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
> >> index 5f9c728..1f5916a 100644
> >> --- a/drivers/pci/bus.c
> >> +++ b/drivers/pci/bus.c
> >> @@ -160,6 +160,15 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
> >>  
> >>  void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { }
> >>  
> >> +static void pci_bus_attach_device(struct pci_dev *dev)
> >> +{
> >> +	int ret;
> >> +
> >> +	dev->match_driver = true;
> >> +	ret = device_attach(&dev->dev);
> >> +	WARN_ON(ret < 0);
> >> +}
> >> +
> >>  /**
> >>   * pci_bus_add_device - add a single device
> >>   * @dev: device to add
> >> @@ -181,6 +190,7 @@ int pci_bus_add_device(struct pci_dev *dev)
> >>  	if (retval)
> >>  		return retval;
> >>  
> >> +	pci_bus_attach_device(dev);
> >>  	dev->is_added = 1;
> >>  	pci_proc_attach_device(dev);
> >>  	pci_create_sysfs_dev_files(dev);
> >> diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
> >> index f79cbcd..acdcc3c 100644
> >> --- a/drivers/pci/pci-driver.c
> >> +++ b/drivers/pci/pci-driver.c
> >> @@ -1186,9 +1186,13 @@ pci_dev_driver(const struct pci_dev *dev)
> >>  static int pci_bus_match(struct device *dev, struct device_driver *drv)
> >>  {
> >>  	struct pci_dev *pci_dev = to_pci_dev(dev);
> >> -	struct pci_driver *pci_drv = to_pci_driver(drv);
> >> +	struct pci_driver *pci_drv;
> >>  	const struct pci_device_id *found_id;
> >>  
> >> +	if (!pci_dev->match_driver)
> >> +		return 0;
> >> +
> >> +	pci_drv = to_pci_driver(drv);
> >>  	found_id = pci_match_device(pci_drv, pci_dev);
> >>  	if (found_id)
> >>  		return 1;
> >> diff --git a/include/linux/pci.h b/include/linux/pci.h
> >> index 907b455..d73af08 100644
> >> --- a/include/linux/pci.h
> >> +++ b/include/linux/pci.h
> >> @@ -286,6 +286,7 @@ struct pci_dev {
> >>  	unsigned int	irq;
> >>  	struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
> >>  
> >> +	bool match_driver;
> >>  	/* These fields are used by common fixups */
> >>  	unsigned int	transparent:1;	/* Transparent PCI bridge */
> >>  	unsigned int	multifunction:1;/* Part of multi-function device */
> >>
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 02/22] PCI: Add root bus children dev's res to fail list
  2013-01-12 21:37   ` Rafael J. Wysocki
@ 2013-01-15  6:23     ` Yinghai Lu
  2013-01-15 11:21       ` Rafael J. Wysocki
  0 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-15  6:23 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Sat, Jan 12, 2013 at 1:37 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Friday, January 11, 2013 02:40:29 PM Yinghai Lu wrote:
>> We can stop trying according to try number now and do not need to use
>> root_bus checking as stop sign anymore.
>>
>> In extreme case we could need to reallocate resource for device just
>> under root bus.
>
> Well, the above says that we _can_ do the change, but it doesn't explain why it
> is needed.  So what's the reason why we need to do that?

In extreme case we could need to reallocate resource for device just
under root bus.

otherwise, those devices just under root bus will not be assigned
resources again.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 06/22] PCI: split registration of PCI bus devices into two stages
  2013-01-13 15:25     ` Jiang Liu
@ 2013-01-15  6:29       ` Yinghai Lu
  0 siblings, 0 replies; 78+ messages in thread
From: Yinghai Lu @ 2013-01-15  6:29 UTC (permalink / raw)
  To: Jiang Liu
  Cc: Rafael J. Wysocki, Bjorn Helgaas, Len Brown, Taku Izumi,
	Jiang Liu, linux-pci, linux-kernel, linux-acpi

On Sun, Jan 13, 2013 at 7:25 AM, Jiang Liu <liuj97@gmail.com> wrote:
> On 01/13/2013 06:34 AM, Rafael J. Wysocki wrote:
>> On Friday, January 11, 2013 02:40:33 PM Yinghai Lu wrote:
>>> From: Jiang Liu <jiang.liu@huawei.com>
>>>
>>> When handling BUS_NOTIFY_ADD_DEVICE event for a PCI bridge device,
>>> the notification handler can't hold reference count to the new PCI bus
>>> because the device object for the new bus (pci_dev->subordinate->dev)
>>> hasn't been initialized yet.
>>
>> It doesn't look like BUS_NOTIFY_ADD_DEVICE is used by the PCI bus type
>> in the mainline.
>>
>> Is it in linux-next?
>>
>> If not, then I don't see why we need this patch.
> Hi Rafael,
>         Originally it's a preparation patch for pci_slot/acpiphp/pci_bind
> related fixups. With recent work from you to remove bind/unbind from struct
> acpi_bus_type, we have no dependency on this patch anymore.

ok, will drop this one.

Yinghai

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 07/22] ACPI: Separate acpi_bus_trim to support two steps.
  2013-01-12 22:40   ` Rafael J. Wysocki
@ 2013-01-15  6:31     ` Yinghai Lu
  2013-01-15 11:22       ` Rafael J. Wysocki
  0 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-15  6:31 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Sat, Jan 12, 2013 at 2:40 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Friday, January 11, 2013 02:40:34 PM Yinghai Lu wrote:
>> Current all acpi_bus_trim callers have rmdevice to 1.
>> that means it will remove all acpi devices.
>>
>> When 0, is passed, it will keep the parent.
>>
>> For root bus hotremove support, we need to have pci device to be
>> removed before acpi devices.
>>
>> So try to keep all acpi devices, and only stop drivers with them.
>>
>> This change should be safe because all current callers all have 1 passed.
>
> I'm not sure how the chanelog is related to the patch itself.
>
> The patch modifies the behavior of acpi_bus_trim() to avoid removing all
> devices (not just the start point) for rmdevice==0, which doesn't really change
> the functionality, because all callers pass rmdevice=1 anyway.
>
> Yes, we can make this change, but why is it necessary?
>
> And why don't we remove the rmdevice argument from acpi_bus_trim() altogether?

this patch is not needed after your changes with acpi_bus_trim.

Yinghai

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 08/22] PCI, acpiphp: Separate out hot-add support of pci host bridge
  2013-01-12 23:18   ` Rafael J. Wysocki
@ 2013-01-15  6:44     ` Yinghai Lu
  2013-01-15 15:54       ` Yinghai Lu
  0 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-15  6:44 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Sat, Jan 12, 2013 at 3:18 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> @@ -673,3 +673,223 @@ int __init acpi_pci_root_init(void)
>>
>>       return 0;
>>  }
>> +
>> +/*
>> + * Separated from drivers/pci/hotplug/acpiphp_glue.c
>> + *   only support root bridge
>> + */
>
> This comment will be useless after applying the patch.
>
>> +
>> +static LIST_HEAD(acpi_root_bridge_list);
>> +struct acpi_root_bridge {
>> +     struct list_head list;
>> +     acpi_handle handle;
>> +     u32 flags;
>> +};
>
> We have struct acpi_pci_root already.  Why do we need this in addition?

will address that in following patch.

>
> Also, we have acpi_pci_roots, so why do we need another list of root bridges?
>
>> +
>> +/* bridge flags */
>> +#define ROOT_BRIDGE_HAS_EJ0  (0x00000002)
>> +#define ROOT_BRIDGE_HAS_PS3  (0x00000080)
>
> What is that needed for?

will address that in following patch.

>
>> +
>> +#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;
>> +
>
> Why do we need to evaluate all of the methods directly here?
>
> Don't we have a struct acpi_device for handle already?
>
>> +     /* 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;
>
> All of this attempts to duplicate the scanning code from scan.c in a very
> incomplete and questionable way.
>
> For example, what if the root bridge has _PR0?

will address that in following patch

>
>> +
>> +     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);
>> +}
>
> The function above is called only once and used by __init stuff only.
> Why don't we move it to the caller and mark that caller as __init too?

will merge the function and shared with acpiphp

>
>> +
>> +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...
>> +              */
>
> Why?  Shouldn't we just bail out here?

should be the same from acpiphp.

>
>> +             /* remove pci devices at first */
>> +             ret_val = acpi_bus_trim(device, 0);
>> +             printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
>> +             /* remove acpi devices */
>> +             ret_val = acpi_bus_trim(device, 1);
>
> Oh, I see why you need the second argument of acpi_bus_trim() now.
>
> Do I think correctly that you want acpi_pci_root_remove() to be executed before
> all of the struct acpi_device objects are removed?  In which case why don't we
> call acpi_pci_root_remove() directly before doing the acpi_bus_trim(device, 1)
> instead of making the code next to impossible to understand?

yes.

>
>> +             printk(KERN_DEBUG "acpi_bus_trim remove return %x\n", ret_val);
>> +     }
>> +     if (acpi_bus_add(handle))
>> +             printk(KERN_ERR "cannot add bridge to acpi list\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);
>
> I don't think we should call add_acpi_root_bridge() for handle if the above
> fails.  So probably handle_root_bridge_insertion() should return error codes?

yes

>
>> +                     add_acpi_root_bridge(handle);

will remove root bridge in following patch.

>> +             }
>> +
>> +             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;
>> +}
>
> Why do we need to do that from an initcall?  Couldn't we simply hook up
> that code to acpi_pci_root_add() somewhere?

no, not inserted host bridge will not have acpi_pci_root_add called.

>
> And even if not, why don't we call acpi_pci_root_hp_init() from
> acpi_pci_root_init()?

will check if can move that to acpi_pci_root_init and address that in
another patch.

>
> All of the changes in acpiphp_glue.c look reasonable to me.

Good.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 09/22] PCI, ACPI: Add pci_root_hp hot removal notification support.
  2013-01-12 23:26   ` Rafael J. Wysocki
@ 2013-01-15  6:45     ` Yinghai Lu
  0 siblings, 0 replies; 78+ messages in thread
From: Yinghai Lu @ 2013-01-15  6:45 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Sat, Jan 12, 2013 at 3:26 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Friday, January 11, 2013 02:40:36 PM Yinghai Lu wrote:
>> Add missing hot_remove support for root device.
>>
>> How to test it?
>> Find out root bus number to acpi root name mapping from dmesg or /sys
>>
>>   echo "\_SB.PCIB 3" > /sys/kernel/debug/acpi/sci_notify
>> to remove root bus
>>
>> -v2: separate stop and remove, so it will be safe for comingi
>>       acpi_pci_bind_notify() changes.
>>
>> 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 |   67 +++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 67 insertions(+)
>>
>> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
>> index 5c1f462c..5ae36d8 100644
>> --- a/drivers/acpi/pci_root.c
>> +++ b/drivers/acpi/pci_root.c
>> @@ -740,6 +740,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;
>> @@ -800,6 +806,61 @@ static void handle_root_bridge_insertion(acpi_handle handle)
>>               printk(KERN_ERR "cannot add bridge to acpi list\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)) {
>> +             pr_warn("%s: %s to %d failed\n",
>> +                              __func__, cmd, val);
>> +             return -1;
>
> Please use a meaningful error code.
>
>> +     }
>> +
>> +     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;
>> +
>> +             /* remove pci devices at first */
>> +             ret_val = acpi_bus_trim(device, 0);
>> +             printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
>> +
>> +             /* remove acpi devices */
>> +             ret_val = acpi_bus_trim(device, 1);
>> +             printk(KERN_DEBUG "acpi_bus_trim remove return %x\n", ret_val);
>
> First of all, I don't agree with the way acpi_bus_trim() is used here, as
> I said in the previous message.
>
> Second, this code duplicates the code you're adding on [08/22] almost exactly.
> Please put it into a one separate function instead of duplicating it like this.
>
>> +     }
>> +
>> +     if (flags & ROOT_BRIDGE_HAS_PS3) {
>> +             acpi_status status;
>> +
>> +             status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
>> +             if (ACPI_FAILURE(status))
>> +                     pr_warn("%s: _PS3 failed\n", __func__);
>
> No, please.  acpi_device_set_power() is for that.
>
>> +     }
>> +     if (flags & ROOT_BRIDGE_HAS_EJ0)
>> +             acpi_root_evaluate_object(handle, "_EJ0", 1);
>
> That seems to duplicate some code from scan.c.

yes, will address in the following patch.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 01/22] PCI, acpiphp: Add is_hotplug_bridge detection
  2013-01-11 22:40 ` [PATCH v8 01/22] PCI, acpiphp: Add is_hotplug_bridge detection Yinghai Lu
  2013-01-12 21:35   ` Rafael J. Wysocki
@ 2013-01-15  6:45   ` Yijing Wang
  2013-01-15  7:05     ` Yinghai Lu
  1 sibling, 1 reply; 78+ messages in thread
From: Yijing Wang @ 2013-01-15  6:45 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi,
	Jiang Liu, linux-pci, linux-kernel, linux-acpi

On 2013/1/12 6:40, Yinghai Lu wrote:
> When system support hotplug bridge with children hotplug slots, we need
> to make sure that parent bridge get preallocated resource so later when
> device is plugged into children slot, those children devices will get
> resource allocated.
> 
> We do not meet this problem, because for pcie hotplug card, when acpiphp
> is used, pci_scan_bridge will set that for us when detect hotplug bit in
> slot cap.
> 
> Reported-and-tested-by: Jason Baron <jbaron@redhat.com>
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Acked-by: Jason Baron <jbaron@redhat.com>
> ---
>  drivers/pci/hotplug/acpiphp_glue.c |   27 ++++++++++++++++++++++++++-
>  1 file changed, 26 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
> index 91b5ad8..1e5c5df 100644
> --- a/drivers/pci/hotplug/acpiphp_glue.c
> +++ b/drivers/pci/hotplug/acpiphp_glue.c
> @@ -797,6 +797,29 @@ static void acpiphp_set_acpi_region(struct acpiphp_slot *slot)
>  	}
>  }
>  
> +static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev)
> +{
> +	struct acpiphp_func *func;
> +
> +	if (!dev->subordinate)
> +		return;
> +
> +	/* quirk, or pcie could set it already */
> +	if (dev->is_hotplug_bridge)
> +		return;
> +
> +	if (PCI_SLOT(dev->devfn) != slot->device)
> +		return;
> +
> +	list_for_each_entry(func, &slot->funcs, sibling) {
> +		if (PCI_FUNC(dev->devfn) == func->function) {
> +			/* check if this bridge has ejectable slots */
> +			if ((detect_ejectable_slots(func->handle) > 0))
> +				dev->is_hotplug_bridge = 1;
> +			break;

Hi Yinghai,
   Need to put the "break" in parentheses of "if"? If the first func which device number == dev->devfn has't ejectable slot,
don't check the rest funcs whether have ejectable slots?

> +		}
> +	}
> +}
>  /**
>   * enable_device - enable, configure a slot
>   * @slot: slot to be enabled
> @@ -831,8 +854,10 @@ static int __ref enable_device(struct acpiphp_slot *slot)
>  			if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
>  			    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
>  				max = pci_scan_bridge(bus, dev, max, pass);
> -				if (pass && dev->subordinate)
> +				if (pass && dev->subordinate) {
> +					check_hotplug_bridge(slot, dev);
>  					pci_bus_size_bridges(dev->subordinate);
> +				}
>  			}
>  		}
>  	}
> 


-- 
Thanks!
Yijing


^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 14/22] ACPI: update ej_event interface to take acpi_device
  2013-01-12 23:40   ` Rafael J. Wysocki
@ 2013-01-15  6:55     ` Yinghai Lu
  2013-01-15 11:26       ` Rafael J. Wysocki
  0 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-15  6:55 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Sat, Jan 12, 2013 at 3:40 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Friday, January 11, 2013 02:40:41 PM Yinghai Lu wrote:
>> Should use acpi_device pointer directly instead of use handle and
>> get the device pointer again later.
>
> Looks good.
>
> I can take this one right now if you want.

yes, in acpi-scan branch?

othewise i can not base on pci/next again.

>
> Thanks,
> Rafael
>
>
>> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>> ---
>>  drivers/acpi/acpi_memhotplug.c  |    2 +-
>>  drivers/acpi/processor_driver.c |    2 +-
>>  drivers/acpi/scan.c             |   14 ++++----------
>>  include/acpi/acpi_bus.h         |    2 +-
>>  4 files changed, 7 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
>> index 327ab44..eaddb7a 100644
>> --- a/drivers/acpi/acpi_memhotplug.c
>> +++ b/drivers/acpi/acpi_memhotplug.c
>> @@ -361,7 +361,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
>>                       break;
>>               }
>>
>> -             ej_event->handle = handle;
>> +             ej_event->device = device;
>>               ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
>>               acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
>>                                       (void *)ej_event);
>> diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
>> index 0777663..a24ee43 100644
>> --- a/drivers/acpi/processor_driver.c
>> +++ b/drivers/acpi/processor_driver.c
>> @@ -733,7 +733,7 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
>>                       break;
>>               }
>>
>> -             ej_event->handle = handle;
>> +             ej_event->device = device;
>>               ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
>>               acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
>>                                       (void *)ej_event);
>> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
>> index 8883539..f4c6305 100644
>> --- a/drivers/acpi/scan.c
>> +++ b/drivers/acpi/scan.c
>> @@ -116,20 +116,14 @@ static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
>>  void acpi_bus_hot_remove_device(void *context)
>>  {
>>       struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context;
>> -     struct acpi_device *device;
>> -     acpi_handle handle = ej_event->handle;
>> +     struct acpi_device *device = ej_event->device;
>> +     acpi_handle handle = device->handle;
>>       acpi_handle temp;
>>       struct acpi_object_list arg_list;
>>       union acpi_object arg;
>>       acpi_status status = AE_OK;
>>       u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
>>
>> -     if (acpi_bus_get_device(handle, &device))
>> -             goto err_out;
>> -
>> -     if (!device)
>> -             goto err_out;
>> -
>>       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
>>               "Hot-removing device %s...\n", dev_name(&device->dev)));
>>
>> @@ -215,7 +209,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
>>               goto err;
>>       }
>>
>> -     ej_event->handle = acpi_device->handle;
>> +     ej_event->device = acpi_device;
>>       if (acpi_device->flags.eject_pending) {
>>               /* event originated from ACPI eject notification */
>>               ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
>> @@ -223,7 +217,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
>>       } else {
>>               /* event originated from user */
>>               ej_event->event = ACPI_OST_EC_OSPM_EJECT;
>> -             (void) acpi_evaluate_hotplug_ost(ej_event->handle,
>> +             (void) acpi_evaluate_hotplug_ost(acpi_device->handle,
>>                       ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
>>       }
>>
>> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
>> index 2246ba9..181ff2d 100644
>> --- a/include/acpi/acpi_bus.h
>> +++ b/include/acpi/acpi_bus.h
>> @@ -309,7 +309,7 @@ struct acpi_bus_event {
>>  };
>>
>>  struct acpi_eject_event {
>> -     acpi_handle     handle;
>> +     struct acpi_device      *device;
>>       u32             event;
>>  };
>>
>>
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 17/22] PCI, ACPI: Add alloc_acpi_hp_work()
  2013-01-12 23:45   ` Rafael J. Wysocki
@ 2013-01-15  6:59     ` Yinghai Lu
  2013-01-15 11:27       ` Rafael J. Wysocki
  0 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-15  6:59 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Sat, Jan 12, 2013 at 3:45 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Friday, January 11, 2013 02:40:44 PM Yinghai Lu wrote:
>> Will use it with acpiphp and pci_root_hp events handling
>
> I think it would be better if you folded patches [17-20/22] together.

just want to make move/split more simple. so could separate out old
code in acpiphp is
moved at first, then apply change etc.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 01/22] PCI, acpiphp: Add is_hotplug_bridge detection
  2013-01-15  6:45   ` Yijing Wang
@ 2013-01-15  7:05     ` Yinghai Lu
  0 siblings, 0 replies; 78+ messages in thread
From: Yinghai Lu @ 2013-01-15  7:05 UTC (permalink / raw)
  To: Yijing Wang
  Cc: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi,
	Jiang Liu, linux-pci, linux-kernel, linux-acpi

On Mon, Jan 14, 2013 at 10:45 PM, Yijing Wang <wangyijing@huawei.com> wrote:
>> +     list_for_each_entry(func, &slot->funcs, sibling) {
>> +             if (PCI_FUNC(dev->devfn) == func->function) {
>> +                     /* check if this bridge has ejectable slots */
>> +                     if ((detect_ejectable_slots(func->handle) > 0))
>> +                             dev->is_hotplug_bridge = 1;
>> +                     break;
>
> Hi Yinghai,
>    Need to put the "break" in parentheses of "if"? If the first func which device number == dev->devfn has't ejectable slot,
> don't check the rest funcs whether have ejectable slots?

no, we should break when PCI_FUNC(dev->devfn) == func->function

that iteration is for find the func for dev.

Thanks

Yinghai

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 22/22] PCI: move device_add out of pci_bus_add_device()
  2013-01-12 23:54   ` Rafael J. Wysocki
@ 2013-01-15  7:10     ` Yinghai Lu
  2013-01-15 11:19       ` Rafael J. Wysocki
  0 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-15  7:10 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Sat, Jan 12, 2013 at 3:54 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> Move out device registering out of pci_bus_add_devices, so we could
>> put new created pci devices in device tree early.
>>
>> new pci_bus_add_devices will do the device_attach work to load pci drivers
>> instead.
>
> I wonder what problem it solves?

we want to put created pci device in the device tree as soon as possible.
so for_pci_dev will not miss them.

but at that time, we can not load driver for them yet. need to after
pci_assign_unsigned_resources etc to make sure all pci devices get
resource allocated at first.

so only move adding to device tree early, and leave loading driver on
the old places.

Yinghai

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 22/22] PCI: move device_add out of pci_bus_add_device()
  2013-01-15  7:10     ` Yinghai Lu
@ 2013-01-15 11:19       ` Rafael J. Wysocki
  2013-01-15 15:45         ` Yinghai Lu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-15 11:19 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Monday, January 14, 2013 11:10:36 PM Yinghai Lu wrote:
> On Sat, Jan 12, 2013 at 3:54 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> >> Move out device registering out of pci_bus_add_devices, so we could
> >> put new created pci devices in device tree early.
> >>
> >> new pci_bus_add_devices will do the device_attach work to load pci drivers
> >> instead.
> >
> > I wonder what problem it solves?
> 
> we want to put created pci device in the device tree as soon as possible.
> so for_pci_dev will not miss them.
> 
> but at that time, we can not load driver for them yet. need to after
> pci_assign_unsigned_resources etc to make sure all pci devices get
> resource allocated at first.
> 
> so only move adding to device tree early, and leave loading driver on
> the old places.

I see, thanks.

Perhaps you can put that explanation into the changelog? It would help people
to understand the reason for the change in the future.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 02/22] PCI: Add root bus children dev's res to fail list
  2013-01-15  6:23     ` Yinghai Lu
@ 2013-01-15 11:21       ` Rafael J. Wysocki
  2013-01-15 15:44         ` Yinghai Lu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-15 11:21 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Monday, January 14, 2013 10:23:47 PM Yinghai Lu wrote:
> On Sat, Jan 12, 2013 at 1:37 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Friday, January 11, 2013 02:40:29 PM Yinghai Lu wrote:
> >> We can stop trying according to try number now and do not need to use
> >> root_bus checking as stop sign anymore.
> >>
> >> In extreme case we could need to reallocate resource for device just
> >> under root bus.
> >
> > Well, the above says that we _can_ do the change, but it doesn't explain why it
> > is needed.  So what's the reason why we need to do that?
> 
> In extreme case we could need to reallocate resource for device just
> under root bus.
> 
> otherwise, those devices just under root bus will not be assigned
> resources again.

IOW, our current code will not cover the case when we hot plug a host bridge
and need to reassign resources for devices integrated into it?

Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 07/22] ACPI: Separate acpi_bus_trim to support two steps.
  2013-01-15  6:31     ` Yinghai Lu
@ 2013-01-15 11:22       ` Rafael J. Wysocki
  0 siblings, 0 replies; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-15 11:22 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Monday, January 14, 2013 10:31:35 PM Yinghai Lu wrote:
> On Sat, Jan 12, 2013 at 2:40 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Friday, January 11, 2013 02:40:34 PM Yinghai Lu wrote:
> >> Current all acpi_bus_trim callers have rmdevice to 1.
> >> that means it will remove all acpi devices.
> >>
> >> When 0, is passed, it will keep the parent.
> >>
> >> For root bus hotremove support, we need to have pci device to be
> >> removed before acpi devices.
> >>
> >> So try to keep all acpi devices, and only stop drivers with them.
> >>
> >> This change should be safe because all current callers all have 1 passed.
> >
> > I'm not sure how the chanelog is related to the patch itself.
> >
> > The patch modifies the behavior of acpi_bus_trim() to avoid removing all
> > devices (not just the start point) for rmdevice==0, which doesn't really change
> > the functionality, because all callers pass rmdevice=1 anyway.
> >
> > Yes, we can make this change, but why is it necessary?
> >
> > And why don't we remove the rmdevice argument from acpi_bus_trim() altogether?
> 
> this patch is not needed after your changes with acpi_bus_trim.

OK, cool. :-)

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 14/22] ACPI: update ej_event interface to take acpi_device
  2013-01-15  6:55     ` Yinghai Lu
@ 2013-01-15 11:26       ` Rafael J. Wysocki
  2013-01-15 23:43         ` Yinghai Lu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-15 11:26 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Monday, January 14, 2013 10:55:49 PM Yinghai Lu wrote:
> On Sat, Jan 12, 2013 at 3:40 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Friday, January 11, 2013 02:40:41 PM Yinghai Lu wrote:
> >> Should use acpi_device pointer directly instead of use handle and
> >> get the device pointer again later.
> >
> > Looks good.
> >
> > I can take this one right now if you want.
> 
> yes, in acpi-scan branch?
> 
> othewise i can not base on pci/next again.

OK

So I think there will be more patches in acpi-scan you'll need anyway, so
I'll put this one on that branch too.

Thanks,
Rafael


> >> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> >> ---
> >>  drivers/acpi/acpi_memhotplug.c  |    2 +-
> >>  drivers/acpi/processor_driver.c |    2 +-
> >>  drivers/acpi/scan.c             |   14 ++++----------
> >>  include/acpi/acpi_bus.h         |    2 +-
> >>  4 files changed, 7 insertions(+), 13 deletions(-)
> >>
> >> diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
> >> index 327ab44..eaddb7a 100644
> >> --- a/drivers/acpi/acpi_memhotplug.c
> >> +++ b/drivers/acpi/acpi_memhotplug.c
> >> @@ -361,7 +361,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
> >>                       break;
> >>               }
> >>
> >> -             ej_event->handle = handle;
> >> +             ej_event->device = device;
> >>               ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
> >>               acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
> >>                                       (void *)ej_event);
> >> diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
> >> index 0777663..a24ee43 100644
> >> --- a/drivers/acpi/processor_driver.c
> >> +++ b/drivers/acpi/processor_driver.c
> >> @@ -733,7 +733,7 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
> >>                       break;
> >>               }
> >>
> >> -             ej_event->handle = handle;
> >> +             ej_event->device = device;
> >>               ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
> >>               acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
> >>                                       (void *)ej_event);
> >> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> >> index 8883539..f4c6305 100644
> >> --- a/drivers/acpi/scan.c
> >> +++ b/drivers/acpi/scan.c
> >> @@ -116,20 +116,14 @@ static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
> >>  void acpi_bus_hot_remove_device(void *context)
> >>  {
> >>       struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context;
> >> -     struct acpi_device *device;
> >> -     acpi_handle handle = ej_event->handle;
> >> +     struct acpi_device *device = ej_event->device;
> >> +     acpi_handle handle = device->handle;
> >>       acpi_handle temp;
> >>       struct acpi_object_list arg_list;
> >>       union acpi_object arg;
> >>       acpi_status status = AE_OK;
> >>       u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
> >>
> >> -     if (acpi_bus_get_device(handle, &device))
> >> -             goto err_out;
> >> -
> >> -     if (!device)
> >> -             goto err_out;
> >> -
> >>       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
> >>               "Hot-removing device %s...\n", dev_name(&device->dev)));
> >>
> >> @@ -215,7 +209,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
> >>               goto err;
> >>       }
> >>
> >> -     ej_event->handle = acpi_device->handle;
> >> +     ej_event->device = acpi_device;
> >>       if (acpi_device->flags.eject_pending) {
> >>               /* event originated from ACPI eject notification */
> >>               ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
> >> @@ -223,7 +217,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
> >>       } else {
> >>               /* event originated from user */
> >>               ej_event->event = ACPI_OST_EC_OSPM_EJECT;
> >> -             (void) acpi_evaluate_hotplug_ost(ej_event->handle,
> >> +             (void) acpi_evaluate_hotplug_ost(acpi_device->handle,
> >>                       ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
> >>       }
> >>
> >> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> >> index 2246ba9..181ff2d 100644
> >> --- a/include/acpi/acpi_bus.h
> >> +++ b/include/acpi/acpi_bus.h
> >> @@ -309,7 +309,7 @@ struct acpi_bus_event {
> >>  };
> >>
> >>  struct acpi_eject_event {
> >> -     acpi_handle     handle;
> >> +     struct acpi_device      *device;
> >>       u32             event;
> >>  };
> >>
> >>
> > --
> > I speak only for myself.
> > Rafael J. Wysocki, Intel Open Source Technology Center.
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 17/22] PCI, ACPI: Add alloc_acpi_hp_work()
  2013-01-15  6:59     ` Yinghai Lu
@ 2013-01-15 11:27       ` Rafael J. Wysocki
  0 siblings, 0 replies; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-15 11:27 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Monday, January 14, 2013 10:59:28 PM Yinghai Lu wrote:
> On Sat, Jan 12, 2013 at 3:45 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Friday, January 11, 2013 02:40:44 PM Yinghai Lu wrote:
> >> Will use it with acpiphp and pci_root_hp events handling
> >
> > I think it would be better if you folded patches [17-20/22] together.
> 
> just want to make move/split more simple. so could separate out old
> code in acpiphp is
> moved at first, then apply change etc.

Well, OK.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 02/22] PCI: Add root bus children dev's res to fail list
  2013-01-15 11:21       ` Rafael J. Wysocki
@ 2013-01-15 15:44         ` Yinghai Lu
  2013-01-15 21:52           ` Rafael J. Wysocki
  0 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-15 15:44 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Tue, Jan 15, 2013 at 3:21 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Monday, January 14, 2013 10:23:47 PM Yinghai Lu wrote:
>> On Sat, Jan 12, 2013 at 1:37 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> > On Friday, January 11, 2013 02:40:29 PM Yinghai Lu wrote:
>> >> We can stop trying according to try number now and do not need to use
>> >> root_bus checking as stop sign anymore.
>> >>
>> >> In extreme case we could need to reallocate resource for device just
>> >> under root bus.
>> >
>> > Well, the above says that we _can_ do the change, but it doesn't explain why it
>> > is needed.  So what's the reason why we need to do that?
>>
>> In extreme case we could need to reallocate resource for device just
>> under root bus.
>>
>> otherwise, those devices just under root bus will not be assigned
>> resources again.
>
> IOW, our current code will not cover the case when we hot plug a host bridge
> and need to reassign resources for devices integrated into it?

yes. in extreme case if _CRS range is not big enough.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 22/22] PCI: move device_add out of pci_bus_add_device()
  2013-01-15 11:19       ` Rafael J. Wysocki
@ 2013-01-15 15:45         ` Yinghai Lu
  0 siblings, 0 replies; 78+ messages in thread
From: Yinghai Lu @ 2013-01-15 15:45 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Tue, Jan 15, 2013 at 3:19 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Monday, January 14, 2013 11:10:36 PM Yinghai Lu wrote:
>> On Sat, Jan 12, 2013 at 3:54 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> >> Move out device registering out of pci_bus_add_devices, so we could
>> >> put new created pci devices in device tree early.
>> >>
>> >> new pci_bus_add_devices will do the device_attach work to load pci drivers
>> >> instead.
>> >
>> > I wonder what problem it solves?
>>
>> we want to put created pci device in the device tree as soon as possible.
>> so for_pci_dev will not miss them.
>>
>> but at that time, we can not load driver for them yet. need to after
>> pci_assign_unsigned_resources etc to make sure all pci devices get
>> resource allocated at first.
>>
>> so only move adding to device tree early, and leave loading driver on
>> the old places.
>
> I see, thanks.
>
> Perhaps you can put that explanation into the changelog? It would help people
> to understand the reason for the change in the future.

ok

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 08/22] PCI, acpiphp: Separate out hot-add support of pci host bridge
  2013-01-15  6:44     ` Yinghai Lu
@ 2013-01-15 15:54       ` Yinghai Lu
  2013-01-15 22:00         ` Rafael J. Wysocki
  0 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-15 15:54 UTC (permalink / raw)
  To: Rafael J. Wysocki, Bjorn Helgaas
  Cc: Len Brown, Taku Izumi, Jiang Liu, linux-pci, linux-kernel, linux-acpi

[-- Attachment #1: Type: text/plain, Size: 819 bytes --]

On Mon, Jan 14, 2013 at 10:44 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> On Sat, Jan 12, 2013 at 3:18 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>>> @@ -673,3 +673,223 @@ int __init acpi_pci_root_init(void)
>>>
>>>       return 0;
>>>  }
>>> +
>>> +/*
>>> + * Separated from drivers/pci/hotplug/acpiphp_glue.c
>>> + *   only support root bridge
>>> + */
>>
>> This comment will be useless after applying the patch.
>>
>>> +
>>> +static LIST_HEAD(acpi_root_bridge_list);
>>> +struct acpi_root_bridge {
>>> +     struct list_head list;
>>> +     acpi_handle handle;
>>> +     u32 flags;
>>> +};
>>
>> We have struct acpi_pci_root already.  Why do we need this in addition?
>
> will address that in following patch.

please check if you are ok with merging attached 5 patches in to one
patches instead.

Thanks

Yinghai

[-- Attachment #2: pci_root_acpiphp_split_before_jiang_hotplug_rework.patch --]
[-- Type: application/octet-stream, Size: 10334 bytes --]

Subject: [PATCH] PCI, acpiphp: Separate out hot-add support of pci host bridge

It causes confusion.

We may only need acpi hp for pci host bridge.

Move host bridge hot-add support to pci_root_hp, and keep acpiphp simple.

-v2: put back pci_root_hp change in one patch
-v3: add pcibios_resource_survey_bus() calling
-v4: remove not needed code with remove_bridge
-v5: put back support for acpiphp support for slots just on root bus.
-v6: change some functions to *_p2p_* to make it more clean.
-v7: split hot_added change out.
-v8: Move to pci_root.c instead of adding another file requested by Bjorn.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>

---
 drivers/acpi/pci_root.c            |  220 +++++++++++++++++++++++++++++++++++++
 drivers/pci/hotplug/acpiphp_glue.c |   59 ++-------
 2 files changed, 235 insertions(+), 44 deletions(-)

Index: linux-2.6/drivers/pci/hotplug/acpiphp_glue.c
===================================================================
--- linux-2.6.orig/drivers/pci/hotplug/acpiphp_glue.c
+++ linux-2.6/drivers/pci/hotplug/acpiphp_glue.c
@@ -543,10 +543,13 @@ static void cleanup_bridge(struct acpiph
 	acpi_status status;
 	acpi_handle handle = bridge->handle;
 
-	status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+	if (bridge->type != BRIDGE_TYPE_HOST) {
+		status = acpi_remove_notify_handler(handle,
+					    ACPI_SYSTEM_NOTIFY,
 					    handle_hotplug_event_bridge);
-	if (ACPI_FAILURE(status))
-		err("failed to remove notify handler\n");
+		if (ACPI_FAILURE(status))
+			err("failed to remove notify handler\n");
+	}
 
 	if ((bridge->type != BRIDGE_TYPE_HOST) &&
 	    ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func)) {
@@ -630,9 +633,6 @@ static void remove_bridge(struct acpi_pc
 	bridge = acpiphp_handle_to_bridge(handle);
 	if (bridge)
 		cleanup_bridge(bridge);
-	else
-		acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
-					   handle_hotplug_event_bridge);
 }
 
 static int power_on_slot(struct acpiphp_slot *slot)
@@ -1123,18 +1123,12 @@ static void acpiphp_sanitize_bus(struct
 }
 
 /* Program resources in newly inserted bridge */
-static int acpiphp_configure_bridge (acpi_handle handle)
+static int acpiphp_configure_p2p_bridge(acpi_handle handle)
 {
-	struct pci_bus *bus;
+	struct pci_dev *pdev = acpi_get_pci_dev(handle);
+	struct pci_bus *bus = pdev->subordinate;
 
-	if (acpi_is_root_bridge(handle)) {
-		struct acpi_pci_root *root = acpi_pci_find_root(handle);
-		bus = root->bus;
-	} else {
-		struct pci_dev *pdev = acpi_get_pci_dev(handle);
-		bus = pdev->subordinate;
-		pci_dev_put(pdev);
-	}
+	pci_dev_put(pdev);
 
 	pci_bus_size_bridges(bus);
 	pci_bus_assign_resources(bus);
@@ -1144,7 +1138,7 @@ static int acpiphp_configure_bridge (acp
 	return 0;
 }
 
-static void handle_bridge_insertion(acpi_handle handle, u32 type)
+static void handle_p2p_bridge_insertion(acpi_handle handle, u32 type)
 {
 	struct acpi_device *device;
 
@@ -1162,8 +1156,8 @@ static void handle_bridge_insertion(acpi
 		err("ACPI device object missing\n");
 		return;
 	}
-	if (!acpiphp_configure_bridge(handle))
-		add_bridge(handle);
+	if (!acpiphp_configure_p2p_bridge(handle))
+		add_p2p_bridge(handle);
 	else
 		err("cannot configure and start bridge\n");
 
@@ -1249,7 +1243,7 @@ static void _handle_hotplug_event_bridge
 
 	if (acpi_bus_get_device(handle, &device)) {
 		/* This bridge must have just been physically inserted */
-		handle_bridge_insertion(handle, type);
+		handle_p2p_bridge_insertion(handle, type);
 		goto out;
 	}
 
@@ -1426,21 +1420,6 @@ static void handle_hotplug_event_func(ac
 			      _handle_hotplug_event_func);
 }
 
-static acpi_status
-find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-	int *count = (int *)context;
-
-	if (!acpi_is_root_bridge(handle))
-		return AE_OK;
-
-	(*count)++;
-	acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
-				    handle_hotplug_event_bridge, NULL);
-
-	return AE_OK ;
-}
-
 static struct acpi_pci_driver acpi_pci_hp_driver = {
 	.add =		add_bridge,
 	.remove =	remove_bridge,
@@ -1451,15 +1430,7 @@ static struct acpi_pci_driver acpi_pci_h
  */
 int __init acpiphp_glue_init(void)
 {
-	int num = 0;
-
-	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-			ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL);
-
-	if (num <= 0)
-		return -1;
-	else
-		acpi_pci_register_driver(&acpi_pci_hp_driver);
+	acpi_pci_register_driver(&acpi_pci_hp_driver);
 
 	return 0;
 }
Index: linux-2.6/drivers/acpi/pci_root.c
===================================================================
--- linux-2.6.orig/drivers/acpi/pci_root.c
+++ linux-2.6/drivers/acpi/pci_root.c
@@ -673,3 +673,223 @@ int __init acpi_pci_root_init(void)
 
 	return 0;
 }
+
+/*
+ * Separated from drivers/pci/hotplug/acpiphp_glue.c
+ *	only support root bridge
+ */
+
+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);
+}
+
+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...
+		 */
+		/* remove pci devices at first */
+		ret_val = acpi_bus_trim(device, 0);
+		printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
+		/* remove acpi devices */
+		ret_val = acpi_bus_trim(device, 1);
+		printk(KERN_DEBUG "acpi_bus_trim remove return %x\n", ret_val);
+	}
+	if (acpi_bus_add(handle))
+		printk(KERN_ERR "cannot add bridge to acpi list\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);

[-- Attachment #3: pci_root_hp_1.patch --]
[-- Type: application/octet-stream, Size: 3084 bytes --]

Subject: [PATCH] PCI, ACPI: Add pci_root_hp hot removal notification support.

Add missing hot_remove support for root device.

How to test it?
Find out root bus number to acpi root name mapping from dmesg or /sys

  echo "\_SB.PCIB 3" > /sys/kernel/debug/acpi/sci_notify
to remove root bus

-v2: separate stop and remove, so it will be safe for comingi
	acpi_pci_bind_notify() changes.

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 |   67 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

Index: linux-2.6/drivers/acpi/pci_root.c
===================================================================
--- linux-2.6.orig/drivers/acpi/pci_root.c
+++ linux-2.6/drivers/acpi/pci_root.c
@@ -740,6 +740,12 @@ static void add_acpi_root_bridge(acpi_ha
 	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;
@@ -800,6 +806,61 @@ static void handle_root_bridge_insertion
 		printk(KERN_ERR "cannot add bridge to acpi list\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)) {
+		pr_warn("%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;
+
+		/* remove pci devices at first */
+		ret_val = acpi_bus_trim(device, 0);
+		printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
+
+		/* remove acpi devices */
+		ret_val = acpi_bus_trim(device, 1);
+		printk(KERN_DEBUG "acpi_bus_trim remove 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))
+			pr_warn("%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;
@@ -840,6 +901,12 @@ static void _handle_hotplug_event_root(s
 		}
 		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);

[-- Attachment #4: kill_remove_acpi_root_bridge.patch --]
[-- Type: application/octet-stream, Size: 5630 bytes --]

Subject: [PATCH] PCI, ACPI: remove acpi_root_bridge in pci_root_hp

Tang noticed that hotplug through container will not update acpi_root_bridge
list.

After closely checking, we don't need that for struct for tracking and
could use acpi_pci_root directly.

Reported-by: Tang Chen <tangchen@cn.fujitsu.com>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>

---
 drivers/acpi/pci_root.c |  111 +++++++++---------------------------------------
 1 file changed, 21 insertions(+), 90 deletions(-)

Index: linux-2.6/drivers/acpi/pci_root.c
===================================================================
--- linux-2.6.orig/drivers/acpi/pci_root.c
+++ linux-2.6/drivers/acpi/pci_root.c
@@ -679,73 +679,12 @@ int __init acpi_pci_root_init(void)
  *	only support root bridge
  */
 
-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);
-}
-
-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;
@@ -827,28 +766,25 @@ static int acpi_root_evaluate_object(acp
 	return 0;
 }
 
-static void handle_root_bridge_removal(acpi_handle handle,
-		 struct acpi_root_bridge *bridge)
+static void handle_root_bridge_removal(struct acpi_device *device)
 {
+	int ret_val;
 	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_handle dummy_handle;
+	acpi_handle handle = device->handle;
 
-		/* remove pci devices at first */
-		ret_val = acpi_bus_trim(device, 0);
-		printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
+	if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &dummy_handle)))
+		flags |= ROOT_BRIDGE_HAS_EJ0;
+	if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &dummy_handle)))
+		flags |= ROOT_BRIDGE_HAS_PS3;
 
-		/* remove acpi devices */
-		ret_val = acpi_bus_trim(device, 1);
-		printk(KERN_DEBUG "acpi_bus_trim remove return %x\n", ret_val);
-	}
+	/* remove pci devices at first */
+	ret_val = acpi_bus_trim(device, 0);
+	printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
+
+	/* remove acpi devices */
+	ret_val = acpi_bus_trim(device, 1);
+	printk(KERN_DEBUG "acpi_bus_trim remove return %x\n", ret_val);
 
 	if (flags & ROOT_BRIDGE_HAS_PS3) {
 		acpi_status status;
@@ -863,7 +799,7 @@ static void handle_root_bridge_removal(a
 
 static void _handle_hotplug_event_root(struct work_struct *work)
 {
-	struct acpi_root_bridge *bridge;
+	struct acpi_pci_root *root;
 	char objname[64];
 	struct acpi_buffer buffer = { .length = sizeof(objname),
 				      .pointer = objname };
@@ -875,7 +811,7 @@ static void _handle_hotplug_event_root(s
 	handle = hp_work->handle;
 	type = hp_work->type;
 
-	bridge = acpi_root_handle_to_bridge(handle);
+	root = acpi_pci_find_root(handle);
 
 	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 
@@ -884,10 +820,8 @@ static void _handle_hotplug_event_root(s
 		/* bus enumerate */
 		printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__,
 				 objname);
-		if (!bridge) {
+		if (!root)
 			handle_root_bridge_insertion(handle);
-			add_acpi_root_bridge(handle);
-		}
 
 		break;
 
@@ -895,17 +829,16 @@ static void _handle_hotplug_event_root(s
 		/* device check */
 		printk(KERN_DEBUG "%s: Device check notify on %s\n", __func__,
 				 objname);
-		if (!bridge) {
+		if (!root)
 			handle_root_bridge_insertion(handle);
-			add_acpi_root_bridge(handle);
-		}
 		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);
+		if (root)
+			handle_root_bridge_removal(root->device);
 		break;
 	default:
 		printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n",
@@ -965,8 +898,6 @@ find_root_bridges(acpi_handle handle, u3
 		printk(KERN_DEBUG "acpi root: %s notify handler is installed\n",
 				 objname);
 
-	add_acpi_root_bridge(handle);
-
 	return AE_OK;
 }
 

[-- Attachment #5: root_bridge_remove_2.patch --]
[-- Type: application/octet-stream, Size: 2523 bytes --]

Subject: [PATCH] ACPI, PCI: Simplify handle_root_bridge_removal()

Tang Chen found handle_root_bridge_removal is very similiar to
acpi_bus_hot_remove_device().
Only difference is that it call trim two times.

Change to handle_root_bridge_removal to call trim one time and then 
use acpi_bus_hot_remove_device. 

Signed-off-by: Yinghai Lu <yinghai@kernel.org>

---
 drivers/acpi/pci_root.c |   51 ++++++++----------------------------------------
 1 file changed, 9 insertions(+), 42 deletions(-)

Index: linux-2.6/drivers/acpi/pci_root.c
===================================================================
--- linux-2.6.orig/drivers/acpi/pci_root.c
+++ linux-2.6/drivers/acpi/pci_root.c
@@ -745,56 +745,23 @@ static void handle_root_bridge_insertion
 		printk(KERN_ERR "cannot add bridge to acpi list\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)) {
-		pr_warn("%s: %s to %d failed\n",
-				 __func__, cmd, val);
-		return -1;
-	}
-
-	return 0;
-}
-
 static void handle_root_bridge_removal(struct acpi_device *device)
 {
 	int ret_val;
-	u32 flags = 0;
-	acpi_handle dummy_handle;
-	acpi_handle handle = device->handle;
-
-	if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &dummy_handle)))
-		flags |= ROOT_BRIDGE_HAS_EJ0;
-	if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &dummy_handle)))
-		flags |= ROOT_BRIDGE_HAS_PS3;
+	struct acpi_eject_event *ej_event;
+
+	ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
+	if (!ej_event)
+		return;
+
+	ej_event->device = device;
+	ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
 
 	/* remove pci devices at first */
 	ret_val = acpi_bus_trim(device, 0);
 	printk(KERN_DEBUG "acpi_bus_trim stop return %x\n", ret_val);
 
-	/* remove acpi devices */
-	ret_val = acpi_bus_trim(device, 1);
-	printk(KERN_DEBUG "acpi_bus_trim remove 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))
-			pr_warn("%s: _PS3 failed\n", __func__);
-	}
-	if (flags & ROOT_BRIDGE_HAS_EJ0)
-		acpi_root_evaluate_object(handle, "_EJ0", 1);
+	acpi_bus_hot_remove_device(ej_event);
 }
 
 static void _handle_hotplug_event_root(struct work_struct *work)

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 02/22] PCI: Add root bus children dev's res to fail list
  2013-01-15 15:44         ` Yinghai Lu
@ 2013-01-15 21:52           ` Rafael J. Wysocki
  2013-01-15 22:03             ` Yinghai Lu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-15 21:52 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Tuesday, January 15, 2013 07:44:21 AM Yinghai Lu wrote:
> On Tue, Jan 15, 2013 at 3:21 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Monday, January 14, 2013 10:23:47 PM Yinghai Lu wrote:
> >> On Sat, Jan 12, 2013 at 1:37 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> >> > On Friday, January 11, 2013 02:40:29 PM Yinghai Lu wrote:
> >> >> We can stop trying according to try number now and do not need to use
> >> >> root_bus checking as stop sign anymore.
> >> >>
> >> >> In extreme case we could need to reallocate resource for device just
> >> >> under root bus.
> >> >
> >> > Well, the above says that we _can_ do the change, but it doesn't explain why it
> >> > is needed.  So what's the reason why we need to do that?
> >>
> >> In extreme case we could need to reallocate resource for device just
> >> under root bus.
> >>
> >> otherwise, those devices just under root bus will not be assigned
> >> resources again.
> >
> > IOW, our current code will not cover the case when we hot plug a host bridge
> > and need to reassign resources for devices integrated into it?
> 
> yes. in extreme case if _CRS range is not big enough.

It would be good to say that in the changelog too.  It's a clear justification
for the change if we're going to support root bridge hotplug (which we are).

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 08/22] PCI, acpiphp: Separate out hot-add support of pci host bridge
  2013-01-15 15:54       ` Yinghai Lu
@ 2013-01-15 22:00         ` Rafael J. Wysocki
  2013-01-15 22:04           ` Yinghai Lu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-15 22:00 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Tuesday, January 15, 2013 07:54:22 AM Yinghai Lu wrote:
> On Mon, Jan 14, 2013 at 10:44 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> > On Sat, Jan 12, 2013 at 3:18 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> >>> @@ -673,3 +673,223 @@ int __init acpi_pci_root_init(void)
> >>>
> >>>       return 0;
> >>>  }
> >>> +
> >>> +/*
> >>> + * Separated from drivers/pci/hotplug/acpiphp_glue.c
> >>> + *   only support root bridge
> >>> + */
> >>
> >> This comment will be useless after applying the patch.
> >>
> >>> +
> >>> +static LIST_HEAD(acpi_root_bridge_list);
> >>> +struct acpi_root_bridge {
> >>> +     struct list_head list;
> >>> +     acpi_handle handle;
> >>> +     u32 flags;
> >>> +};
> >>
> >> We have struct acpi_pci_root already.  Why do we need this in addition?
> >
> > will address that in following patch.
> 
> please check if you are ok with merging attached 5 patches in to one
> patches instead.

Do I understand correctly that you're asking whether to merge the attached
patches together, so as to obtain one combined patch?

If so, yes, I'd like that to be done.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 02/22] PCI: Add root bus children dev's res to fail list
  2013-01-15 21:52           ` Rafael J. Wysocki
@ 2013-01-15 22:03             ` Yinghai Lu
  0 siblings, 0 replies; 78+ messages in thread
From: Yinghai Lu @ 2013-01-15 22:03 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Tue, Jan 15, 2013 at 1:52 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Tuesday, January 15, 2013 07:44:21 AM Yinghai Lu wrote:
>> On Tue, Jan 15, 2013 at 3:21 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> > On Monday, January 14, 2013 10:23:47 PM Yinghai Lu wrote:
>> >> On Sat, Jan 12, 2013 at 1:37 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> >> > On Friday, January 11, 2013 02:40:29 PM Yinghai Lu wrote:
>> >> >> We can stop trying according to try number now and do not need to use
>> >> >> root_bus checking as stop sign anymore.
>> >> >>
>> >> >> In extreme case we could need to reallocate resource for device just
>> >> >> under root bus.
>> >> >
>> >> > Well, the above says that we _can_ do the change, but it doesn't explain why it
>> >> > is needed.  So what's the reason why we need to do that?
>> >>
>> >> In extreme case we could need to reallocate resource for device just
>> >> under root bus.
>> >>
>> >> otherwise, those devices just under root bus will not be assigned
>> >> resources again.
>> >
>> > IOW, our current code will not cover the case when we hot plug a host bridge
>> > and need to reassign resources for devices integrated into it?
>>
>> yes. in extreme case if _CRS range is not big enough.
>
> It would be good to say that in the changelog too.  It's a clear justification
> for the change if we're going to support root bridge hotplug (which we are).
>

ok.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 08/22] PCI, acpiphp: Separate out hot-add support of pci host bridge
  2013-01-15 22:00         ` Rafael J. Wysocki
@ 2013-01-15 22:04           ` Yinghai Lu
  0 siblings, 0 replies; 78+ messages in thread
From: Yinghai Lu @ 2013-01-15 22:04 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Tue, Jan 15, 2013 at 2:00 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> Do I understand correctly that you're asking whether to merge the attached
> patches together, so as to obtain one combined patch?
>
> If so, yes, I'd like that to be done.

good, will merge them for easy review.

Thanks

Yinghai

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 14/22] ACPI: update ej_event interface to take acpi_device
  2013-01-15 11:26       ` Rafael J. Wysocki
@ 2013-01-15 23:43         ` Yinghai Lu
  2013-01-15 23:55           ` Rafael J. Wysocki
  0 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-15 23:43 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Tue, Jan 15, 2013 at 3:26 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Monday, January 14, 2013 10:55:49 PM Yinghai Lu wrote:
>> On Sat, Jan 12, 2013 at 3:40 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> > On Friday, January 11, 2013 02:40:41 PM Yinghai Lu wrote:
>> >> Should use acpi_device pointer directly instead of use handle and
>> >> get the device pointer again later.
>> >
>> > Looks good.
>> >
>> > I can take this one right now if you want.
>>
>> yes, in acpi-scan branch?
>>
>> othewise i can not base on pci/next again.
>
> OK
>
> So I think there will be more patches in acpi-scan you'll need anyway, so
> I'll put this one on that branch too.

after updating pci root bus hotplug patches against your linux-next,
got panic during removal:

echo "PCI0 3" > /sys/kernel/debug/acpi/sci_notify
[   55.223155] ACPI: ACPI device name is <PCI0>, event code is <3>
[   55.226746] ACPI: Notify event is queued
[   55.228648] _handle_hotplug_event_root: Device eject notify on \_SB_.PCI0
10:~ # [   55.340169] ACPI: Device 0000:00:03.0 -x-> \_SB_.PCI0.S03_
[   55.341040] ACPI: Device 0000:00:02.0 -x-> \_SB_.PCI0.VGA_
[   55.341711] i2c i2c-0: adapter [SMBus PIIX4 adapter at b100] unregistered
[   55.342585] i2c-dev: adapter [SMBus PIIX4 adapter at b100] unregistered
[   55.343522] ACPI: Device 0000:00:01.3 -x-> \_SB_.PCI0.PX13
[   55.344660] ata1.00: disabled
[   55.350377] sd 0:0:0:0: [sda] Synchronizing SCSI cache
[   55.352729] sd 0:0:0:0: [sda]
[   55.353405] Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[   55.354010] sd 0:0:0:0: [sda] Stopping disk
[   55.358144] sd 0:0:0:0: [sda] START_STOP FAILED
[   55.358660] sd 0:0:0:0: [sda]
[   55.359026] Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[   55.361348] ata2.00: disabled
[   55.371548] ACPI: Device 0000:00:01.0 -x-> \_SB_.PCI0.ISA_
[   55.372268] ACPI: Device pci0000:00 -x-> \_SB_.PCI0
[   55.372747]   remove_bridge is called for \_SB_.PCI0 ffff8801964661e0
[   55.373581] acpiphp: Slot [31] unregistered
[   55.374110] pci_hotplug: pci_hp_deregister: Removed slot 31 from the list
[   55.374720] acpiphp: release_slot - physical_slot = 31
[   55.375195] pci_bus 0000:00: dev 1f, dec refcount to 0
[   55.375781] pci_bus 0000:00: dev 1f, released physical slot 31
[   55.376370] acpiphp: Slot [30] unregistered
[   55.376839] pci_hotplug: pci_hp_deregister: Removed slot 30 from the list
[   55.377512] acpiphp: release_slot - physical_slot = 30
[   55.377968] pci_bus 0000:00: dev 1e, dec refcount to 0
[   55.378432] pci_bus 0000:00: dev 1e, released physical slot 30
[   55.378976] acpiphp: Slot [29] unregistered
[   55.379375] pci_hotplug: pci_hp_deregister: Removed slot 29 from the list
[   55.379977] acpiphp: release_slot - physical_slot = 29
[   55.380479] pci_bus 0000:00: dev 1d, dec refcount to 0
[   55.380967] pci_bus 0000:00: dev 1d, released physical slot 29
[   55.381484] acpiphp: Slot [28] unregistered
[   55.381860] pci_hotplug: pci_hp_deregister: Removed slot 28 from the list
[   55.382485] acpiphp: release_slot - physical_slot = 28
[   55.383067] pci_bus 0000:00: dev 1c, dec refcount to 0
[   55.384426] pci_bus 0000:00: dev 1c, released physical slot 28
[   55.385830] acpiphp: Slot [27] unregistered
[   55.386852] pci_hotplug: pci_hp_deregister: Removed slot 27 from the list
[   55.388511] acpiphp: release_slot - physical_slot = 27
[   55.389750] pci_bus 0000:00: dev 1b, dec refcount to 0
[   55.390994] pci_bus 0000:00: dev 1b, released physical slot 27
[   55.392418] acpiphp: Slot [26] unregistered
[   55.393419] pci_hotplug: pci_hp_deregister: Removed slot 26 from the list
[   55.395034] acpiphp: release_slot - physical_slot = 26
[   55.396283] pci_bus 0000:00: dev 1a, dec refcount to 0
[   55.397514] pci_bus 0000:00: dev 1a, released physical slot 26
[   55.398901] acpiphp: Slot [25] unregistered
[   55.399927] pci_hotplug: pci_hp_deregister: Removed slot 25 from the list
[   55.401059] acpiphp: release_slot - physical_slot = 25
[   55.401761] pci_bus 0000:00: dev 19, dec refcount to 0
[   55.402715] pci_bus 0000:00: dev 19, released physical slot 25
[   55.403838] acpiphp: Slot [24] unregistered
[   55.404892] pci_hotplug: pci_hp_deregister: Removed slot 24 from the list
[   55.406501] acpiphp: release_slot - physical_slot = 24
[   55.407720] pci_bus 0000:00: dev 18, dec refcount to 0
[   55.409001] pci_bus 0000:00: dev 18, released physical slot 24
[   55.410220] acpiphp: Slot [23] unregistered
[   55.410951] pci_hotplug: pci_hp_deregister: Removed slot 23 from the list
[   55.412601] acpiphp: release_slot - physical_slot = 23
[   55.413840] pci_bus 0000:00: dev 17, dec refcount to 0
[   55.415092] pci_bus 0000:00: dev 17, released physical slot 23
[   55.416510] acpiphp: Slot [22] unregistered
[   55.417529] pci_hotplug: pci_hp_deregister: Removed slot 22 from the list
[   55.419153] acpiphp: release_slot - physical_slot = 22
[   55.420415] pci_bus 0000:00: dev 16, dec refcount to 0
[   55.421665] pci_bus 0000:00: dev 16, released physical slot 22
[   55.423069] acpiphp: Slot [21] unregistered
[   55.424110] pci_hotplug: pci_hp_deregister: Removed slot 21 from the list
[   55.425722] acpiphp: release_slot - physical_slot = 21
[   55.426952] pci_bus 0000:00: dev 15, dec refcount to 0
[   55.428209] pci_bus 0000:00: dev 15, released physical slot 21
[   55.429578] acpiphp: Slot [20] unregistered
[   55.430219] pci_hotplug: pci_hp_deregister: Removed slot 20 from the list
[   55.431123] acpiphp: release_slot - physical_slot = 20
[   55.431796] pci_bus 0000:00: dev 14, dec refcount to 0
[   55.432986] pci_bus 0000:00: dev 14, released physical slot 20
[   55.434392] acpiphp: Slot [19] unregistered
[   55.435411] pci_hotplug: pci_hp_deregister: Removed slot 19 from the list
[   55.437051] acpiphp: release_slot - physical_slot = 19
[   55.438309] pci_bus 0000:00: dev 13, dec refcount to 0
[   55.439556] pci_bus 0000:00: dev 13, released physical slot 19
[   55.440987] acpiphp: Slot [18] unregistered
[   55.441993] pci_hotplug: pci_hp_deregister: Removed slot 18 from the list
[   55.443511] acpiphp: release_slot - physical_slot = 18
[   55.444269] pci_bus 0000:00: dev 12, dec refcount to 0
[   55.445522] pci_bus 0000:00: dev 12, released physical slot 18
[   55.446949] acpiphp: Slot [17] unregistered
[   55.447961] pci_hotplug: pci_hp_deregister: Removed slot 17 from the list
[   55.449610] acpiphp: release_slot - physical_slot = 17
[   55.450839] pci_bus 0000:00: dev 11, dec refcount to 0
[   55.452097] pci_bus 0000:00: dev 11, released physical slot 17
[   55.453501] acpiphp: Slot [16] unregistered
[   55.454509] pci_hotplug: pci_hp_deregister: Removed slot 16 from the list
[   55.456151] acpiphp: release_slot - physical_slot = 16
[   55.457370] pci_bus 0000:00: dev 10, dec refcount to 0
[   55.458601] pci_bus 0000:00: dev 10, released physical slot 16
[   55.459775] acpiphp: Slot [15] unregistered
[   55.460444] pci_hotplug: pci_hp_deregister: Removed slot 15 from the list
[   55.461354] acpiphp: release_slot - physical_slot = 15
[   55.462059] pci_bus 0000:00: dev 0f, dec refcount to 0
[   55.462985] pci_bus 0000:00: dev 0f, released physical slot 15
[   55.464475] acpiphp: Slot [14] unregistered
[   55.465481] pci_hotplug: pci_hp_deregister: Removed slot 14 from the list
[   55.467089] acpiphp: release_slot - physical_slot = 14
[   55.468351] pci_bus 0000:00: dev 0e, dec refcount to 0
[   55.469597] pci_bus 0000:00: dev 0e, released physical slot 14
[   55.470994] acpiphp: Slot [13] unregistered
[   55.472033] pci_hotplug: pci_hp_deregister: Removed slot 13 from the list
[   55.473650] acpiphp: release_slot - physical_slot = 13
[   55.474878] pci_bus 0000:00: dev 0d, dec refcount to 0
[   55.476144] pci_bus 0000:00: dev 0d, released physical slot 13
[   55.477198] acpiphp: Slot [12] unregistered
[   55.477926] pci_hotplug: pci_hp_deregister: Removed slot 12 from the list
[   55.479561] acpiphp: release_slot - physical_slot = 12
[   55.480816] pci_bus 0000:00: dev 0c, dec refcount to 0
[   55.482073] pci_bus 0000:00: dev 0c, released physical slot 12
[   55.483475] acpiphp: Slot [11] unregistered
[   55.484515] pci_hotplug: pci_hp_deregister: Removed slot 11 from the list
[   55.486123] acpiphp: release_slot - physical_slot = 11
[   55.487338] pci_bus 0000:00: dev 0b, dec refcount to 0
[   55.488597] pci_bus 0000:00: dev 0b, released physical slot 11
[   55.489670] acpiphp: Slot [10] unregistered
[   55.490285] pci_hotplug: pci_hp_deregister: Removed slot 10 from the list
[   55.491700] acpiphp: release_slot - physical_slot = 10
[   55.492975] pci_bus 0000:00: dev 0a, dec refcount to 0
[   55.493800] pci_bus 0000:00: dev 0a, released physical slot 10
[   55.495103] acpiphp: Slot [9] unregistered
[   55.496121] pci_hotplug: pci_hp_deregister: Removed slot 9 from the list
[   55.497715] acpiphp: release_slot - physical_slot = 9
[   55.498929] pci_bus 0000:00: dev 09, dec refcount to 0
[   55.500206] pci_bus 0000:00: dev 09, released physical slot 9
[   55.501588] acpiphp: Slot [8] unregistered
[   55.502584] pci_hotplug: pci_hp_deregister: Removed slot 8 from the list
[   55.504196] acpiphp: release_slot - physical_slot = 8
[   55.505405] pci_bus 0000:00: dev 08, dec refcount to 0
[   55.506652] pci_bus 0000:00: dev 08, released physical slot 8
[   55.508057] acpiphp: Slot [7] unregistered
[   55.509060] pci_hotplug: pci_hp_deregister: Removed slot 7 from the list
[   55.510639] acpiphp: release_slot - physical_slot = 7
[   55.511838] pci_bus 0000:00: dev 07, dec refcount to 0
[   55.513117] pci_bus 0000:00: dev 07, released physical slot 7
[   55.514496] acpiphp: Slot [6] unregistered
[   55.515486] pci_hotplug: pci_hp_deregister: Removed slot 6 from the list
[   55.517099] acpiphp: release_slot - physical_slot = 6
[   55.518283] pci_bus 0000:00: dev 06, dec refcount to 0
[   55.519504] pci_bus 0000:00: dev 06, released physical slot 6
[   55.520365] acpiphp: Slot [5] unregistered
[   55.522045] pci_hotplug: pci_hp_deregister: Removed slot 5 from the list
[   55.523383] acpiphp: release_slot - physical_slot = 5
[   55.524627] pci_bus 0000:00: dev 05, dec refcount to 0
[   55.525887] pci_bus 0000:00: dev 05, released physical slot 5
[   55.527122] acpiphp: Slot [4] unregistered
[   55.527770] pci_hotplug: pci_hp_deregister: Removed slot 4 from the list
[   55.529417] acpiphp: release_slot - physical_slot = 4
[   55.530620] pci_bus 0000:00: dev 04, dec refcount to 0
[   55.531912] pci_bus 0000:00: dev 04, released physical slot 4
[   55.533325] acpiphp: Slot [3] unregistered
[   55.534327] pci_hotplug: pci_hp_deregister: Removed slot 3 from the list
[   55.535915] acpiphp: release_slot - physical_slot = 3
[   55.537147] pci_bus 0000:00: dev 03, dec refcount to 0
[   55.538388] pci_bus 0000:00: dev 03, released physical slot 3
[   55.539763]   acpi_pci_iommu_remove is called for \_SB_.PCI0 ffff8801964661e0
[   55.541569]   acpi_pci_ioapic_remove is called for \_SB_.PCI0
ffff8801964661e0
[   55.543356] ACPI: Delete PCI Interrupt Routing Table for 0000:00
[   55.544848] pci 0000:00:00.0: freeing pci_dev info
[   55.546002] pci 0000:00:01.0: freeing pci_dev info
[   55.547148] pci 0000:00:01.1: freeing pci_dev info
[   55.548304] pci 0000:00:01.3: freeing pci_dev info
[   55.549346] pci 0000:00:02.0: freeing pci_dev info
[   55.550058] pci 0000:00:03.0: freeing pci_dev info
[   55.550707] pci_bus 0000:00: busn_res: [bus 00-ff] is released
[   55.552535] pci_bus 0000:00: freeing pci_bus info
[   55.553424] pci_host_bridge pci0000:00: freeing pci_host_bridge info
[   55.555303] BUG: unable to handle kernel NULL pointer dereference
at           (null)
[   55.556269] IP: [<ffffffff8153bf9a>] acpi_power_resources_list_free+0x15/0x3f
[   55.556269] PGD 0
[   55.556269] Oops: 0000 [#1] SMP
[   55.556269] Modules linked in:
[   55.556269] CPU 0
[   55.556269] Pid: 1036, comm: kworker/0:1 Not tainted
3.8.0-rc3-yh-00703-gf602aca-dirty #1131 Bochs Bochs
[   55.556269] RIP: 0010:[<ffffffff8153bf9a>]  [<ffffffff8153bf9a>]
acpi_power_resources_list_free+0x15/0x3f
[   55.556269] RSP: 0018:ffff8801962479b8  EFLAGS: 00010292
[   55.556269] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000006
[   55.556269] RDX: 00000000000033a0 RSI: ffff8801960c2e18 RDI: ffff8801965db988
[   55.556269] RBP: ffff8801962479d8 R08: 0000000000000002 R09: 0000000000000000
[   55.556269] R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000000
[   55.556269] R13: ffff8801965db988 R14: ffff8801965db9e0 R15: ffff880196466528
[   55.556269] FS:  0000000000000000(0000) GS:ffff880199200000(0000)
knlGS:0000000000000000
[   55.556269] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[   55.556269] CR2: 0000000000000000 CR3: 0000000002c13000 CR4: 00000000000006f0
[   55.556269] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   55.556269] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[   55.556269] Process kworker/0:1 (pid: 1036, threadinfo
ffff880196246000, task ffff8801960c2500)
[   55.556269] Stack:
[   55.556269]  0000000000000000 ffff8801965db800 0000000000000000
ffff8801965db9d0
[   55.556269]  ffff880196247a08 ffffffff81536e2f ffffffff81536dff
ffff8801965db9e0
[   55.556269]  ffff8801965db9d0 ffff88019666de00 ffff880196247a38
ffffffff81710385
[   55.556269] Call Trace:
[   55.556269]  [<ffffffff81536e2f>] acpi_device_release+0x30/0x6a
[   55.556269]  [<ffffffff81536dff>] ? acpi_free_ids+0x50/0x50
[   55.556269]  [<ffffffff81710385>] device_release+0xa5/0x110
[   55.556269]  [<ffffffff814bda7f>] kobject_release+0x6f/0x90
[   55.556269]  [<ffffffff814bd93c>] kobject_put+0x4c/0x60
[   55.556269]  [<ffffffff81710087>] put_device+0x17/0x20
[   55.556269]  [<ffffffff8171133e>] device_unregister+0x1e/0x30
[   55.556269]  [<ffffffff815367ed>] acpi_device_unregister+0x162/0x177
[   55.556269]  [<ffffffff8153682d>] acpi_bus_remove+0x2b/0x2f
[   55.556269]  [<ffffffff815601c4>] acpi_ns_walk_namespace+0x114/0x250
[   55.556269]  [<ffffffff81536802>] ? acpi_device_unregister+0x177/0x177
[   55.556269]  [<ffffffff81536802>] ? acpi_device_unregister+0x177/0x177
[   55.556269]  [<ffffffff815607c5>] acpi_walk_namespace+0xee/0x137
[   55.556269]  [<ffffffff81536921>] acpi_bus_trim+0x64/0x7c
[   55.556269]  [<ffffffff815369b2>] acpi_bus_hot_remove_device+0x79/0x16d
[   55.556269]  [<ffffffff81196dc2>] ? kmem_cache_alloc_trace+0x42/0x150
[   55.556269]  [<ffffffff81539c18>] _handle_hotplug_event_root+0x108/0x149
[   55.556269]  [<ffffffff810a8b20>] ? process_one_work+0x270/0x560
[   55.556269]  [<ffffffff810a8b8d>] process_one_work+0x2dd/0x560
[   55.556269]  [<ffffffff810a8b20>] ? process_one_work+0x270/0x560
[   55.556269]  [<ffffffff810a9679>] ? worker_thread+0x59/0x3a0
[   55.556269]  [<ffffffff81539b10>] ? acpi_pci_find_root+0x3f/0x3f
[   55.556269]  [<ffffffff810a989a>] worker_thread+0x27a/0x3a0
[   55.556269]  [<ffffffff810e9f4d>] ? trace_hardirqs_on+0xd/0x10
[   55.556269]  [<ffffffff810a9620>] ? manage_workers+0x280/0x280
[   55.556269]  [<ffffffff810af088>] kthread+0xe8/0xf0
[   55.556269]  [<ffffffff810aefa0>] ? __init_kthread_worker+0x70/0x70
[   55.556269]  [<ffffffff8216d61c>] ret_from_fork+0x7c/0xb0
[   55.556269]  [<ffffffff810aefa0>] ? __init_kthread_worker+0x70/0x70
[   55.556269] Code: fe ff ff 48 8b 1b 4c 39 e3 75 ef 5b 5b 41 5c 44
89 e8 41 5d 5d c3 0f 1f 44 00 00 55 48 89 e5 41 55 49 89 fd 41 54 53
50 48 8b 1f <4c> 8b 23 eb 17 48 89 df e8 c9 34 f9 ff 48 89 df 4c 89 e3
e8 6e


looks like:

acpi_device_release+0x30
0xffffffff81536e2f is in acpi_device_release (drivers/acpi/scan.c:524).
519	static void acpi_free_power_resources_lists(struct acpi_device *device)
520	{
521		int i;
522	
523		acpi_power_resources_list_free(&device->wakeup.resources);
524		if (!device->flags.power_manageable)
525			return;
526	
527		for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
528			struct acpi_device_power_state *ps = &device->power.states[i];

wakeup.resources has problem?

Thanks

Yinghai

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 14/22] ACPI: update ej_event interface to take acpi_device
  2013-01-15 23:43         ` Yinghai Lu
@ 2013-01-15 23:55           ` Rafael J. Wysocki
  2013-01-16  0:22             ` Rafael J. Wysocki
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-15 23:55 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Tuesday, January 15, 2013 03:43:17 PM Yinghai Lu wrote:
> On Tue, Jan 15, 2013 at 3:26 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Monday, January 14, 2013 10:55:49 PM Yinghai Lu wrote:
> >> On Sat, Jan 12, 2013 at 3:40 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> >> > On Friday, January 11, 2013 02:40:41 PM Yinghai Lu wrote:
> >> >> Should use acpi_device pointer directly instead of use handle and
> >> >> get the device pointer again later.
> >> >
> >> > Looks good.
> >> >
> >> > I can take this one right now if you want.
> >>
> >> yes, in acpi-scan branch?
> >>
> >> othewise i can not base on pci/next again.
> >
> > OK
> >
> > So I think there will be more patches in acpi-scan you'll need anyway, so
> > I'll put this one on that branch too.
> 
> after updating pci root bus hotplug patches against your linux-next,
> got panic during removal:
> 
> echo "PCI0 3" > /sys/kernel/debug/acpi/sci_notify
> [   55.223155] ACPI: ACPI device name is <PCI0>, event code is <3>
> [   55.226746] ACPI: Notify event is queued
> [   55.228648] _handle_hotplug_event_root: Device eject notify on \_SB_.PCI0
> 10:~ # [   55.340169] ACPI: Device 0000:00:03.0 -x-> \_SB_.PCI0.S03_
> [   55.341040] ACPI: Device 0000:00:02.0 -x-> \_SB_.PCI0.VGA_
> [   55.341711] i2c i2c-0: adapter [SMBus PIIX4 adapter at b100] unregistered
> [   55.342585] i2c-dev: adapter [SMBus PIIX4 adapter at b100] unregistered
> [   55.343522] ACPI: Device 0000:00:01.3 -x-> \_SB_.PCI0.PX13
> [   55.344660] ata1.00: disabled
> [   55.350377] sd 0:0:0:0: [sda] Synchronizing SCSI cache
> [   55.352729] sd 0:0:0:0: [sda]
> [   55.353405] Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
> [   55.354010] sd 0:0:0:0: [sda] Stopping disk
> [   55.358144] sd 0:0:0:0: [sda] START_STOP FAILED
> [   55.358660] sd 0:0:0:0: [sda]
> [   55.359026] Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
> [   55.361348] ata2.00: disabled
> [   55.371548] ACPI: Device 0000:00:01.0 -x-> \_SB_.PCI0.ISA_
> [   55.372268] ACPI: Device pci0000:00 -x-> \_SB_.PCI0
> [   55.372747]   remove_bridge is called for \_SB_.PCI0 ffff8801964661e0
> [   55.373581] acpiphp: Slot [31] unregistered
> [   55.374110] pci_hotplug: pci_hp_deregister: Removed slot 31 from the list
> [   55.374720] acpiphp: release_slot - physical_slot = 31
> [   55.375195] pci_bus 0000:00: dev 1f, dec refcount to 0
> [   55.375781] pci_bus 0000:00: dev 1f, released physical slot 31
> [   55.376370] acpiphp: Slot [30] unregistered
> [   55.376839] pci_hotplug: pci_hp_deregister: Removed slot 30 from the list
> [   55.377512] acpiphp: release_slot - physical_slot = 30
> [   55.377968] pci_bus 0000:00: dev 1e, dec refcount to 0
> [   55.378432] pci_bus 0000:00: dev 1e, released physical slot 30
> [   55.378976] acpiphp: Slot [29] unregistered
> [   55.379375] pci_hotplug: pci_hp_deregister: Removed slot 29 from the list
> [   55.379977] acpiphp: release_slot - physical_slot = 29
> [   55.380479] pci_bus 0000:00: dev 1d, dec refcount to 0
> [   55.380967] pci_bus 0000:00: dev 1d, released physical slot 29
> [   55.381484] acpiphp: Slot [28] unregistered
> [   55.381860] pci_hotplug: pci_hp_deregister: Removed slot 28 from the list
> [   55.382485] acpiphp: release_slot - physical_slot = 28
> [   55.383067] pci_bus 0000:00: dev 1c, dec refcount to 0
> [   55.384426] pci_bus 0000:00: dev 1c, released physical slot 28
> [   55.385830] acpiphp: Slot [27] unregistered
> [   55.386852] pci_hotplug: pci_hp_deregister: Removed slot 27 from the list
> [   55.388511] acpiphp: release_slot - physical_slot = 27
> [   55.389750] pci_bus 0000:00: dev 1b, dec refcount to 0
> [   55.390994] pci_bus 0000:00: dev 1b, released physical slot 27
> [   55.392418] acpiphp: Slot [26] unregistered
> [   55.393419] pci_hotplug: pci_hp_deregister: Removed slot 26 from the list
> [   55.395034] acpiphp: release_slot - physical_slot = 26
> [   55.396283] pci_bus 0000:00: dev 1a, dec refcount to 0
> [   55.397514] pci_bus 0000:00: dev 1a, released physical slot 26
> [   55.398901] acpiphp: Slot [25] unregistered
> [   55.399927] pci_hotplug: pci_hp_deregister: Removed slot 25 from the list
> [   55.401059] acpiphp: release_slot - physical_slot = 25
> [   55.401761] pci_bus 0000:00: dev 19, dec refcount to 0
> [   55.402715] pci_bus 0000:00: dev 19, released physical slot 25
> [   55.403838] acpiphp: Slot [24] unregistered
> [   55.404892] pci_hotplug: pci_hp_deregister: Removed slot 24 from the list
> [   55.406501] acpiphp: release_slot - physical_slot = 24
> [   55.407720] pci_bus 0000:00: dev 18, dec refcount to 0
> [   55.409001] pci_bus 0000:00: dev 18, released physical slot 24
> [   55.410220] acpiphp: Slot [23] unregistered
> [   55.410951] pci_hotplug: pci_hp_deregister: Removed slot 23 from the list
> [   55.412601] acpiphp: release_slot - physical_slot = 23
> [   55.413840] pci_bus 0000:00: dev 17, dec refcount to 0
> [   55.415092] pci_bus 0000:00: dev 17, released physical slot 23
> [   55.416510] acpiphp: Slot [22] unregistered
> [   55.417529] pci_hotplug: pci_hp_deregister: Removed slot 22 from the list
> [   55.419153] acpiphp: release_slot - physical_slot = 22
> [   55.420415] pci_bus 0000:00: dev 16, dec refcount to 0
> [   55.421665] pci_bus 0000:00: dev 16, released physical slot 22
> [   55.423069] acpiphp: Slot [21] unregistered
> [   55.424110] pci_hotplug: pci_hp_deregister: Removed slot 21 from the list
> [   55.425722] acpiphp: release_slot - physical_slot = 21
> [   55.426952] pci_bus 0000:00: dev 15, dec refcount to 0
> [   55.428209] pci_bus 0000:00: dev 15, released physical slot 21
> [   55.429578] acpiphp: Slot [20] unregistered
> [   55.430219] pci_hotplug: pci_hp_deregister: Removed slot 20 from the list
> [   55.431123] acpiphp: release_slot - physical_slot = 20
> [   55.431796] pci_bus 0000:00: dev 14, dec refcount to 0
> [   55.432986] pci_bus 0000:00: dev 14, released physical slot 20
> [   55.434392] acpiphp: Slot [19] unregistered
> [   55.435411] pci_hotplug: pci_hp_deregister: Removed slot 19 from the list
> [   55.437051] acpiphp: release_slot - physical_slot = 19
> [   55.438309] pci_bus 0000:00: dev 13, dec refcount to 0
> [   55.439556] pci_bus 0000:00: dev 13, released physical slot 19
> [   55.440987] acpiphp: Slot [18] unregistered
> [   55.441993] pci_hotplug: pci_hp_deregister: Removed slot 18 from the list
> [   55.443511] acpiphp: release_slot - physical_slot = 18
> [   55.444269] pci_bus 0000:00: dev 12, dec refcount to 0
> [   55.445522] pci_bus 0000:00: dev 12, released physical slot 18
> [   55.446949] acpiphp: Slot [17] unregistered
> [   55.447961] pci_hotplug: pci_hp_deregister: Removed slot 17 from the list
> [   55.449610] acpiphp: release_slot - physical_slot = 17
> [   55.450839] pci_bus 0000:00: dev 11, dec refcount to 0
> [   55.452097] pci_bus 0000:00: dev 11, released physical slot 17
> [   55.453501] acpiphp: Slot [16] unregistered
> [   55.454509] pci_hotplug: pci_hp_deregister: Removed slot 16 from the list
> [   55.456151] acpiphp: release_slot - physical_slot = 16
> [   55.457370] pci_bus 0000:00: dev 10, dec refcount to 0
> [   55.458601] pci_bus 0000:00: dev 10, released physical slot 16
> [   55.459775] acpiphp: Slot [15] unregistered
> [   55.460444] pci_hotplug: pci_hp_deregister: Removed slot 15 from the list
> [   55.461354] acpiphp: release_slot - physical_slot = 15
> [   55.462059] pci_bus 0000:00: dev 0f, dec refcount to 0
> [   55.462985] pci_bus 0000:00: dev 0f, released physical slot 15
> [   55.464475] acpiphp: Slot [14] unregistered
> [   55.465481] pci_hotplug: pci_hp_deregister: Removed slot 14 from the list
> [   55.467089] acpiphp: release_slot - physical_slot = 14
> [   55.468351] pci_bus 0000:00: dev 0e, dec refcount to 0
> [   55.469597] pci_bus 0000:00: dev 0e, released physical slot 14
> [   55.470994] acpiphp: Slot [13] unregistered
> [   55.472033] pci_hotplug: pci_hp_deregister: Removed slot 13 from the list
> [   55.473650] acpiphp: release_slot - physical_slot = 13
> [   55.474878] pci_bus 0000:00: dev 0d, dec refcount to 0
> [   55.476144] pci_bus 0000:00: dev 0d, released physical slot 13
> [   55.477198] acpiphp: Slot [12] unregistered
> [   55.477926] pci_hotplug: pci_hp_deregister: Removed slot 12 from the list
> [   55.479561] acpiphp: release_slot - physical_slot = 12
> [   55.480816] pci_bus 0000:00: dev 0c, dec refcount to 0
> [   55.482073] pci_bus 0000:00: dev 0c, released physical slot 12
> [   55.483475] acpiphp: Slot [11] unregistered
> [   55.484515] pci_hotplug: pci_hp_deregister: Removed slot 11 from the list
> [   55.486123] acpiphp: release_slot - physical_slot = 11
> [   55.487338] pci_bus 0000:00: dev 0b, dec refcount to 0
> [   55.488597] pci_bus 0000:00: dev 0b, released physical slot 11
> [   55.489670] acpiphp: Slot [10] unregistered
> [   55.490285] pci_hotplug: pci_hp_deregister: Removed slot 10 from the list
> [   55.491700] acpiphp: release_slot - physical_slot = 10
> [   55.492975] pci_bus 0000:00: dev 0a, dec refcount to 0
> [   55.493800] pci_bus 0000:00: dev 0a, released physical slot 10
> [   55.495103] acpiphp: Slot [9] unregistered
> [   55.496121] pci_hotplug: pci_hp_deregister: Removed slot 9 from the list
> [   55.497715] acpiphp: release_slot - physical_slot = 9
> [   55.498929] pci_bus 0000:00: dev 09, dec refcount to 0
> [   55.500206] pci_bus 0000:00: dev 09, released physical slot 9
> [   55.501588] acpiphp: Slot [8] unregistered
> [   55.502584] pci_hotplug: pci_hp_deregister: Removed slot 8 from the list
> [   55.504196] acpiphp: release_slot - physical_slot = 8
> [   55.505405] pci_bus 0000:00: dev 08, dec refcount to 0
> [   55.506652] pci_bus 0000:00: dev 08, released physical slot 8
> [   55.508057] acpiphp: Slot [7] unregistered
> [   55.509060] pci_hotplug: pci_hp_deregister: Removed slot 7 from the list
> [   55.510639] acpiphp: release_slot - physical_slot = 7
> [   55.511838] pci_bus 0000:00: dev 07, dec refcount to 0
> [   55.513117] pci_bus 0000:00: dev 07, released physical slot 7
> [   55.514496] acpiphp: Slot [6] unregistered
> [   55.515486] pci_hotplug: pci_hp_deregister: Removed slot 6 from the list
> [   55.517099] acpiphp: release_slot - physical_slot = 6
> [   55.518283] pci_bus 0000:00: dev 06, dec refcount to 0
> [   55.519504] pci_bus 0000:00: dev 06, released physical slot 6
> [   55.520365] acpiphp: Slot [5] unregistered
> [   55.522045] pci_hotplug: pci_hp_deregister: Removed slot 5 from the list
> [   55.523383] acpiphp: release_slot - physical_slot = 5
> [   55.524627] pci_bus 0000:00: dev 05, dec refcount to 0
> [   55.525887] pci_bus 0000:00: dev 05, released physical slot 5
> [   55.527122] acpiphp: Slot [4] unregistered
> [   55.527770] pci_hotplug: pci_hp_deregister: Removed slot 4 from the list
> [   55.529417] acpiphp: release_slot - physical_slot = 4
> [   55.530620] pci_bus 0000:00: dev 04, dec refcount to 0
> [   55.531912] pci_bus 0000:00: dev 04, released physical slot 4
> [   55.533325] acpiphp: Slot [3] unregistered
> [   55.534327] pci_hotplug: pci_hp_deregister: Removed slot 3 from the list
> [   55.535915] acpiphp: release_slot - physical_slot = 3
> [   55.537147] pci_bus 0000:00: dev 03, dec refcount to 0
> [   55.538388] pci_bus 0000:00: dev 03, released physical slot 3
> [   55.539763]   acpi_pci_iommu_remove is called for \_SB_.PCI0 ffff8801964661e0
> [   55.541569]   acpi_pci_ioapic_remove is called for \_SB_.PCI0
> ffff8801964661e0
> [   55.543356] ACPI: Delete PCI Interrupt Routing Table for 0000:00
> [   55.544848] pci 0000:00:00.0: freeing pci_dev info
> [   55.546002] pci 0000:00:01.0: freeing pci_dev info
> [   55.547148] pci 0000:00:01.1: freeing pci_dev info
> [   55.548304] pci 0000:00:01.3: freeing pci_dev info
> [   55.549346] pci 0000:00:02.0: freeing pci_dev info
> [   55.550058] pci 0000:00:03.0: freeing pci_dev info
> [   55.550707] pci_bus 0000:00: busn_res: [bus 00-ff] is released
> [   55.552535] pci_bus 0000:00: freeing pci_bus info
> [   55.553424] pci_host_bridge pci0000:00: freeing pci_host_bridge info
> [   55.555303] BUG: unable to handle kernel NULL pointer dereference
> at           (null)
> [   55.556269] IP: [<ffffffff8153bf9a>] acpi_power_resources_list_free+0x15/0x3f
> [   55.556269] PGD 0
> [   55.556269] Oops: 0000 [#1] SMP
> [   55.556269] Modules linked in:
> [   55.556269] CPU 0
> [   55.556269] Pid: 1036, comm: kworker/0:1 Not tainted
> 3.8.0-rc3-yh-00703-gf602aca-dirty #1131 Bochs Bochs
> [   55.556269] RIP: 0010:[<ffffffff8153bf9a>]  [<ffffffff8153bf9a>]
> acpi_power_resources_list_free+0x15/0x3f
> [   55.556269] RSP: 0018:ffff8801962479b8  EFLAGS: 00010292
> [   55.556269] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000006
> [   55.556269] RDX: 00000000000033a0 RSI: ffff8801960c2e18 RDI: ffff8801965db988
> [   55.556269] RBP: ffff8801962479d8 R08: 0000000000000002 R09: 0000000000000000
> [   55.556269] R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000000
> [   55.556269] R13: ffff8801965db988 R14: ffff8801965db9e0 R15: ffff880196466528
> [   55.556269] FS:  0000000000000000(0000) GS:ffff880199200000(0000)
> knlGS:0000000000000000
> [   55.556269] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> [   55.556269] CR2: 0000000000000000 CR3: 0000000002c13000 CR4: 00000000000006f0
> [   55.556269] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [   55.556269] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> [   55.556269] Process kworker/0:1 (pid: 1036, threadinfo
> ffff880196246000, task ffff8801960c2500)
> [   55.556269] Stack:
> [   55.556269]  0000000000000000 ffff8801965db800 0000000000000000
> ffff8801965db9d0
> [   55.556269]  ffff880196247a08 ffffffff81536e2f ffffffff81536dff
> ffff8801965db9e0
> [   55.556269]  ffff8801965db9d0 ffff88019666de00 ffff880196247a38
> ffffffff81710385
> [   55.556269] Call Trace:
> [   55.556269]  [<ffffffff81536e2f>] acpi_device_release+0x30/0x6a
> [   55.556269]  [<ffffffff81536dff>] ? acpi_free_ids+0x50/0x50
> [   55.556269]  [<ffffffff81710385>] device_release+0xa5/0x110
> [   55.556269]  [<ffffffff814bda7f>] kobject_release+0x6f/0x90
> [   55.556269]  [<ffffffff814bd93c>] kobject_put+0x4c/0x60
> [   55.556269]  [<ffffffff81710087>] put_device+0x17/0x20
> [   55.556269]  [<ffffffff8171133e>] device_unregister+0x1e/0x30
> [   55.556269]  [<ffffffff815367ed>] acpi_device_unregister+0x162/0x177
> [   55.556269]  [<ffffffff8153682d>] acpi_bus_remove+0x2b/0x2f
> [   55.556269]  [<ffffffff815601c4>] acpi_ns_walk_namespace+0x114/0x250
> [   55.556269]  [<ffffffff81536802>] ? acpi_device_unregister+0x177/0x177
> [   55.556269]  [<ffffffff81536802>] ? acpi_device_unregister+0x177/0x177
> [   55.556269]  [<ffffffff815607c5>] acpi_walk_namespace+0xee/0x137
> [   55.556269]  [<ffffffff81536921>] acpi_bus_trim+0x64/0x7c
> [   55.556269]  [<ffffffff815369b2>] acpi_bus_hot_remove_device+0x79/0x16d
> [   55.556269]  [<ffffffff81196dc2>] ? kmem_cache_alloc_trace+0x42/0x150
> [   55.556269]  [<ffffffff81539c18>] _handle_hotplug_event_root+0x108/0x149
> [   55.556269]  [<ffffffff810a8b20>] ? process_one_work+0x270/0x560
> [   55.556269]  [<ffffffff810a8b8d>] process_one_work+0x2dd/0x560
> [   55.556269]  [<ffffffff810a8b20>] ? process_one_work+0x270/0x560
> [   55.556269]  [<ffffffff810a9679>] ? worker_thread+0x59/0x3a0
> [   55.556269]  [<ffffffff81539b10>] ? acpi_pci_find_root+0x3f/0x3f
> [   55.556269]  [<ffffffff810a989a>] worker_thread+0x27a/0x3a0
> [   55.556269]  [<ffffffff810e9f4d>] ? trace_hardirqs_on+0xd/0x10
> [   55.556269]  [<ffffffff810a9620>] ? manage_workers+0x280/0x280
> [   55.556269]  [<ffffffff810af088>] kthread+0xe8/0xf0
> [   55.556269]  [<ffffffff810aefa0>] ? __init_kthread_worker+0x70/0x70
> [   55.556269]  [<ffffffff8216d61c>] ret_from_fork+0x7c/0xb0
> [   55.556269]  [<ffffffff810aefa0>] ? __init_kthread_worker+0x70/0x70
> [   55.556269] Code: fe ff ff 48 8b 1b 4c 39 e3 75 ef 5b 5b 41 5c 44
> 89 e8 41 5d 5d c3 0f 1f 44 00 00 55 48 89 e5 41 55 49 89 fd 41 54 53
> 50 48 8b 1f <4c> 8b 23 eb 17 48 89 df e8 c9 34 f9 ff 48 89 df 4c 89 e3
> e8 6e
> 
> 
> looks like:
> 
> acpi_device_release+0x30
> 0xffffffff81536e2f is in acpi_device_release (drivers/acpi/scan.c:524).
> 519	static void acpi_free_power_resources_lists(struct acpi_device *device)
> 520	{
> 521		int i;
> 522	
> 523		acpi_power_resources_list_free(&device->wakeup.resources);
> 524		if (!device->flags.power_manageable)
> 525			return;
> 526	
> 527		for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
> 528			struct acpi_device_power_state *ps = &device->power.states[i];
> 
> wakeup.resources has problem?

Yes, it seems to.

Thanks for the report, looking into it.

Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 14/22] ACPI: update ej_event interface to take acpi_device
  2013-01-15 23:55           ` Rafael J. Wysocki
@ 2013-01-16  0:22             ` Rafael J. Wysocki
  2013-01-16  0:36               ` Yinghai Lu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-16  0:22 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Wednesday, January 16, 2013 12:55:20 AM Rafael J. Wysocki wrote:
> On Tuesday, January 15, 2013 03:43:17 PM Yinghai Lu wrote:
> > On Tue, Jan 15, 2013 at 3:26 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > > On Monday, January 14, 2013 10:55:49 PM Yinghai Lu wrote:
[...]
> > 
> > 
> > looks like:
> > 
> > acpi_device_release+0x30
> > 0xffffffff81536e2f is in acpi_device_release (drivers/acpi/scan.c:524).
> > 519	static void acpi_free_power_resources_lists(struct acpi_device *device)
> > 520	{
> > 521		int i;
> > 522	
> > 523		acpi_power_resources_list_free(&device->wakeup.resources);
> > 524		if (!device->flags.power_manageable)
> > 525			return;
> > 526	
> > 527		for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
> > 528			struct acpi_device_power_state *ps = &device->power.states[i];
> > 
> > wakeup.resources has problem?
> 
> Yes, it seems to.
> 
> Thanks for the report, looking into it.

Found a bug, fixed it and updated the tree (device->flags.wakeup.valid should
be checked before the acpi_power_resources_list_free(&device->wakeup.resources),
otherwise the list may not be initialized).

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 14/22] ACPI: update ej_event interface to take acpi_device
  2013-01-16  0:22             ` Rafael J. Wysocki
@ 2013-01-16  0:36               ` Yinghai Lu
  2013-01-16 14:05                 ` Rafael J. Wysocki
  0 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-16  0:36 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Tue, Jan 15, 2013 at 4:22 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Wednesday, January 16, 2013 12:55:20 AM Rafael J. Wysocki wrote:
>> On Tuesday, January 15, 2013 03:43:17 PM Yinghai Lu wrote:
>> > On Tue, Jan 15, 2013 at 3:26 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> > > On Monday, January 14, 2013 10:55:49 PM Yinghai Lu wrote:
> [...]
>> >
>> >
>> > looks like:
>> >
>> > acpi_device_release+0x30
>> > 0xffffffff81536e2f is in acpi_device_release (drivers/acpi/scan.c:524).
>> > 519 static void acpi_free_power_resources_lists(struct acpi_device *device)
>> > 520 {
>> > 521         int i;
>> > 522
>> > 523         acpi_power_resources_list_free(&device->wakeup.resources);
>> > 524         if (!device->flags.power_manageable)
>> > 525                 return;
>> > 526
>> > 527         for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
>> > 528                 struct acpi_device_power_state *ps = &device->power.states[i];
>> >
>> > wakeup.resources has problem?
>>
>> Yes, it seems to.
>>
>> Thanks for the report, looking into it.
>
> Found a bug, fixed it and updated the tree (device->flags.wakeup.valid should
> be checked before the acpi_power_resources_list_free(&device->wakeup.resources),
> otherwise the list may not be initialized).
>

still have problems:

[   63.971903] BUG: unable to handle kernel NULL pointer dereference
at 0000000000000010
[   63.972708] IP: [<ffffffff8153bf53>] acpi_power_off_list+0x19/0x53
[   63.972708] PGD 0
[   63.972708] Oops: 0000 [#1] SMP
[   63.972708] Modules linked in:
[   63.972708] CPU 0
[   63.972708] Pid: 4, comm: kworker/0:0 Not tainted
3.8.0-rc3-yh-00703-g5955587-dirty #1132 Bochs Bochs
[   63.972708] RIP: 0010:[<ffffffff8153bf53>]  [<ffffffff8153bf53>]
acpi_power_off_list+0x19/0x53
[   63.972708] RSP: 0018:ffff8801964bba78  EFLAGS: 00010203
[   63.972708] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00000001810000e5
[   63.972708] RDX: 00000001810000e6 RSI: 0000000000000004 RDI: ffff8801965de8e0
[   63.972708] RBP: ffff8801964bba98 R08: 0000000000000002 R09: ffff8801993d64b0
[   63.972708] R10: 0000000000000000 R11: 0000000000000001 R12: ffff8801965de8e0
[   63.972708] R13: 0000000000000001 R14: 0000000000000000 R15: ffff880196466528
[   63.972708] FS:  0000000000000000(0000) GS:ffff880199200000(0000)
knlGS:0000000000000000
[   63.972708] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[   63.972708] CR2: 0000000000000010 CR3: 000000017f10a000 CR4: 00000000000006f0
[   63.972708] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   63.972708] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[   63.972708] Process kworker/0:0 (pid: 4, threadinfo
ffff8801964ba000, task ffff880196580000)
[   63.972708] Stack:
[   63.972708]  ffff8801965de800 0000000000000004 ffff8801965de800
0000000000000001
[   63.972708]  ffff8801964bbab8 ffffffff8153c65e ffff8801965de800
ffff8801965de9d0
[   63.972708]  ffff8801964bbae8 ffffffff815367fa ffff8801964bbb08
0000000000000001
[   63.972708] Call Trace:
[   63.972708]  [<ffffffff8153c65e>] acpi_power_transition+0x6c/0x98
[   63.972708]  [<ffffffff815367fa>] acpi_device_unregister+0x16f/0x177
[   63.972708]  [<ffffffff8153682d>] acpi_bus_remove+0x2b/0x2f
[   63.972708]  [<ffffffff815601cc>] acpi_ns_walk_namespace+0x114/0x250
[   63.972708]  [<ffffffff81536802>] ? acpi_device_unregister+0x177/0x177
[   63.972708]  [<ffffffff81536802>] ? acpi_device_unregister+0x177/0x177
[   63.972708]  [<ffffffff815607cd>] acpi_walk_namespace+0xee/0x137
[   63.972708]  [<ffffffff81536921>] acpi_bus_trim+0x64/0x7c
[   63.972708]  [<ffffffff815369b2>] acpi_bus_hot_remove_device+0x79/0x16d
[   63.972708]  [<ffffffff81196dc2>] ? kmem_cache_alloc_trace+0x42/0x150
[   63.972708]  [<ffffffff81539c20>] _handle_hotplug_event_root+0x108/0x149
[   63.972708]  [<ffffffff810a8b20>] ? process_one_work+0x270/0x560
[   63.972708]  [<ffffffff810a8b8d>] process_one_work+0x2dd/0x560
[   63.972708]  [<ffffffff810a8b20>] ? process_one_work+0x270/0x560
[   63.972708]  [<ffffffff810a9679>] ? worker_thread+0x59/0x3a0
[   63.972708]  [<ffffffff81539b18>] ? acpi_pci_find_root+0x3f/0x3f
[   63.972708]  [<ffffffff810a989a>] worker_thread+0x27a/0x3a0
[   63.972708]  [<ffffffff810e9f4d>] ? trace_hardirqs_on+0xd/0x10
[   63.972708]  [<ffffffff810a9620>] ? manage_workers+0x280/0x280
[   63.972708]  [<ffffffff810af088>] kthread+0xe8/0xf0
[   63.972708]  [<ffffffff810aefa0>] ? __init_kthread_worker+0x70/0x70
[   63.972708]  [<ffffffff8216d61c>] ret_from_fork+0x7c/0xb0
[   63.972708]  [<ffffffff810aefa0>] ? __init_kthread_worker+0x70/0x70
[   63.972708] Code: 08 4c 39 e3 75 ee 41 5a 5b 41 5c 44 89 e8 41 5d
5d c3 0f 1f 44 00 00 55 48 89 e5 41 55 41 54 53 41 54 49 89 fc 48 8b
5f 08 eb 14 <48> 8b 7b 10 e8 22 fd ff ff 85 c0 41 89 c5 75 17 48 8b 5b
08 4c

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 22/22] PCI: move device_add out of pci_bus_add_device()
  2013-01-11 22:40 ` [PATCH v8 22/22] PCI: move device_add out of pci_bus_add_device() Yinghai Lu
  2013-01-12 23:54   ` Rafael J. Wysocki
@ 2013-01-16  2:29   ` Yijing Wang
  2013-01-16  2:41     ` Yinghai Lu
  1 sibling, 1 reply; 78+ messages in thread
From: Yijing Wang @ 2013-01-16  2:29 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi,
	Jiang Liu, linux-pci, linux-kernel, linux-acpi

On 2013/1/12 6:40, Yinghai Lu wrote:
> Move out device registering out of pci_bus_add_devices, so we could
> put new created pci devices in device tree early.
> 
> new pci_bus_add_devices will do the device_attach work to load pci drivers
> instead.
> 
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/pci/bus.c   |   47 +++--------------------------------------------
>  drivers/pci/iov.c   |    7 -------
>  drivers/pci/probe.c |   34 +++++++++++++++++++++++++++-------
>  3 files changed, 30 insertions(+), 58 deletions(-)
> 
> diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
> index 1f5916a..0a55845 100644
> --- a/drivers/pci/bus.c
> +++ b/drivers/pci/bus.c
> @@ -178,22 +178,9 @@ static void pci_bus_attach_device(struct pci_dev *dev)
>   */
>  int pci_bus_add_device(struct pci_dev *dev)
>  {
> -	int retval;
> -
> -	pci_fixup_device(pci_fixup_final, dev);
> -
> -	retval = pcibios_add_device(dev);
> -	if (retval)
> -		return retval;
> -
> -	retval = device_add(&dev->dev);
> -	if (retval)
> -		return retval;
> -
>  	pci_bus_attach_device(dev);
>  	dev->is_added = 1;
> -	pci_proc_attach_device(dev);
> -	pci_create_sysfs_dev_files(dev);
> +
>  	return 0;
>  }


Hi Yinghai,
   Should change pci_bus_add_device() function to void return now? So some unnecessary ret check can remove.

>  
> @@ -205,21 +192,9 @@ int pci_bus_add_device(struct pci_dev *dev)
>   */
>  int pci_bus_add_child(struct pci_bus *bus)
>  {
> -	int retval;
> -
> -	if (bus->bridge)
> -		bus->dev.parent = bus->bridge;
> -
> -	retval = device_add(&bus->dev);
> -	if (retval)
> -		return retval;
> -
>  	bus->is_added = 1;
>  
> -	/* Create legacy_io and legacy_mem files for this bus */
> -	pci_create_legacy_files(bus);
> -
> -	return retval;
> +	return 0;
>  }
>  
>  /**
> @@ -245,36 +220,20 @@ void pci_bus_add_devices(const struct pci_bus *bus)
>  		if (dev->is_added)
>  			continue;
>  		retval = pci_bus_add_device(dev);
> -		if (retval)
> -			dev_err(&dev->dev, "Error adding device, continuing\n");
>  	}
>  
>  	list_for_each_entry(dev, &bus->devices, bus_list) {
>  		BUG_ON(!dev->is_added);
>  
>  		child = dev->subordinate;
> -		/*
> -		 * If there is an unattached subordinate bus, attach
> -		 * it and then scan for unattached PCI devices.
> -		 */
> +
>  		if (!child)
>  			continue;
> -		if (list_empty(&child->node)) {
> -			down_write(&pci_bus_sem);
> -			list_add_tail(&child->node, &dev->bus->children);
> -			up_write(&pci_bus_sem);
> -		}
>  		pci_bus_add_devices(child);
>  
> -		/*
> -		 * register the bus with sysfs as the parent is now
> -		 * properly registered.
> -		 */
>  		if (child->is_added)
>  			continue;
>  		retval = pci_bus_add_child(child);
> -		if (retval)
> -			dev_err(&dev->dev, "Error adding bus, continuing\n");
>  	}
>  }
>  
> diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
> index bafd2bb..dbad72e 100644
> --- a/drivers/pci/iov.c
> +++ b/drivers/pci/iov.c
> @@ -48,12 +48,7 @@ static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
>  		return NULL;
>  
>  	pci_bus_insert_busn_res(child, busnr, busnr);
> -	child->dev.parent = bus->bridge;
>  	rc = pci_bus_add_child(child);
> -	if (rc) {
> -		pci_remove_bus(child);
> -		return NULL;
> -	}
>  
>  	return child;
>  }
> @@ -123,8 +118,6 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
>  	virtfn->is_virtfn = 1;
>  
>  	rc = pci_bus_add_device(virtfn);
> -	if (rc)
> -		goto failed1;
>  	sprintf(buf, "virtfn%u", id);
>  	rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
>  	if (rc)
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index dc4fde3..84c92a0 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -623,6 +623,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
>  {
>  	struct pci_bus *child;
>  	int i;
> +	int ret;
>  
>  	/*
>  	 * Allocate a new bus, and inherit stuff from the parent..
> @@ -637,8 +638,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
>  	child->bus_flags = parent->bus_flags;
>  
>  	/* initialize some portions of the bus device, but don't register it
> -	 * now as the parent is not properly set up yet.  This device will get
> -	 * registered later in pci_bus_add_devices()
> +	 * now as the parent is not properly set up yet.
>  	 */
>  	child->dev.class = &pcibus_class;
>  	dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr);
> @@ -652,11 +652,14 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
>  	child->primary = parent->busn_res.start;
>  	child->busn_res.end = 0xff;
>  
> -	if (!bridge)
> -		return child;
> +	if (!bridge) {
> +		child->dev.parent = parent->bridge;
> +		goto add_dev;
> +	}
>  
>  	child->self = bridge;
>  	child->bridge = get_device(&bridge->dev);
> +	child->dev.parent = child->bridge;
>  	pci_set_bus_of_node(child);
>  	pci_set_bus_speed(child);
>  
> @@ -667,6 +670,13 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
>  	}
>  	bridge->subordinate = child;
>  
> +add_dev:
> +	ret = device_add(&child->dev);
> +	WARN_ON(ret < 0);
> +
> +	/* Create legacy_io and legacy_mem files for this bus */
> +	pci_create_legacy_files(child);
> +
>  	return child;
>  }
>  
> @@ -1297,6 +1307,8 @@ static void pci_init_capabilities(struct pci_dev *dev)
>  
>  void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>  {
> +	int ret;
> +
>  	device_initialize(&dev->dev);
>  	dev->dev.release = pci_release_dev;
>  
> @@ -1327,6 +1339,16 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>  	down_write(&pci_bus_sem);
>  	list_add_tail(&dev->bus_list, &bus->devices);
>  	up_write(&pci_bus_sem);
> +
> +	pci_fixup_device(pci_fixup_final, dev);
> +        ret = pcibios_add_device(dev);
> +	WARN_ON(ret < 0);
> +	/* notifier could use pci capabilities */
> +	ret = device_add(&dev->dev);
> +	WARN_ON(ret < 0);
> +
> +	pci_proc_attach_device(dev);
> +	pci_create_sysfs_dev_files(dev);
>  }
>  
>  struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn)
> @@ -1645,13 +1667,13 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>  	char bus_addr[64];
>  	char *fmt;
>  
> -
>  	b = pci_alloc_bus();
>  	if (!b)
>  		return NULL;
>  
>  	b->sysdata = sysdata;
>  	b->ops = ops;
> +	b->number = b->busn_res.start = bus;
>  	b2 = pci_find_bus(pci_domain_nr(b), bus);
>  	if (b2) {
>  		/* If we already got to this bus through a different bridge, ignore it */
> @@ -1687,8 +1709,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>  	/* Create legacy_io and legacy_mem files for this bus */
>  	pci_create_legacy_files(b);
>  
> -	b->number = b->busn_res.start = bus;
> -
>  	if (parent)
>  		dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
>  	else
> 


-- 
Thanks!
Yijing


^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 22/22] PCI: move device_add out of pci_bus_add_device()
  2013-01-16  2:29   ` Yijing Wang
@ 2013-01-16  2:41     ` Yinghai Lu
  0 siblings, 0 replies; 78+ messages in thread
From: Yinghai Lu @ 2013-01-16  2:41 UTC (permalink / raw)
  To: Yijing Wang
  Cc: Bjorn Helgaas, Rafael J. Wysocki, Len Brown, Taku Izumi,
	Jiang Liu, linux-pci, linux-kernel, linux-acpi

On Tue, Jan 15, 2013 at 6:29 PM, Yijing Wang <wangyijing@huawei.com> wrote:
> On 2013/1/12 6:40, Yinghai Lu wrote:
>> Move out device registering out of pci_bus_add_devices, so we could
>> put new created pci devices in device tree early.
>>
>> new pci_bus_add_devices will do the device_attach work to load pci drivers
>> instead.
>>
>> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>> ---
>>  drivers/pci/bus.c   |   47 +++--------------------------------------------
>>  drivers/pci/iov.c   |    7 -------
>>  drivers/pci/probe.c |   34 +++++++++++++++++++++++++++-------
>>  3 files changed, 30 insertions(+), 58 deletions(-)
>>
>> diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
>> index 1f5916a..0a55845 100644
>> --- a/drivers/pci/bus.c
>> +++ b/drivers/pci/bus.c
>> @@ -178,22 +178,9 @@ static void pci_bus_attach_device(struct pci_dev *dev)
>>   */
>>  int pci_bus_add_device(struct pci_dev *dev)
>>  {
>> -     int retval;
>> -
>> -     pci_fixup_device(pci_fixup_final, dev);
>> -
>> -     retval = pcibios_add_device(dev);
>> -     if (retval)
>> -             return retval;
>> -
>> -     retval = device_add(&dev->dev);
>> -     if (retval)
>> -             return retval;
>> -
>>       pci_bus_attach_device(dev);
>>       dev->is_added = 1;
>> -     pci_proc_attach_device(dev);
>> -     pci_create_sysfs_dev_files(dev);
>> +
>>       return 0;
>>  }
>
>
> Hi Yinghai,
>    Should change pci_bus_add_device() function to void return now? So some unnecessary ret check can remove.
>

yeah, maybe later. this patch is already some kind of big now.

also there is outside caller...

drivers/edac/i82875p_edac.c:            err = pci_bus_add_device(dev);
drivers/platform/x86/asus-wmi.c:                                if
(pci_bus_add_device(dev))
drivers/platform/x86/eeepc-laptop.c:                            if
(pci_bus_add_device(dev))

so let change that later.

Thanks

Yinghai

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 14/22] ACPI: update ej_event interface to take acpi_device
  2013-01-16  0:36               ` Yinghai Lu
@ 2013-01-16 14:05                 ` Rafael J. Wysocki
  2013-01-16 19:37                   ` Yinghai Lu
  0 siblings, 1 reply; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-16 14:05 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Tuesday, January 15, 2013 04:36:19 PM Yinghai Lu wrote:
> On Tue, Jan 15, 2013 at 4:22 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Wednesday, January 16, 2013 12:55:20 AM Rafael J. Wysocki wrote:
> >> On Tuesday, January 15, 2013 03:43:17 PM Yinghai Lu wrote:
> >> > On Tue, Jan 15, 2013 at 3:26 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> >> > > On Monday, January 14, 2013 10:55:49 PM Yinghai Lu wrote:
> > [...]
> >> >
> >> >
> >> > looks like:
> >> >
> >> > acpi_device_release+0x30
> >> > 0xffffffff81536e2f is in acpi_device_release (drivers/acpi/scan.c:524).
> >> > 519 static void acpi_free_power_resources_lists(struct acpi_device *device)
> >> > 520 {
> >> > 521         int i;
> >> > 522
> >> > 523         acpi_power_resources_list_free(&device->wakeup.resources);
> >> > 524         if (!device->flags.power_manageable)
> >> > 525                 return;
> >> > 526
> >> > 527         for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
> >> > 528                 struct acpi_device_power_state *ps = &device->power.states[i];
> >> >
> >> > wakeup.resources has problem?
> >>
> >> Yes, it seems to.
> >>
> >> Thanks for the report, looking into it.
> >
> > Found a bug, fixed it and updated the tree (device->flags.wakeup.valid should
> > be checked before the acpi_power_resources_list_free(&device->wakeup.resources),
> > otherwise the list may not be initialized).
> >
> 
> still have problems:

My bad, sorry about that.

> [   63.971903] BUG: unable to handle kernel NULL pointer dereference
> at 0000000000000010
> [   63.972708] IP: [<ffffffff8153bf53>] acpi_power_off_list+0x19/0x53
> [   63.972708] PGD 0
> [   63.972708] Oops: 0000 [#1] SMP
> [   63.972708] Modules linked in:
> [   63.972708] CPU 0
> [   63.972708] Pid: 4, comm: kworker/0:0 Not tainted
> 3.8.0-rc3-yh-00703-g5955587-dirty #1132 Bochs Bochs
> [   63.972708] RIP: 0010:[<ffffffff8153bf53>]  [<ffffffff8153bf53>]
> acpi_power_off_list+0x19/0x53
> [   63.972708] RSP: 0018:ffff8801964bba78  EFLAGS: 00010203
> [   63.972708] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00000001810000e5
> [   63.972708] RDX: 00000001810000e6 RSI: 0000000000000004 RDI: ffff8801965de8e0
> [   63.972708] RBP: ffff8801964bba98 R08: 0000000000000002 R09: ffff8801993d64b0
> [   63.972708] R10: 0000000000000000 R11: 0000000000000001 R12: ffff8801965de8e0
> [   63.972708] R13: 0000000000000001 R14: 0000000000000000 R15: ffff880196466528
> [   63.972708] FS:  0000000000000000(0000) GS:ffff880199200000(0000)
> knlGS:0000000000000000
> [   63.972708] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> [   63.972708] CR2: 0000000000000010 CR3: 000000017f10a000 CR4: 00000000000006f0
> [   63.972708] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [   63.972708] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> [   63.972708] Process kworker/0:0 (pid: 4, threadinfo
> ffff8801964ba000, task ffff880196580000)
> [   63.972708] Stack:
> [   63.972708]  ffff8801965de800 0000000000000004 ffff8801965de800
> 0000000000000001
> [   63.972708]  ffff8801964bbab8 ffffffff8153c65e ffff8801965de800
> ffff8801965de9d0
> [   63.972708]  ffff8801964bbae8 ffffffff815367fa ffff8801964bbb08
> 0000000000000001
> [   63.972708] Call Trace:
> [   63.972708]  [<ffffffff8153c65e>] acpi_power_transition+0x6c/0x98
> [   63.972708]  [<ffffffff815367fa>] acpi_device_unregister+0x16f/0x177
> [   63.972708]  [<ffffffff8153682d>] acpi_bus_remove+0x2b/0x2f
> [   63.972708]  [<ffffffff815601cc>] acpi_ns_walk_namespace+0x114/0x250
> [   63.972708]  [<ffffffff81536802>] ? acpi_device_unregister+0x177/0x177
> [   63.972708]  [<ffffffff81536802>] ? acpi_device_unregister+0x177/0x177
> [   63.972708]  [<ffffffff815607cd>] acpi_walk_namespace+0xee/0x137
> [   63.972708]  [<ffffffff81536921>] acpi_bus_trim+0x64/0x7c
> [   63.972708]  [<ffffffff815369b2>] acpi_bus_hot_remove_device+0x79/0x16d
> [   63.972708]  [<ffffffff81196dc2>] ? kmem_cache_alloc_trace+0x42/0x150
> [   63.972708]  [<ffffffff81539c20>] _handle_hotplug_event_root+0x108/0x149
> [   63.972708]  [<ffffffff810a8b20>] ? process_one_work+0x270/0x560
> [   63.972708]  [<ffffffff810a8b8d>] process_one_work+0x2dd/0x560
> [   63.972708]  [<ffffffff810a8b20>] ? process_one_work+0x270/0x560
> [   63.972708]  [<ffffffff810a9679>] ? worker_thread+0x59/0x3a0
> [   63.972708]  [<ffffffff81539b18>] ? acpi_pci_find_root+0x3f/0x3f
> [   63.972708]  [<ffffffff810a989a>] worker_thread+0x27a/0x3a0
> [   63.972708]  [<ffffffff810e9f4d>] ? trace_hardirqs_on+0xd/0x10
> [   63.972708]  [<ffffffff810a9620>] ? manage_workers+0x280/0x280
> [   63.972708]  [<ffffffff810af088>] kthread+0xe8/0xf0
> [   63.972708]  [<ffffffff810aefa0>] ? __init_kthread_worker+0x70/0x70
> [   63.972708]  [<ffffffff8216d61c>] ret_from_fork+0x7c/0xb0
> [   63.972708]  [<ffffffff810aefa0>] ? __init_kthread_worker+0x70/0x70
> [   63.972708] Code: 08 4c 39 e3 75 ee 41 5a 5b 41 5c 44 89 e8 41 5d
> 5d c3 0f 1f 44 00 00 55 48 89 e5 41 55 41 54 53 41 54 49 89 fc 48 8b
> 5f 08 eb 14 <48> 8b 7b 10 e8 22 fd ff ff 85 c0 41 89 c5 75 17 48 8b 5b
> 08 4c

acpi_power_transition() has to check if the device is power-manageable, since
otherwise the power resources lists will not be initialized.  It should be
fixed now.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 14/22] ACPI: update ej_event interface to take acpi_device
  2013-01-16 14:05                 ` Rafael J. Wysocki
@ 2013-01-16 19:37                   ` Yinghai Lu
  2013-01-16 21:48                     ` Rafael J. Wysocki
  0 siblings, 1 reply; 78+ messages in thread
From: Yinghai Lu @ 2013-01-16 19:37 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Wed, Jan 16, 2013 at 6:05 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>
> acpi_power_transition() has to check if the device is power-manageable, since
> otherwise the power resources lists will not be initialized.  It should be
> fixed now.

yes, it works now with pm/linux-next.

will resend updated patchset after new acpi-scan get into pci/next.

Thanks

Yinghai

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v8 14/22] ACPI: update ej_event interface to take acpi_device
  2013-01-16 19:37                   ` Yinghai Lu
@ 2013-01-16 21:48                     ` Rafael J. Wysocki
  0 siblings, 0 replies; 78+ messages in thread
From: Rafael J. Wysocki @ 2013-01-16 21:48 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, Len Brown, Taku Izumi, Jiang Liu, linux-pci,
	linux-kernel, linux-acpi

On Wednesday, January 16, 2013 11:37:40 AM Yinghai Lu wrote:
> On Wed, Jan 16, 2013 at 6:05 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> >
> > acpi_power_transition() has to check if the device is power-manageable, since
> > otherwise the power resources lists will not be initialized.  It should be
> > fixed now.
> 
> yes, it works now with pm/linux-next.

Cool, thanks for testing!

> will resend updated patchset after new acpi-scan get into pci/next.

I'll put the new patches into acpi-scan tomorrow.  After that it's up to Bjorn
to decide when to pull them.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 78+ messages in thread

end of thread, other threads:[~2013-01-16 21:42 UTC | newest]

Thread overview: 78+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-11 22:40 [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Yinghai Lu
2013-01-11 22:40 ` [PATCH v8 01/22] PCI, acpiphp: Add is_hotplug_bridge detection Yinghai Lu
2013-01-12 21:35   ` Rafael J. Wysocki
2013-01-15  6:45   ` Yijing Wang
2013-01-15  7:05     ` Yinghai Lu
2013-01-11 22:40 ` [PATCH v8 02/22] PCI: Add root bus children dev's res to fail list Yinghai Lu
2013-01-12 21:37   ` Rafael J. Wysocki
2013-01-15  6:23     ` Yinghai Lu
2013-01-15 11:21       ` Rafael J. Wysocki
2013-01-15 15:44         ` Yinghai Lu
2013-01-15 21:52           ` Rafael J. Wysocki
2013-01-15 22:03             ` Yinghai Lu
2013-01-11 22:40 ` [PATCH v8 03/22] PCI: Set dev_node early for pci_dev Yinghai Lu
2013-01-12 21:38   ` Rafael J. Wysocki
2013-01-11 22:40 ` [PATCH v8 04/22] PCI: Fix a device reference count leakage issue in pci_dev_present() Yinghai Lu
2013-01-12 21:39   ` Rafael J. Wysocki
2013-01-11 22:40 ` [PATCH v8 05/22] PCI: make PCI device create/destroy logic symmetric Yinghai Lu
2013-01-12 21:40   ` Rafael J. Wysocki
2013-01-11 22:40 ` [PATCH v8 06/22] PCI: split registration of PCI bus devices into two stages Yinghai Lu
2013-01-12 22:34   ` Rafael J. Wysocki
2013-01-13 15:25     ` Jiang Liu
2013-01-15  6:29       ` Yinghai Lu
2013-01-11 22:40 ` [PATCH v8 07/22] ACPI: Separate acpi_bus_trim to support two steps Yinghai Lu
2013-01-12 22:40   ` Rafael J. Wysocki
2013-01-15  6:31     ` Yinghai Lu
2013-01-15 11:22       ` Rafael J. Wysocki
2013-01-11 22:40 ` [PATCH v8 08/22] PCI, acpiphp: Separate out hot-add support of pci host bridge Yinghai Lu
2013-01-12 23:18   ` Rafael J. Wysocki
2013-01-15  6:44     ` Yinghai Lu
2013-01-15 15:54       ` Yinghai Lu
2013-01-15 22:00         ` Rafael J. Wysocki
2013-01-15 22:04           ` Yinghai Lu
2013-01-11 22:40 ` [PATCH v8 09/22] PCI, ACPI: Add pci_root_hp hot removal notification support Yinghai Lu
2013-01-12 23:26   ` Rafael J. Wysocki
2013-01-15  6:45     ` Yinghai Lu
2013-01-11 22:40 ` [PATCH v8 10/22] ACPI: Introduce a new acpi handle to determine HID match Yinghai Lu
2013-01-12 23:27   ` Rafael J. Wysocki
2013-01-11 22:40 ` [PATCH v8 11/22] PCI: correctly detect ACPI PCI host bridge objects Yinghai Lu
2013-01-12 23:34   ` Rafael J. Wysocki
2013-01-13 15:32     ` Jiang Liu
2013-01-11 22:40 ` [PATCH v8 12/22] PCI, ACPI: debug print for installation of acpi root bridge's notifier Yinghai Lu
2013-01-12 23:37   ` Rafael J. Wysocki
2013-01-11 22:40 ` [PATCH v8 13/22] PCI, ACPI: remove acpi_root_bridge in pci_root_hp Yinghai Lu
2013-01-12 23:39   ` Rafael J. Wysocki
2013-01-11 22:40 ` [PATCH v8 14/22] ACPI: update ej_event interface to take acpi_device Yinghai Lu
2013-01-12 23:40   ` Rafael J. Wysocki
2013-01-15  6:55     ` Yinghai Lu
2013-01-15 11:26       ` Rafael J. Wysocki
2013-01-15 23:43         ` Yinghai Lu
2013-01-15 23:55           ` Rafael J. Wysocki
2013-01-16  0:22             ` Rafael J. Wysocki
2013-01-16  0:36               ` Yinghai Lu
2013-01-16 14:05                 ` Rafael J. Wysocki
2013-01-16 19:37                   ` Yinghai Lu
2013-01-16 21:48                     ` Rafael J. Wysocki
2013-01-11 22:40 ` [PATCH v8 15/22] ACPI, PCI: Simplify handle_root_bridge_removal() Yinghai Lu
2013-01-12 23:42   ` Rafael J. Wysocki
2013-01-11 22:40 ` [PATCH v8 16/22] PCI, acpiphp: Don't bailout even no slots found yet Yinghai Lu
2013-01-12 23:43   ` Rafael J. Wysocki
2013-01-11 22:40 ` [PATCH v8 17/22] PCI, ACPI: Add alloc_acpi_hp_work() Yinghai Lu
2013-01-12 23:45   ` Rafael J. Wysocki
2013-01-15  6:59     ` Yinghai Lu
2013-01-15 11:27       ` Rafael J. Wysocki
2013-01-11 22:40 ` [PATCH v8 18/22] PCI, acpiphp: Use acpi_hp_work Yinghai Lu
2013-01-11 22:40 ` [PATCH v8 19/22] PCI, pci_root_hp: " Yinghai Lu
2013-01-11 22:40 ` [PATCH v8 20/22] PCI, ACPI: Make kacpi_hotplug_wq static Yinghai Lu
2013-01-11 22:40 ` [PATCH v8 21/22] PCI: add match_driver in struct pci_dev Yinghai Lu
2013-01-12 23:49   ` Rafael J. Wysocki
2013-01-13 15:40     ` Jiang Liu
2013-01-13 20:01       ` Rafael J. Wysocki
2013-01-11 22:40 ` [PATCH v8 22/22] PCI: move device_add out of pci_bus_add_device() Yinghai Lu
2013-01-12 23:54   ` Rafael J. Wysocki
2013-01-15  7:10     ` Yinghai Lu
2013-01-15 11:19       ` Rafael J. Wysocki
2013-01-15 15:45         ` Yinghai Lu
2013-01-16  2:29   ` Yijing Wang
2013-01-16  2:41     ` Yinghai Lu
2013-01-12 21:35 ` [PATCH v8 00/22] PCI, ACPI: pci root bus hotplug support / pci match_driver Rafael J. Wysocki

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).