From 10a9574756201fbbdd0cac11f370f00d3d02bfa1 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 12 Apr 2013 05:44:20 +0000 Subject: PCI: Add pcibios hooks for adding and removing PCI buses 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 buses for PCI host and P2P bridges. They could be used to setup/destroy platform dependent stuff in a unified way, both at boot time and for PCI hotplug operations. Signed-off-by: Jiang Liu Signed-off-by: Yijing Wang Signed-off-by: Bjorn Helgaas Reviewed-by: Yinghai Lu Cc: "Rafael J. Wysocki" Cc: Toshi Kani Cc: Tony Luck Cc: Fenghua Yu Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Myron Stowe --- include/linux/pci.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 2461033a7987..be9399452133 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -678,6 +678,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) */ -- cgit v1.2.3 From 5090d4a6a1f150ec593ac5f2a755b5a3e878b21e Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 12 Apr 2013 05:44:21 +0000 Subject: PCI/ACPI: Prepare stub functions to handle ACPI PCI (hotplug) slots 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 Signed-off-by: Yijing Wang Signed-off-by: Bjorn Helgaas Reviewed-by: Yinghai Lu Cc: "Rafael J. Wysocki" Cc: Toshi Kani Cc: Tony Luck Cc: Fenghua Yu Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Myron Stowe --- include/linux/pci-acpi.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 9a22b5efb384..2b1743cc3186 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); -- cgit v1.2.3 From 5c0b04e3d913c91aee6e48e567e20a3f67849618 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 12 Apr 2013 05:44:24 +0000 Subject: PCI/ACPI: Handle PCI slot devices when creating/destroying PCI buses 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. [bhelgas: removed "extern" from function declarations] Signed-off-by: Jiang Liu Signed-off-by: Yijing Wang Signed-off-by: Bjorn Helgaas Reviewed-by: Yinghai Lu Acked-by: Rafael J. Wysocki Cc: Toshi Kani --- include/linux/pci-acpi.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 2b1743cc3186..23cd40abba4f 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 +void acpi_pci_slot_init(void); +void acpi_pci_slot_enumerate(struct pci_bus *bus, acpi_handle handle); +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) { } -- cgit v1.2.3 From 3b63aaa70e1ccc4b66d60acc78da09700706a703 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 12 Apr 2013 05:44:26 +0000 Subject: PCI: acpiphp: Do not use ACPI PCI subdriver mechanism Previously the acpiphp driver registered itself as an ACPI PCI subdriver, so its callbacks were 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 behaviour if there are hotplug slots associated with a hot-removed P2P bridge. This patch fixes this issue by: 1) Directly hooking into PCI core to update hotplug slot devices when creating/destroying PCI buses through: pci_{add|remove}_bus() -> acpi_pci_{add|remove}_bus() 2) Getting rid of unused ACPI PCI subdriver-related code It also cleans up unused code in the acpiphp driver. [bhelgaas: keep acpi_pci_add_bus() stub for CONFIG_ACPI=n] Signed-off-by: Jiang Liu Signed-off-by: Yijing Wang Signed-off-by: Bjorn Helgaas Reviewed-by: Yinghai Lu Cc: "Rafael J. Wysocki" Cc: Toshi Kani --- include/linux/pci-acpi.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 23cd40abba4f..81b31613eb25 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h @@ -56,6 +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 +#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 + #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) { } -- cgit v1.2.3 From c309dbb4debb714566e4cf0d5d4e4023c3c4ff2f Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Fri, 12 Apr 2013 05:44:30 +0000 Subject: PCI/ACPI: Remove support of ACPI PCI subdrivers 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 Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas Reviewed-by: Yinghai Lu Cc: "Rafael J. Wysocki" Cc: Toshi Kani --- include/linux/acpi.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index bcbdd7484e58..03053aca5b32 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, -- cgit v1.2.3