linux-acpi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism
@ 2013-04-12 15:44 Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 01/16] PCI: do not check is_added flag in pci_remove_bus() Jiang Liu
                   ` (16 more replies)
  0 siblings, 17 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Jiang Liu, Yinghai Lu, Yijing Wang, Jiang Liu, linux-kernel,
	linux-pci, Greg Kroah-Hartman, ACPI Devel Maling List,
	Toshi Kani, Myron Stowe

PCI, ACPI: remove ACPI PCI subdriver mechanism

This patch set is directly derived from two sources:
1) '[PATCH 00/15] PCI/ACPI: Remove "pci_root" sub-driver support' at
https://lkml.org/lkml/2012/12/7/11 from Myron Stowe
The major goal is to resolve any potential sequencing inter-dependencies
by converting sub-driver functionality to being only supported as
statically built-in to the kernel as part of the "pci_root" driver
itself.

2) 'introduce PCI bus notifier chain to get rid of the ACPI PCI subdriver'
at http://lwn.net/Articles/533547/
The major goal is to update PCI slots(pci_slot), ACPI based PCI hotplug
slots(acpiphp), PCIe AER(aer) etc when hot-plugging PCI devices and P2P
bridges, and eventually get rid of the ACPI PCI subdriver interfaces.

This patchset applies to Bjorn's pci-next branch. Patch 1-4 are minor
fixups for 3.9-rc1. Patch 5-8 introduce two hooks into PCI core which
will be called when creating/destroying PCI buses. Patch 9-12 replace
ACPI PCI subdriver interfaces with the new hook mechanism for pci_slot
and acpiphp. Patch 13 removes the ACPI PCI subdriver interfaces.

v7->v8:
	Hook directly into the PCI core to replace pci_bus notification
	Remove ACPI PCI subdriver related code

v8->v9:
	Introduce kernel boot option "acpiphp.disable" to disable the
	acpiphp driver.

Jiang Liu (13):
  PCI: do not check is_added flag in pci_remove_bus()
  pci: clean up usages of pci_bus->is_added
  PCI/acpiphp: don't rely on function 0 in disable_device()
  ACPI/acpiphp: replace local macros with standard ACPI macros
  PCI: introduce platform dependent hooks for creating/destroying PCI
    busses
  PCI, ACPI: prepare stub functions to handle ACPI PCI (hotplug) slots
  PCI, IA64: implement pcibios_{add|remove}_bus() hooks
  PCI, x86: implement pcibios_{add|remove}_bus() hooks
  PCI, ACPI: handle PCI slot devices when creating/destroying PCI
    busses
  PCI/acpiphp: convert acpiphp as a builtin driver
  PCI/acpiphp: do not use ACPI PCI subdriver mechanism
  PCI/acpiphp: protect acpiphp data structures from concurrent updating
  PCI/acpiphp: introduce a kernel option to disable the acpiphp driver

Myron Stowe (1):
  PCI, ACPI: remove support of ACPI PCI subdrivers

Yijing Wang (2):
  PCI/acpiphp: use list_for_each_entry_safe() in acpiphp_sanitize_bus()
  PCI/acpiphp: use normal list to simplify implementation

 Documentation/kernel-parameters.txt |    3 +
 arch/ia64/pci/pci.c                 |   11 +
 arch/x86/pci/common.c               |   11 +
 drivers/acpi/pci_root.c             |   48 +---
 drivers/acpi/pci_slot.c             |  170 ++------------
 drivers/acpi/scan.c                 |    1 -
 drivers/pci/bus.c                   |   11 +-
 drivers/pci/hotplug/Kconfig         |    7 +-
 drivers/pci/hotplug/acpiphp.h       |   13 +-
 drivers/pci/hotplug/acpiphp_core.c  |   29 +--
 drivers/pci/hotplug/acpiphp_glue.c  |  415 ++++++++++++-----------------------
 drivers/pci/pci-acpi.c              |   30 +++
 drivers/pci/probe.c                 |   15 +-
 drivers/pci/remove.c                |    4 +-
 include/linux/acpi.h                |    9 -
 include/linux/pci-acpi.h            |   26 +++
 include/linux/pci.h                 |    2 +
 17 files changed, 280 insertions(+), 525 deletions(-)

-- 
1.7.9.5

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

* [PATCH v9 01/16] PCI: do not check is_added flag in pci_remove_bus()
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 02/16] pci: clean up usages of pci_bus->is_added Jiang Liu
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Jiang Liu, Yinghai Lu, Yijing Wang, Jiang Liu, linux-kernel,
	linux-pci, Greg Kroah-Hartman, ACPI Devel Maling List,
	Toshi Kani, Myron Stowe, Rafael J. Wysocki

The is_added flag in struct pci_bus is always set after invoking
device_register() and pci_create_legacy_files(). The related code
paths are:
1) pci_create_root_bus() and pci_add_new_bus()
	bus = pci_alloc_bus()
	device_register(&bus->dev)
	pci_create_legacy_file(bus)
2.a) pci_scan_child_bus(bus)
	set is_added flag for PCI root buses
2.b) pci_bus_add_devices(bus)
	set is_added flag for normal PCI buses

So pci_remove_bus() shouldn't use is_added flag to guard invoking of
pci_remove_lagecy_files() and device_unregister().

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: linux-pci@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/pci/remove.c |    3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index cc875e6..a831880 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -50,9 +50,6 @@ 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);
 }
-- 
1.7.9.5


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

* [PATCH v9 02/16] pci: clean up usages of pci_bus->is_added
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 01/16] PCI: do not check is_added flag in pci_remove_bus() Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 03/16] PCI/acpiphp: use list_for_each_entry_safe() in acpiphp_sanitize_bus() Jiang Liu
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Jiang Liu, Yinghai Lu, Yijing Wang, Jiang Liu, linux-kernel,
	linux-pci, Greg Kroah-Hartman, ACPI Devel Maling List,
	Toshi Kani, Myron Stowe

Now pci_bus->is_added is only used to guard invoking of
pcibios_fixup_bus(), so clean up the code.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
 drivers/pci/bus.c   |   11 ++---------
 drivers/pci/probe.c |    3 +--
 2 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 8647dc6..bdc1e8b 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -206,16 +206,9 @@ void pci_bus_add_devices(const struct pci_bus *bus)
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		BUG_ON(!dev->is_added);
-
 		child = dev->subordinate;
-
-		if (!child)
-			continue;
-		pci_bus_add_devices(child);
-
-		if (child->is_added)
-			continue;
-		child->is_added = 1;
+		if (child)
+			pci_bus_add_devices(child);
 	}
 }
 
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index b494066..45c93b3 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1627,8 +1627,7 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus)
 	if (!bus->is_added) {
 		dev_dbg(&bus->dev, "fixups for bus\n");
 		pcibios_fixup_bus(bus);
-		if (pci_is_root_bus(bus))
-			bus->is_added = 1;
+		bus->is_added = 1;
 	}
 
 	for (pass=0; pass < 2; pass++)
-- 
1.7.9.5

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

* [PATCH v9 03/16] PCI/acpiphp: use list_for_each_entry_safe() in acpiphp_sanitize_bus()
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 01/16] PCI: do not check is_added flag in pci_remove_bus() Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 02/16] pci: clean up usages of pci_bus->is_added Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 04/16] PCI/acpiphp: don't rely on function 0 in disable_device() Jiang Liu
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Yijing Wang, Yinghai Lu, Jiang Liu, linux-kernel, linux-pci,
	Greg Kroah-Hartman, ACPI Devel Maling List, Toshi Kani,
	Myron Stowe, Jiang Liu, Rafael J. Wysocki

From: Yijing Wang <wangyijing@huawei.com>

Function acpiphp_sanitize_bus() may call pci_stop_and_remove_bus_device(),
which in turn may remove device from bus->devices list. So walk the
bus->devices list with list_for_each_entry_safe().

Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: linux-pci@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/pci/hotplug/acpiphp_glue.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 270fdba..7948bc9 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1082,11 +1082,11 @@ static void acpiphp_set_hpp_values(struct pci_bus *bus)
  */
 static void acpiphp_sanitize_bus(struct pci_bus *bus)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev, *tmp;
 	int i;
 	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
 
-	list_for_each_entry(dev, &bus->devices, bus_list) {
+	list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
 		for (i=0; i<PCI_BRIDGE_RESOURCES; i++) {
 			struct resource *res = &dev->resource[i];
 			if ((res->flags & type_mask) && !res->start &&
-- 
1.7.9.5

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

* [PATCH v9 04/16] PCI/acpiphp: don't rely on function 0 in disable_device()
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
                   ` (2 preceding siblings ...)
  2013-04-12 15:44 ` [PATCH v9 03/16] PCI/acpiphp: use list_for_each_entry_safe() in acpiphp_sanitize_bus() Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 05/16] ACPI/acpiphp: replace local macros with standard ACPI macros Jiang Liu
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Jiang Liu, Yinghai Lu, Yijing Wang, Jiang Liu, linux-kernel,
	linux-pci, Greg Kroah-Hartman, ACPI Devel Maling List,
	Toshi Kani, Myron Stowe, Rafael J. Wysocki

Currently function disable_device() detects slot state by checking
existence of PCI device for function 0. It's unreliable because PCI
device for function 0 may be removed through sysfs interface. If that
happens, it will cause powering off a hotplug slot without destroying
all PCI devices.

On the other hand, it won't hurt us except wasting some computation
power if the check is removed, because all code of disable_device()
is self-protected. So remove the check.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: linux-pci@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/pci/hotplug/acpiphp_glue.c |    7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 7948bc9..a1c8dd6 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -914,13 +914,6 @@ static int disable_device(struct acpiphp_slot *slot)
 	struct pci_dev *pdev;
 	struct pci_bus *bus = slot->bridge->pci_bus;
 
-	/* The slot will be enabled when func 0 is added, so check
-	   func 0 before disable the slot. */
-	pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0));
-	if (!pdev)
-		goto err_exit;
-	pci_dev_put(pdev);
-
 	list_for_each_entry(func, &slot->funcs, sibling) {
 		if (func->bridge) {
 			/* cleanup p2p bridges under this P2P bridge */
-- 
1.7.9.5

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

* [PATCH v9 05/16] ACPI/acpiphp: replace local macros with standard ACPI macros
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
                   ` (3 preceding siblings ...)
  2013-04-12 15:44 ` [PATCH v9 04/16] PCI/acpiphp: don't rely on function 0 in disable_device() Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 06/16] PCI: introduce platform dependent hooks for creating/destroying PCI busses Jiang Liu
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Jiang Liu, Yinghai Lu, Yijing Wang, Jiang Liu, linux-kernel,
	linux-pci, Greg Kroah-Hartman, ACPI Devel Maling List,
	Toshi Kani, Myron Stowe, Rafael J. Wysocki

Replace local defined macros (ACPI_STA_xxx) with standard ACPI macros
(ACPI_STA_DEVICE_xxx).

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: linux-pci@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/pci/hotplug/acpiphp.h      |    4 ----
 drivers/pci/hotplug/acpiphp_glue.c |    4 ++--
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index b70ac00..1b311f9 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -146,10 +146,6 @@ struct acpiphp_attention_info
 #define ACPI_PCI_HOST_HID		"PNP0A03"
 
 /* ACPI _STA method value (ignore bit 4; battery present) */
-#define ACPI_STA_PRESENT		(0x00000001)
-#define ACPI_STA_ENABLED		(0x00000002)
-#define ACPI_STA_SHOW_IN_UI		(0x00000004)
-#define ACPI_STA_FUNCTIONING		(0x00000008)
 #define ACPI_STA_ALL			(0x0000000f)
 
 /* bridge flags */
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index a1c8dd6..718464f 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -487,7 +487,7 @@ static int add_bridge(struct acpi_pci_root *root)
 			dbg("%s: _STA evaluation failure\n", __func__);
 			return 0;
 		}
-		if ((tmp & ACPI_STA_FUNCTIONING) == 0)
+		if ((tmp & ACPI_STA_DEVICE_FUNCTIONING) == 0)
 			/* don't register this object */
 			return 0;
 	}
@@ -1389,7 +1389,7 @@ u8 acpiphp_get_latch_status(struct acpiphp_slot *slot)
 
 	sta = get_slot_status(slot);
 
-	return (sta & ACPI_STA_SHOW_IN_UI) ? 0 : 1;
+	return (sta & ACPI_STA_DEVICE_UI) ? 0 : 1;
 }
 
 
-- 
1.7.9.5

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

* [PATCH v9 06/16] PCI: introduce platform dependent hooks for creating/destroying PCI busses
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
                   ` (4 preceding siblings ...)
  2013-04-12 15:44 ` [PATCH v9 05/16] ACPI/acpiphp: replace local macros with standard ACPI macros Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 07/16] PCI, ACPI: prepare stub functions to handle ACPI PCI (hotplug) slots Jiang Liu
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Jiang Liu, Yinghai Lu, Yijing Wang, Jiang Liu, linux-kernel,
	linux-pci, Greg Kroah-Hartman, ACPI Devel Maling List,
	Toshi Kani, Myron Stowe, Rafael J. Wysocki, Tony Luck,
	Fenghua Yu, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	linux-ia64, x86

On ACPI based platforms, the pci_slot driver creates PCI slot devices
according to information from ACPI tables by registering an ACPI PCI
subdriver. The ACPI PCI subdriver will only be called when creating/
destroying PCI root buses, and it won't be called when hot-plugging
P2P bridges. It may cause stale PCI slot devices after hot-removing
a P2P bridge if that bridge has associated PCI slots. And the acpiphp
driver has the same issue too.

This patch introduces two hook points into the PCI core, which will
be invoked when creating/destroying PCI busses for PCI host and P2P
bridges. They could be used to setup/destroy platform dependent staffs
in a unified way, both at boot time and for PCI hotplug operations.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Myron Stowe <myron.stowe@redhat.com>
Cc: linux-pci@vger.kernel.org
Cc: linux-ia64@vger.kernel.org
Cc: x86@kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/pci/probe.c  |   12 ++++++++++++
 drivers/pci/remove.c |    1 +
 include/linux/pci.h  |    2 ++
 3 files changed, 15 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 45c93b3..43ece5d 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -673,6 +673,8 @@ add_dev:
 	ret = device_register(&child->dev);
 	WARN_ON(ret < 0);
 
+	pcibios_add_bus(child);
+
 	/* Create legacy_io and legacy_mem files for this bus */
 	pci_create_legacy_files(child);
 
@@ -1660,6 +1662,14 @@ int __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
 	return 0;
 }
 
+void __weak pcibios_add_bus(struct pci_bus *bus)
+{
+}
+
+void __weak pcibios_remove_bus(struct pci_bus *bus)
+{
+}
+
 struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 		struct pci_ops *ops, void *sysdata, struct list_head *resources)
 {
@@ -1714,6 +1724,8 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	if (error)
 		goto class_dev_reg_err;
 
+	pcibios_add_bus(b);
+
 	/* Create legacy_io and legacy_mem files for this bus */
 	pci_create_legacy_files(b);
 
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index a831880..8fc54b7 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -51,6 +51,7 @@ void pci_remove_bus(struct pci_bus *bus)
 	pci_bus_release_busn_res(bus);
 	up_write(&pci_bus_sem);
 	pci_remove_legacy_files(bus);
+	pcibios_remove_bus(bus);
 	device_unregister(&bus->dev);
 }
 EXPORT_SYMBOL(pci_remove_bus);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 849a336..7eb6023 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -693,6 +693,8 @@ extern struct list_head pci_root_buses;	/* list of all known PCI buses */
 extern int no_pci_devices(void);
 
 void pcibios_resource_survey_bus(struct pci_bus *bus);
+void pcibios_add_bus(struct pci_bus *bus);
+void pcibios_remove_bus(struct pci_bus *bus);
 void pcibios_fixup_bus(struct pci_bus *);
 int __must_check pcibios_enable_device(struct pci_dev *, int mask);
 /* Architecture specific versions may override this (weak) */
-- 
1.7.9.5

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

* [PATCH v9 07/16] PCI, ACPI: prepare stub functions to handle ACPI PCI (hotplug) slots
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
                   ` (5 preceding siblings ...)
  2013-04-12 15:44 ` [PATCH v9 06/16] PCI: introduce platform dependent hooks for creating/destroying PCI busses Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 08/16] PCI, IA64: implement pcibios_{add|remove}_bus() hooks Jiang Liu
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Jiang Liu, Yinghai Lu, Yijing Wang, Jiang Liu, linux-kernel,
	linux-pci, Greg Kroah-Hartman, ACPI Devel Maling List,
	Toshi Kani, Myron Stowe, Rafael J. Wysocki, Tony Luck,
	Fenghua Yu, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	linux-ia64, x86

Prepare two stub functions to handle ACPI PCI slots and ACPI PCI hotplug
slots, which will be invoked by the PCI core when creating/destroying
PCI buses.

It will be used to get rid of ACPI PCI subdrivers for pci_slot and
acpiphp, and eventually remove the ACPI PCI subdriver mechanism.

And it will also be used to handle ACPI PCI (hotplug) slots in a unified
way, both at boot time and for PCI hotplug operations.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Myron Stowe <myron.stowe@redhat.com>
Cc: linux-pci@vger.kernel.org
Cc: linux-ia64@vger.kernel.org
Cc: x86@kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/pci/pci-acpi.c   |   24 ++++++++++++++++++++++++
 include/linux/pci-acpi.h |    8 +++++++-
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index dee5ddd..b8b8437 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -287,6 +287,30 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = {
 	.run_wake = acpi_pci_run_wake,
 };
 
+void acpi_pci_add_bus(struct pci_bus *bus)
+{
+	acpi_handle handle = NULL;
+
+	if (bus->bridge)
+		handle = ACPI_HANDLE(bus->bridge);
+	if (acpi_pci_disabled || handle == NULL)
+		return;
+
+	/* TODO: add PCI slots and acpiphp hotplug slots */
+}
+
+void acpi_pci_remove_bus(struct pci_bus *bus)
+{
+	/*
+	 * bus->bridge->acpi_node.handle has already been reset to NULL
+	 * when acpi_pci_remove_bus() is called, so don't check ACPI handle.
+	 */
+	if (acpi_pci_disabled)
+		return;
+
+	/* TODO: remove PCI slots and acpiphp hotplug slots */
+}
+
 /* ACPI bus type */
 static int acpi_pci_find_device(struct device *dev, acpi_handle *handle)
 {
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 9a22b5e..2b1743c 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -41,7 +41,13 @@ static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus)
 
 	return DEVICE_ACPI_HANDLE(dev);
 }
-#endif
+
+void acpi_pci_add_bus(struct pci_bus *bus);
+void acpi_pci_remove_bus(struct pci_bus *bus);
+#else	/* CONFIG_ACPI */
+static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
+static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
+#endif	/* CONFIG_ACPI */
 
 #ifdef CONFIG_ACPI_APEI
 extern bool aer_acpi_firmware_first(void);
-- 
1.7.9.5

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

* [PATCH v9 08/16] PCI, IA64: implement pcibios_{add|remove}_bus() hooks
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
                   ` (6 preceding siblings ...)
  2013-04-12 15:44 ` [PATCH v9 07/16] PCI, ACPI: prepare stub functions to handle ACPI PCI (hotplug) slots Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 09/16] PCI, x86: " Jiang Liu
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Jiang Liu, Yinghai Lu, Yijing Wang, Jiang Liu, linux-kernel,
	linux-pci, Greg Kroah-Hartman, ACPI Devel Maling List,
	Toshi Kani, Myron Stowe, Rafael J. Wysocki, Tony Luck,
	Fenghua Yu, linux-ia64

Implement pcibios_{add|remove}_bus() hooks for IA64 platforms.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: linux-ia64@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 arch/ia64/pci/pci.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 60532ab..de1474f 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/pci-acpi.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
@@ -458,6 +459,16 @@ void pcibios_fixup_bus(struct pci_bus *b)
 	platform_pci_fixup_bus(b);
 }
 
+void pcibios_add_bus(struct pci_bus *bus)
+{
+	acpi_pci_add_bus(bus);
+}
+
+void pcibios_remove_bus(struct pci_bus *bus)
+{
+	acpi_pci_remove_bus(bus);
+}
+
 void pcibios_set_master (struct pci_dev *dev)
 {
 	/* No special bus mastering setup handling */
-- 
1.7.9.5

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

* [PATCH v9 09/16] PCI, x86: implement pcibios_{add|remove}_bus() hooks
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
                   ` (7 preceding siblings ...)
  2013-04-12 15:44 ` [PATCH v9 08/16] PCI, IA64: implement pcibios_{add|remove}_bus() hooks Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-16 20:27   ` David Rientjes
  2013-04-12 15:44 ` [PATCH v9 10/16] PCI, ACPI: handle PCI slot devices when creating/destroying PCI busses Jiang Liu
                   ` (7 subsequent siblings)
  16 siblings, 1 reply; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Jiang Liu, Yinghai Lu, Yijing Wang, Jiang Liu, linux-kernel,
	linux-pci, Greg Kroah-Hartman, ACPI Devel Maling List,
	Toshi Kani, Myron Stowe, Rafael J. Wysocki, Thomas Gleixner,
	Ingo Molnar, H. Peter Anvin, x86

Implement pcibios_{add|remove}_bus() hooks for x86 platforms.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Myron Stowe <myron.stowe@redhat.com>
Cc: linux-kernel@vger.kernel.org
Cc: x86@kernel.org
---
 arch/x86/pci/common.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 901177d..305c68b 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -6,6 +6,7 @@
 
 #include <linux/sched.h>
 #include <linux/pci.h>
+#include <linux/pci-acpi.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/dmi.h>
@@ -170,6 +171,16 @@ void pcibios_fixup_bus(struct pci_bus *b)
 		pcibios_fixup_device_resources(dev);
 }
 
+void pcibios_add_bus(struct pci_bus *bus)
+{
+	acpi_pci_add_bus(bus);
+}
+
+void pcibios_remove_bus(struct pci_bus *bus)
+{
+	acpi_pci_remove_bus(bus);
+}
+
 /*
  * Only use DMI information to set this if nothing was passed
  * on the kernel command line (which was parsed earlier).
-- 
1.7.9.5

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

* [PATCH v9 10/16] PCI, ACPI: handle PCI slot devices when creating/destroying PCI busses
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
                   ` (8 preceding siblings ...)
  2013-04-12 15:44 ` [PATCH v9 09/16] PCI, x86: " Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 11/16] PCI/acpiphp: convert acpiphp as a builtin driver Jiang Liu
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Jiang Liu, Yinghai Lu, Yijing Wang, Jiang Liu, linux-kernel,
	linux-pci, Greg Kroah-Hartman, ACPI Devel Maling List,
	Toshi Kani, Myron Stowe

Currently the pci_slot driver doesn't update PCI slot devices when PCI
device hotplug event happens, which may cause memory leak and returning
stale information to user.

Now the pci_slot driver has been changed as built-in driver, so invoke
PCI slot enumeration and destroy routines directly from the PCI core.
And remove ACPI PCI sub-driver related code because it isn't needed
any more.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: linux-pci@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/acpi/pci_slot.c  |  170 +++++++---------------------------------------
 drivers/acpi/scan.c      |    1 -
 drivers/pci/pci-acpi.c   |    7 +-
 include/linux/pci-acpi.h |   12 ++++
 4 files changed, 41 insertions(+), 149 deletions(-)

diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c
index cd1434e..033d117 100644
--- a/drivers/acpi/pci_slot.c
+++ b/drivers/acpi/pci_slot.c
@@ -9,6 +9,9 @@
  *  Copyright (C) 2007-2008 Hewlett-Packard Development Company, L.P.
  *  	Alex Chiang <achiang@hp.com>
  *
+ *  Copyright (C) 2013 Huawei Tech. Co., Ltd.
+ *	Jiang Liu <jiang.liu@huawei.com>
+ *
  *  This program is free software; you can redistribute it and/or modify it
  *  under the terms and conditions of the GNU General Public License,
  *  version 2, as published by the Free Software Foundation.
@@ -28,10 +31,9 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/types.h>
+#include <linux/list.h>
 #include <linux/pci.h>
 #include <linux/acpi.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
 #include <linux/dmi.h>
 
 static bool debug;
@@ -61,20 +63,12 @@ ACPI_MODULE_NAME("pci_slot");
 #define SLOT_NAME_SIZE 21		/* Inspired by #define in acpiphp.h */
 
 struct acpi_pci_slot {
-	acpi_handle root_handle;	/* handle of the root bridge */
 	struct pci_slot *pci_slot;	/* corresponding pci_slot */
 	struct list_head list;		/* node in the list of slots */
 };
 
-static int acpi_pci_slot_add(struct acpi_pci_root *root);
-static void acpi_pci_slot_remove(struct acpi_pci_root *root);
-
 static LIST_HEAD(slot_list);
 static DEFINE_MUTEX(slot_list_lock);
-static struct acpi_pci_driver acpi_pci_slot_driver = {
-	.add = acpi_pci_slot_add,
-	.remove = acpi_pci_slot_remove,
-};
 
 static int
 check_slot(acpi_handle handle, unsigned long long *sun)
@@ -113,21 +107,8 @@ out:
 	return device;
 }
 
-struct callback_args {
-	acpi_walk_callback	user_function;	/* only for walk_p2p_bridge */
-	struct pci_bus		*pci_bus;
-	acpi_handle		root_handle;
-};
-
 /*
- * register_slot
- *
- * Called once for each SxFy object in the namespace. Don't worry about
- * calling pci_create_slot multiple times for the same pci_bus:device,
- * since each subsequent call simply bumps the refcount on the pci_slot.
- *
- * The number of calls to pci_destroy_slot from unregister_slot is
- * symmetrical.
+ * Check whether handle has an associated slot and create PCI slot if it has.
  */
 static acpi_status
 register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
@@ -137,13 +118,22 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 	char name[SLOT_NAME_SIZE];
 	struct acpi_pci_slot *slot;
 	struct pci_slot *pci_slot;
-	struct callback_args *parent_context = context;
-	struct pci_bus *pci_bus = parent_context->pci_bus;
+	struct pci_bus *pci_bus = context;
 
 	device = check_slot(handle, &sun);
 	if (device < 0)
 		return AE_OK;
 
+	/*
+	 * There may be multiple PCI functions associated with the same slot.
+	 * Check whether PCI slot has already been created for this PCI device.
+	 */
+	list_for_each_entry(slot, &slot_list, list) {
+		pci_slot = slot->pci_slot;
+		if (pci_slot->bus == pci_bus && pci_slot->number == device)
+			return AE_OK;
+	}
+
 	slot = kmalloc(sizeof(*slot), GFP_KERNEL);
 	if (!slot) {
 		err("%s: cannot allocate memory\n", __func__);
@@ -158,12 +148,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 		return AE_OK;
 	}
 
-	slot->root_handle = parent_context->root_handle;
 	slot->pci_slot = pci_slot;
-	INIT_LIST_HEAD(&slot->list);
-	mutex_lock(&slot_list_lock);
 	list_add(&slot->list, &slot_list);
-	mutex_unlock(&slot_list_lock);
 
 	get_device(&pci_bus->dev);
 
@@ -173,131 +159,24 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 	return AE_OK;
 }
 
-/*
- * walk_p2p_bridge - discover and walk p2p bridges
- * @handle: points to an acpi_pci_root
- * @context: p2p_bridge_context pointer
- *
- * Note that when we call ourselves recursively, we pass a different
- * value of pci_bus in the child_context.
- */
-static acpi_status
-walk_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-	int device, function;
-	unsigned long long adr;
-	acpi_status status;
-	acpi_handle dummy_handle;
-	acpi_walk_callback user_function;
-
-	struct pci_dev *dev;
-	struct pci_bus *pci_bus;
-	struct callback_args child_context;
-	struct callback_args *parent_context = context;
-
-	pci_bus = parent_context->pci_bus;
-	user_function = parent_context->user_function;
-
-	status = acpi_get_handle(handle, "_ADR", &dummy_handle);
-	if (ACPI_FAILURE(status))
-		return AE_OK;
-
-	status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
-	if (ACPI_FAILURE(status))
-		return AE_OK;
-
-	device = (adr >> 16) & 0xffff;
-	function = adr & 0xffff;
-
-	dev = pci_get_slot(pci_bus, PCI_DEVFN(device, function));
-	if (!dev || !dev->subordinate)
-		goto out;
-
-	child_context.pci_bus = dev->subordinate;
-	child_context.user_function = user_function;
-	child_context.root_handle = parent_context->root_handle;
-
-	dbg("p2p bridge walk, pci_bus = %x\n", dev->subordinate->number);
-	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     user_function, NULL, &child_context, NULL);
-	if (ACPI_FAILURE(status))
-		goto out;
-
-	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     walk_p2p_bridge, NULL, &child_context, NULL);
-out:
-	pci_dev_put(dev);
-	return AE_OK;
-}
-
-/*
- * walk_root_bridge - generic root bridge walker
- * @root: poiner of an acpi_pci_root
- * @user_function: user callback for slot objects
- *
- * Call user_function for all objects underneath this root bridge.
- * Walk p2p bridges underneath us and call user_function on those too.
- */
-static int
-walk_root_bridge(struct acpi_pci_root *root, acpi_walk_callback user_function)
-{
-	acpi_status status;
-	acpi_handle handle = root->device->handle;
-	struct pci_bus *pci_bus = root->bus;
-	struct callback_args context;
-
-	context.pci_bus = pci_bus;
-	context.user_function = user_function;
-	context.root_handle = handle;
-
-	dbg("root bridge walk, pci_bus = %x\n", pci_bus->number);
-	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     user_function, NULL, &context, NULL);
-	if (ACPI_FAILURE(status))
-		return status;
-
-	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     walk_p2p_bridge, NULL, &context, NULL);
-	if (ACPI_FAILURE(status))
-		err("%s: walk_p2p_bridge failure - %d\n", __func__, status);
-
-	return status;
-}
-
-/*
- * acpi_pci_slot_add
- * @handle: points to an acpi_pci_root
- */
-static int
-acpi_pci_slot_add(struct acpi_pci_root *root)
+void acpi_pci_slot_enumerate(struct pci_bus *bus, acpi_handle handle)
 {
-	acpi_status status;
-
-	status = walk_root_bridge(root, register_slot);
-	if (ACPI_FAILURE(status))
-		err("%s: register_slot failure - %d\n", __func__, status);
-
-	return status;
+	mutex_lock(&slot_list_lock);
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+			    register_slot, NULL, bus, NULL);
+	mutex_unlock(&slot_list_lock);
 }
 
-/*
- * acpi_pci_slot_remove
- * @handle: points to an acpi_pci_root
- */
-static void
-acpi_pci_slot_remove(struct acpi_pci_root *root)
+void acpi_pci_slot_remove(struct pci_bus *bus)
 {
 	struct acpi_pci_slot *slot, *tmp;
-	struct pci_bus *pbus;
-	acpi_handle handle = root->device->handle;
 
 	mutex_lock(&slot_list_lock);
 	list_for_each_entry_safe(slot, tmp, &slot_list, list) {
-		if (slot->root_handle == handle) {
+		if (slot->pci_slot->bus == bus) {
 			list_del(&slot->list);
-			pbus = slot->pci_slot->bus;
 			pci_destroy_slot(slot->pci_slot);
-			put_device(&pbus->dev);
+			put_device(&bus->dev);
 			kfree(slot);
 		}
 	}
@@ -332,5 +211,4 @@ static struct dmi_system_id acpi_pci_slot_dmi_table[] __initdata = {
 void __init acpi_pci_slot_init(void)
 {
 	dmi_check_system(acpi_pci_slot_dmi_table);
-	acpi_pci_register_driver(&acpi_pci_slot_driver);
 }
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 5e7e991..f54d198 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1790,7 +1790,6 @@ int __init acpi_scan_init(void)
 	acpi_platform_init();
 	acpi_csrt_init();
 	acpi_container_init();
-	acpi_pci_slot_init();
 
 	mutex_lock(&acpi_scan_lock);
 	/*
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index b8b8437..98e582a 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -296,7 +296,7 @@ void acpi_pci_add_bus(struct pci_bus *bus)
 	if (acpi_pci_disabled || handle == NULL)
 		return;
 
-	/* TODO: add PCI slots and acpiphp hotplug slots */
+	acpi_pci_slot_enumerate(bus, handle);
 }
 
 void acpi_pci_remove_bus(struct pci_bus *bus)
@@ -308,7 +308,7 @@ void acpi_pci_remove_bus(struct pci_bus *bus)
 	if (acpi_pci_disabled)
 		return;
 
-	/* TODO: remove PCI slots and acpiphp hotplug slots */
+	acpi_pci_slot_remove(bus);
 }
 
 /* ACPI bus type */
@@ -385,7 +385,10 @@ static int __init acpi_pci_init(void)
 	ret = register_acpi_bus_type(&acpi_pci_bus);
 	if (ret)
 		return 0;
+
 	pci_set_platform_pm(&acpi_pci_platform_pm);
+	acpi_pci_slot_init();
+
 	return 0;
 }
 arch_initcall(acpi_pci_init);
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 2b1743c..1ef126f 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -44,6 +44,18 @@ static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus)
 
 void acpi_pci_add_bus(struct pci_bus *bus);
 void acpi_pci_remove_bus(struct pci_bus *bus);
+
+#ifdef	CONFIG_ACPI_PCI_SLOT
+extern void acpi_pci_slot_init(void);
+extern void acpi_pci_slot_enumerate(struct pci_bus *bus, acpi_handle handle);
+extern void acpi_pci_slot_remove(struct pci_bus *bus);
+#else
+static inline void acpi_pci_slot_init(void) { }
+static inline void acpi_pci_slot_enumerate(struct pci_bus *bus,
+					   acpi_handle handle) { }
+static inline void acpi_pci_slot_remove(struct pci_bus *bus) { }
+#endif
+
 #else	/* CONFIG_ACPI */
 static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
 static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
-- 
1.7.9.5

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

* [PATCH v9 11/16] PCI/acpiphp: convert acpiphp as a builtin driver
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
                   ` (9 preceding siblings ...)
  2013-04-12 15:44 ` [PATCH v9 10/16] PCI, ACPI: handle PCI slot devices when creating/destroying PCI busses Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 12/16] PCI/acpiphp: do not use ACPI PCI subdriver mechanism Jiang Liu
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Jiang Liu, Yinghai Lu, Yijing Wang, Jiang Liu, linux-kernel,
	linux-pci, Greg Kroah-Hartman, ACPI Devel Maling List,
	Toshi Kani, Myron Stowe

Prepare for coming bugfixes by converting acpiphp as a builtin driver.
This change has a drawback that user has no way to disable the acpiphp
driver anymore once it becomes a builtin driver. We may introduce a
kernel option to disable the acpiphp driver if needed.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
 drivers/pci/hotplug/Kconfig        |    7 ++-----
 drivers/pci/hotplug/acpiphp_core.c |   10 ----------
 2 files changed, 2 insertions(+), 15 deletions(-)

diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index 13e9e63..9fcb87f 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -52,15 +52,12 @@ config HOTPLUG_PCI_IBM
 	  When in doubt, say N.
 
 config HOTPLUG_PCI_ACPI
-	tristate "ACPI PCI Hotplug driver"
-	depends on (!ACPI_DOCK && ACPI) || (ACPI_DOCK)
+	bool "ACPI PCI Hotplug driver"
+	depends on HOTPLUG_PCI=y && ((!ACPI_DOCK && ACPI) || (ACPI_DOCK))
 	help
 	  Say Y here if you have a system that supports PCI Hotplug using
 	  ACPI.
 
-	  To compile this driver as a module, choose M here: the
-	  module will be called acpiphp.
-
 	  When in doubt, say N.
 
 config HOTPLUG_PCI_ACPI_IBM
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index c2fd309..45312e5 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -364,14 +364,4 @@ static int __init acpiphp_init(void)
 }
 
 
-static void __exit acpiphp_exit(void)
-{
-	if (acpi_pci_disabled)
-		return;
-
-	/* deallocate internal data structures etc. */
-	acpiphp_glue_exit();
-}
-
 module_init(acpiphp_init);
-module_exit(acpiphp_exit);
-- 
1.7.9.5

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

* [PATCH v9 12/16] PCI/acpiphp: do not use ACPI PCI subdriver mechanism
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
                   ` (10 preceding siblings ...)
  2013-04-12 15:44 ` [PATCH v9 11/16] PCI/acpiphp: convert acpiphp as a builtin driver Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 13/16] PCI/acpiphp: use normal list to simplify implementation Jiang Liu
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Jiang Liu, Yinghai Lu, Yijing Wang, Jiang Liu, linux-kernel,
	linux-pci, Greg Kroah-Hartman, ACPI Devel Maling List,
	Toshi Kani, Myron Stowe, Rafael J. Wysocki

Previously the acpiphp driver registers itself as an ACPI PCI subdriver,
so it's callbacks will be invoked when creating/destroying PCI root
buses to manage ACPI based PCI hotplug slots. But it doesn't handle
P2P bridge hotplug events, so it will cause strange behavours if there
are hotplug slots associated with a hot-removed P2P bridge.

So this patch tries to fix this issue by:
1) Directly hook into PCI core to update hotplug slot devices when
   creating/destroying PCI buses through:
	pci_{add|remove}_bus() -> acpi_pci_{add|remove}_bus()
2) Get rid of ACPI PCI subdriver related code, it's not used any more.

It also clean up unused code in the acpiphp driver.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: linux-pci@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/pci/hotplug/acpiphp.h      |    3 -
 drivers/pci/hotplug/acpiphp_core.c |   13 +-
 drivers/pci/hotplug/acpiphp_glue.c |  282 +++++++-----------------------------
 drivers/pci/pci-acpi.c             |    3 +
 include/linux/pci-acpi.h           |   14 +-
 5 files changed, 65 insertions(+), 250 deletions(-)

diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index 1b311f9..69b4aac 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -119,7 +119,6 @@ struct acpiphp_slot {
  */
 struct acpiphp_func {
 	struct acpiphp_slot *slot;	/* parent */
-	struct acpiphp_bridge *bridge;	/* Ejectable PCI-to-PCI bridge */
 
 	struct list_head sibling;
 	struct notifier_block nb;
@@ -176,8 +175,6 @@ extern int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot);
 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);
 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 45312e5..80d777c 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -37,6 +37,7 @@
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/pci-acpi.h>
 #include <linux/pci_hotplug.h>
 #include <linux/slab.h>
 #include <linux/smp.h>
@@ -351,17 +352,7 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
 }
 
 
-static int __init acpiphp_init(void)
+void __init acpiphp_init(void)
 {
 	info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
-
-	if (acpi_pci_disabled)
-		return 0;
-
-	/* read all the ACPI info from the system */
-	/* initialize internal data structure etc. */
-	return acpiphp_glue_init();
 }
-
-
-module_init(acpiphp_init);
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 718464f..372c030 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -157,6 +157,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 	int device, function, retval;
 	struct pci_bus *pbus = bridge->pci_bus;
 	struct pci_dev *pdev;
+	u32 val;
 
 	if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle))
 		return AE_OK;
@@ -249,11 +250,9 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 	newfunc->slot = slot;
 	list_add_tail(&newfunc->sibling, &slot->funcs);
 
-	pdev = pci_get_slot(pbus, PCI_DEVFN(device, function));
-	if (pdev) {
+	if (pci_bus_read_dev_vendor_id(pbus, PCI_DEVFN(device, function),
+				       &val, 60*1000))
 		slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
-		pci_dev_put(pdev);
-	}
 
 	if (is_dock_device(handle)) {
 		/* we don't want to call this device's _EJ0
@@ -366,148 +365,6 @@ static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle
 }
 
 
-static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge)
-{
-	acpi_handle dummy_handle;
-	struct acpiphp_func *func;
-
-	if (ACPI_SUCCESS(acpi_get_handle(bridge->handle,
-					"_EJ0", &dummy_handle))) {
-		bridge->flags |= BRIDGE_HAS_EJ0;
-
-		dbg("found ejectable p2p bridge\n");
-
-		/* make link between PCI bridge and PCI function */
-		func = acpiphp_bridge_handle_to_function(bridge->handle);
-		if (!func)
-			return;
-		bridge->func = func;
-		func->bridge = bridge;
-	}
-}
-
-
-/* allocate and initialize host bridge data structure */
-static void add_host_bridge(struct acpi_pci_root *root)
-{
-	struct acpiphp_bridge *bridge;
-	acpi_handle handle = root->device->handle;
-
-	bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
-	if (bridge == NULL)
-		return;
-
-	bridge->handle = handle;
-
-	bridge->pci_bus = root->bus;
-
-	init_bridge_misc(bridge);
-}
-
-
-/* allocate and initialize PCI-to-PCI bridge data structure */
-static void add_p2p_bridge(acpi_handle *handle)
-{
-	struct acpiphp_bridge *bridge;
-
-	bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
-	if (bridge == NULL) {
-		err("out of memory\n");
-		return;
-	}
-
-	bridge->handle = handle;
-	config_p2p_bridge_flags(bridge);
-
-	bridge->pci_dev = acpi_get_pci_dev(handle);
-	bridge->pci_bus = bridge->pci_dev->subordinate;
-	if (!bridge->pci_bus) {
-		err("This is not a PCI-to-PCI bridge!\n");
-		goto err;
-	}
-
-	/*
-	 * Grab a ref to the subordinate PCI bus in case the bus is
-	 * removed via PCI core logical hotplug. The ref pins the bus
-	 * (which we access during module unload).
-	 */
-	get_device(&bridge->pci_bus->dev);
-
-	init_bridge_misc(bridge);
-	return;
- err:
-	pci_dev_put(bridge->pci_dev);
-	kfree(bridge);
-	return;
-}
-
-
-/* callback routine to find P2P bridges */
-static acpi_status
-find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-	acpi_status status;
-	struct pci_dev *dev;
-
-	dev = acpi_get_pci_dev(handle);
-	if (!dev || !dev->subordinate)
-		goto out;
-
-	/* check if this bridge has ejectable slots */
-	if ((detect_ejectable_slots(handle) > 0)) {
-		dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
-		add_p2p_bridge(handle);
-	}
-
-	/* search P2P bridges under this p2p bridge */
-	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     find_p2p_bridge, NULL, NULL, NULL);
-	if (ACPI_FAILURE(status))
-		warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
-
- out:
-	pci_dev_put(dev);
-	return AE_OK;
-}
-
-
-/* find hot-pluggable slots, and then find P2P bridge */
-static int add_bridge(struct acpi_pci_root *root)
-{
-	acpi_status status;
-	unsigned long long tmp;
-	acpi_handle dummy_handle;
-	acpi_handle handle = root->device->handle;
-
-	/* 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)) {
-		status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp);
-		if (ACPI_FAILURE(status)) {
-			dbg("%s: _STA evaluation failure\n", __func__);
-			return 0;
-		}
-		if ((tmp & ACPI_STA_DEVICE_FUNCTIONING) == 0)
-			/* don't register this object */
-			return 0;
-	}
-
-	/* check if this bridge has ejectable slots */
-	if (detect_ejectable_slots(handle) > 0) {
-		dbg("found PCI host-bus bridge with hot-pluggable slots\n");
-		add_host_bridge(root);
-	}
-
-	/* search P2P bridges under this host bridge */
-	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     find_p2p_bridge, NULL, NULL, NULL);
-
-	if (ACPI_FAILURE(status))
-		warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
-
-	return 0;
-}
-
 static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)
 {
 	struct acpiphp_bridge *bridge;
@@ -567,56 +424,12 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
 		slot = next;
 	}
 
-	/*
-	 * Only P2P bridges have a pci_dev
-	 */
-	if (bridge->pci_dev)
-		put_device(&bridge->pci_bus->dev);
-
+	put_device(&bridge->pci_bus->dev);
 	pci_dev_put(bridge->pci_dev);
 	list_del(&bridge->list);
 	kfree(bridge);
 }
 
-static acpi_status
-cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-	struct acpiphp_bridge *bridge;
-
-	/* cleanup p2p bridges under this P2P bridge
-	   in a depth-first manner */
-	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				cleanup_p2p_bridge, NULL, NULL, NULL);
-
-	bridge = acpiphp_handle_to_bridge(handle);
-	if (bridge)
-		cleanup_bridge(bridge);
-
-	return AE_OK;
-}
-
-static void remove_bridge(struct acpi_pci_root *root)
-{
-	struct acpiphp_bridge *bridge;
-	acpi_handle handle = root->device->handle;
-
-	/* cleanup p2p bridges under this host bridge
-	   in a depth-first manner */
-	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
-				(u32)1, cleanup_p2p_bridge, NULL, NULL, NULL);
-
-	/*
-	 * On root bridges with hotplug slots directly underneath (ie,
-	 * no p2p bridge between), we call cleanup_bridge(). 
-	 *
-	 * The else clause cleans up root bridges that either had no
-	 * hotplug slots at all, or had a p2p bridge underneath.
-	 */
-	bridge = acpiphp_handle_to_bridge(handle);
-	if (bridge)
-		cleanup_bridge(bridge);
-}
-
 static int power_on_slot(struct acpiphp_slot *slot)
 {
 	acpi_status status;
@@ -798,6 +611,7 @@ static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev)
 		}
 	}
 }
+
 /**
  * enable_device - enable, configure a slot
  * @slot: slot to be enabled
@@ -812,7 +626,6 @@ static int __ref enable_device(struct acpiphp_slot *slot)
 	struct acpiphp_func *func;
 	int retval = 0;
 	int num, max, pass;
-	acpi_status status;
 
 	if (slot->flags & SLOT_ENABLED)
 		goto err_exit;
@@ -867,18 +680,6 @@ static int __ref enable_device(struct acpiphp_slot *slot)
 			slot->flags &= (~SLOT_ENABLED);
 			continue;
 		}
-
-		if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE &&
-		    dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) {
-			pci_dev_put(dev);
-			continue;
-		}
-
-		status = find_p2p_bridge(func->handle, (u32)1, bus, NULL);
-		if (ACPI_FAILURE(status))
-			warn("find_p2p_bridge failed (error code = 0x%x)\n",
-				status);
-		pci_dev_put(dev);
 	}
 
 
@@ -912,16 +713,6 @@ static int disable_device(struct acpiphp_slot *slot)
 {
 	struct acpiphp_func *func;
 	struct pci_dev *pdev;
-	struct pci_bus *bus = slot->bridge->pci_bus;
-
-	list_for_each_entry(func, &slot->funcs, sibling) {
-		if (func->bridge) {
-			/* cleanup p2p bridges under this P2P bridge */
-			cleanup_p2p_bridge(func->bridge->handle,
-						(u32)1, NULL, NULL);
-			func->bridge = NULL;
-		}
-	}
 
 	/*
 	 * enable_device() enumerates all functions in this device via
@@ -940,7 +731,6 @@ static int disable_device(struct acpiphp_slot *slot)
 
 	slot->flags &= (~SLOT_ENABLED);
 
-err_exit:
 	return 0;
 }
 
@@ -1287,30 +1077,56 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type,
 	alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func);
 }
 
-static struct acpi_pci_driver acpi_pci_hp_driver = {
-	.add =		add_bridge,
-	.remove =	remove_bridge,
-};
-
-/**
- * acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures
+/*
+ * Create hotplug slots for the PCI bus.
+ * It should always return 0 to avoid skipping following notifiers.
  */
-int __init acpiphp_glue_init(void)
+void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle)
 {
-	acpi_pci_register_driver(&acpi_pci_hp_driver);
+	acpi_handle dummy_handle;
+	struct acpiphp_bridge *bridge;
 
-	return 0;
-}
+	if (detect_ejectable_slots(handle) <= 0)
+		return;
 
+	bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
+	if (bridge == NULL) {
+		err("out of memory\n");
+		return;
+	}
 
-/**
- * acpiphp_glue_exit - terminates all PCI hotplug - ACPI glue data structures
- *
- * This function frees all data allocated in acpiphp_glue_init().
- */
-void  acpiphp_glue_exit(void)
+	bridge->handle = handle;
+	bridge->pci_dev = pci_dev_get(bus->self);
+	bridge->pci_bus = bus;
+
+	/*
+	 * Grab a ref to the subordinate PCI bus in case the bus is
+	 * removed via PCI core logical hotplug. The ref pins the bus
+	 * (which we access during module unload).
+	 */
+	get_device(&bus->dev);
+
+	if (!pci_is_root_bus(bridge->pci_bus) &&
+	    ACPI_SUCCESS(acpi_get_handle(bridge->handle,
+					"_EJ0", &dummy_handle))) {
+		dbg("found ejectable p2p bridge\n");
+		bridge->flags |= BRIDGE_HAS_EJ0;
+		bridge->func = acpiphp_bridge_handle_to_function(handle);
+	}
+
+	init_bridge_misc(bridge);
+}
+
+/* Destroy hotplug slots associated with the PCI bus */
+void acpiphp_remove_slots(struct pci_bus *bus)
 {
-	acpi_pci_unregister_driver(&acpi_pci_hp_driver);
+	struct acpiphp_bridge *bridge, *tmp;
+
+	list_for_each_entry_safe(bridge, tmp, &bridge_list, list)
+		if (bridge->pci_bus == bus) {
+			cleanup_bridge(bridge);
+			break;
+		}
 }
 
 /**
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 98e582a..d927933 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -297,6 +297,7 @@ void acpi_pci_add_bus(struct pci_bus *bus)
 		return;
 
 	acpi_pci_slot_enumerate(bus, handle);
+	acpiphp_enumerate_slots(bus, handle);
 }
 
 void acpi_pci_remove_bus(struct pci_bus *bus)
@@ -308,6 +309,7 @@ void acpi_pci_remove_bus(struct pci_bus *bus)
 	if (acpi_pci_disabled)
 		return;
 
+	acpiphp_remove_slots(bus);
 	acpi_pci_slot_remove(bus);
 }
 
@@ -388,6 +390,7 @@ static int __init acpi_pci_init(void)
 
 	pci_set_platform_pm(&acpi_pci_platform_pm);
 	acpi_pci_slot_init();
+	acpiphp_init();
 
 	return 0;
 }
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 1ef126f..f1b2380 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -56,9 +56,17 @@ static inline void acpi_pci_slot_enumerate(struct pci_bus *bus,
 static inline void acpi_pci_slot_remove(struct pci_bus *bus) { }
 #endif
 
-#else	/* CONFIG_ACPI */
-static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
-static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
+#ifdef	CONFIG_HOTPLUG_PCI_ACPI
+void acpiphp_init(void);
+void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle);
+void acpiphp_remove_slots(struct pci_bus *bus);
+#else
+static inline void acpiphp_init(void) { }
+static inline void acpiphp_enumerate_slots(struct pci_bus *bus,
+					   acpi_handle handle) { }
+static inline void acpiphp_remove_slots(struct pci_bus *bus) { }
+#endif
+
 #endif	/* CONFIG_ACPI */
 
 #ifdef CONFIG_ACPI_APEI
-- 
1.7.9.5

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

* [PATCH v9 13/16] PCI/acpiphp: use normal list to simplify implementation
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
                   ` (11 preceding siblings ...)
  2013-04-12 15:44 ` [PATCH v9 12/16] PCI/acpiphp: do not use ACPI PCI subdriver mechanism Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 14/16] PCI/acpiphp: protect acpiphp data structures from concurrent updating Jiang Liu
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Yijing Wang, Yinghai Lu, Jiang Liu, linux-kernel, linux-pci,
	Greg Kroah-Hartman, ACPI Devel Maling List, Toshi Kani,
	Myron Stowe, Jiang Liu, Rafael J. Wysocki

From: Yijing Wang <wangyijing@huawei.com>

Use normal list for struct acpiphp_slot to simplify implementation.

Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: linux-pci@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/pci/hotplug/acpiphp.h      |    4 ++--
 drivers/pci/hotplug/acpiphp_glue.c |   23 ++++++++++-------------
 2 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index 69b4aac..0b30045 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -73,8 +73,8 @@ static inline const char *slot_name(struct slot *slot)
  */
 struct acpiphp_bridge {
 	struct list_head list;
+	struct list_head slots;
 	acpi_handle handle;
-	struct acpiphp_slot *slots;
 
 	/* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */
 	struct acpiphp_func *func;
@@ -97,7 +97,7 @@ struct acpiphp_bridge {
  * PCI slot information for each *physical* PCI slot
  */
 struct acpiphp_slot {
-	struct acpiphp_slot *next;
+	struct list_head node;
 	struct acpiphp_bridge *bridge;	/* parent */
 	struct list_head funcs;		/* one slot may have different
 					   objects (i.e. for each function) */
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 372c030..6bfd5a0 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -154,7 +154,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 	acpi_handle tmp;
 	acpi_status status = AE_OK;
 	unsigned long long adr, sun;
-	int device, function, retval;
+	int device, function, retval, found = 0;
 	struct pci_bus *pbus = bridge->pci_bus;
 	struct pci_dev *pdev;
 	u32 val;
@@ -208,14 +208,15 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 	}
 
 	/* search for objects that share the same slot */
-	for (slot = bridge->slots; slot; slot = slot->next)
+	list_for_each_entry(slot, &bridge->slots, node)
 		if (slot->device == device) {
 			if (slot->sun != sun)
 				warn("sibling found, but _SUN doesn't match!\n");
+			found = 1;
 			break;
 		}
 
-	if (!slot) {
+	if (!found) {
 		slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL);
 		if (!slot) {
 			kfree(newfunc);
@@ -228,9 +229,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 		INIT_LIST_HEAD(&slot->funcs);
 		mutex_init(&slot->crit_sect);
 
-		slot->next = bridge->slots;
-		bridge->slots = slot;
-
+		list_add_tail(&slot->node, &bridge->slots);
 		bridge->nr_slots++;
 
 		dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n",
@@ -289,7 +288,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 
  err_exit:
 	bridge->nr_slots--;
-	bridge->slots = slot->next;
+	list_del(&slot->node);
 	kfree(slot);
 	kfree(newfunc);
 
@@ -353,7 +352,7 @@ static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle
 	struct acpiphp_func *func;
 
 	list_for_each_entry(bridge, &bridge_list, list) {
-		for (slot = bridge->slots; slot; slot = slot->next) {
+		list_for_each_entry(slot, &bridge->slots, node) {
 			list_for_each_entry(func, &slot->funcs, sibling) {
 				if (func->handle == handle)
 					return func;
@@ -400,9 +399,7 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
 			err("failed to install interrupt notify handler\n");
 	}
 
-	slot = bridge->slots;
-	while (slot) {
-		next = slot->next;
+	list_for_each_entry_safe(slot, next, &bridge->slots, node) {
 		list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) {
 			if (is_dock_device(func->handle)) {
 				unregister_hotplug_dock_device(func->handle);
@@ -421,7 +418,6 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
 		acpiphp_unregister_hotplug_slot(slot);
 		list_del(&slot->funcs);
 		kfree(slot);
-		slot = next;
 	}
 
 	put_device(&bridge->pci_bus->dev);
@@ -820,7 +816,7 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge)
 
 	enabled = disabled = 0;
 
-	for (slot = bridge->slots; slot; slot = slot->next) {
+	list_for_each_entry(slot, &bridge->slots, node) {
 		unsigned int status = get_slot_status(slot);
 		if (slot->flags & SLOT_ENABLED) {
 			if (status == ACPI_STA_ALL)
@@ -1095,6 +1091,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle)
 		return;
 	}
 
+	INIT_LIST_HEAD(&bridge->slots);
 	bridge->handle = handle;
 	bridge->pci_dev = pci_dev_get(bus->self);
 	bridge->pci_bus = bus;
-- 
1.7.9.5

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

* [PATCH v9 14/16] PCI/acpiphp: protect acpiphp data structures from concurrent updating
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
                   ` (12 preceding siblings ...)
  2013-04-12 15:44 ` [PATCH v9 13/16] PCI/acpiphp: use normal list to simplify implementation Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 15/16] PCI/acpiphp: introduce a kernel option to disable the acpiphp driver Jiang Liu
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Jiang Liu, Yinghai Lu, Yijing Wang, Jiang Liu, linux-kernel,
	linux-pci, Greg Kroah-Hartman, ACPI Devel Maling List,
	Toshi Kani, Myron Stowe, Rafael J. Wysocki

Now acpiphp_enumerate_slots() and acpiphp_remove_slots() may be invoked
concurrently by the PCI core, so add a bridge_mutex and reference count
mechanism to protect acpiphp bridge/slot/function data structures.

To avoid deadlock, handle_hotplug_event_bridge() will requeue the
hotplug event onto the kacpi_hotplug_wq by calling alloc_acpi_hp_work().
But the workaround has introduced a minor race window because the
'bridge' passed to _handle_hotplug_event_bridge() may have already been
destroyed when _handle_hotplug_event_bridge() is actually executed by
the kacpi_hotplug_wq. So hold a reference count on the passed 'bridge'.
Fix the same issue for handle_hotplug_event_func() too.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: linux-pci@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/pci/hotplug/acpiphp.h      |    1 +
 drivers/pci/hotplug/acpiphp_glue.c |   95 +++++++++++++++++++++++++++++-------
 2 files changed, 78 insertions(+), 18 deletions(-)

diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index 0b30045..7577bb3 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -74,6 +74,7 @@ static inline const char *slot_name(struct slot *slot)
 struct acpiphp_bridge {
 	struct list_head list;
 	struct list_head slots;
+	struct kref ref;
 	acpi_handle handle;
 
 	/* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 6bfd5a0..896d680 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -54,6 +54,7 @@
 #include "acpiphp.h"
 
 static LIST_HEAD(bridge_list);
+static DEFINE_MUTEX(bridge_mutex);
 
 #define MY_NAME "acpiphp_glue"
 
@@ -61,6 +62,7 @@ static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
 static void acpiphp_sanitize_bus(struct pci_bus *bus);
 static void acpiphp_set_hpp_values(struct pci_bus *bus);
 static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context);
+static void free_bridge(struct kref *kref);
 
 /* callback routine to check for the existence of a pci dock device */
 static acpi_status
@@ -76,6 +78,39 @@ is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv)
 	}
 }
 
+static inline void get_bridge(struct acpiphp_bridge *bridge)
+{
+	kref_get(&bridge->ref);
+}
+
+static inline void put_bridge(struct acpiphp_bridge *bridge)
+{
+	kref_put(&bridge->ref, free_bridge);
+}
+
+static void free_bridge(struct kref *kref)
+{
+	struct acpiphp_bridge *bridge;
+	struct acpiphp_slot *slot, *next;
+	struct acpiphp_func *func, *tmp;
+
+	bridge = container_of(kref, struct acpiphp_bridge, ref);
+
+	list_for_each_entry_safe(slot, next, &bridge->slots, node) {
+		list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) {
+			kfree(func);
+		}
+		kfree(slot);
+	}
+
+	/* Release reference acquired by acpiphp_bridge_handle_to_function() */
+	if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func)
+		put_bridge(bridge->func->slot->bridge);
+	put_device(&bridge->pci_bus->dev);
+	pci_dev_put(bridge->pci_dev);
+	kfree(bridge);
+}
+
 /*
  * the _DCK method can do funny things... and sometimes not
  * hah-hah funny.
@@ -171,7 +206,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 	device = (adr >> 16) & 0xffff;
 	function = adr & 0xffff;
 
-	pdev = pbus->self;
+	pdev = bridge->pci_dev;
 	if (pdev && device_is_managed_by_native_pciehp(pdev))
 		return AE_OK;
 
@@ -179,7 +214,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 	if (!newfunc)
 		return AE_NO_MEMORY;
 
-	INIT_LIST_HEAD(&newfunc->sibling);
 	newfunc->handle = handle;
 	newfunc->function = function;
 
@@ -229,7 +263,9 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 		INIT_LIST_HEAD(&slot->funcs);
 		mutex_init(&slot->crit_sect);
 
+		mutex_lock(&bridge_mutex);
 		list_add_tail(&slot->node, &bridge->slots);
+		mutex_unlock(&bridge_mutex);
 		bridge->nr_slots++;
 
 		dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n",
@@ -247,7 +283,9 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 	}
 
 	newfunc->slot = slot;
+	mutex_lock(&bridge_mutex);
 	list_add_tail(&newfunc->sibling, &slot->funcs);
+	mutex_unlock(&bridge_mutex);
 
 	if (pci_bus_read_dev_vendor_id(pbus, PCI_DEVFN(device, function),
 				       &val, 60*1000))
@@ -288,7 +326,9 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 
  err_exit:
 	bridge->nr_slots--;
+	mutex_lock(&bridge_mutex);
 	list_del(&slot->node);
+	mutex_unlock(&bridge_mutex);
 	kfree(slot);
 	kfree(newfunc);
 
@@ -313,13 +353,17 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge)
 	acpi_status status;
 
 	/* must be added to the list prior to calling register_slot */
+	mutex_lock(&bridge_mutex);
 	list_add(&bridge->list, &bridge_list);
+	mutex_unlock(&bridge_mutex);
 
 	/* register all slot objects under this bridge */
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
 				     register_slot, NULL, bridge, NULL);
 	if (ACPI_FAILURE(status)) {
+		mutex_lock(&bridge_mutex);
 		list_del(&bridge->list);
+		mutex_unlock(&bridge_mutex);
 		return;
 	}
 
@@ -349,16 +393,21 @@ static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle
 {
 	struct acpiphp_bridge *bridge;
 	struct acpiphp_slot *slot;
-	struct acpiphp_func *func;
+	struct acpiphp_func *func = NULL;
 
+	mutex_lock(&bridge_mutex);
 	list_for_each_entry(bridge, &bridge_list, list) {
 		list_for_each_entry(slot, &bridge->slots, node) {
 			list_for_each_entry(func, &slot->funcs, sibling) {
-				if (func->handle == handle)
+				if (func->handle == handle) {
+					get_bridge(func->slot->bridge);
+					mutex_unlock(&bridge_mutex);
 					return func;
+				}
 			}
 		}
 	}
+	mutex_unlock(&bridge_mutex);
 
 	return NULL;
 }
@@ -368,17 +417,22 @@ static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)
 {
 	struct acpiphp_bridge *bridge;
 
+	mutex_lock(&bridge_mutex);
 	list_for_each_entry(bridge, &bridge_list, list)
-		if (bridge->handle == handle)
+		if (bridge->handle == handle) {
+			get_bridge(bridge);
+			mutex_unlock(&bridge_mutex);
 			return bridge;
+		}
+	mutex_unlock(&bridge_mutex);
 
 	return NULL;
 }
 
 static void cleanup_bridge(struct acpiphp_bridge *bridge)
 {
-	struct acpiphp_slot *slot, *next;
-	struct acpiphp_func *func, *tmp;
+	struct acpiphp_slot *slot;
+	struct acpiphp_func *func;
 	acpi_status status;
 	acpi_handle handle = bridge->handle;
 
@@ -399,8 +453,8 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
 			err("failed to install interrupt notify handler\n");
 	}
 
-	list_for_each_entry_safe(slot, next, &bridge->slots, node) {
-		list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) {
+	list_for_each_entry(slot, &bridge->slots, node) {
+		list_for_each_entry(func, &slot->funcs, sibling) {
 			if (is_dock_device(func->handle)) {
 				unregister_hotplug_dock_device(func->handle);
 				unregister_dock_notifier(&func->nb);
@@ -412,18 +466,13 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
 				if (ACPI_FAILURE(status))
 					err("failed to remove notify handler\n");
 			}
-			list_del(&func->sibling);
-			kfree(func);
 		}
 		acpiphp_unregister_hotplug_slot(slot);
-		list_del(&slot->funcs);
-		kfree(slot);
 	}
 
-	put_device(&bridge->pci_bus->dev);
-	pci_dev_put(bridge->pci_dev);
+	mutex_lock(&bridge_mutex);
 	list_del(&bridge->list);
-	kfree(bridge);
+	mutex_unlock(&bridge_mutex);
 }
 
 static int power_on_slot(struct acpiphp_slot *slot)
@@ -620,7 +669,6 @@ static int __ref enable_device(struct acpiphp_slot *slot)
 	struct pci_dev *dev;
 	struct pci_bus *bus = slot->bridge->pci_bus;
 	struct acpiphp_func *func;
-	int retval = 0;
 	int num, max, pass;
 
 	if (slot->flags & SLOT_ENABLED)
@@ -680,7 +728,7 @@ static int __ref enable_device(struct acpiphp_slot *slot)
 
 
  err_exit:
-	return retval;
+	return 0;
 }
 
 /* return first device in slot, acquiring a reference on it */
@@ -897,6 +945,7 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
 		dbg("%s: re-enumerating slots under %s\n",
 			__func__, objname);
 		acpiphp_check_bridge(bridge);
+		put_bridge(bridge);
 	}
 	return AE_OK ;
 }
@@ -974,6 +1023,7 @@ static void _handle_hotplug_event_bridge(struct work_struct *work)
 
 	acpi_scan_lock_release();
 	kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
+	put_bridge(bridge);
 }
 
 /**
@@ -987,6 +1037,8 @@ static void _handle_hotplug_event_bridge(struct work_struct *work)
 static void handle_hotplug_event_bridge(acpi_handle handle, u32 type,
 					void *context)
 {
+	struct acpiphp_bridge *bridge = context;
+
 	/*
 	 * Currently the code adds all hotplug events to the kacpid_wq
 	 * queue when it should add hotplug events to the kacpi_hotplug_wq.
@@ -995,6 +1047,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.
 	 */
+	get_bridge(bridge);
 	alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge);
 }
 
@@ -1049,6 +1102,7 @@ static void _handle_hotplug_event_func(struct work_struct *work)
 
 	acpi_scan_lock_release();
 	kfree(hp_work); /* allocated in handle_hotplug_event_func */
+	put_bridge(func->slot->bridge);
 }
 
 /**
@@ -1062,6 +1116,8 @@ static void _handle_hotplug_event_func(struct work_struct *work)
 static void handle_hotplug_event_func(acpi_handle handle, u32 type,
 				      void *context)
 {
+	struct acpiphp_func *func = context;
+
 	/*
 	 * Currently the code adds all hotplug events to the kacpid_wq
 	 * queue when it should add hotplug events to the kacpi_hotplug_wq.
@@ -1070,6 +1126,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.
 	 */
+	get_bridge(func->slot->bridge);
 	alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func);
 }
 
@@ -1092,6 +1149,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle)
 	}
 
 	INIT_LIST_HEAD(&bridge->slots);
+	kref_init(&bridge->ref);
 	bridge->handle = handle;
 	bridge->pci_dev = pci_dev_get(bus->self);
 	bridge->pci_bus = bus;
@@ -1122,6 +1180,7 @@ void acpiphp_remove_slots(struct pci_bus *bus)
 	list_for_each_entry_safe(bridge, tmp, &bridge_list, list)
 		if (bridge->pci_bus == bus) {
 			cleanup_bridge(bridge);
+			put_bridge(bridge);
 			break;
 		}
 }
-- 
1.7.9.5

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

* [PATCH v9 15/16] PCI/acpiphp: introduce a kernel option to disable the acpiphp driver
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
                   ` (13 preceding siblings ...)
  2013-04-12 15:44 ` [PATCH v9 14/16] PCI/acpiphp: protect acpiphp data structures from concurrent updating Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-12 15:44 ` [PATCH v9 16/16] PCI, ACPI: remove support of ACPI PCI subdrivers Jiang Liu
  2013-04-12 22:17 ` [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Bjorn Helgaas
  16 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Jiang Liu, Yinghai Lu, Yijing Wang, Jiang Liu, linux-kernel,
	linux-pci, Greg Kroah-Hartman, ACPI Devel Maling List,
	Toshi Kani, Myron Stowe

Now the acpiphp driver has been converted as builtin, so introduce
a kernel boot option "acpiphp.disable" to disable the acpiphp driver
on boot.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
 Documentation/kernel-parameters.txt |    3 +++
 drivers/pci/hotplug/acpiphp.h       |    1 +
 drivers/pci/hotplug/acpiphp_core.c  |    6 +++++-
 drivers/pci/hotplug/acpiphp_glue.c  |    6 ++++++
 4 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 4609e81..38baa0d 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -290,6 +290,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			no: ACPI OperationRegions are not marked as reserved,
 			no further checks are performed.
 
+	acpiphp.disable
+			Disable the PCI acpiphp hotplug driver.
+
 	add_efi_memmap	[EFI; X86] Include EFI memory map in
 			kernel's map of available physical RAM.
 
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index 7577bb3..6a319f4 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -188,5 +188,6 @@ extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
 
 /* variables */
 extern bool acpiphp_debug;
+extern bool acpiphp_disabled;
 
 #endif /* _ACPIPHP_H */
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index 80d777c..cdbd983 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -49,6 +49,7 @@
 #define SLOT_NAME_SIZE  21              /* {_SUN} */
 
 bool acpiphp_debug;
+bool acpiphp_disabled;
 
 /* local variables */
 static struct acpiphp_attention_info *attention_info;
@@ -61,7 +62,9 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
+MODULE_PARM_DESC(disable, "disable acpiphp driver");
 module_param_named(debug, acpiphp_debug, bool, 0644);
+module_param_named(disable, acpiphp_disabled, bool, 0444);
 
 /* export the attention callback registration methods */
 EXPORT_SYMBOL_GPL(acpiphp_register_attention);
@@ -354,5 +357,6 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
 
 void __init acpiphp_init(void)
 {
-	info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+	info(DRIVER_DESC " version: " DRIVER_VERSION "%s\n",
+	     acpiphp_disabled ? ", disabled by user" : "");
 }
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 896d680..96fed19 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1139,6 +1139,9 @@ void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle)
 	acpi_handle dummy_handle;
 	struct acpiphp_bridge *bridge;
 
+	if (acpiphp_disabled)
+		return;
+
 	if (detect_ejectable_slots(handle) <= 0)
 		return;
 
