mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
PCI changes for the 3.7 merge window:
Host bridge hotplug
- Protect acpi_pci_drivers and acpi_pci_roots (Taku Izumi)
- Clear host bridge resource info to avoid issue when releasing (Yinghai Lu)
- Notify acpi_pci_drivers when hot-plugging host bridges (Jiang Liu)
- Use standard list ops for acpi_pci_drivers (Jiang Liu)
Device hotplug
- Use pci_get_domain_bus_and_slot() to close hotplug races (Jiang Liu)
- Remove fakephp driver (Bjorn Helgaas)
- Fix VGA ref count in hotplug remove path (Yinghai Lu)
- Allow acpiphp to handle PCIe ports without native hotplug (Jiang Liu)
- Implement resume regardless of pciehp_force param (Oliver Neukum)
- Make pci_fixup_irqs() work after init (Thierry Reding)
Miscellaneous
- Add pci_pcie_type(dev) and remove pci_dev.pcie_type (Yijing Wang)
- Factor out PCI Express Capability accessors (Jiang Liu)
- Add pcibios_window_alignment() so powerpc EEH can use generic resource assignment (Gavin Shan)
- Make pci_error_handlers const (Stephen Hemminger)
- Cleanup drivers/pci/remove.c (Bjorn Helgaas)
- Improve Vendor-Specific Extended Capability support (Bjorn Helgaas)
- Use standard list ops for bus->devices (Bjorn Helgaas)
- Avoid kmalloc in pci_get_subsys() and pci_get_class() (Feng Tang)
- Reassign invalid bus number ranges (Intel DP43BF workaround) (Yinghai Lu)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
iQIcBAABAgAGBQJQac4hAAoJEPGMOI97Hn6zjZYP/iaqU9kjmgTsBbSyzB4oApv/
RRxo3I+ad9GF6XlMQfVAtyx1pgCD1gdGAtoDgGSCTqgdYD3CO10AxKU+yleAk1wo
dbMxLifJNTrT3G1mZ/NL16yEGhCwvhfwzRtB1VoZmCT4lSApO/7cJkXl2DzHfA/i
pmltOOiQCN8kbUcJbVPtUyTVPi2zl/8bsyCyTkS7YG0VXeGRM+ZUvPWZJ7MnWYYB
5qoCdrw5ENCCiDQ9yw5SAfgL23b+0p6OI/x3Lkex0QQOWwSqGSiaHt4b7eitrC5b
2eAJg32f/AzZke1YbKLMfdsL0VJP3GAswhDVHlgmo63rZkOZChm+97dgZ35Mcv5v
kEXkWyBb1xJ3t8rZir6Qer9Iv2wOB+MkZ5qtU/Vf+l0wLQLYTrRVsKngrEDREONk
dXbokp6iVSPeA1sTSdH9MmHlTUIj82ZLSGcxcjTsN8NWZjxx6g3rNx1uay+5MYOW
4ET9zNu5snrAqN6N4Tb81gvtG8qYfxzdvVfrA9AaGKI6xxB7jkqgFJRp55JiEcFc
x4cmWkhvdlhVsG2TQwFxYNfswOqD+7NCs6V4kSVZX6ezpDrH7I5VvcnnhstF7C8l
KZul0EV7OW+kDK23pNe24lVP2xtOv6G8eK/3PmeKIXWl1V83nqre/oLufRzTfs+Z
SxkILwY/MFpuCFteKE1t
=haBu
-----END PGP SIGNATURE-----
Merge tag 'for-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas:
"Host bridge hotplug
- Protect acpi_pci_drivers and acpi_pci_roots (Taku Izumi)
- Clear host bridge resource info to avoid issue when releasing
(Yinghai Lu)
- Notify acpi_pci_drivers when hot-plugging host bridges (Jiang Liu)
- Use standard list ops for acpi_pci_drivers (Jiang Liu)
Device hotplug
- Use pci_get_domain_bus_and_slot() to close hotplug races (Jiang
Liu)
- Remove fakephp driver (Bjorn Helgaas)
- Fix VGA ref count in hotplug remove path (Yinghai Lu)
- Allow acpiphp to handle PCIe ports without native hotplug (Jiang
Liu)
- Implement resume regardless of pciehp_force param (Oliver Neukum)
- Make pci_fixup_irqs() work after init (Thierry Reding)
Miscellaneous
- Add pci_pcie_type(dev) and remove pci_dev.pcie_type (Yijing Wang)
- Factor out PCI Express Capability accessors (Jiang Liu)
- Add pcibios_window_alignment() so powerpc EEH can use generic
resource assignment (Gavin Shan)
- Make pci_error_handlers const (Stephen Hemminger)
- Cleanup drivers/pci/remove.c (Bjorn Helgaas)
- Improve Vendor-Specific Extended Capability support (Bjorn
Helgaas)
- Use standard list ops for bus->devices (Bjorn Helgaas)
- Avoid kmalloc in pci_get_subsys() and pci_get_class() (Feng Tang)
- Reassign invalid bus number ranges (Intel DP43BF workaround)
(Yinghai Lu)"
* tag 'for-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (102 commits)
PCI: acpiphp: Handle PCIe ports without native hotplug capability
PCI/ACPI: Use acpi_driver_data() rather than searching acpi_pci_roots
PCI/ACPI: Protect acpi_pci_roots list with mutex
PCI/ACPI: Use acpi_pci_root info rather than looking it up again
PCI/ACPI: Pass acpi_pci_root to acpi_pci_drivers' add/remove interface
PCI/ACPI: Protect acpi_pci_drivers list with mutex
PCI/ACPI: Notify acpi_pci_drivers when hot-plugging PCI root bridges
PCI/ACPI: Use normal list for struct acpi_pci_driver
PCI/ACPI: Use DEVICE_ACPI_HANDLE rather than searching acpi_pci_roots
PCI: Fix default vga ref_count
ia64/PCI: Clear host bridge aperture struct resource
x86/PCI: Clear host bridge aperture struct resource
PCI: Stop all children first, before removing all children
Revert "PCI: Use hotplug-safe pci_get_domain_bus_and_slot()"
PCI: Provide a default pcibios_update_irq()
PCI: Discard __init annotations for pci_fixup_irqs() and related functions
PCI: Use correct type when freeing bus resource list
PCI: Check P2P bridge for invalid secondary/subordinate range
PCI: Convert "new_id"/"remove_id" into generic pci_bus driver attributes
xen-pcifront: Use hotplug-safe pci_get_domain_bus_and_slot()
...
This commit is contained in:
commit
fdb2f9c2eb
123 changed files with 1078 additions and 1750 deletions
|
|
@ -27,7 +27,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/pci.h>
|
||||
|
|
@ -71,9 +71,11 @@ static struct acpi_driver acpi_pci_root_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
/* Lock to protect both acpi_pci_roots and acpi_pci_drivers lists */
|
||||
static DEFINE_MUTEX(acpi_pci_root_lock);
|
||||
static LIST_HEAD(acpi_pci_roots);
|
||||
static LIST_HEAD(acpi_pci_drivers);
|
||||
|
||||
static struct acpi_pci_driver *sub_driver;
|
||||
static DEFINE_MUTEX(osc_lock);
|
||||
|
||||
int acpi_pci_register_driver(struct acpi_pci_driver *driver)
|
||||
|
|
@ -81,55 +83,46 @@ int acpi_pci_register_driver(struct acpi_pci_driver *driver)
|
|||
int n = 0;
|
||||
struct acpi_pci_root *root;
|
||||
|
||||
struct acpi_pci_driver **pptr = &sub_driver;
|
||||
while (*pptr)
|
||||
pptr = &(*pptr)->next;
|
||||
*pptr = driver;
|
||||
|
||||
if (!driver->add)
|
||||
return 0;
|
||||
|
||||
list_for_each_entry(root, &acpi_pci_roots, node) {
|
||||
driver->add(root->device->handle);
|
||||
n++;
|
||||
}
|
||||
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;
|
||||
|
||||
struct acpi_pci_driver **pptr = &sub_driver;
|
||||
while (*pptr) {
|
||||
if (*pptr == driver)
|
||||
break;
|
||||
pptr = &(*pptr)->next;
|
||||
}
|
||||
BUG_ON(!*pptr);
|
||||
*pptr = (*pptr)->next;
|
||||
|
||||
if (!driver->remove)
|
||||
return;
|
||||
|
||||
list_for_each_entry(root, &acpi_pci_roots, node)
|
||||
driver->remove(root->device->handle);
|
||||
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_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
|
||||
{
|
||||
struct acpi_pci_root *root;
|
||||
acpi_handle handle = NULL;
|
||||
|
||||
mutex_lock(&acpi_pci_root_lock);
|
||||
list_for_each_entry(root, &acpi_pci_roots, node)
|
||||
if ((root->segment == (u16) seg) &&
|
||||
(root->secondary.start == (u16) bus))
|
||||
return root->device->handle;
|
||||
return NULL;
|
||||
(root->secondary.start == (u16) bus)) {
|
||||
handle = root->device->handle;
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&acpi_pci_root_lock);
|
||||
return handle;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
|
||||
|
|
@ -277,12 +270,15 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags)
|
|||
struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
|
||||
{
|
||||
struct acpi_pci_root *root;
|
||||
struct acpi_device *device;
|
||||
|
||||
list_for_each_entry(root, &acpi_pci_roots, node) {
|
||||
if (root->device->handle == handle)
|
||||
return root;
|
||||
}
|
||||
return NULL;
|
||||
if (acpi_bus_get_device(handle, &device) ||
|
||||
acpi_match_device_ids(device, root_device_ids))
|
||||
return NULL;
|
||||
|
||||
root = acpi_driver_data(device);
|
||||
|
||||
return root;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_pci_find_root);
|
||||
|
||||
|
|
@ -518,8 +514,9 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
|||
* TBD: Need PCI interface for enumeration/configuration of roots.
|
||||
*/
|
||||
|
||||
/* TBD: Locking */
|
||||
mutex_lock(&acpi_pci_root_lock);
|
||||
list_add_tail(&root->node, &acpi_pci_roots);
|
||||
mutex_unlock(&acpi_pci_root_lock);
|
||||
|
||||
printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n",
|
||||
acpi_device_name(device), acpi_device_bid(device),
|
||||
|
|
@ -538,7 +535,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
|||
"Bus %04x:%02x not present in PCI namespace\n",
|
||||
root->segment, (unsigned int)root->secondary.start);
|
||||
result = -ENODEV;
|
||||
goto end;
|
||||
goto out_del_root;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -548,7 +545,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
|||
*/
|
||||
result = acpi_pci_bind_root(device);
|
||||
if (result)
|
||||
goto end;
|
||||
goto out_del_root;
|
||||
|
||||
/*
|
||||
* PCI Routing Table
|
||||
|
|
@ -633,9 +630,11 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
|||
|
||||
return 0;
|
||||
|
||||
out_del_root:
|
||||
mutex_lock(&acpi_pci_root_lock);
|
||||
list_del(&root->node);
|
||||
mutex_unlock(&acpi_pci_root_lock);
|
||||
end:
|
||||
if (!list_empty(&root->node))
|
||||
list_del(&root->node);
|
||||
kfree(root);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -643,18 +642,34 @@ end:
|
|||
static int acpi_pci_root_start(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_pci_root *root = acpi_driver_data(device);
|
||||
struct acpi_pci_driver *driver;
|
||||
|
||||
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);
|
||||
|
||||
pci_bus_add_devices(root->bus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_pci_root_remove(struct acpi_device *device, int type)
|
||||
{
|
||||
struct acpi_pci_root *root = acpi_driver_data(device);
|
||||
struct acpi_pci_driver *driver;
|
||||
|
||||
mutex_lock(&acpi_pci_root_lock);
|
||||
list_for_each_entry(driver, &acpi_pci_drivers, node)
|
||||
if (driver->remove)
|
||||
driver->remove(root);
|
||||
|
||||
device_set_run_wake(root->bus->bridge, false);
|
||||
pci_acpi_remove_bus_pm_notifier(device);
|
||||
|
||||
list_del(&root->node);
|
||||
mutex_unlock(&acpi_pci_root_lock);
|
||||
kfree(root);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ struct acpi_pci_slot {
|
|||
struct list_head list; /* node in the list of slots */
|
||||
};
|
||||
|
||||
static int acpi_pci_slot_add(acpi_handle handle);
|
||||
static void acpi_pci_slot_remove(acpi_handle handle);
|
||||
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);
|
||||
|
|
@ -233,45 +233,20 @@ out:
|
|||
|
||||
/*
|
||||
* walk_root_bridge - generic root bridge walker
|
||||
* @handle: points to an acpi_pci_root
|
||||
* @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(acpi_handle handle, acpi_walk_callback user_function)
|
||||
walk_root_bridge(struct acpi_pci_root *root, acpi_walk_callback user_function)
|
||||
{
|
||||
int seg, bus;
|
||||
unsigned long long tmp;
|
||||
acpi_status status;
|
||||
acpi_handle dummy_handle;
|
||||
struct pci_bus *pci_bus;
|
||||
acpi_handle handle = root->device->handle;
|
||||
struct pci_bus *pci_bus = root->bus;
|
||||
struct callback_args context;
|
||||
|
||||
/* 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)) {
|
||||
info("%s: _STA evaluation failure\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
if ((tmp & ACPI_STA_DEVICE_FUNCTIONING) == 0)
|
||||
/* don't register this object */
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = acpi_evaluate_integer(handle, "_SEG", NULL, &tmp);
|
||||
seg = ACPI_SUCCESS(status) ? tmp : 0;
|
||||
|
||||
status = acpi_evaluate_integer(handle, "_BBN", NULL, &tmp);
|
||||
bus = ACPI_SUCCESS(status) ? tmp : 0;
|
||||
|
||||
pci_bus = pci_find_bus(seg, bus);
|
||||
if (!pci_bus)
|
||||
return 0;
|
||||
|
||||
context.pci_bus = pci_bus;
|
||||
context.user_function = user_function;
|
||||
context.root_handle = handle;
|
||||
|
|
@ -295,11 +270,11 @@ walk_root_bridge(acpi_handle handle, acpi_walk_callback user_function)
|
|||
* @handle: points to an acpi_pci_root
|
||||
*/
|
||||
static int
|
||||
acpi_pci_slot_add(acpi_handle handle)
|
||||
acpi_pci_slot_add(struct acpi_pci_root *root)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
status = walk_root_bridge(handle, register_slot);
|
||||
status = walk_root_bridge(root, register_slot);
|
||||
if (ACPI_FAILURE(status))
|
||||
err("%s: register_slot failure - %d\n", __func__, status);
|
||||
|
||||
|
|
@ -311,10 +286,11 @@ acpi_pci_slot_add(acpi_handle handle)
|
|||
* @handle: points to an acpi_pci_root
|
||||
*/
|
||||
static void
|
||||
acpi_pci_slot_remove(acpi_handle handle)
|
||||
acpi_pci_slot_remove(struct acpi_pci_root *root)
|
||||
{
|
||||
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) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue