diff options
58 files changed, 764 insertions, 1049 deletions
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 60532ab2734..de1474ff0bc 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 */ diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 0872f12f268..594e60d6a43 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -115,7 +115,6 @@ static void pcibios_scanbus(struct pci_controller *hose)  			pci_bus_assign_resources(bus);  			pci_enable_bridges(bus);  		} -		bus->dev.of_node = hose->of_node;  	}  } @@ -169,6 +168,13 @@ void pci_load_of_ranges(struct pci_controller *hose, struct device_node *node)  		}  	}  } + +struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) +{ +	struct pci_controller *hose = bus->sysdata; + +	return of_node_get(hose->of_node); +}  #endif  static DEFINE_MUTEX(pci_scan_mutex); diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 901177d75ff..305c68b8d53 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). diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 0ac546d5e53..b80e06e0b2d 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/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index cd1434eb1de..033d1179bdb 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 5e7e991717d..f54d1985e59 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/ata/ahci.c b/drivers/ata/ahci.c index a99112cfd8b..616952facd6 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -413,17 +413,17 @@ static const struct pci_device_id ahci_pci_tbl[] = {  	/* Marvell */  	{ PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv },	/* 6145 */  	{ PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv },	/* 6121 */ -	{ PCI_DEVICE(0x1b4b, 0x9123), +	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9123),  	  .class = PCI_CLASS_STORAGE_SATA_AHCI,  	  .class_mask = 0xffffff,  	  .driver_data = board_ahci_yes_fbs },			/* 88se9128 */ -	{ PCI_DEVICE(0x1b4b, 0x9125), +	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9125),  	  .driver_data = board_ahci_yes_fbs },			/* 88se9125 */ -	{ PCI_DEVICE(0x1b4b, 0x917a), +	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x917a),  	  .driver_data = board_ahci_yes_fbs },			/* 88se9172 */ -	{ PCI_DEVICE(0x1b4b, 0x9192), +	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192),  	  .driver_data = board_ahci_yes_fbs },			/* 88se9172 on some Gigabyte */ -	{ PCI_DEVICE(0x1b4b, 0x91a3), +	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a3),  	  .driver_data = board_ahci_yes_fbs },  	/* Promise */ diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c index 806c77bfd43..272a3ec3595 100644 --- a/drivers/eisa/eisa-bus.c +++ b/drivers/eisa/eisa-bus.c @@ -275,19 +275,18 @@ static int __init eisa_request_resources(struct eisa_root_device *root,  		}  		if (slot) { -			edev->res[i].name  = NULL;  			edev->res[i].start = SLOT_ADDRESS(root, slot)  					     + (i * 0x400);  			edev->res[i].end   = edev->res[i].start + 0xff;  			edev->res[i].flags = IORESOURCE_IO;  		} else { -			edev->res[i].name  = NULL;  			edev->res[i].start = SLOT_ADDRESS(root, slot)  					     + EISA_VENDOR_ID_OFFSET;  			edev->res[i].end   = edev->res[i].start + 3; -			edev->res[i].flags = IORESOURCE_BUSY; +			edev->res[i].flags = IORESOURCE_IO | IORESOURCE_BUSY;  		} +		dev_printk(KERN_DEBUG, &edev->dev, "%pR\n", &edev->res[i]);  		if (request_resource(root->res, &edev->res[i]))  			goto failed;  	} @@ -314,41 +313,40 @@ static int __init eisa_probe(struct eisa_root_device *root)  {          int i, c;  	struct eisa_device *edev; +	char *enabled_str; -	printk(KERN_INFO "EISA: Probing bus %d at %s\n", -	       root->bus_nr, dev_name(root->dev)); +	dev_info(root->dev, "Probing EISA bus %d\n", root->bus_nr);  	/* First try to get hold of slot 0. If there is no device  	 * here, simply fail, unless root->force_probe is set. */  	edev = kzalloc(sizeof(*edev), GFP_KERNEL);  	if (!edev) { -		printk(KERN_ERR "EISA: Couldn't allocate mainboard slot\n"); +		dev_err(root->dev, "EISA: Couldn't allocate mainboard slot\n");  		return -ENOMEM;  	} -	if (eisa_request_resources(root, edev, 0)) { -		printk(KERN_WARNING \ -		       "EISA: Cannot allocate resource for mainboard\n"); +	if (eisa_init_device(root, edev, 0)) {  		kfree(edev);  		if (!root->force_probe) -			return -EBUSY; +			return -ENODEV;  		goto force_probe;  	} -	if (eisa_init_device(root, edev, 0)) { -		eisa_release_resources(edev); +	if (eisa_request_resources(root, edev, 0)) { +		dev_warn(root->dev, +		         "EISA: Cannot allocate resource for mainboard\n");  		kfree(edev);  		if (!root->force_probe) -			return -ENODEV; +			return -EBUSY;  		goto force_probe;  	} -	printk(KERN_INFO "EISA: Mainboard %s detected.\n", edev->id.sig); +	dev_info(&edev->dev, "EISA: Mainboard %s detected\n", edev->id.sig);  	if (eisa_register_device(edev)) { -		printk(KERN_ERR "EISA: Failed to register %s\n", -		       edev->id.sig); +		dev_err(&edev->dev, "EISA: Failed to register %s\n", +		        edev->id.sig);  		eisa_release_resources(edev);  		kfree(edev);  	} @@ -358,55 +356,47 @@ static int __init eisa_probe(struct eisa_root_device *root)          for (c = 0, i = 1; i <= root->slots; i++) {  		edev = kzalloc(sizeof(*edev), GFP_KERNEL);  		if (!edev) { -			printk(KERN_ERR "EISA: Out of memory for slot %d\n", i); +			dev_err(root->dev, "EISA: Out of memory for slot %d\n", +				i);  			continue;  		} -		if (eisa_request_resources(root, edev, i)) { -			printk(KERN_WARNING \ -			       "Cannot allocate resource for EISA slot %d\n", -			       i); +		if (eisa_init_device(root, edev, i)) {  			kfree(edev);  			continue;  		} -		if (eisa_init_device(root, edev, i)) { -			eisa_release_resources(edev); +		if (eisa_request_resources(root, edev, i)) { +			dev_warn(root->dev, +			         "Cannot allocate resource for EISA slot %d\n", +			         i);  			kfree(edev);  			continue;  		} -		 -		printk(KERN_INFO "EISA: slot %d : %s detected", -		       i, edev->id.sig); -			 -		switch (edev->state) { -		case EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED: -			printk(" (forced enabled)"); -			break; -		case EISA_CONFIG_FORCED: -			printk(" (forced disabled)"); -			break; +		if (edev->state == (EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED)) +			enabled_str = " (forced enabled)"; +		else if (edev->state == EISA_CONFIG_FORCED) +			enabled_str = " (forced disabled)"; +		else if (edev->state == 0) +			enabled_str = " (disabled)"; +		else +			enabled_str = ""; -		case 0: -			printk(" (disabled)"); -			break; -		} -			 -		printk (".\n"); +		dev_info(&edev->dev, "EISA: slot %d: %s detected%s\n", i, +			 edev->id.sig, enabled_str);  		c++;  		if (eisa_register_device(edev)) { -			printk(KERN_ERR "EISA: Failed to register %s\n", -			       edev->id.sig); +			dev_err(&edev->dev, "EISA: Failed to register %s\n", +			        edev->id.sig);  			eisa_release_resources(edev);  			kfree(edev);  		}          } -	printk(KERN_INFO "EISA: Detected %d card%s.\n", c, c == 1 ? "" : "s"); - +	dev_info(root->dev, "EISA: Detected %d card%s\n", c, c == 1 ? "" : "s");  	return 0;  } diff --git a/drivers/eisa/pci_eisa.c b/drivers/eisa/pci_eisa.c index cdae207028a..0d42ea79106 100644 --- a/drivers/eisa/pci_eisa.c +++ b/drivers/eisa/pci_eisa.c @@ -25,8 +25,7 @@ static int __init pci_eisa_init(struct pci_dev *pdev,  	int rc;  	if ((rc = pci_enable_device (pdev))) { -		printk (KERN_ERR "pci_eisa : Could not enable device %s\n", -			pci_name(pdev)); +		dev_err(&pdev->dev, "Could not enable device\n");  		return rc;  	} @@ -38,7 +37,7 @@ static int __init pci_eisa_init(struct pci_dev *pdev,  	dev_set_drvdata(pci_eisa_root.dev, &pci_eisa_root);  	if (eisa_root_register (&pci_eisa_root)) { -		printk (KERN_ERR "pci_eisa : Could not register EISA root\n"); +		dev_err(&pdev->dev, "Could not register EISA root\n");  		return -1;  	} diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 98f555dafb5..e046d7acca8 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -173,7 +173,7 @@ static inline u16 get_device_id(struct device *dev)  {  	struct pci_dev *pdev = to_pci_dev(dev); -	return calc_devid(pdev->bus->number, pdev->devfn); +	return PCI_DEVID(pdev->bus->number, pdev->devfn);  }  static struct iommu_dev_data *get_dev_data(struct device *dev) @@ -649,26 +649,26 @@ retry:  	case EVENT_TYPE_ILL_DEV:  		printk("ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x "  		       "address=0x%016llx flags=0x%04x]\n", -		       PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), +		       PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),  		       address, flags);  		dump_dte_entry(devid);  		break;  	case EVENT_TYPE_IO_FAULT:  		printk("IO_PAGE_FAULT device=%02x:%02x.%x "  		       "domain=0x%04x address=0x%016llx flags=0x%04x]\n", -		       PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), +		       PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),  		       domid, address, flags);  		break;  	case EVENT_TYPE_DEV_TAB_ERR:  		printk("DEV_TAB_HARDWARE_ERROR device=%02x:%02x.%x "  		       "address=0x%016llx flags=0x%04x]\n", -		       PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), +		       PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),  		       address, flags);  		break;  	case EVENT_TYPE_PAGE_TAB_ERR:  		printk("PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x "  		       "domain=0x%04x address=0x%016llx flags=0x%04x]\n", -		       PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), +		       PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),  		       domid, address, flags);  		break;  	case EVENT_TYPE_ILL_CMD: @@ -682,13 +682,13 @@ retry:  	case EVENT_TYPE_IOTLB_INV_TO:  		printk("IOTLB_INV_TIMEOUT device=%02x:%02x.%x "  		       "address=0x%016llx]\n", -		       PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), +		       PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),  		       address);  		break;  	case EVENT_TYPE_INV_DEV_REQ:  		printk("INVALID_DEVICE_REQUEST device=%02x:%02x.%x "  		       "address=0x%016llx flags=0x%04x]\n", -		       PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), +		       PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),  		       address, flags);  		break;  	default: diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index b6ecddb63cd..551768af3fe 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -406,7 +406,7 @@ static int __init find_last_devid_on_pci(int bus, int dev, int fn, int cap_ptr)  	u32 cap;  	cap = read_pci_config(bus, dev, fn, cap_ptr+MMIO_RANGE_OFFSET); -	update_last_devid(calc_devid(MMIO_GET_BUS(cap), MMIO_GET_LD(cap))); +	update_last_devid(PCI_DEVID(MMIO_GET_BUS(cap), MMIO_GET_LD(cap)));  	return 0;  } @@ -423,7 +423,7 @@ static int __init find_last_devid_from_ivhd(struct ivhd_header *h)  	p += sizeof(*h);  	end += h->length; -	find_last_devid_on_pci(PCI_BUS(h->devid), +	find_last_devid_on_pci(PCI_BUS_NUM(h->devid),  			PCI_SLOT(h->devid),  			PCI_FUNC(h->devid),  			h->cap_ptr); @@ -784,10 +784,10 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,  			DUMP_printk("  DEV_ALL\t\t\t first devid: %02x:%02x.%x"  				    " last device %02x:%02x.%x flags: %02x\n", -				    PCI_BUS(iommu->first_device), +				    PCI_BUS_NUM(iommu->first_device),  				    PCI_SLOT(iommu->first_device),  				    PCI_FUNC(iommu->first_device), -				    PCI_BUS(iommu->last_device), +				    PCI_BUS_NUM(iommu->last_device),  				    PCI_SLOT(iommu->last_device),  				    PCI_FUNC(iommu->last_device),  				    e->flags); @@ -801,7 +801,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,  			DUMP_printk("  DEV_SELECT\t\t\t devid: %02x:%02x.%x "  				    "flags: %02x\n", -				    PCI_BUS(e->devid), +				    PCI_BUS_NUM(e->devid),  				    PCI_SLOT(e->devid),  				    PCI_FUNC(e->devid),  				    e->flags); @@ -813,7 +813,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,  			DUMP_printk("  DEV_SELECT_RANGE_START\t "  				    "devid: %02x:%02x.%x flags: %02x\n", -				    PCI_BUS(e->devid), +				    PCI_BUS_NUM(e->devid),  				    PCI_SLOT(e->devid),  				    PCI_FUNC(e->devid),  				    e->flags); @@ -827,11 +827,11 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,  			DUMP_printk("  DEV_ALIAS\t\t\t devid: %02x:%02x.%x "  				    "flags: %02x devid_to: %02x:%02x.%x\n", -				    PCI_BUS(e->devid), +				    PCI_BUS_NUM(e->devid),  				    PCI_SLOT(e->devid),  				    PCI_FUNC(e->devid),  				    e->flags, -				    PCI_BUS(e->ext >> 8), +				    PCI_BUS_NUM(e->ext >> 8),  				    PCI_SLOT(e->ext >> 8),  				    PCI_FUNC(e->ext >> 8)); @@ -846,11 +846,11 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,  			DUMP_printk("  DEV_ALIAS_RANGE\t\t "  				    "devid: %02x:%02x.%x flags: %02x "  				    "devid_to: %02x:%02x.%x\n", -				    PCI_BUS(e->devid), +				    PCI_BUS_NUM(e->devid),  				    PCI_SLOT(e->devid),  				    PCI_FUNC(e->devid),  				    e->flags, -				    PCI_BUS(e->ext >> 8), +				    PCI_BUS_NUM(e->ext >> 8),  				    PCI_SLOT(e->ext >> 8),  				    PCI_FUNC(e->ext >> 8)); @@ -864,7 +864,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,  			DUMP_printk("  DEV_EXT_SELECT\t\t devid: %02x:%02x.%x "  				    "flags: %02x ext: %08x\n", -				    PCI_BUS(e->devid), +				    PCI_BUS_NUM(e->devid),  				    PCI_SLOT(e->devid),  				    PCI_FUNC(e->devid),  				    e->flags, e->ext); @@ -877,7 +877,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,  			DUMP_printk("  DEV_EXT_SELECT_RANGE\t devid: "  				    "%02x:%02x.%x flags: %02x ext: %08x\n", -				    PCI_BUS(e->devid), +				    PCI_BUS_NUM(e->devid),  				    PCI_SLOT(e->devid),  				    PCI_FUNC(e->devid),  				    e->flags, e->ext); @@ -890,7 +890,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,  		case IVHD_DEV_RANGE_END:  			DUMP_printk("  DEV_RANGE_END\t\t devid: %02x:%02x.%x\n", -				    PCI_BUS(e->devid), +				    PCI_BUS_NUM(e->devid),  				    PCI_SLOT(e->devid),  				    PCI_FUNC(e->devid)); @@ -924,7 +924,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,  			DUMP_printk("  DEV_SPECIAL(%s[%d])\t\tdevid: %02x:%02x.%x\n",  				    var, (int)handle, -				    PCI_BUS(devid), +				    PCI_BUS_NUM(devid),  				    PCI_SLOT(devid),  				    PCI_FUNC(devid)); @@ -1086,7 +1086,7 @@ static int __init init_iommu_all(struct acpi_table_header *table)  			DUMP_printk("device: %02x:%02x.%01x cap: %04x "  				    "seg: %d flags: %01x info %04x\n", -				    PCI_BUS(h->devid), PCI_SLOT(h->devid), +				    PCI_BUS_NUM(h->devid), PCI_SLOT(h->devid),  				    PCI_FUNC(h->devid), h->cap_ptr,  				    h->pci_seg, h->flags, h->info);  			DUMP_printk("       mmio-addr: %016llx\n", @@ -1116,7 +1116,7 @@ static int iommu_init_pci(struct amd_iommu *iommu)  	int cap_ptr = iommu->cap_ptr;  	u32 range, misc, low, high; -	iommu->dev = pci_get_bus_and_slot(PCI_BUS(iommu->devid), +	iommu->dev = pci_get_bus_and_slot(PCI_BUS_NUM(iommu->devid),  					  iommu->devid & 0xff);  	if (!iommu->dev)  		return -ENODEV; @@ -1128,9 +1128,9 @@ static int iommu_init_pci(struct amd_iommu *iommu)  	pci_read_config_dword(iommu->dev, cap_ptr + MMIO_MISC_OFFSET,  			      &misc); -	iommu->first_device = calc_devid(MMIO_GET_BUS(range), +	iommu->first_device = PCI_DEVID(MMIO_GET_BUS(range),  					 MMIO_GET_FD(range)); -	iommu->last_device = calc_devid(MMIO_GET_BUS(range), +	iommu->last_device = PCI_DEVID(MMIO_GET_BUS(range),  					MMIO_GET_LD(range));  	if (!(iommu->cap & (1 << IOMMU_CAP_IOTLB))) @@ -1388,8 +1388,8 @@ static int __init init_unity_map_range(struct ivmd_header *m)  	DUMP_printk("%s devid_start: %02x:%02x.%x devid_end: %02x:%02x.%x"  		    " range_start: %016llx range_end: %016llx flags: %x\n", s, -		    PCI_BUS(e->devid_start), PCI_SLOT(e->devid_start), -		    PCI_FUNC(e->devid_start), PCI_BUS(e->devid_end), +		    PCI_BUS_NUM(e->devid_start), PCI_SLOT(e->devid_start), +		    PCI_FUNC(e->devid_start), PCI_BUS_NUM(e->devid_end),  		    PCI_SLOT(e->devid_end), PCI_FUNC(e->devid_end),  		    e->address_start, e->address_end, m->flags); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index e38ab438bb3..ec36cf63e0c 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -24,6 +24,7 @@  #include <linux/mutex.h>  #include <linux/list.h>  #include <linux/spinlock.h> +#include <linux/pci.h>  /*   * Maximum number of IOMMUs supported @@ -315,9 +316,6 @@  #define MAX_DOMAIN_ID 65536 -/* FIXME: move this macro to <linux/pci.h> */ -#define PCI_BUS(x) (((x) >> 8) & 0xff) -  /* Protection domain flags */  #define PD_DMA_OPS_MASK		(1UL << 0) /* domain used for dma_ops */  #define PD_DEFAULT_MASK		(1UL << 1) /* domain is a default dma_ops @@ -703,13 +701,6 @@ extern int amd_iommu_max_glx_val;   */  extern void iommu_flush_all_caches(struct amd_iommu *iommu); -/* takes bus and device/function and returns the device id - * FIXME: should that be in generic PCI code? */ -static inline u16 calc_devid(u8 bus, u8 devfn) -{ -	return (((u16)bus) << 8) | devfn; -} -  static inline int get_ioapic_devid(int id)  {  	struct devid_map *entry; diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 8647dc6f52d..748f8f3e9ff 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -202,20 +202,16 @@ void pci_bus_add_devices(const struct pci_bus *bus)  		if (dev->is_added)  			continue;  		retval = pci_bus_add_device(dev); +		if (retval) +			dev_err(&dev->dev, "Error adding device (%d)\n", +				retval);  	}  	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/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index 13e9e63a726..9fcb87f353d 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.h b/drivers/pci/hotplug/acpiphp.h index b70ac00a117..6fdd49c6f0b 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h @@ -73,8 +73,9 @@ 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; -	struct acpiphp_slot *slots;  	/* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */  	struct acpiphp_func *func; @@ -97,7 +98,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) */ @@ -119,7 +120,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; @@ -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 */ @@ -174,25 +170,24 @@ struct acpiphp_attention_info  /* function prototypes */  /* acpiphp_core.c */ -extern int acpiphp_register_attention(struct acpiphp_attention_info*info); -extern int acpiphp_unregister_attention(struct acpiphp_attention_info *info); -extern int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot); -extern void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); +int acpiphp_register_attention(struct acpiphp_attention_info*info); +int acpiphp_unregister_attention(struct acpiphp_attention_info *info); +int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot); +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); -extern int acpiphp_disable_slot (struct acpiphp_slot *slot); -extern int acpiphp_eject_slot (struct acpiphp_slot *slot); -extern u8 acpiphp_get_power_status (struct acpiphp_slot *slot); -extern u8 acpiphp_get_attention_status (struct acpiphp_slot *slot); -extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot); -extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot); +int acpiphp_enable_slot(struct acpiphp_slot *slot); +int acpiphp_disable_slot(struct acpiphp_slot *slot); +int acpiphp_eject_slot(struct acpiphp_slot *slot); +u8 acpiphp_get_power_status(struct acpiphp_slot *slot); +u8 acpiphp_get_attention_status(struct acpiphp_slot *slot); +u8 acpiphp_get_latch_status(struct acpiphp_slot *slot); +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 c2fd3095701..ca8127950fc 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> @@ -48,6 +49,7 @@  #define SLOT_NAME_SIZE  21              /* {_SUN} */  bool acpiphp_debug; +bool acpiphp_disabled;  /* local variables */  static struct acpiphp_attention_info *attention_info; @@ -60,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); @@ -351,27 +355,9 @@ 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(); -} - - -static void __exit acpiphp_exit(void) -{ -	if (acpi_pci_disabled) -		return; - -	/* deallocate internal data structures etc. */ -	acpiphp_glue_exit(); +	info(DRIVER_DESC " version: " DRIVER_VERSION "%s\n", +		acpiphp_disabled ? ", disabled by user; please report a bug" +				 : "");  } - -module_init(acpiphp_init); -module_exit(acpiphp_exit); diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 270fdbadc19..96fed19c6d9 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. @@ -154,9 +189,10 @@ 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;  	if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle))  		return AE_OK; @@ -170,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; @@ -178,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; @@ -207,14 +242,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); @@ -227,9 +263,9 @@ 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; - +		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,13 +283,13 @@ 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); -	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 @@ -290,7 +326,9 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)   err_exit:  	bridge->nr_slots--; -	bridge->slots = slot->next; +	mutex_lock(&bridge_mutex); +	list_del(&slot->node); +	mutex_unlock(&bridge_mutex);  	kfree(slot);  	kfree(newfunc); @@ -315,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;  	} @@ -351,178 +393,46 @@ 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) { -		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) +				if (func->handle == handle) { +					get_bridge(func->slot->bridge); +					mutex_unlock(&bridge_mutex);  					return func; +				}  			}  		}  	} +	mutex_unlock(&bridge_mutex);  	return NULL;  } -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_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; +	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; @@ -543,10 +453,8 @@ 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(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); @@ -558,63 +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); -		slot = next;  	} -	/* -	 * Only P2P bridges have a pci_dev -	 */ -	if (bridge->pci_dev) -		put_device(&bridge->pci_bus->dev); - -	pci_dev_put(bridge->pci_dev); +	mutex_lock(&bridge_mutex);  	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); +	mutex_unlock(&bridge_mutex);  }  static int power_on_slot(struct acpiphp_slot *slot) @@ -798,6 +656,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 @@ -810,9 +669,7 @@ 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; -	acpi_status status;  	if (slot->flags & SLOT_ENABLED)  		goto err_exit; @@ -867,23 +724,11 @@ 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);  	}   err_exit: -	return retval; +	return 0;  }  /* return first device in slot, acquiring a reference on it */ @@ -912,23 +757,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; - -	/* 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 */ -			cleanup_p2p_bridge(func->bridge->handle, -						(u32)1, NULL, NULL); -			func->bridge = NULL; -		} -	}  	/*  	 * enable_device() enumerates all functions in this device via @@ -947,7 +775,6 @@ static int disable_device(struct acpiphp_slot *slot)  	slot->flags &= (~SLOT_ENABLED); -err_exit:  	return 0;  } @@ -1037,7 +864,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) @@ -1082,11 +909,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 && @@ -1118,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 ;  } @@ -1195,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);  }  /** @@ -1208,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. @@ -1216,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);  } @@ -1270,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);  }  /** @@ -1283,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. @@ -1291,33 +1126,69 @@ 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);  } -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 (acpiphp_disabled) +		return; +	if (detect_ejectable_slots(handle) <= 0) +		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 = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); +	if (bridge == NULL) { +		err("out of memory\n"); +		return; +	} + +	INIT_LIST_HEAD(&bridge->slots); +	kref_init(&bridge->ref); +	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; + +	if (acpiphp_disabled) +		return; + +	list_for_each_entry_safe(bridge, tmp, &bridge_list, list) +		if (bridge->pci_bus == bus) { +			cleanup_bridge(bridge); +			put_bridge(bridge); +			break; +		}  }  /** @@ -1396,7 +1267,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;  } diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h index 9fff878cf02..1356211431d 100644 --- a/drivers/pci/hotplug/cpci_hotplug.h +++ b/drivers/pci/hotplug/cpci_hotplug.h @@ -75,28 +75,36 @@ static inline const char *slot_name(struct slot *slot)  	return hotplug_slot_name(slot->hotplug_slot);  } -extern int cpci_hp_register_controller(struct cpci_hp_controller *controller); -extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller); -extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last); -extern int cpci_hp_unregister_bus(struct pci_bus *bus); -extern int cpci_hp_start(void); -extern int cpci_hp_stop(void); +int cpci_hp_register_controller(struct cpci_hp_controller *controller); +int cpci_hp_unregister_controller(struct cpci_hp_controller *controller); +int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last); +int cpci_hp_unregister_bus(struct pci_bus *bus); +int cpci_hp_start(void); +int cpci_hp_stop(void);  /*   * Internal function prototypes, these functions should not be used by   * board/chassis drivers.   */ -extern u8 cpci_get_attention_status(struct slot *slot); -extern u8 cpci_get_latch_status(struct slot *slot); -extern u8 cpci_get_adapter_status(struct slot *slot); -extern u16 cpci_get_hs_csr(struct slot * slot); -extern int cpci_set_attention_status(struct slot *slot, int status); -extern int cpci_check_and_clear_ins(struct slot * slot); -extern int cpci_check_ext(struct slot * slot); -extern int cpci_clear_ext(struct slot * slot); -extern int cpci_led_on(struct slot * slot); -extern int cpci_led_off(struct slot * slot); -extern int cpci_configure_slot(struct slot *slot); -extern int cpci_unconfigure_slot(struct slot *slot); +u8 cpci_get_attention_status(struct slot *slot); +u8 cpci_get_latch_status(struct slot *slot); +u8 cpci_get_adapter_status(struct slot *slot); +u16 cpci_get_hs_csr(struct slot * slot); +int cpci_set_attention_status(struct slot *slot, int status); +int cpci_check_and_clear_ins(struct slot * slot); +int cpci_check_ext(struct slot * slot); +int cpci_clear_ext(struct slot * slot); +int cpci_led_on(struct slot * slot); +int cpci_led_off(struct slot * slot); +int cpci_configure_slot(struct slot *slot); +int cpci_unconfigure_slot(struct slot *slot); + +#ifdef CONFIG_HOTPLUG_PCI_CPCI +int cpci_hotplug_init(int debug); +void cpci_hotplug_exit(void); +#else +static inline int cpci_hotplug_init(int debug) { return 0; } +static inline void cpci_hotplug_exit(void) { } +#endif  #endif	/* _CPCI_HOTPLUG_H */ diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h index d8ffc736680..516b87738b6 100644 --- a/drivers/pci/hotplug/cpqphp.h +++ b/drivers/pci/hotplug/cpqphp.h @@ -404,50 +404,44 @@ struct resource_lists {  /* debugfs functions for the hotplug controller info */ -extern void cpqhp_initialize_debugfs(void); -extern void cpqhp_shutdown_debugfs(void); -extern void cpqhp_create_debugfs_files(struct controller *ctrl); -extern void cpqhp_remove_debugfs_files(struct controller *ctrl); +void cpqhp_initialize_debugfs(void); +void cpqhp_shutdown_debugfs(void); +void cpqhp_create_debugfs_files(struct controller *ctrl); +void cpqhp_remove_debugfs_files(struct controller *ctrl);  /* controller functions */ -extern void cpqhp_pushbutton_thread(unsigned long event_pointer); -extern irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data); -extern int cpqhp_find_available_resources(struct controller *ctrl, -					  void __iomem *rom_start); -extern int cpqhp_event_start_thread(void); -extern void cpqhp_event_stop_thread(void); -extern struct pci_func *cpqhp_slot_create(unsigned char busnumber); -extern struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device, -					unsigned char index); -extern int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func); -extern int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func); -extern int cpqhp_hardware_test(struct controller *ctrl, int test_num); +void cpqhp_pushbutton_thread(unsigned long event_pointer); +irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data); +int cpqhp_find_available_resources(struct controller *ctrl, +				   void __iomem *rom_start); +int cpqhp_event_start_thread(void); +void cpqhp_event_stop_thread(void); +struct pci_func *cpqhp_slot_create(unsigned char busnumber); +struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device, +				 unsigned char index); +int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func); +int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func); +int cpqhp_hardware_test(struct controller *ctrl, int test_num);  /* resource functions */ -extern int	cpqhp_resource_sort_and_combine	(struct pci_resource **head); +int	cpqhp_resource_sort_and_combine	(struct pci_resource **head);  /* pci functions */ -extern int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); -extern int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, -			     u8 slot); -extern int cpqhp_save_config(struct controller *ctrl, int busnumber, -			     int is_hot_plug); -extern int cpqhp_save_base_addr_length(struct controller *ctrl, -				       struct pci_func *func); -extern int cpqhp_save_used_resources(struct controller *ctrl, -				     struct pci_func *func); -extern int cpqhp_configure_board(struct controller *ctrl, -				 struct pci_func *func); -extern int cpqhp_save_slot_config(struct controller *ctrl, -				  struct pci_func *new_slot); -extern int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func); -extern void cpqhp_destroy_board_resources(struct pci_func *func); -extern int cpqhp_return_board_resources	(struct pci_func *func, -					 struct resource_lists *resources); -extern void cpqhp_destroy_resource_list(struct resource_lists *resources); -extern int cpqhp_configure_device(struct controller *ctrl, -				  struct pci_func *func); -extern int cpqhp_unconfigure_device(struct pci_func *func); +int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); +int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, +		      u8 slot); +int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug); +int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func); +int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func); +int cpqhp_configure_board(struct controller *ctrl, struct pci_func *func); +int cpqhp_save_slot_config(struct controller *ctrl, struct pci_func *new_slot); +int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func); +void cpqhp_destroy_board_resources(struct pci_func *func); +int cpqhp_return_board_resources(struct pci_func *func, +				 struct resource_lists *resources); +void cpqhp_destroy_resource_list(struct resource_lists *resources); +int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func); +int cpqhp_unconfigure_device(struct pci_func *func);  /* Global variables */  extern int cpqhp_debug; diff --git a/drivers/pci/hotplug/cpqphp_nvram.h b/drivers/pci/hotplug/cpqphp_nvram.h index e89c0702119..34e4e54fcf1 100644 --- a/drivers/pci/hotplug/cpqphp_nvram.h +++ b/drivers/pci/hotplug/cpqphp_nvram.h @@ -30,26 +30,26 @@  #ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM -static inline void compaq_nvram_init (void __iomem *rom_start) +static inline void compaq_nvram_init(void __iomem *rom_start)  {  	return;  } -static inline int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl) +static inline int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl)  {  	return 0;  } -static inline int compaq_nvram_store (void __iomem *rom_start) +static inline int compaq_nvram_store(void __iomem *rom_start)  {  	return 0;  }  #else -extern void compaq_nvram_init	(void __iomem *rom_start); -extern int compaq_nvram_load	(void __iomem *rom_start, struct controller *ctrl); -extern int compaq_nvram_store	(void __iomem *rom_start); +void compaq_nvram_init(void __iomem *rom_start); +int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl); +int compaq_nvram_store(void __iomem *rom_start);  #endif diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h index a8d391a4957..8c5b25871d0 100644 --- a/drivers/pci/hotplug/ibmphp.h +++ b/drivers/pci/hotplug/ibmphp.h @@ -275,17 +275,17 @@ extern struct list_head ibmphp_slot_head;  * FUNCTION PROTOTYPES                                      *  ***********************************************************/ -extern void ibmphp_free_ebda_hpc_queue (void); -extern int ibmphp_access_ebda (void); -extern struct slot *ibmphp_get_slot_from_physical_num (u8); -extern int ibmphp_get_total_hp_slots (void); -extern void ibmphp_free_ibm_slot (struct slot *); -extern void ibmphp_free_bus_info_queue (void); -extern void ibmphp_free_ebda_pci_rsrc_queue (void); -extern struct bus_info *ibmphp_find_same_bus_num (u32); -extern int ibmphp_get_bus_index (u8); -extern u16 ibmphp_get_total_controllers (void); -extern int ibmphp_register_pci (void); +void ibmphp_free_ebda_hpc_queue(void); +int ibmphp_access_ebda(void); +struct slot *ibmphp_get_slot_from_physical_num(u8); +int ibmphp_get_total_hp_slots(void); +void ibmphp_free_ibm_slot(struct slot *); +void ibmphp_free_bus_info_queue(void); +void ibmphp_free_ebda_pci_rsrc_queue(void); +struct bus_info *ibmphp_find_same_bus_num(u32); +int ibmphp_get_bus_index(u8); +u16 ibmphp_get_total_controllers(void); +int ibmphp_register_pci(void);  /* passed parameters */  #define MEM		0 @@ -381,24 +381,24 @@ struct res_needed {  /* functions */ -extern int ibmphp_rsrc_init (void); -extern int ibmphp_add_resource (struct resource_node *); -extern int ibmphp_remove_resource (struct resource_node *); -extern int ibmphp_find_resource (struct bus_node *, u32, struct resource_node **, int); -extern int ibmphp_check_resource (struct resource_node *, u8); -extern int ibmphp_remove_bus (struct bus_node *, u8); -extern void ibmphp_free_resources (void); -extern int ibmphp_add_pfmem_from_mem (struct resource_node *); -extern struct bus_node *ibmphp_find_res_bus (u8); -extern void ibmphp_print_test (void);	/* for debugging purposes */ +int ibmphp_rsrc_init(void); +int ibmphp_add_resource(struct resource_node *); +int ibmphp_remove_resource(struct resource_node *); +int ibmphp_find_resource(struct bus_node *, u32, struct resource_node **, int); +int ibmphp_check_resource(struct resource_node *, u8); +int ibmphp_remove_bus(struct bus_node *, u8); +void ibmphp_free_resources(void); +int ibmphp_add_pfmem_from_mem(struct resource_node *); +struct bus_node *ibmphp_find_res_bus(u8); +void ibmphp_print_test(void);	/* for debugging purposes */ -extern void ibmphp_hpc_initvars (void); -extern int ibmphp_hpc_readslot (struct slot *, u8, u8 *); -extern int ibmphp_hpc_writeslot (struct slot *, u8); -extern void ibmphp_lock_operations (void); -extern void ibmphp_unlock_operations (void); -extern int ibmphp_hpc_start_poll_thread (void); -extern void ibmphp_hpc_stop_poll_thread (void); +void ibmphp_hpc_initvars(void); +int ibmphp_hpc_readslot(struct slot *, u8, u8 *); +int ibmphp_hpc_writeslot(struct slot *, u8); +void ibmphp_lock_operations(void); +void ibmphp_unlock_operations(void); +int ibmphp_hpc_start_poll_thread(void); +void ibmphp_hpc_stop_poll_thread(void);  //---------------------------------------------------------------------------- @@ -749,11 +749,11 @@ struct controller {  /* Functions */ -extern int ibmphp_init_devno (struct slot **);	/* This function is called from EBDA, so we need it not be static */ -extern int ibmphp_do_disable_slot (struct slot *slot_cur); -extern int ibmphp_update_slot_info (struct slot *);	/* This function is called from HPC, so we need it to not be be static */ -extern int ibmphp_configure_card (struct pci_func *, u8); -extern int ibmphp_unconfigure_card (struct slot **, int); +int ibmphp_init_devno(struct slot **);	/* This function is called from EBDA, so we need it not be static */ +int ibmphp_do_disable_slot(struct slot *slot_cur); +int ibmphp_update_slot_info(struct slot *);	/* This function is called from HPC, so we need it to not be be static */ +int ibmphp_configure_card(struct pci_func *, u8); +int ibmphp_unconfigure_card(struct slot **, int);  extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops;  #endif				//__IBMPHP_H diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 202f4a969eb..ec20f74c898 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c @@ -41,6 +41,7 @@  #include <linux/pci_hotplug.h>  #include <asm/uaccess.h>  #include "../pci.h" +#include "cpci_hotplug.h"  #define MY_NAME	"pci_hotplug" @@ -63,14 +64,6 @@ static bool debug;  static LIST_HEAD(pci_hotplug_slot_list);  static DEFINE_MUTEX(pci_hp_mutex); -#ifdef CONFIG_HOTPLUG_PCI_CPCI -extern int cpci_hotplug_init(int debug); -extern void cpci_hotplug_exit(void); -#else -static inline int cpci_hotplug_init(int debug) { return 0; } -static inline void cpci_hotplug_exit(void) { } -#endif -  /* Weee, fun with macros... */  #define GET_STATUS(name,type)	\  static int get_##name (struct hotplug_slot *slot, type *value)		\ @@ -524,13 +517,11 @@ int pci_hp_deregister(struct hotplug_slot *hotplug)   *   * Returns 0 if successful, anything else for an error.   */ -int __must_check pci_hp_change_slot_info(struct hotplug_slot *hotplug, -					 struct hotplug_slot_info *info) +int pci_hp_change_slot_info(struct hotplug_slot *hotplug, +			    struct hotplug_slot_info *info)  { -	struct pci_slot *slot;  	if (!hotplug || !info)  		return -ENODEV; -	slot = hotplug->pci_slot;  	memcpy(hotplug->info, info, sizeof(struct hotplug_slot_info)); diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 2c113de9432..7fb326983ed 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -127,15 +127,15 @@ struct controller {  #define NO_CMD_CMPL(ctrl)	((ctrl)->slot_cap & PCI_EXP_SLTCAP_NCCS)  #define PSN(ctrl)		((ctrl)->slot_cap >> 19) -extern int pciehp_sysfs_enable_slot(struct slot *slot); -extern int pciehp_sysfs_disable_slot(struct slot *slot); -extern u8 pciehp_handle_attention_button(struct slot *p_slot); -extern u8 pciehp_handle_switch_change(struct slot *p_slot); -extern u8 pciehp_handle_presence_change(struct slot *p_slot); -extern u8 pciehp_handle_power_fault(struct slot *p_slot); -extern int pciehp_configure_device(struct slot *p_slot); -extern int pciehp_unconfigure_device(struct slot *p_slot); -extern void pciehp_queue_pushbutton_work(struct work_struct *work); +int pciehp_sysfs_enable_slot(struct slot *slot); +int pciehp_sysfs_disable_slot(struct slot *slot); +u8 pciehp_handle_attention_button(struct slot *p_slot); +u8 pciehp_handle_switch_change(struct slot *p_slot); +u8 pciehp_handle_presence_change(struct slot *p_slot); +u8 pciehp_handle_power_fault(struct slot *p_slot); +int pciehp_configure_device(struct slot *p_slot); +int pciehp_unconfigure_device(struct slot *p_slot); +void pciehp_queue_pushbutton_work(struct work_struct *work);  struct controller *pcie_init(struct pcie_device *dev);  int pcie_init_notification(struct controller *ctrl);  int pciehp_enable_slot(struct slot *p_slot); @@ -166,8 +166,8 @@ static inline const char *slot_name(struct slot *slot)  #include <acpi/acpi_bus.h>  #include <linux/pci-acpi.h> -extern void __init pciehp_acpi_slot_detection_init(void); -extern int pciehp_acpi_slot_detection_check(struct pci_dev *dev); +void __init pciehp_acpi_slot_detection_init(void); +int pciehp_acpi_slot_detection_check(struct pci_dev *dev);  static inline void pciehp_firmware_init(void)  { diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 24d709b7388..ead7c534095 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c @@ -90,7 +90,7 @@ static int __init dummy_probe(struct pcie_device *dev)  	slot = kzalloc(sizeof(*slot), GFP_KERNEL);  	if (!slot)  		return -ENOMEM; -	slot->number = slot_cap >> 19; +	slot->number = (slot_cap & PCI_EXP_SLTCAP_PSN) >> 19;  	list_for_each_entry(tmp, &dummy_slots, list) {  		if (tmp->number == slot->number)  			dup_slot_id++; diff --git a/drivers/pci/hotplug/rpadlpar.h b/drivers/pci/hotplug/rpadlpar.h index 4a0a59b82ea..81df93931ad 100644 --- a/drivers/pci/hotplug/rpadlpar.h +++ b/drivers/pci/hotplug/rpadlpar.h @@ -15,10 +15,10 @@  #ifndef _RPADLPAR_IO_H_  #define _RPADLPAR_IO_H_ -extern int dlpar_sysfs_init(void); -extern void dlpar_sysfs_exit(void); +int dlpar_sysfs_init(void); +void dlpar_sysfs_exit(void); -extern int dlpar_add_slot(char *drc_name); -extern int dlpar_remove_slot(char *drc_name); +int dlpar_add_slot(char *drc_name); +int dlpar_remove_slot(char *drc_name);  #endif diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index df5677440a0..3135856e5e1 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -86,18 +86,18 @@ extern struct list_head rpaphp_slot_head;  /* function prototypes */  /* rpaphp_pci.c */ -extern int rpaphp_enable_slot(struct slot *slot); -extern int rpaphp_get_sensor_state(struct slot *slot, int *state); +int rpaphp_enable_slot(struct slot *slot); +int rpaphp_get_sensor_state(struct slot *slot, int *state);  /* rpaphp_core.c */ -extern int rpaphp_add_slot(struct device_node *dn); -extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, +int rpaphp_add_slot(struct device_node *dn); +int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,  		char **drc_name, char **drc_type, int *drc_power_domain);  /* rpaphp_slot.c */ -extern void dealloc_slot_struct(struct slot *slot); -extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); -extern int rpaphp_register_slot(struct slot *slot); -extern int rpaphp_deregister_slot(struct slot *slot); +void dealloc_slot_struct(struct slot *slot); +struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); +int rpaphp_register_slot(struct slot *slot); +int rpaphp_deregister_slot(struct slot *slot);  #endif				/* _PPC64PHP_H */ diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index b849f995075..e260f207a90 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -168,19 +168,19 @@ struct controller {  #define WRONG_BUS_FREQUENCY		0x0000000D  #define POWER_FAILURE			0x0000000E -extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl); -extern void shpchp_remove_ctrl_files(struct controller *ctrl); -extern int shpchp_sysfs_enable_slot(struct slot *slot); -extern int shpchp_sysfs_disable_slot(struct slot *slot); -extern u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl); -extern u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl); -extern u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl); -extern u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); -extern int shpchp_configure_device(struct slot *p_slot); -extern int shpchp_unconfigure_device(struct slot *p_slot); -extern void cleanup_slots(struct controller *ctrl); -extern void shpchp_queue_pushbutton_work(struct work_struct *work); -extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev); +int __must_check shpchp_create_ctrl_files(struct controller *ctrl); +void shpchp_remove_ctrl_files(struct controller *ctrl); +int shpchp_sysfs_enable_slot(struct slot *slot); +int shpchp_sysfs_disable_slot(struct slot *slot); +u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl); +u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl); +u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl); +u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); +int shpchp_configure_device(struct slot *p_slot); +int shpchp_unconfigure_device(struct slot *p_slot); +void cleanup_slots(struct controller *ctrl); +void shpchp_queue_pushbutton_work(struct work_struct *work); +int shpc_init( struct controller *ctrl, struct pci_dev *pdev);  static inline const char *slot_name(struct slot *slot)  { diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index eeb23ceae4a..e8c31fe2056 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c @@ -85,7 +85,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha  }  static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); -int __must_check shpchp_create_ctrl_files (struct controller *ctrl) +int shpchp_create_ctrl_files (struct controller *ctrl)  {  	return device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);  } diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index f8a1f39e4f6..d40bed72676 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -476,12 +476,12 @@ static struct msi_attribute mode_attribute =  	__ATTR(mode, S_IRUGO, show_msi_mode, NULL); -struct attribute *msi_irq_default_attrs[] = { +static struct attribute *msi_irq_default_attrs[] = {  	&mode_attribute.attr,  	NULL  }; -void msi_kobj_release(struct kobject *kobj) +static void msi_kobj_release(struct kobject *kobj)  {  	struct msi_desc *entry = to_msi_desc(kobj); diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index dee5dddaa29..d927933dcf4 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -287,6 +287,32 @@ 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; + +	acpi_pci_slot_enumerate(bus, handle); +	acpiphp_enumerate_slots(bus, handle); +} + +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; + +	acpiphp_remove_slots(bus); +	acpi_pci_slot_remove(bus); +} +  /* ACPI bus type */  static int acpi_pci_find_device(struct device *dev, acpi_handle *handle)  { @@ -361,7 +387,11 @@ 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(); +	acpiphp_init(); +  	return 0;  }  arch_initcall(acpi_pci_init); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 9c6e9bb674e..5b4a9d9cd20 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -897,7 +897,7 @@ int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,  	if (pci_resource_len(pdev, resno) == 0)  		return 0; -	nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; +	nr = vma_pages(vma);  	start = vma->vm_pgoff;  	size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;  	pci_start = (mmap_api == PCI_MMAP_PROCFS) ? diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b099e0025d2..a899d8bb190 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -646,15 +646,11 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state)  		error = platform_pci_set_power_state(dev, state);  		if (!error)  			pci_update_current_state(dev, state); -		/* Fall back to PCI_D0 if native PM is not supported */ -		if (!dev->pm_cap) -			dev->current_state = PCI_D0; -	} else { +	} else  		error = -ENODEV; -		/* Fall back to PCI_D0 if native PM is not supported */ -		if (!dev->pm_cap) -			dev->current_state = PCI_D0; -	} + +	if (error && !dev->pm_cap) /* Fall back to PCI_D0 */ +		dev->current_state = PCI_D0;  	return error;  } @@ -1575,7 +1571,7 @@ void pci_pme_active(struct pci_dev *dev, bool enable)  {  	u16 pmcsr; -	if (!dev->pm_cap) +	if (!dev->pme_support)  		return;  	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); @@ -1924,6 +1920,7 @@ void pci_pm_init(struct pci_dev *dev)  	dev->wakeup_prepared = false;  	dev->pm_cap = 0; +	dev->pme_support = 0;  	/* find PCI PM capability in list */  	pm = pci_find_capability(dev, PCI_CAP_ID_PM); @@ -1975,8 +1972,6 @@ void pci_pm_init(struct pci_dev *dev)  		device_set_wakeup_capable(&dev->dev, true);  		/* Disable the PME# generation functionality */  		pci_pme_active(dev, false); -	} else { -		dev->pme_support = 0;  	}  } @@ -2619,7 +2614,7 @@ void pci_release_selected_regions(struct pci_dev *pdev, int bars)  			pci_release_region(pdev, i);  } -int __pci_request_selected_regions(struct pci_dev *pdev, int bars, +static int __pci_request_selected_regions(struct pci_dev *pdev, int bars,  				 const char *res_name, int excl)  {  	int i; @@ -3699,7 +3694,7 @@ static DEFINE_SPINLOCK(resource_alignment_lock);   * RETURNS: Resource alignment if it is specified.   *          Zero if it is not specified.   */ -resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) +static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev)  {  	int seg, bus, slot, func, align_order, count;  	resource_size_t align = 0; @@ -3812,7 +3807,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev)  	}  } -ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) +static ssize_t pci_set_resource_alignment_param(const char *buf, size_t count)  {  	if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1)  		count = RESOURCE_ALIGNMENT_PARAM_SIZE - 1; @@ -3823,7 +3818,7 @@ ssize_t pci_set_resource_alignment_param(const char *buf, size_t count)  	return count;  } -ssize_t pci_get_resource_alignment_param(char *buf, size_t size) +static ssize_t pci_get_resource_alignment_param(char *buf, size_t size)  {  	size_t count;  	spin_lock(&resource_alignment_lock); diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 7346ee68f47..68678ed76b0 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -8,26 +8,25 @@  /* Functions internal to the PCI core code */ -extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); -extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); +int pci_create_sysfs_dev_files(struct pci_dev *pdev); +void pci_remove_sysfs_dev_files(struct pci_dev *pdev);  #if !defined(CONFIG_DMI) && !defined(CONFIG_ACPI)  static inline void pci_create_firmware_label_files(struct pci_dev *pdev)  { return; }  static inline void pci_remove_firmware_label_files(struct pci_dev *pdev)  { return; }  #else -extern void pci_create_firmware_label_files(struct pci_dev *pdev); -extern void pci_remove_firmware_label_files(struct pci_dev *pdev); +void pci_create_firmware_label_files(struct pci_dev *pdev); +void pci_remove_firmware_label_files(struct pci_dev *pdev);  #endif -extern void pci_cleanup_rom(struct pci_dev *dev); +void pci_cleanup_rom(struct pci_dev *dev);  #ifdef HAVE_PCI_MMAP  enum pci_mmap_api {  	PCI_MMAP_SYSFS,	/* mmap on /sys/bus/pci/devices/<BDF>/resource<N> */  	PCI_MMAP_PROCFS	/* mmap on /proc/bus/pci/<BDF> */  }; -extern int pci_mmap_fits(struct pci_dev *pdev, int resno, -			 struct vm_area_struct *vmai, -			 enum pci_mmap_api mmap_api); +int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vmai, +		  enum pci_mmap_api mmap_api);  #endif  int pci_probe_reset_function(struct pci_dev *dev); @@ -60,17 +59,17 @@ struct pci_platform_pm_ops {  	int (*run_wake)(struct pci_dev *dev, bool enable);  }; -extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); -extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); -extern void pci_power_up(struct pci_dev *dev); -extern void pci_disable_enabled_device(struct pci_dev *dev); -extern int pci_finish_runtime_suspend(struct pci_dev *dev); -extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); -extern void pci_wakeup_bus(struct pci_bus *bus); -extern void pci_config_pm_runtime_get(struct pci_dev *dev); -extern void pci_config_pm_runtime_put(struct pci_dev *dev); -extern void pci_pm_init(struct pci_dev *dev); -extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); +int pci_set_platform_pm(struct pci_platform_pm_ops *ops); +void pci_update_current_state(struct pci_dev *dev, pci_power_t state); +void pci_power_up(struct pci_dev *dev); +void pci_disable_enabled_device(struct pci_dev *dev); +int pci_finish_runtime_suspend(struct pci_dev *dev); +int __pci_pme_wakeup(struct pci_dev *dev, void *ign); +void pci_wakeup_bus(struct pci_bus *bus); +void pci_config_pm_runtime_get(struct pci_dev *dev); +void pci_config_pm_runtime_put(struct pci_dev *dev); +void pci_pm_init(struct pci_dev *dev); +void pci_allocate_cap_save_buffers(struct pci_dev *dev);  void pci_free_cap_save_buffers(struct pci_dev *dev);  static inline void pci_wakeup_event(struct pci_dev *dev) @@ -96,7 +95,7 @@ struct pci_vpd {  	struct bin_attribute *attr; /* descriptor for sysfs VPD entry */  }; -extern int pci_vpd_pci22_init(struct pci_dev *dev); +int pci_vpd_pci22_init(struct pci_dev *dev);  static inline void pci_vpd_release(struct pci_dev *dev)  {  	if (dev->vpd) @@ -105,9 +104,9 @@ static inline void pci_vpd_release(struct pci_dev *dev)  /* PCI /proc functions */  #ifdef CONFIG_PROC_FS -extern int pci_proc_attach_device(struct pci_dev *dev); -extern int pci_proc_detach_device(struct pci_dev *dev); -extern int pci_proc_detach_bus(struct pci_bus *bus); +int pci_proc_attach_device(struct pci_dev *dev); +int pci_proc_detach_device(struct pci_dev *dev); +int pci_proc_detach_bus(struct pci_bus *bus);  #else  static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; }  static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; } @@ -118,8 +117,8 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }  int pci_hp_add_bridge(struct pci_dev *dev);  #ifdef HAVE_PCI_LEGACY -extern void pci_create_legacy_files(struct pci_bus *bus); -extern void pci_remove_legacy_files(struct pci_bus *bus); +void pci_create_legacy_files(struct pci_bus *bus); +void pci_remove_legacy_files(struct pci_bus *bus);  #else  static inline void pci_create_legacy_files(struct pci_bus *bus) { return; }  static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; } @@ -134,7 +133,7 @@ extern unsigned int pci_pm_d3_delay;  #ifdef CONFIG_PCI_MSI  void pci_no_msi(void); -extern void pci_msi_init_pci_dev(struct pci_dev *dev); +void pci_msi_init_pci_dev(struct pci_dev *dev);  #else  static inline void pci_no_msi(void) { }  static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } @@ -198,12 +197,11 @@ enum pci_bar_type {  bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl,  				int crs_timeout); -extern int pci_setup_device(struct pci_dev *dev); -extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, -				struct resource *res, unsigned int reg); -extern int pci_resource_bar(struct pci_dev *dev, int resno, -			    enum pci_bar_type *type); -extern void pci_configure_ari(struct pci_dev *dev); +int pci_setup_device(struct pci_dev *dev); +int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, +		    struct resource *res, unsigned int reg); +int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); +void pci_configure_ari(struct pci_dev *dev);  /**   * pci_ari_enabled - query ARI forwarding status @@ -217,7 +215,7 @@ static inline int pci_ari_enabled(struct pci_bus *bus)  }  void pci_reassigndev_resource_alignment(struct pci_dev *dev); -extern void pci_disable_bridge_window(struct pci_dev *dev); +void pci_disable_bridge_window(struct pci_dev *dev);  /* Single Root I/O Virtualization */  struct pci_sriov { @@ -241,7 +239,7 @@ struct pci_sriov {  };  #ifdef CONFIG_PCI_ATS -extern void pci_restore_ats_state(struct pci_dev *dev); +void pci_restore_ats_state(struct pci_dev *dev);  #else  static inline void pci_restore_ats_state(struct pci_dev *dev)  { @@ -249,14 +247,13 @@ static inline void pci_restore_ats_state(struct pci_dev *dev)  #endif /* CONFIG_PCI_ATS */  #ifdef CONFIG_PCI_IOV -extern int pci_iov_init(struct pci_dev *dev); -extern void pci_iov_release(struct pci_dev *dev); -extern int pci_iov_resource_bar(struct pci_dev *dev, int resno, -				enum pci_bar_type *type); -extern resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, -						    int resno); -extern void pci_restore_iov_state(struct pci_dev *dev); -extern int pci_iov_bus_range(struct pci_bus *bus); +int pci_iov_init(struct pci_dev *dev); +void pci_iov_release(struct pci_dev *dev); +int pci_iov_resource_bar(struct pci_dev *dev, int resno, +			 enum pci_bar_type *type); +resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); +void pci_restore_iov_state(struct pci_dev *dev); +int pci_iov_bus_range(struct pci_bus *bus);  #else  static inline int pci_iov_init(struct pci_dev *dev) @@ -282,10 +279,10 @@ static inline int pci_iov_bus_range(struct pci_bus *bus)  #endif /* CONFIG_PCI_IOV */ -extern unsigned long pci_cardbus_resource_alignment(struct resource *); +unsigned long pci_cardbus_resource_alignment(struct resource *);  static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, -					 struct resource *res) +						     struct resource *res)  {  #ifdef CONFIG_PCI_IOV  	int resno = res - dev->resource; @@ -298,7 +295,7 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev,  	return resource_alignment(res);  } -extern void pci_enable_acs(struct pci_dev *dev); +void pci_enable_acs(struct pci_dev *dev);  struct pci_dev_reset_methods {  	u16 vendor; @@ -307,7 +304,7 @@ struct pci_dev_reset_methods {  };  #ifdef CONFIG_PCI_QUIRKS -extern int pci_dev_specific_reset(struct pci_dev *dev, int probe); +int pci_dev_specific_reset(struct pci_dev *dev, int probe);  #else  static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)  { diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index fde4a32a029..569f82fc9e2 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig @@ -82,4 +82,4 @@ endchoice  config PCIE_PME  	def_bool y -	depends on PCIEPORTBUS && PM_RUNTIME && ACPI +	depends on PCIEPORTBUS && PM_RUNTIME diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 4e24cb8a94a..587e7e85310 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c @@ -212,8 +212,8 @@ out:  	return ops->read(bus, devfn, where, size, val);  } -int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, int size, -		  u32 val) +static int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, +			 int size, u32 val)  {  	u32 *sim;  	struct aer_error *err; @@ -334,13 +334,13 @@ static int aer_inject(struct aer_error_inj *einj)  		return -ENODEV;  	rpdev = pcie_find_root_port(dev);  	if (!rpdev) { -		ret = -ENOTTY; +		ret = -ENODEV;  		goto out_put;  	}  	pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);  	if (!pos_cap_err) { -		ret = -ENOTTY; +		ret = -EPERM;  		goto out_put;  	}  	pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); @@ -350,7 +350,7 @@ static int aer_inject(struct aer_error_inj *einj)  	rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR);  	if (!rp_pos_cap_err) { -		ret = -ENOTTY; +		ret = -EPERM;  		goto out_put;  	} diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index 22f840f4dda..d12c77cd699 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h @@ -110,15 +110,15 @@ static inline pci_ers_result_t merge_result(enum pci_ers_result orig,  }  extern struct bus_type pcie_port_bus_type; -extern void aer_do_secondary_bus_reset(struct pci_dev *dev); -extern int aer_init(struct pcie_device *dev); -extern void aer_isr(struct work_struct *work); -extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); -extern void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info); -extern irqreturn_t aer_irq(int irq, void *context); +void aer_do_secondary_bus_reset(struct pci_dev *dev); +int aer_init(struct pcie_device *dev); +void aer_isr(struct work_struct *work); +void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); +void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info); +irqreturn_t aer_irq(int irq, void *context);  #ifdef CONFIG_ACPI_APEI -extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); +int pcie_aer_get_firmware_first(struct pci_dev *pci_dev);  #else  static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev)  { diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 564d97f94b6..8ec8b4f4856 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -89,8 +89,6 @@ static int add_error_device(struct aer_err_info *e_info, struct pci_dev *dev)  	return -ENOSPC;  } -#define	PCI_BUS(x)	(((x) >> 8) & 0xff) -  /**   * is_error_source - check whether the device is source of reported error   * @dev: pointer to pci_dev to be checked @@ -106,7 +104,7 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info)  	 * When bus id is equal to 0, it might be a bad id  	 * reported by root port.  	 */ -	if (!nosourceid && (PCI_BUS(e_info->id) != 0)) { +	if (!nosourceid && (PCI_BUS_NUM(e_info->id) != 0)) {  		/* Device ID match? */  		if (e_info->id == ((dev->bus->number << 8) | dev->devfn))  			return true; diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index 9ca0dc9ffd8..795db1f9d50 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c @@ -19,8 +19,6 @@  #include <linux/interrupt.h>  #include <linux/device.h>  #include <linux/pcieport_if.h> -#include <linux/acpi.h> -#include <linux/pci-acpi.h>  #include <linux/pm_runtime.h>  #include "../pci.h" diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index eea2ca2375e..d2eb80aab56 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h @@ -21,18 +21,18 @@  #define get_descriptor_id(type, service) (((type - 4) << 4) | service)  extern struct bus_type pcie_port_bus_type; -extern int pcie_port_device_register(struct pci_dev *dev); +int pcie_port_device_register(struct pci_dev *dev);  #ifdef CONFIG_PM -extern int pcie_port_device_suspend(struct device *dev); -extern int pcie_port_device_resume(struct device *dev); +int pcie_port_device_suspend(struct device *dev); +int pcie_port_device_resume(struct device *dev);  #endif -extern void pcie_port_device_remove(struct pci_dev *dev); -extern int __must_check pcie_port_bus_register(void); -extern void pcie_port_bus_unregister(void); +void pcie_port_device_remove(struct pci_dev *dev); +int __must_check pcie_port_bus_register(void); +void pcie_port_bus_unregister(void);  struct pci_dev; -extern void pcie_clear_root_pme_status(struct pci_dev *dev); +void pcie_clear_root_pme_status(struct pci_dev *dev);  #ifdef CONFIG_HOTPLUG_PCI_PCIE  extern bool pciehp_msi_disabled; @@ -59,7 +59,7 @@ static inline bool pcie_pme_no_msi(void)  	return pcie_pme_msi_disabled;  } -extern void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable); +void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable);  #else /* !CONFIG_PCIE_PME */  static inline void pcie_pme_disable_msi(void) {}  static inline bool pcie_pme_no_msi(void) { return false; } @@ -67,7 +67,7 @@ static inline void pcie_pme_interrupt_enable(struct pci_dev *dev, bool en) {}  #endif /* !CONFIG_PCIE_PME */  #ifdef CONFIG_ACPI -extern int pcie_port_acpi_setup(struct pci_dev *port, int *mask); +int pcie_port_acpi_setup(struct pci_dev *port, int *mask);  static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask)  { diff --git a/drivers/pci/pcie/portdrv_acpi.c b/drivers/pci/pcie/portdrv_acpi.c index a86b56e5f2f..b4d2894ee3f 100644 --- a/drivers/pci/pcie/portdrv_acpi.c +++ b/drivers/pci/pcie/portdrv_acpi.c @@ -17,6 +17,7 @@  #include "aer/aerdrv.h"  #include "../pci.h" +#include "portdrv.h"  /**   * pcie_port_acpi_setup - Request the BIOS to release control of PCIe services. diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 08c243ab034..0efba0539cc 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -272,11 +272,9 @@ static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev,  					enum pci_channel_state error)  {  	struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER}; -	int ret; - -	/* can not fail */ -	ret = device_for_each_child(&dev->dev, &data, error_detected_iter); +	/* get true return value from &data */ +	device_for_each_child(&dev->dev, &data, error_detected_iter);  	return data.result;  } @@ -308,10 +306,9 @@ static int mmio_enabled_iter(struct device *device, void *data)  static pci_ers_result_t pcie_portdrv_mmio_enabled(struct pci_dev *dev)  {  	pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; -	int retval;  	/* get true return value from &status */ -	retval = device_for_each_child(&dev->dev, &status, mmio_enabled_iter); +	device_for_each_child(&dev->dev, &status, mmio_enabled_iter);  	return status;  } @@ -343,7 +340,6 @@ static int slot_reset_iter(struct device *device, void *data)  static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev)  {  	pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; -	int retval;  	/* If fatal, restore cfg space for possible link reset at upstream */  	if (dev->error_state == pci_channel_io_frozen) { @@ -354,8 +350,7 @@ static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev)  	}  	/* get true return value from &status */ -	retval = device_for_each_child(&dev->dev, &status, slot_reset_iter); - +	device_for_each_child(&dev->dev, &status, slot_reset_iter);  	return status;  } @@ -381,9 +376,7 @@ static int resume_iter(struct device *device, void *data)  static void pcie_portdrv_err_resume(struct pci_dev *dev)  { -	int retval; -	/* nothing to do with error value, if it ever happens */ -	retval = device_for_each_child(&dev->dev, NULL, resume_iter); +	device_for_each_child(&dev->dev, NULL, resume_iter);  }  /* diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index b494066ef32..43ece5d41d3 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); @@ -1627,8 +1629,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++) @@ -1661,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)  { @@ -1715,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/quirks.c b/drivers/pci/quirks.c index 0369fb6fc1d..7d68aeebf56 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -324,29 +324,30 @@ static void quirk_cs5536_vsa(struct pci_dev *dev)  }  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, quirk_cs5536_vsa); -static void quirk_io_region(struct pci_dev *dev, unsigned region, -	unsigned size, int nr, const char *name) +static void quirk_io_region(struct pci_dev *dev, int port, +				unsigned size, int nr, const char *name)  { -	region &= ~(size-1); -	if (region) { -		struct pci_bus_region bus_region; -		struct resource *res = dev->resource + nr; +	u16 region; +	struct pci_bus_region bus_region; +	struct resource *res = dev->resource + nr; -		res->name = pci_name(dev); -		res->start = region; -		res->end = region + size - 1; -		res->flags = IORESOURCE_IO; +	pci_read_config_word(dev, port, ®ion); +	region &= ~(size - 1); -		/* Convert from PCI bus to resource space.  */ -		bus_region.start = res->start; -		bus_region.end = res->end; -		pcibios_bus_to_resource(dev, res, &bus_region); +	if (!region) +		return; -		if (pci_claim_resource(dev, nr) == 0) -			dev_info(&dev->dev, "quirk: %pR claimed by %s\n", -				 res, name); -	} -}	 +	res->name = pci_name(dev); +	res->flags = IORESOURCE_IO; + +	/* Convert from PCI bus to resource space */ +	bus_region.start = region; +	bus_region.end = region + size - 1; +	pcibios_bus_to_resource(dev, res, &bus_region); + +	if (!pci_claim_resource(dev, nr)) +		dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name); +}  /*   *	ATI Northbridge setups MCE the processor if you even @@ -374,12 +375,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI,	PCI_DEVICE_ID_ATI_RS100,   quirk_ati_   */  static void quirk_ali7101_acpi(struct pci_dev *dev)  { -	u16 region; - -	pci_read_config_word(dev, 0xE0, ®ion); -	quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "ali7101 ACPI"); -	pci_read_config_word(dev, 0xE2, ®ion); -	quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB"); +	quirk_io_region(dev, 0xE0, 64, PCI_BRIDGE_RESOURCES, "ali7101 ACPI"); +	quirk_io_region(dev, 0xE2, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB");  }  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL,	PCI_DEVICE_ID_AL_M7101,		quirk_ali7101_acpi); @@ -442,12 +439,10 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int   */  static void quirk_piix4_acpi(struct pci_dev *dev)  { -	u32 region, res_a; +	u32 res_a; -	pci_read_config_dword(dev, 0x40, ®ion); -	quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI"); -	pci_read_config_dword(dev, 0x90, ®ion); -	quirk_io_region(dev, region, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB"); +	quirk_io_region(dev, 0x40, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI"); +	quirk_io_region(dev, 0x90, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB");  	/* Device resource A has enables for some of the other ones */  	pci_read_config_dword(dev, 0x5c, &res_a); @@ -491,7 +486,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82443MX_3,	qui   */  static void quirk_ich4_lpc_acpi(struct pci_dev *dev)  { -	u32 region;  	u8 enable;  	/* @@ -503,22 +497,14 @@ static void quirk_ich4_lpc_acpi(struct pci_dev *dev)  	*/  	pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); -	if (enable & ICH4_ACPI_EN) { -		pci_read_config_dword(dev, ICH_PMBASE, ®ion); -		region &= PCI_BASE_ADDRESS_IO_MASK; -		if (region >= PCIBIOS_MIN_IO) -			quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, -					"ICH4 ACPI/GPIO/TCO"); -	} +	if (enable & ICH4_ACPI_EN) +		quirk_io_region(dev, ICH_PMBASE, 128, PCI_BRIDGE_RESOURCES, +				 "ICH4 ACPI/GPIO/TCO");  	pci_read_config_byte(dev, ICH4_GPIO_CNTL, &enable); -	if (enable & ICH4_GPIO_EN) { -		pci_read_config_dword(dev, ICH4_GPIOBASE, ®ion); -		region &= PCI_BASE_ADDRESS_IO_MASK; -		if (region >= PCIBIOS_MIN_IO) -			quirk_io_region(dev, region, 64, -					PCI_BRIDGE_RESOURCES + 1, "ICH4 GPIO"); -	} +	if (enable & ICH4_GPIO_EN) +		quirk_io_region(dev, ICH4_GPIOBASE, 64, PCI_BRIDGE_RESOURCES+1, +				"ICH4 GPIO");  }  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801AA_0,		quirk_ich4_lpc_acpi);  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801AB_0,		quirk_ich4_lpc_acpi); @@ -533,26 +519,17 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_ESB_1,		qui  static void ich6_lpc_acpi_gpio(struct pci_dev *dev)  { -	u32 region;  	u8 enable;  	pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); -	if (enable & ICH6_ACPI_EN) { -		pci_read_config_dword(dev, ICH_PMBASE, ®ion); -		region &= PCI_BASE_ADDRESS_IO_MASK; -		if (region >= PCIBIOS_MIN_IO) -			quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, -					"ICH6 ACPI/GPIO/TCO"); -	} +	if (enable & ICH6_ACPI_EN) +		quirk_io_region(dev, ICH_PMBASE, 128, PCI_BRIDGE_RESOURCES, +				 "ICH6 ACPI/GPIO/TCO");  	pci_read_config_byte(dev, ICH6_GPIO_CNTL, &enable); -	if (enable & ICH6_GPIO_EN) { -		pci_read_config_dword(dev, ICH6_GPIOBASE, ®ion); -		region &= PCI_BASE_ADDRESS_IO_MASK; -		if (region >= PCIBIOS_MIN_IO) -			quirk_io_region(dev, region, 64, -					PCI_BRIDGE_RESOURCES + 1, "ICH6 GPIO"); -	} +	if (enable & ICH6_GPIO_EN) +		quirk_io_region(dev, ICH6_GPIOBASE, 64, PCI_BRIDGE_RESOURCES+1, +				"ICH6 GPIO");  }  static void ich6_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const char *name, int dynsize) @@ -650,13 +627,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_ICH10_1, qui   */  static void quirk_vt82c586_acpi(struct pci_dev *dev)  { -	u32 region; - -	if (dev->revision & 0x10) { -		pci_read_config_dword(dev, 0x48, ®ion); -		region &= PCI_BASE_ADDRESS_IO_MASK; -		quirk_io_region(dev, region, 256, PCI_BRIDGE_RESOURCES, "vt82c586 ACPI"); -	} +	if (dev->revision & 0x10) +		quirk_io_region(dev, 0x48, 256, PCI_BRIDGE_RESOURCES, +				"vt82c586 ACPI");  }  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_3,	quirk_vt82c586_acpi); @@ -668,18 +641,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_3,	quirk_vt   */  static void quirk_vt82c686_acpi(struct pci_dev *dev)  { -	u16 hm; -	u32 smb; -  	quirk_vt82c586_acpi(dev); -	pci_read_config_word(dev, 0x70, &hm); -	hm &= PCI_BASE_ADDRESS_IO_MASK; -	quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c686 HW-mon"); +	quirk_io_region(dev, 0x70, 128, PCI_BRIDGE_RESOURCES+1, +				 "vt82c686 HW-mon"); -	pci_read_config_dword(dev, 0x90, &smb); -	smb &= PCI_BASE_ADDRESS_IO_MASK; -	quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c686 SMB"); +	quirk_io_region(dev, 0x90, 16, PCI_BRIDGE_RESOURCES+2, "vt82c686 SMB");  }  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	quirk_vt82c686_acpi); @@ -690,15 +657,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	quirk_vt   */  static void quirk_vt8235_acpi(struct pci_dev *dev)  { -	u16 pm, smb; - -	pci_read_config_word(dev, 0x88, &pm); -	pm &= PCI_BASE_ADDRESS_IO_MASK; -	quirk_io_region(dev, pm, 128, PCI_BRIDGE_RESOURCES, "vt8235 PM"); - -	pci_read_config_word(dev, 0xd0, &smb); -	smb &= PCI_BASE_ADDRESS_IO_MASK; -	quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 1, "vt8235 SMB"); +	quirk_io_region(dev, 0x88, 128, PCI_BRIDGE_RESOURCES, "vt8235 PM"); +	quirk_io_region(dev, 0xd0, 16, PCI_BRIDGE_RESOURCES+1, "vt8235 SMB");  }  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8235,	quirk_vt8235_acpi); @@ -2594,6 +2554,14 @@ static void quirk_msi_intx_disable_ati_bug(struct pci_dev *dev)  		dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG;  	pci_dev_put(p);  } +static void quirk_msi_intx_disable_qca_bug(struct pci_dev *dev) +{ +	/* AR816X/AR817X/E210X MSI is fixed at HW level from revision 0x18 */ +	if (dev->revision < 0x18) { +		dev_info(&dev->dev, "set MSI_INTX_DISABLE_BUG flag\n"); +		dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; +	} +}  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,  			PCI_DEVICE_ID_TIGON3_5780,  			quirk_msi_intx_disable_bug); @@ -2643,6 +2611,16 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1073,  			quirk_msi_intx_disable_bug);  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1083,  			quirk_msi_intx_disable_bug); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1090, +			quirk_msi_intx_disable_qca_bug); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1091, +			quirk_msi_intx_disable_qca_bug); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x10a0, +			quirk_msi_intx_disable_qca_bug); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x10a1, +			quirk_msi_intx_disable_qca_bug); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0xe091, +			quirk_msi_intx_disable_qca_bug);  #endif /* CONFIG_PCI_MSI */  /* Allow manual resource allocation for PCI hotplug bridges diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index cc875e6ed15..8fc54b7327b 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -50,10 +50,8 @@ 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); +	pcibios_remove_bus(bus);  	device_unregister(&bus->dev);  }  EXPORT_SYMBOL(pci_remove_bus); diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 7e8739e25b9..16abaaa1f83 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1044,7 +1044,7 @@ handle_done:  	;  } -void __ref __pci_bus_size_bridges(struct pci_bus *bus, +static void __ref __pci_bus_size_bridges(struct pci_bus *bus,  			struct list_head *realloc_head)  {  	struct pci_dev *dev; @@ -1545,6 +1545,8 @@ again:  enable_all:  	retval = pci_reenable_device(bridge); +	if (retval) +		dev_err(&bridge->dev, "Error reenabling bridge (%d)\n", retval);  	pci_set_master(bridge);  	pci_enable_bridges(parent);  } diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 81b88bda793..07f2eddc09c 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -261,7 +261,6 @@ int pci_assign_resource(struct pci_dev *dev, int resno)  {  	struct resource *res = dev->resource + resno;  	resource_size_t align, size; -	struct pci_bus *bus;  	int ret;  	align = pci_resource_alignment(dev, res); @@ -271,7 +270,6 @@ int pci_assign_resource(struct pci_dev *dev, int resno)  		return -EINVAL;  	} -	bus = dev->bus;  	size = resource_size(res);  	ret = _pci_assign_resource(dev, resno, size, align); diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index ac6412fb8d6..c1e9284a677 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c @@ -377,14 +377,17 @@ void pci_hp_create_module_link(struct pci_slot *pci_slot)  {  	struct hotplug_slot *slot = pci_slot->hotplug;  	struct kobject *kobj = NULL; -	int no_warn; +	int ret;  	if (!slot || !slot->ops)  		return;  	kobj = kset_find_obj(module_kset, slot->ops->mod_name);  	if (!kobj)  		return; -	no_warn = sysfs_create_link(&pci_slot->kobj, kobj, "module"); +	ret = sysfs_create_link(&pci_slot->kobj, kobj, "module"); +	if (ret) +		dev_err(&pci_slot->bus->dev, "Error creating sysfs link (%d)\n", +			ret);  	kobject_put(kobj);  }  EXPORT_SYMBOL_GPL(pci_hp_create_module_link); diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index ce90d0546cd..74550922ad5 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -703,7 +703,7 @@ static struct pci_device_id mvs_pci_table[] = {  	{ PCI_VDEVICE(TTI, 0x2744), chip_9480 },  	{ PCI_VDEVICE(TTI, 0x2760), chip_9480 },  	{ -		.vendor		= 0x1b4b, +		.vendor		= PCI_VENDOR_ID_MARVELL_EXT,  		.device		= 0x9480,  		.subvendor	= PCI_ANY_ID,  		.subdevice	= 0x9480, @@ -712,7 +712,7 @@ static struct pci_device_id mvs_pci_table[] = {  		.driver_data	= chip_9480,  	},  	{ -		.vendor		= 0x1b4b, +		.vendor		= PCI_VENDOR_ID_MARVELL_EXT,  		.device		= 0x9445,  		.subvendor	= PCI_ANY_ID,  		.subdevice	= 0x9480, @@ -721,7 +721,7 @@ static struct pci_device_id mvs_pci_table[] = {  		.driver_data	= chip_9445,  	},  	{ -		.vendor		= 0x1b4b, +		.vendor		= PCI_VENDOR_ID_MARVELL_EXT,  		.device		= 0x9485,  		.subvendor	= PCI_ANY_ID,  		.subdevice	= 0x9480, diff --git a/drivers/scsi/mvumi.c b/drivers/scsi/mvumi.c index 4594ccaaf49..c3601b57a80 100644 --- a/drivers/scsi/mvumi.c +++ b/drivers/scsi/mvumi.c @@ -49,8 +49,8 @@ MODULE_AUTHOR("jyli@marvell.com");  MODULE_DESCRIPTION("Marvell UMI Driver");  static DEFINE_PCI_DEVICE_TABLE(mvumi_pci_table) = { -	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_2, PCI_DEVICE_ID_MARVELL_MV9143) }, -	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_2, PCI_DEVICE_ID_MARVELL_MV9580) }, +	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, PCI_DEVICE_ID_MARVELL_MV9143) }, +	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, PCI_DEVICE_ID_MARVELL_MV9580) },  	{ 0 }  }; diff --git a/drivers/scsi/mvumi.h b/drivers/scsi/mvumi.h index e360135fd1b..41f168702ac 100644 --- a/drivers/scsi/mvumi.h +++ b/drivers/scsi/mvumi.h @@ -32,7 +32,6 @@  #define VER_BUILD		1500  #define MV_DRIVER_NAME			"mvumi" -#define PCI_VENDOR_ID_MARVELL_2		0x1b4b  #define PCI_DEVICE_ID_MARVELL_MV9143	0x9143  #define PCI_DEVICE_ID_MARVELL_MV9580	0x9580 diff --git a/include/linux/acpi.h b/include/linux/acpi.h index bcbdd7484e5..03053aca5b3 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, diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 9a22b5efb38..81b31613eb2 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h @@ -41,8 +41,37 @@ static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus)  	return DEVICE_ACPI_HANDLE(dev);  } + +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 +#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) { } +#endif	/* CONFIG_ACPI */ +  #ifdef CONFIG_ACPI_APEI  extern bool aer_acpi_firmware_first(void);  #else diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h index c8320144fe7..8af4610c2e4 100644 --- a/include/linux/pci-aspm.h +++ b/include/linux/pci-aspm.h @@ -23,14 +23,14 @@  #define PCIE_LINK_STATE_CLKPM	4  #ifdef CONFIG_PCIEASPM -extern void pcie_aspm_init_link_state(struct pci_dev *pdev); -extern void pcie_aspm_exit_link_state(struct pci_dev *pdev); -extern void pcie_aspm_pm_state_change(struct pci_dev *pdev); -extern void pcie_aspm_powersave_config_link(struct pci_dev *pdev); -extern void pci_disable_link_state(struct pci_dev *pdev, int state); -extern void pci_disable_link_state_locked(struct pci_dev *pdev, int state); -extern void pcie_clear_aspm(struct pci_bus *bus); -extern void pcie_no_aspm(void); +void pcie_aspm_init_link_state(struct pci_dev *pdev); +void pcie_aspm_exit_link_state(struct pci_dev *pdev); +void pcie_aspm_pm_state_change(struct pci_dev *pdev); +void pcie_aspm_powersave_config_link(struct pci_dev *pdev); +void pci_disable_link_state(struct pci_dev *pdev, int state); +void pci_disable_link_state_locked(struct pci_dev *pdev, int state); +void pcie_clear_aspm(struct pci_bus *bus); +void pcie_no_aspm(void);  #else  static inline void pcie_aspm_init_link_state(struct pci_dev *pdev)  { @@ -56,8 +56,8 @@ static inline void pcie_no_aspm(void)  #endif  #ifdef CONFIG_PCIEASPM_DEBUG /* this depends on CONFIG_PCIEASPM */ -extern void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev); -extern void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev); +void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev); +void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev);  #else  static inline void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev)  { diff --git a/include/linux/pci-ats.h b/include/linux/pci-ats.h index 7ef68724f0f..68bcefd7fca 100644 --- a/include/linux/pci-ats.h +++ b/include/linux/pci-ats.h @@ -14,9 +14,9 @@ struct pci_ats {  #ifdef CONFIG_PCI_ATS -extern int pci_enable_ats(struct pci_dev *dev, int ps); -extern void pci_disable_ats(struct pci_dev *dev); -extern int pci_ats_queue_depth(struct pci_dev *dev); +int pci_enable_ats(struct pci_dev *dev, int ps); +void pci_disable_ats(struct pci_dev *dev); +int pci_ats_queue_depth(struct pci_dev *dev);  /**   * pci_ats_enabled - query the ATS status @@ -54,12 +54,12 @@ static inline int pci_ats_enabled(struct pci_dev *dev)  #ifdef CONFIG_PCI_PRI -extern int  pci_enable_pri(struct pci_dev *pdev, u32 reqs); -extern void pci_disable_pri(struct pci_dev *pdev); -extern bool pci_pri_enabled(struct pci_dev *pdev); -extern int  pci_reset_pri(struct pci_dev *pdev); -extern bool pci_pri_stopped(struct pci_dev *pdev); -extern int  pci_pri_status(struct pci_dev *pdev); +int pci_enable_pri(struct pci_dev *pdev, u32 reqs); +void pci_disable_pri(struct pci_dev *pdev); +bool pci_pri_enabled(struct pci_dev *pdev); +int pci_reset_pri(struct pci_dev *pdev); +bool pci_pri_stopped(struct pci_dev *pdev); +int pci_pri_status(struct pci_dev *pdev);  #else /* CONFIG_PCI_PRI */ @@ -95,10 +95,10 @@ static inline int pci_pri_status(struct pci_dev *pdev)  #ifdef CONFIG_PCI_PASID -extern int pci_enable_pasid(struct pci_dev *pdev, int features); -extern void pci_disable_pasid(struct pci_dev *pdev); -extern int pci_pasid_features(struct pci_dev *pdev); -extern int pci_max_pasids(struct pci_dev *pdev); +int pci_enable_pasid(struct pci_dev *pdev, int features); +void pci_disable_pasid(struct pci_dev *pdev); +int pci_pasid_features(struct pci_dev *pdev); +int pci_max_pasids(struct pci_dev *pdev);  #else  /* CONFIG_PCI_PASID */ diff --git a/include/linux/pci.h b/include/linux/pci.h index b73c2460ad5..e19d8648e0e 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -35,6 +35,21 @@  /* Include the ID list */  #include <linux/pci_ids.h> +/* + * The PCI interface treats multi-function devices as independent + * devices.  The slot/function address of each device is encoded + * in a single byte as follows: + * + *	7:3 = slot + *	2:0 = function + * PCI_DEVFN(), PCI_SLOT(), and PCI_FUNC() are defined uapi/linux/pci.h + * In the interest of not exposing interfaces to user-space unnecessarily, + * the following kernel only defines are being added here. + */ +#define PCI_DEVID(bus, devfn)  ((((u16)bus) << 8) | devfn) +/* return bus from PCI devid = ((u16)bus_number) << 8) | devfn */ +#define PCI_BUS_NUM(x) (((x) >> 8) & 0xff) +  /* pci_slot represents a physical slot */  struct pci_slot {  	struct pci_bus *bus;		/* The bus this slot is on */ @@ -349,7 +364,7 @@ static inline struct pci_dev *pci_physfn(struct pci_dev *dev)  	return dev;  } -extern struct pci_dev *alloc_pci_dev(void); +struct pci_dev *alloc_pci_dev(void);  #define	to_pci_dev(n) container_of(n, struct pci_dev, dev)  #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) @@ -505,10 +520,10 @@ struct pci_ops {   * ACPI needs to be able to access PCI config space before we've done a   * PCI bus scan and created pci_bus structures.   */ -extern int raw_pci_read(unsigned int domain, unsigned int bus, -			unsigned int devfn, int reg, int len, u32 *val); -extern int raw_pci_write(unsigned int domain, unsigned int bus, -			unsigned int devfn, int reg, int len, u32 val); +int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn, +		 int reg, int len, u32 *val); +int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn, +		  int reg, int len, u32 val);  struct pci_bus_region {  	resource_size_t start; @@ -659,7 +674,7 @@ struct pci_driver {  /* these external functions are only available when PCI support is enabled */  #ifdef CONFIG_PCI -extern void pcie_bus_configure_settings(struct pci_bus *bus, u8 smpss); +void pcie_bus_configure_settings(struct pci_bus *bus, u8 smpss);  enum pcie_bus_config_types {  	PCIE_BUS_TUNE_OFF, @@ -676,9 +691,11 @@ extern struct bus_type pci_bus_type;   * code, or pci core code. */  extern struct list_head pci_root_buses;	/* list of all known PCI buses */  /* Some device drivers need know if pci is initiated */ -extern int no_pci_devices(void); +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) */ @@ -700,7 +717,7 @@ void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,  void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,  			     struct pci_bus_region *region);  void pcibios_scan_specific_bus(int busn); -extern struct pci_bus *pci_find_bus(int domain, int busnr); +struct pci_bus *pci_find_bus(int domain, int busnr);  void pci_bus_add_devices(const struct pci_bus *bus);  struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,  				      struct pci_ops *ops, void *sysdata); @@ -733,14 +750,14 @@ struct resource *pci_find_parent_resource(const struct pci_dev *dev,  u8 pci_swizzle_interrupt_pin(const struct pci_dev *dev, u8 pin);  int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge);  u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp); -extern struct pci_dev *pci_dev_get(struct pci_dev *dev); -extern void pci_dev_put(struct pci_dev *dev); -extern void pci_remove_bus(struct pci_bus *b); -extern void pci_stop_and_remove_bus_device(struct pci_dev *dev); +struct pci_dev *pci_dev_get(struct pci_dev *dev); +void pci_dev_put(struct pci_dev *dev); +void pci_remove_bus(struct pci_bus *b); +void pci_stop_and_remove_bus_device(struct pci_dev *dev);  void pci_stop_root_bus(struct pci_bus *bus);  void pci_remove_root_bus(struct pci_bus *bus);  void pci_setup_cardbus(struct pci_bus *bus); -extern void pci_sort_breadthfirst(void); +void pci_sort_breadthfirst(void);  #define dev_is_pci(d) ((d)->bus == &pci_bus_type)  #define dev_is_pf(d) ((dev_is_pci(d) ? to_pci_dev(d)->is_physfn : false))  #define dev_num_vf(d) ((dev_is_pci(d) ? pci_num_vf(to_pci_dev(d)) : 0)) @@ -1142,18 +1159,17 @@ static inline int pci_msi_enabled(void)  	return 0;  }  #else -extern int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); -extern int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec); -extern void pci_msi_shutdown(struct pci_dev *dev); -extern void pci_disable_msi(struct pci_dev *dev); -extern int pci_msix_table_size(struct pci_dev *dev); -extern int pci_enable_msix(struct pci_dev *dev, -	struct msix_entry *entries, int nvec); -extern void pci_msix_shutdown(struct pci_dev *dev); -extern void pci_disable_msix(struct pci_dev *dev); -extern void msi_remove_pci_irq_vectors(struct pci_dev *dev); -extern void pci_restore_msi_state(struct pci_dev *dev); -extern int pci_msi_enabled(void); +int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); +int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec); +void pci_msi_shutdown(struct pci_dev *dev); +void pci_disable_msi(struct pci_dev *dev); +int pci_msix_table_size(struct pci_dev *dev); +int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); +void pci_msix_shutdown(struct pci_dev *dev); +void pci_disable_msix(struct pci_dev *dev); +void msi_remove_pci_irq_vectors(struct pci_dev *dev); +void pci_restore_msi_state(struct pci_dev *dev); +int pci_msi_enabled(void);  #endif  #ifdef CONFIG_PCIEPORTBUS @@ -1168,8 +1184,8 @@ extern bool pcie_ports_auto;  static inline int pcie_aspm_enabled(void) { return 0; }  static inline bool pcie_aspm_support_enabled(void) { return false; }  #else -extern int pcie_aspm_enabled(void); -extern bool pcie_aspm_support_enabled(void); +int pcie_aspm_enabled(void); +bool pcie_aspm_support_enabled(void);  #endif  #ifdef CONFIG_PCIEAER @@ -1187,8 +1203,8 @@ static inline void pcie_set_ecrc_checking(struct pci_dev *dev)  }  static inline void pcie_ecrc_get_policy(char *str) {};  #else -extern void pcie_set_ecrc_checking(struct pci_dev *dev); -extern void pcie_ecrc_get_policy(char *str); +void pcie_set_ecrc_checking(struct pci_dev *dev); +void pcie_ecrc_get_policy(char *str);  #endif  #define pci_enable_msi(pdev)	pci_enable_msi_block(pdev, 1) @@ -1199,9 +1215,9 @@ int  ht_create_irq(struct pci_dev *dev, int idx);  void ht_destroy_irq(unsigned int irq);  #endif /* CONFIG_HT_IRQ */ -extern void pci_cfg_access_lock(struct pci_dev *dev); -extern bool pci_cfg_access_trylock(struct pci_dev *dev); -extern void pci_cfg_access_unlock(struct pci_dev *dev); +void pci_cfg_access_lock(struct pci_dev *dev); +bool pci_cfg_access_trylock(struct pci_dev *dev); +void pci_cfg_access_unlock(struct pci_dev *dev);  /*   * PCI domain support.  Sometimes called PCI segment (eg by ACPI), @@ -1226,7 +1242,7 @@ static inline int pci_proc_domain(struct pci_bus *bus)  /* some architectures require additional setup to direct VGA traffic */  typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode,  		      unsigned int command_bits, u32 flags); -extern void pci_register_set_vga_state(arch_set_vga_state_t func); +void pci_register_set_vga_state(arch_set_vga_state_t func);  #else /* CONFIG_PCI is not enabled */ @@ -1628,8 +1644,8 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev,  int pcibios_add_device(struct pci_dev *dev);  #ifdef CONFIG_PCI_MMCONFIG -extern void __init pci_mmcfg_early_init(void); -extern void __init pci_mmcfg_late_init(void); +void __init pci_mmcfg_early_init(void); +void __init pci_mmcfg_late_init(void);  #else  static inline void pci_mmcfg_early_init(void) { }  static inline void pci_mmcfg_late_init(void) { } @@ -1640,12 +1656,12 @@ int pci_ext_cfg_avail(void);  void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar);  #ifdef CONFIG_PCI_IOV -extern int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); -extern void pci_disable_sriov(struct pci_dev *dev); -extern irqreturn_t pci_sriov_migration(struct pci_dev *dev); -extern int pci_num_vf(struct pci_dev *dev); -extern int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); -extern int pci_sriov_get_totalvfs(struct pci_dev *dev); +int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); +void pci_disable_sriov(struct pci_dev *dev); +irqreturn_t pci_sriov_migration(struct pci_dev *dev); +int pci_num_vf(struct pci_dev *dev); +int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); +int pci_sriov_get_totalvfs(struct pci_dev *dev);  #else  static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn)  { @@ -1673,8 +1689,8 @@ static inline int pci_sriov_get_totalvfs(struct pci_dev *dev)  #endif  #if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE) -extern void pci_hp_create_module_link(struct pci_slot *pci_slot); -extern void pci_hp_remove_module_link(struct pci_slot *pci_slot); +void pci_hp_create_module_link(struct pci_slot *pci_slot); +void pci_hp_remove_module_link(struct pci_slot *pci_slot);  #endif  /** @@ -1818,13 +1834,13 @@ int pci_vpd_find_info_keyword(const u8 *buf, unsigned int off,  /* PCI <-> OF binding helpers */  #ifdef CONFIG_OF  struct device_node; -extern void pci_set_of_node(struct pci_dev *dev); -extern void pci_release_of_node(struct pci_dev *dev); -extern void pci_set_bus_of_node(struct pci_bus *bus); -extern void pci_release_bus_of_node(struct pci_bus *bus); +void pci_set_of_node(struct pci_dev *dev); +void pci_release_of_node(struct pci_dev *dev); +void pci_set_bus_of_node(struct pci_bus *bus); +void pci_release_bus_of_node(struct pci_bus *bus);  /* Arch may override this (weak) */ -extern struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus); +struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus);  static inline struct device_node *  pci_device_to_OF_node(const struct pci_dev *pdev) diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index 45fc162cbdc..8db71dcd633 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h @@ -125,12 +125,12 @@ static inline const char *hotplug_slot_name(const struct hotplug_slot *slot)  	return pci_slot_name(slot->pci_slot);  } -extern int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *pbus, -			     int nr, const char *name, -			     struct module *owner, const char *mod_name); -extern int pci_hp_deregister(struct hotplug_slot *slot); -extern int __must_check pci_hp_change_slot_info	(struct hotplug_slot *slot, -						 struct hotplug_slot_info *info); +int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *pbus, int nr, +		      const char *name, struct module *owner, +		      const char *mod_name); +int pci_hp_deregister(struct hotplug_slot *slot); +int __must_check pci_hp_change_slot_info(struct hotplug_slot *slot, +					 struct hotplug_slot_info *info);  /* use a define to avoid include chaining to get THIS_MODULE & friends */  #define pci_hp_register(slot, pbus, devnr, name) \ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index f11c1c2609d..a80f9e6ce9e 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1604,6 +1604,7 @@  #define PCI_SUBDEVICE_ID_KEYSPAN_SX2	0x5334  #define PCI_VENDOR_ID_MARVELL		0x11ab +#define PCI_VENDOR_ID_MARVELL_EXT	0x1b4b  #define PCI_DEVICE_ID_MARVELL_GT64111	0x4146  #define PCI_DEVICE_ID_MARVELL_GT64260	0x6430  #define PCI_DEVICE_ID_MARVELL_MV64360	0x6460 diff --git a/include/linux/pcieport_if.h b/include/linux/pcieport_if.h index e6f91b1406d..9572669eea9 100644 --- a/include/linux/pcieport_if.h +++ b/include/linux/pcieport_if.h @@ -62,7 +62,7 @@ struct pcie_port_service_driver {  #define to_service_driver(d) \  	container_of(d, struct pcie_port_service_driver, driver) -extern int pcie_port_service_register(struct pcie_port_service_driver *new); -extern void pcie_port_service_unregister(struct pcie_port_service_driver *new); +int pcie_port_service_register(struct pcie_port_service_driver *new); +void pcie_port_service_unregister(struct pcie_port_service_driver *new);  #endif /* _PCIEPORT_IF_H_ */  |