@@ -1177,6 +1180,9 @@ void acpiphp_remove_slots(struct pci_bus *bus)
 {
 	struct acpiphp_bridge *bridge, *tmp;
 
+	if (acpiphp_disabled)
+		return;
+
 	list_for_each_entry_safe(bridge, tmp, &bridge_list, list)
 		if (bridge->pci_bus == bus) {
 			cleanup_bridge(bridge);
-- 
1.7.9.5

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

* [PATCH v9 16/16] PCI, ACPI: remove support of ACPI PCI subdrivers
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
                   ` (14 preceding siblings ...)
  2013-04-12 15:44 ` [PATCH v9 15/16] PCI/acpiphp: introduce a kernel option to disable the acpiphp driver Jiang Liu
@ 2013-04-12 15:44 ` Jiang Liu
  2013-04-12 22:17 ` [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Bjorn Helgaas
  16 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-12 15:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J . Wysocki
  Cc: Myron Stowe, Yinghai Lu, Yijing Wang, Jiang Liu, linux-kernel,
	linux-pci, Greg Kroah-Hartman, ACPI Devel Maling List,
	Toshi Kani, Jiang Liu, Rafael J. Wysocki

From: Myron Stowe <myron.stowe@redhat.com>

Both sub-drivers of the "PCI Root Bridge ("pci_bridge")" driver, "acpiphp"
and "pci_slot", have been converted to hook directly into the PCI core.

With the conversions there are no remaining usages of the 'struct
acpi_pci_driver' list based infrastructure.  This patch removes it.

Signed-off-by: Myron Stowe <myron.stowe@redhat.com>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Cc: linux-pci@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/acpi/pci_root.c |   48 +----------------------------------------------
 include/linux/acpi.h    |    9 ---------
 2 files changed, 1 insertion(+), 56 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 0ac546d..b80e06e 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -65,44 +65,12 @@ static struct acpi_scan_handler pci_root_handler = {
 	.detach = acpi_pci_root_remove,
 };
 
-/* Lock to protect both acpi_pci_roots and acpi_pci_drivers lists */
+/* Lock to protect both acpi_pci_roots lists */
 static DEFINE_MUTEX(acpi_pci_root_lock);
 static LIST_HEAD(acpi_pci_roots);
-static LIST_HEAD(acpi_pci_drivers);
 
 static DEFINE_MUTEX(osc_lock);
 
-int acpi_pci_register_driver(struct acpi_pci_driver *driver)
-{
-	int n = 0;
-	struct acpi_pci_root *root;
-
-	mutex_lock(&acpi_pci_root_lock);
-	list_add_tail(&driver->node, &acpi_pci_drivers);
-	if (driver->add)
-		list_for_each_entry(root, &acpi_pci_roots, node) {
-			driver->add(root);
-			n++;
-		}
-	mutex_unlock(&acpi_pci_root_lock);
-
-	return n;
-}
-EXPORT_SYMBOL(acpi_pci_register_driver);
-
-void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
-{
-	struct acpi_pci_root *root;
-
-	mutex_lock(&acpi_pci_root_lock);
-	list_del(&driver->node);
-	if (driver->remove)
-		list_for_each_entry(root, &acpi_pci_roots, node)
-			driver->remove(root);
-	mutex_unlock(&acpi_pci_root_lock);
-}
-EXPORT_SYMBOL(acpi_pci_unregister_driver);
-
 /**
  * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge
  * @handle - the ACPI CA node in question.
@@ -413,7 +381,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
 	acpi_status status;
 	int result;
 	struct acpi_pci_root *root;
-	struct acpi_pci_driver *driver;
 	u32 flags, base_flags;
 	bool is_osc_granted = false;
 
@@ -573,12 +540,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
 		pci_assign_unassigned_bus_resources(root->bus);
 	}
 
-	mutex_lock(&acpi_pci_root_lock);
-	list_for_each_entry(driver, &acpi_pci_drivers, node)
-		if (driver->add)
-			driver->add(root);
-	mutex_unlock(&acpi_pci_root_lock);
-
 	/* need to after hot-added ioapic is registered */
 	if (system_state != SYSTEM_BOOTING)
 		pci_enable_bridges(root->bus);
@@ -599,16 +560,9 @@ end:
 static void acpi_pci_root_remove(struct acpi_device *device)
 {
 	struct acpi_pci_root *root = acpi_driver_data(device);
-	struct acpi_pci_driver *driver;
 
 	pci_stop_root_bus(root->bus);
 
-	mutex_lock(&acpi_pci_root_lock);
-	list_for_each_entry_reverse(driver, &acpi_pci_drivers, node)
-		if (driver->remove)
-			driver->remove(root);
-	mutex_unlock(&acpi_pci_root_lock);
-
 	device_set_run_wake(root->bus->bridge, false);
 	pci_acpi_remove_bus_pm_notifier(device);
 
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index bcbdd74..03053ac 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -152,15 +152,6 @@ void acpi_penalize_isa_irq(int irq, int active);
 
 void acpi_pci_irq_disable (struct pci_dev *dev);
 
-struct acpi_pci_driver {
-	struct list_head node;
-	int (*add)(struct acpi_pci_root *root);
-	void (*remove)(struct acpi_pci_root *root);
-};
-
-int acpi_pci_register_driver(struct acpi_pci_driver *driver);
-void acpi_pci_unregister_driver(struct acpi_pci_driver *driver);
-
 extern int ec_read(u8 addr, u8 *val);
 extern int ec_write(u8 addr, u8 val);
 extern int ec_transaction(u8 command,
-- 
1.7.9.5

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

* Re: [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism
  2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
                   ` (15 preceding siblings ...)
  2013-04-12 15:44 ` [PATCH v9 16/16] PCI, ACPI: remove support of ACPI PCI subdrivers Jiang Liu
@ 2013-04-12 22:17 ` Bjorn Helgaas
  2013-04-13  4:03   ` Jiang Liu
  16 siblings, 1 reply; 23+ messages in thread
From: Bjorn Helgaas @ 2013-04-12 22:17 UTC (permalink / raw)
  To: Jiang Liu
  Cc: Rafael J . Wysocki, Jiang Liu, Yinghai Lu, Yijing Wang,
	linux-kernel, linux-pci, Greg Kroah-Hartman,
	ACPI Devel Maling List, Toshi Kani, Myron Stowe

On Fri, Apr 12, 2013 at 9:44 AM, Jiang Liu <liuj97@gmail.com> wrote:
> PCI, ACPI: remove ACPI PCI subdriver mechanism
>
> This patch set is directly derived from two sources:
> 1) '[PATCH 00/15] PCI/ACPI: Remove "pci_root" sub-driver support' at
> https://lkml.org/lkml/2012/12/7/11 from Myron Stowe
> The major goal is to resolve any potential sequencing inter-dependencies
> by converting sub-driver functionality to being only supported as
> statically built-in to the kernel as part of the "pci_root" driver
> itself.
>
> 2) 'introduce PCI bus notifier chain to get rid of the ACPI PCI subdriver'
> at http://lwn.net/Articles/533547/
> The major goal is to update PCI slots(pci_slot), ACPI based PCI hotplug
> slots(acpiphp), PCIe AER(aer) etc when hot-plugging PCI devices and P2P
> bridges, and eventually get rid of the ACPI PCI subdriver interfaces.
>
> This patchset applies to Bjorn's pci-next branch. Patch 1-4 are minor
> fixups for 3.9-rc1. Patch 5-8 introduce two hooks into PCI core which
> will be called when creating/destroying PCI buses. Patch 9-12 replace
> ACPI PCI subdriver interfaces with the new hook mechanism for pci_slot
> and acpiphp. Patch 13 removes the ACPI PCI subdriver interfaces.
>
> v7->v8:
>         Hook directly into the PCI core to replace pci_bus notification
>         Remove ACPI PCI subdriver related code
>
> v8->v9:
>         Introduce kernel boot option "acpiphp.disable" to disable the
>         acpiphp driver.
>
> Jiang Liu (13):
>   PCI: do not check is_added flag in pci_remove_bus()
>   pci: clean up usages of pci_bus->is_added
>   PCI/acpiphp: don't rely on function 0 in disable_device()
>   ACPI/acpiphp: replace local macros with standard ACPI macros
>   PCI: introduce platform dependent hooks for creating/destroying PCI
>     busses
>   PCI, ACPI: prepare stub functions to handle ACPI PCI (hotplug) slots
>   PCI, IA64: implement pcibios_{add|remove}_bus() hooks
>   PCI, x86: implement pcibios_{add|remove}_bus() hooks
>   PCI, ACPI: handle PCI slot devices when creating/destroying PCI
>     busses
>   PCI/acpiphp: convert acpiphp as a builtin driver
>   PCI/acpiphp: do not use ACPI PCI subdriver mechanism
>   PCI/acpiphp: protect acpiphp data structures from concurrent updating
>   PCI/acpiphp: introduce a kernel option to disable the acpiphp driver
>
> Myron Stowe (1):
>   PCI, ACPI: remove support of ACPI PCI subdrivers
>
> Yijing Wang (2):
>   PCI/acpiphp: use list_for_each_entry_safe() in acpiphp_sanitize_bus()
>   PCI/acpiphp: use normal list to simplify implementation
>
>  Documentation/kernel-parameters.txt |    3 +
>  arch/ia64/pci/pci.c                 |   11 +
>  arch/x86/pci/common.c               |   11 +
>  drivers/acpi/pci_root.c             |   48 +---
>  drivers/acpi/pci_slot.c             |  170 ++------------
>  drivers/acpi/scan.c                 |    1 -
>  drivers/pci/bus.c                   |   11 +-
>  drivers/pci/hotplug/Kconfig         |    7 +-
>  drivers/pci/hotplug/acpiphp.h       |   13 +-
>  drivers/pci/hotplug/acpiphp_core.c  |   29 +--
>  drivers/pci/hotplug/acpiphp_glue.c  |  415 ++++++++++++-----------------------
>  drivers/pci/pci-acpi.c              |   30 +++
>  drivers/pci/probe.c                 |   15 +-
>  drivers/pci/remove.c                |    4 +-
>  include/linux/acpi.h                |    9 -
>  include/linux/pci-acpi.h            |   26 +++
>  include/linux/pci.h                 |    2 +
>  17 files changed, 280 insertions(+), 525 deletions(-)

I applied these to my pci/jiang-subdrivers branch with minor tweaks.
The most significant is that I folded in the acpiphp.disable option to
the patch that makes the driver builtin-only.  That way there's no
window between removing the "edit modules.conf" workaround and adding
the kernel parameter.

Take a look and make sure it's what you want:
http://git.kernel.org/cgit/linux/kernel/git/helgaas/pci.git/log/?h=pci/jiang-subdrivers

Bjorn

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

* Re: [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism
  2013-04-12 22:17 ` [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Bjorn Helgaas
@ 2013-04-13  4:03   ` Jiang Liu
  0 siblings, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-13  4:03 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Rafael J . Wysocki, Jiang Liu, Yinghai Lu, Yijing Wang,
	linux-kernel, linux-pci, Greg Kroah-Hartman,
	ACPI Devel Maling List, Toshi Kani, Myron Stowe

On 04/13/2013 06:17 AM, Bjorn Helgaas wrote:
> On Fri, Apr 12, 2013 at 9:44 AM, Jiang Liu <liuj97@gmail.com> wrote:
> 
> I applied these to my pci/jiang-subdrivers branch with minor tweaks.
> The most significant is that I folded in the acpiphp.disable option to
> the patch that makes the driver builtin-only.  That way there's no
> window between removing the "edit modules.conf" workaround and adding
> the kernel parameter.
> 
> Take a look and make sure it's what you want:
> http://git.kernel.org/cgit/linux/kernel/git/helgaas/pci.git/log/?h=pci/jiang-subdrivers
> 
> Bjorn
Hi Bjorn,
	Thanks for your support, it seems OK to me.
	Regards!
	Gerry

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

* Re: [PATCH v9 09/16] PCI, x86: implement pcibios_{add|remove}_bus() hooks
  2013-04-12 15:44 ` [PATCH v9 09/16] PCI, x86: " Jiang Liu
@ 2013-04-16 20:27   ` David Rientjes
  2013-04-16 22:35     ` Bjorn Helgaas
  2013-04-17  0:00     ` Jiang Liu
  0 siblings, 2 replies; 23+ messages in thread
From: David Rientjes @ 2013-04-16 20:27 UTC (permalink / raw)
  To: Jiang Liu
  Cc: Bjorn Helgaas, Rafael J . Wysocki, Jiang Liu, Yinghai Lu,
	Yijing Wang, linux-kernel, linux-pci, Greg Kroah-Hartman,
	ACPI Devel Maling List, Toshi Kani, Myron Stowe,
	Rafael J. Wysocki, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	x86

On Fri, 12 Apr 2013, Jiang Liu wrote:

> diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
> index 901177d..305c68b 100644
> --- a/arch/x86/pci/common.c
> +++ b/arch/x86/pci/common.c
> @@ -6,6 +6,7 @@
>  
>  #include <linux/sched.h>
>  #include <linux/pci.h>
> +#include <linux/pci-acpi.h>
>  #include <linux/ioport.h>
>  #include <linux/init.h>
>  #include <linux/dmi.h>
> @@ -170,6 +171,16 @@ void pcibios_fixup_bus(struct pci_bus *b)
>  		pcibios_fixup_device_resources(dev);
>  }
>  
> +void pcibios_add_bus(struct pci_bus *bus)
> +{
> +	acpi_pci_add_bus(bus);
> +}
> +
> +void pcibios_remove_bus(struct pci_bus *bus)
> +{
> +	acpi_pci_remove_bus(bus);
> +}
> +
>  /*
>   * Only use DMI information to set this if nothing was passed
>   * on the kernel command line (which was parsed earlier).

This causes build errors when CONFIG_ACPI isn't enabled since both 
acpi_pci_{add,remove}_bus() aren't defined in such a configuration:

arch/x86/pci/common.c: In function 'pcibios_add_bus':
arch/x86/pci/common.c:176:2: error: implicit declaration of function 'acpi_pci_add_bus'
arch/x86/pci/common.c: In function 'pcibios_remove_bus':
arch/x86/pci/common.c:181:2: error: implicit declaration of function 'acpi_pci_remove_bus'

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

* Re: [PATCH v9 09/16] PCI, x86: implement pcibios_{add|remove}_bus() hooks
  2013-04-16 20:27   ` David Rientjes
@ 2013-04-16 22:35     ` Bjorn Helgaas
  2013-04-17 20:49       ` David Rientjes
  2013-04-17  0:00     ` Jiang Liu
  1 sibling, 1 reply; 23+ messages in thread
From: Bjorn Helgaas @ 2013-04-16 22:35 UTC (permalink / raw)
  To: David Rientjes
  Cc: Jiang Liu, Rafael J . Wysocki, Jiang Liu, Yinghai Lu,
	Yijing Wang, linux-kernel, linux-pci, Greg Kroah-Hartman,
	ACPI Devel Maling List, Toshi Kani, Myron Stowe,
	Rafael J. Wysocki, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	x86

On Tue, Apr 16, 2013 at 2:27 PM, David Rientjes <rientjes@google.com> wrote:
> On Fri, 12 Apr 2013, Jiang Liu wrote:
>
>> diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
>> index 901177d..305c68b 100644
>> --- a/arch/x86/pci/common.c
>> +++ b/arch/x86/pci/common.c
>> @@ -6,6 +6,7 @@
>>
>>  #include <linux/sched.h>
>>  #include <linux/pci.h>
>> +#include <linux/pci-acpi.h>
>>  #include <linux/ioport.h>
>>  #include <linux/init.h>
>>  #include <linux/dmi.h>
>> @@ -170,6 +171,16 @@ void pcibios_fixup_bus(struct pci_bus *b)
>>               pcibios_fixup_device_resources(dev);
>>  }
>>
>> +void pcibios_add_bus(struct pci_bus *bus)
>> +{
>> +     acpi_pci_add_bus(bus);
>> +}
>> +
>> +void pcibios_remove_bus(struct pci_bus *bus)
>> +{
>> +     acpi_pci_remove_bus(bus);
>> +}
>> +
>>  /*
>>   * Only use DMI information to set this if nothing was passed
>>   * on the kernel command line (which was parsed earlier).
>
> This causes build errors when CONFIG_ACPI isn't enabled since both
> acpi_pci_{add,remove}_bus() aren't defined in such a configuration:
>
> arch/x86/pci/common.c: In function 'pcibios_add_bus':
> arch/x86/pci/common.c:176:2: error: implicit declaration of function 'acpi_pci_add_bus'
> arch/x86/pci/common.c: In function 'pcibios_remove_bus':
> arch/x86/pci/common.c:181:2: error: implicit declaration of function 'acpi_pci_remove_bus'

Thanks for the report!

I'm pretty sure I fixed this:
http://git.kernel.org/cgit/linux/kernel/git/helgaas/pci.git/commit/?h=pci/jiang-subdrivers&id=3b63aaa70e1ccc4b66d60acc78da09700706a703

The acpi_pci_add_bus()/acpi_pci_remove_bus() stubs for CONFIG_ACPI=n
were added early in the series (patch 07/16: "PCI/ACPI: Prepare stub
functions to handle ACPI PCI (hotplug) slots") but were mistakenly
removed in patch 12/16: "PCI: acpiphp: Do not use ACPI PCI subdriver
mechanism".

I updated my "next" branch with the fixed version of patch 12/16, so
the 20130417 linux-next tree should have the fix.

Bjorn

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

* Re: [PATCH v9 09/16] PCI, x86: implement pcibios_{add|remove}_bus() hooks
  2013-04-16 20:27   ` David Rientjes
  2013-04-16 22:35     ` Bjorn Helgaas
@ 2013-04-17  0:00     ` Jiang Liu
  1 sibling, 0 replies; 23+ messages in thread
From: Jiang Liu @ 2013-04-17  0:00 UTC (permalink / raw)
  To: David Rientjes
  Cc: Bjorn Helgaas, Rafael J . Wysocki, Jiang Liu, Yinghai Lu,
	Yijing Wang, linux-kernel, linux-pci, Greg Kroah-Hartman,
	ACPI Devel Maling List, Toshi Kani, Myron Stowe,
	Rafael J. Wysocki, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	x86

On 04/17/2013 04:27 AM, David Rientjes wrote:
> On Fri, 12 Apr 2013, Jiang Liu wrote:
> 
>> diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
>> index 901177d..305c68b 100644
>> --- a/arch/x86/pci/common.c
>> +++ b/arch/x86/pci/common.c
>> @@ -6,6 +6,7 @@
>>  
>>  #include <linux/sched.h>
>>  #include <linux/pci.h>
>> +#include <linux/pci-acpi.h>
>>  #include <linux/ioport.h>
>>  #include <linux/init.h>
>>  #include <linux/dmi.h>
>> @@ -170,6 +171,16 @@ void pcibios_fixup_bus(struct pci_bus *b)
>>  		pcibios_fixup_device_resources(dev);
>>  }
>>  
>> +void pcibios_add_bus(struct pci_bus *bus)
>> +{
>> +	acpi_pci_add_bus(bus);
>> +}
>> +
>> +void pcibios_remove_bus(struct pci_bus *bus)
>> +{
>> +	acpi_pci_remove_bus(bus);
>> +}
>> +
>>  /*
>>   * Only use DMI information to set this if nothing was passed
>>   * on the kernel command line (which was parsed earlier).
> 
> This causes build errors when CONFIG_ACPI isn't enabled since both 
> acpi_pci_{add,remove}_bus() aren't defined in such a configuration:
> 
> arch/x86/pci/common.c: In function 'pcibios_add_bus':
> arch/x86/pci/common.c:176:2: error: implicit declaration of function 'acpi_pci_add_bus'
> arch/x86/pci/common.c: In function 'pcibios_remove_bus':
> arch/x86/pci/common.c:181:2: error: implicit declaration of function 'acpi_pci_remove_bus'
> 
Hi David,
	Thanks for report, I have sent a patch to Bjorn to fix this issue,
and it should have been fixed in Bjorn's git tree.
	Regards!
	Gerry



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

* Re: [PATCH v9 09/16] PCI, x86: implement pcibios_{add|remove}_bus() hooks
  2013-04-16 22:35     ` Bjorn Helgaas
@ 2013-04-17 20:49       ` David Rientjes
  0 siblings, 0 replies; 23+ messages in thread
From: David Rientjes @ 2013-04-17 20:49 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Jiang Liu, Rafael J . Wysocki, Jiang Liu, Yinghai Lu,
	Yijing Wang, linux-kernel, linux-pci, Greg Kroah-Hartman,
	ACPI Devel Maling List, Toshi Kani, Myron Stowe,
	Rafael J. Wysocki, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	x86

On Tue, 16 Apr 2013, Bjorn Helgaas wrote:

> Thanks for the report!
> 
> I'm pretty sure I fixed this:
> http://git.kernel.org/cgit/linux/kernel/git/helgaas/pci.git/commit/?h=pci/jiang-subdrivers&id=3b63aaa70e1ccc4b66d60acc78da09700706a703
> 
> The acpi_pci_add_bus()/acpi_pci_remove_bus() stubs for CONFIG_ACPI=n
> were added early in the series (patch 07/16: "PCI/ACPI: Prepare stub
> functions to handle ACPI PCI (hotplug) slots") but were mistakenly
> removed in patch 12/16: "PCI: acpiphp: Do not use ACPI PCI subdriver
> mechanism".
> 
> I updated my "next" branch with the fixed version of patch 12/16, so
> the 20130417 linux-next tree should have the fix.
> 

Confirmed it's fixed, thanks.

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

end of thread, other threads:[~2013-04-17 20:49 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-04-12 15:44 [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Jiang Liu
2013-04-12 15:44 ` [PATCH v9 01/16] PCI: do not check is_added flag in pci_remove_bus() Jiang Liu
2013-04-12 15:44 ` [PATCH v9 02/16] pci: clean up usages of pci_bus->is_added Jiang Liu
2013-04-12 15:44 ` [PATCH v9 03/16] PCI/acpiphp: use list_for_each_entry_safe() in acpiphp_sanitize_bus() Jiang Liu
2013-04-12 15:44 ` [PATCH v9 04/16] PCI/acpiphp: don't rely on function 0 in disable_device() Jiang Liu
2013-04-12 15:44 ` [PATCH v9 05/16] ACPI/acpiphp: replace local macros with standard ACPI macros Jiang Liu
2013-04-12 15:44 ` [PATCH v9 06/16] PCI: introduce platform dependent hooks for creating/destroying PCI busses Jiang Liu
2013-04-12 15:44 ` [PATCH v9 07/16] PCI, ACPI: prepare stub functions to handle ACPI PCI (hotplug) slots Jiang Liu
2013-04-12 15:44 ` [PATCH v9 08/16] PCI, IA64: implement pcibios_{add|remove}_bus() hooks Jiang Liu
2013-04-12 15:44 ` [PATCH v9 09/16] PCI, x86: " Jiang Liu
2013-04-16 20:27   ` David Rientjes
2013-04-16 22:35     ` Bjorn Helgaas
2013-04-17 20:49       ` David Rientjes
2013-04-17  0:00     ` Jiang Liu
2013-04-12 15:44 ` [PATCH v9 10/16] PCI, ACPI: handle PCI slot devices when creating/destroying PCI busses Jiang Liu
2013-04-12 15:44 ` [PATCH v9 11/16] PCI/acpiphp: convert acpiphp as a builtin driver Jiang Liu
2013-04-12 15:44 ` [PATCH v9 12/16] PCI/acpiphp: do not use ACPI PCI subdriver mechanism Jiang Liu
2013-04-12 15:44 ` [PATCH v9 13/16] PCI/acpiphp: use normal list to simplify implementation Jiang Liu
2013-04-12 15:44 ` [PATCH v9 14/16] PCI/acpiphp: protect acpiphp data structures from concurrent updating Jiang Liu
2013-04-12 15:44 ` [PATCH v9 15/16] PCI/acpiphp: introduce a kernel option to disable the acpiphp driver Jiang Liu
2013-04-12 15:44 ` [PATCH v9 16/16] PCI, ACPI: remove support of ACPI PCI subdrivers Jiang Liu
2013-04-12 22:17 ` [PATCH v9 00/16] Get rid of the ACPI PCI subdriver mechanism Bjorn Helgaas
2013-04-13  4:03   ` Jiang Liu

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