11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * drivers/pci/pci-driver.c
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
42b937303188807b498d1a3163f60305f0941538eGreg Kroah-Hartman * (C) Copyright 2002-2004, 2007 Greg Kroah-Hartman <greg@kroah.com>
52b937303188807b498d1a3163f60305f0941538eGreg Kroah-Hartman * (C) Copyright 2007 Novell Inc.
62b937303188807b498d1a3163f60305f0941538eGreg Kroah-Hartman *
72b937303188807b498d1a3163f60305f0941538eGreg Kroah-Hartman * Released under the GPL v2 only.
82b937303188807b498d1a3163f60305f0941538eGreg Kroah-Hartman *
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h>
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/device.h>
15d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen#include <linux/mempolicy.h>
164e57b6817880946a3a78d5d8cad1ace363f7e449Tim Schmielau#include <linux/string.h>
174e57b6817880946a3a78d5d8cad1ace363f7e449Tim Schmielau#include <linux/slab.h>
188c65b4a60450590e79a28e9717ceffa9e4debb3fTim Schmielau#include <linux/sched.h>
19873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell#include <linux/cpu.h>
206cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#include <linux/pm_runtime.h>
21eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki#include <linux/suspend.h>
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "pci.h"
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartmanstruct pci_dynid {
2575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman	struct list_head node;
2675865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman	struct pci_device_id id;
2775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman};
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
299dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo/**
309dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * pci_add_dynid - add a new PCI device ID to this driver and re-probe devices
319dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @drv: target pci driver
329dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @vendor: PCI vendor ID
339dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @device: PCI device ID
349dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @subvendor: PCI subvendor ID
359dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @subdevice: PCI subdevice ID
369dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @class: PCI class
379dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @class_mask: PCI class mask
389dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @driver_data: private driver data
399dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo *
409dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * Adds a new dynamic pci device ID to this driver and causes the
419dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * driver to probe for all devices again.  @drv must have been
429dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * registered prior to calling this function.
439dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo *
449dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * CONTEXT:
459dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * Does GFP_KERNEL allocation.
469dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo *
479dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * RETURNS:
489dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * 0 on success, -errno on failure.
499dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo */
509dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heoint pci_add_dynid(struct pci_driver *drv,
519dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo		  unsigned int vendor, unsigned int device,
529dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo		  unsigned int subvendor, unsigned int subdevice,
539dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo		  unsigned int class, unsigned int class_mask,
549dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo		  unsigned long driver_data)
559dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo{
569dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	struct pci_dynid *dynid;
579dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	int retval;
589dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo
599dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
609dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	if (!dynid)
619dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo		return -ENOMEM;
629dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo
639dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	dynid->id.vendor = vendor;
649dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	dynid->id.device = device;
659dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	dynid->id.subvendor = subvendor;
669dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	dynid->id.subdevice = subdevice;
679dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	dynid->id.class = class;
689dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	dynid->id.class_mask = class_mask;
699dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	dynid->id.driver_data = driver_data;
703d3c2ae1101c1f2dff7e2f9d514769779dbd2737Greg Kroah-Hartman
719dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	spin_lock(&drv->dynids.lock);
729dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	list_add_tail(&dynid->node, &drv->dynids.list);
739dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	spin_unlock(&drv->dynids.lock);
749dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo
759dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	retval = driver_attach(&drv->driver);
769dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo
779dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	return retval;
789dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo}
799dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo
809dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heostatic void pci_free_dynids(struct pci_driver *drv)
819dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo{
829dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	struct pci_dynid *dynid, *n;
833d3c2ae1101c1f2dff7e2f9d514769779dbd2737Greg Kroah-Hartman
849dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	spin_lock(&drv->dynids.lock);
859dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
869dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo		list_del(&dynid->node);
879dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo		kfree(dynid);
889dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	}
899dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	spin_unlock(&drv->dynids.lock);
909dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo}
919dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo
929dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo/*
939dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * Dynamic device ID manipulation via sysfs is disabled for !CONFIG_HOTPLUG
949dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo */
959dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo#ifdef CONFIG_HOTPLUG
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
979dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * store_new_id - sysfs frontend to pci_add_dynid()
988f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @driver: target device driver
998f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @buf: buffer for scanning device ID data
1008f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @count: input size
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1029dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * Allow PCI IDs to be added to an existing driver via sysfs.
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
104f8eb1005a5bdb019d2a4ff3ef8d8e8015b22afcbRandy Dunlapstatic ssize_t
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstore_new_id(struct device_driver *driver, const char *buf, size_t count)
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pci_driver *pdrv = to_pci_driver(driver);
108b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare	const struct pci_device_id *ids = pdrv->id_table;
1096ba186361ed2cda7e174856a3ab8a8e3237b3c3dJean Delvare	__u32 vendor, device, subvendor=PCI_ANY_ID,
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		subdevice=PCI_ANY_ID, class=0, class_mask=0;
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long driver_data=0;
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int fields=0;
1139dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	int retval;
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
115b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare	fields = sscanf(buf, "%x %x %x %x %x %x %lx",
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			&vendor, &device, &subvendor, &subdevice,
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			&class, &class_mask, &driver_data);
1186ba186361ed2cda7e174856a3ab8a8e3237b3c3dJean Delvare	if (fields < 2)
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EINVAL;
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
121b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare	/* Only accept driver_data values that match an existing id_table
122b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare	   entry */
1232debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright	if (ids) {
1242debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright		retval = -EINVAL;
1252debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright		while (ids->vendor || ids->subvendor || ids->class_mask) {
1262debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright			if (driver_data == ids->driver_data) {
1272debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright				retval = 0;
1282debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright				break;
1292debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright			}
1302debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright			ids++;
131b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare		}
1322debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright		if (retval)	/* No match */
1332debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright			return retval;
134b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare	}
135b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare
1369dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo	retval = pci_add_dynid(pdrv, vendor, device, subvendor, subdevice,
1379dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo			       class, class_mask, driver_data);
138b19441af185559118e8247382ea4f2f76ebffc6dGreg Kroah-Hartman	if (retval)
139b19441af185559118e8247382ea4f2f76ebffc6dGreg Kroah-Hartman		return retval;
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1440994375e9614f78657031e04e30019b9cdb62795Chris Wright/**
1450994375e9614f78657031e04e30019b9cdb62795Chris Wright * store_remove_id - remove a PCI device ID from this driver
1460994375e9614f78657031e04e30019b9cdb62795Chris Wright * @driver: target device driver
1470994375e9614f78657031e04e30019b9cdb62795Chris Wright * @buf: buffer for scanning device ID data
1480994375e9614f78657031e04e30019b9cdb62795Chris Wright * @count: input size
1490994375e9614f78657031e04e30019b9cdb62795Chris Wright *
1500994375e9614f78657031e04e30019b9cdb62795Chris Wright * Removes a dynamic pci device ID to this driver.
1510994375e9614f78657031e04e30019b9cdb62795Chris Wright */
1520994375e9614f78657031e04e30019b9cdb62795Chris Wrightstatic ssize_t
1530994375e9614f78657031e04e30019b9cdb62795Chris Wrightstore_remove_id(struct device_driver *driver, const char *buf, size_t count)
1540994375e9614f78657031e04e30019b9cdb62795Chris Wright{
1550994375e9614f78657031e04e30019b9cdb62795Chris Wright	struct pci_dynid *dynid, *n;
1560994375e9614f78657031e04e30019b9cdb62795Chris Wright	struct pci_driver *pdrv = to_pci_driver(driver);
1570994375e9614f78657031e04e30019b9cdb62795Chris Wright	__u32 vendor, device, subvendor = PCI_ANY_ID,
1580994375e9614f78657031e04e30019b9cdb62795Chris Wright		subdevice = PCI_ANY_ID, class = 0, class_mask = 0;
1590994375e9614f78657031e04e30019b9cdb62795Chris Wright	int fields = 0;
1600994375e9614f78657031e04e30019b9cdb62795Chris Wright	int retval = -ENODEV;
1610994375e9614f78657031e04e30019b9cdb62795Chris Wright
1620994375e9614f78657031e04e30019b9cdb62795Chris Wright	fields = sscanf(buf, "%x %x %x %x %x %x",
1630994375e9614f78657031e04e30019b9cdb62795Chris Wright			&vendor, &device, &subvendor, &subdevice,
1640994375e9614f78657031e04e30019b9cdb62795Chris Wright			&class, &class_mask);
1650994375e9614f78657031e04e30019b9cdb62795Chris Wright	if (fields < 2)
1660994375e9614f78657031e04e30019b9cdb62795Chris Wright		return -EINVAL;
1670994375e9614f78657031e04e30019b9cdb62795Chris Wright
1680994375e9614f78657031e04e30019b9cdb62795Chris Wright	spin_lock(&pdrv->dynids.lock);
1690994375e9614f78657031e04e30019b9cdb62795Chris Wright	list_for_each_entry_safe(dynid, n, &pdrv->dynids.list, node) {
1700994375e9614f78657031e04e30019b9cdb62795Chris Wright		struct pci_device_id *id = &dynid->id;
1710994375e9614f78657031e04e30019b9cdb62795Chris Wright		if ((id->vendor == vendor) &&
1720994375e9614f78657031e04e30019b9cdb62795Chris Wright		    (id->device == device) &&
1730994375e9614f78657031e04e30019b9cdb62795Chris Wright		    (subvendor == PCI_ANY_ID || id->subvendor == subvendor) &&
1740994375e9614f78657031e04e30019b9cdb62795Chris Wright		    (subdevice == PCI_ANY_ID || id->subdevice == subdevice) &&
1750994375e9614f78657031e04e30019b9cdb62795Chris Wright		    !((id->class ^ class) & class_mask)) {
1760994375e9614f78657031e04e30019b9cdb62795Chris Wright			list_del(&dynid->node);
1770994375e9614f78657031e04e30019b9cdb62795Chris Wright			kfree(dynid);
1780994375e9614f78657031e04e30019b9cdb62795Chris Wright			retval = 0;
1790994375e9614f78657031e04e30019b9cdb62795Chris Wright			break;
1800994375e9614f78657031e04e30019b9cdb62795Chris Wright		}
1810994375e9614f78657031e04e30019b9cdb62795Chris Wright	}
1820994375e9614f78657031e04e30019b9cdb62795Chris Wright	spin_unlock(&pdrv->dynids.lock);
1830994375e9614f78657031e04e30019b9cdb62795Chris Wright
1840994375e9614f78657031e04e30019b9cdb62795Chris Wright	if (retval)
1850994375e9614f78657031e04e30019b9cdb62795Chris Wright		return retval;
1860994375e9614f78657031e04e30019b9cdb62795Chris Wright	return count;
1870994375e9614f78657031e04e30019b9cdb62795Chris Wright}
1880994375e9614f78657031e04e30019b9cdb62795Chris Wrightstatic DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id);
1890994375e9614f78657031e04e30019b9cdb62795Chris Wright
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
191ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Sternpci_create_newid_files(struct pci_driver *drv)
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int error = 0;
1940994375e9614f78657031e04e30019b9cdb62795Chris Wright
195ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern	if (drv->probe != NULL) {
196ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern		error = driver_create_file(&drv->driver, &driver_attr_new_id);
197ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern		if (error == 0) {
198ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern			error = driver_create_file(&drv->driver,
199ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern					&driver_attr_remove_id);
200ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern			if (error)
201ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern				driver_remove_file(&drv->driver,
202ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern						&driver_attr_new_id);
203ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern		}
204ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern	}
2050994375e9614f78657031e04e30019b9cdb62795Chris Wright	return error;
2060994375e9614f78657031e04e30019b9cdb62795Chris Wright}
2070994375e9614f78657031e04e30019b9cdb62795Chris Wright
208ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Sternstatic void pci_remove_newid_files(struct pci_driver *drv)
2090994375e9614f78657031e04e30019b9cdb62795Chris Wright{
2100994375e9614f78657031e04e30019b9cdb62795Chris Wright	driver_remove_file(&drv->driver, &driver_attr_remove_id);
211ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern	driver_remove_file(&drv->driver, &driver_attr_new_id);
2120994375e9614f78657031e04e30019b9cdb62795Chris Wright}
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else /* !CONFIG_HOTPLUG */
214ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Sternstatic inline int pci_create_newid_files(struct pci_driver *drv)
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
218ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Sternstatic inline void pci_remove_newid_files(struct pci_driver *drv) {}
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
22275865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * pci_match_id - See if a pci device matches a given pci_id table
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @ids: array of PCI device id structures to search in
22475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * @dev: the PCI device structure to match against.
22575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman *
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Used by a driver to check whether a PCI device present in the
22775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * system is in its list of supported devices.  Returns the matching
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_device_id structure or %NULL if there is no match.
22975865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman *
2308b60756a628a73bc8bf8b59d8716cb3f09b7e7ebRandy Dunlap * Deprecated, don't use this as it will not catch any dynamic ids
23175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * that a driver might want to check for.
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
23375865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartmanconst struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
23475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman					 struct pci_dev *dev)
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
23675865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman	if (ids) {
23775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman		while (ids->vendor || ids->subvendor || ids->class_mask) {
23875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman			if (pci_match_one_device(ids, dev))
23975865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman				return ids;
24075865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman			ids++;
24175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman		}
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return NULL;
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
247ae9608af9e300395ec032479621f32688c121141Randy Dunlap * pci_match_device - Tell if a PCI device structure has a matching PCI device id structure
24875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * @drv: the PCI driver to match against
24939ba487fe22a63b3df7c543c82d01db0f0fed700Henrik Kretzschmar * @dev: the PCI device structure to match against
25075865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman *
25175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * Used by a driver to check whether a PCI device present in the
25275865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * system is in its list of supported devices.  Returns the matching
25375865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * pci_device_id structure or %NULL if there is no match.
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
255d73460d79bc88de74221d73723ed61a0081b7a36Adrian Bunkstatic const struct pci_device_id *pci_match_device(struct pci_driver *drv,
256d73460d79bc88de74221d73723ed61a0081b7a36Adrian Bunk						    struct pci_dev *dev)
25775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman{
25875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman	struct pci_dynid *dynid;
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2607461b60afa62b26943e97861d87b9f9a32d7fd9cRussell King	/* Look at the dynamic ids first, before the static ones */
26175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman	spin_lock(&drv->dynids.lock);
26275865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman	list_for_each_entry(dynid, &drv->dynids.list, node) {
26375865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman		if (pci_match_one_device(&dynid->id, dev)) {
26475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman			spin_unlock(&drv->dynids.lock);
26575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman			return &dynid->id;
26675865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman		}
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
26875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman	spin_unlock(&drv->dynids.lock);
2697461b60afa62b26943e97861d87b9f9a32d7fd9cRussell King
2707461b60afa62b26943e97861d87b9f9a32d7fd9cRussell King	return pci_match_id(drv->id_table, dev);
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
273873392ca514f87eae39f53b6944caf85b1a047cbRusty Russellstruct drv_dev_and_id {
274873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell	struct pci_driver *drv;
275873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell	struct pci_dev *dev;
276873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell	const struct pci_device_id *id;
277873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell};
278873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell
279873392ca514f87eae39f53b6944caf85b1a047cbRusty Russellstatic long local_pci_probe(void *_ddi)
280873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell{
281873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell	struct drv_dev_and_id *ddi = _ddi;
282f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	struct device *dev = &ddi->dev->dev;
283f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	int rc;
284f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern
285f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	/* Unbound PCI devices are always set to disabled and suspended.
286f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	 * During probe, the device is set to enabled and active and the
287f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	 * usage count is incremented.  If the driver supports runtime PM,
288f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	 * it should call pm_runtime_put_noidle() in its probe routine and
289f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	 * pm_runtime_get_noresume() in its remove routine.
290f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	 */
291f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	pm_runtime_get_noresume(dev);
292f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	pm_runtime_set_active(dev);
293f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	pm_runtime_enable(dev);
294f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern
295f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	rc = ddi->drv->probe(ddi->dev, ddi->id);
296f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	if (rc) {
297f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern		pm_runtime_disable(dev);
298f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern		pm_runtime_set_suspended(dev);
299f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern		pm_runtime_put_noidle(dev);
300f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	}
301f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	return rc;
302873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell}
303873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell
304d42c69972b853fd33a26c8c7405624be41a22136Andi Kleenstatic int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
305d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen			  const struct pci_device_id *id)
306d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen{
307873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell	int error, node;
308873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell	struct drv_dev_and_id ddi = { drv, dev, id };
309873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell
310873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell	/* Execute driver initialization on node where the device's
311873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell	   bus is attached to.  This way the driver likely allocates
312873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell	   its local memory on the right node without any need to
313873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell	   change it. */
314873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell	node = dev_to_node(&dev->dev);
315f70316dace2bb99730800d47044acb818c6735f6Mike Travis	if (node >= 0) {
316873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell		int cpu;
317873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell
318873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell		get_online_cpus();
319a70f730282019f487aa33a84e5ac9a5e89c5abd0Rusty Russell		cpu = cpumask_any_and(cpumask_of_node(node), cpu_online_mask);
320873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell		if (cpu < nr_cpu_ids)
321873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell			error = work_on_cpu(cpu, local_pci_probe, &ddi);
322873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell		else
323873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell			error = local_pci_probe(&ddi);
324873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell		put_online_cpus();
325873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell	} else
326873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell		error = local_pci_probe(&ddi);
327d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen	return error;
328d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen}
329d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
33123ea3793fd368fd6a1ea20659699e280e2996658Randy Dunlap * __pci_device_probe - check if a driver wants to claim a specific PCI device
3328f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @drv: driver to call to check if it wants the PCI device
3338f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @pci_dev: PCI device being probed
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3358f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * returns 0 on success, else error.
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * side-effect: pci_dev->driver is set to drv when drv claims pci_dev.
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds__pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
34075865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman{
34175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman	const struct pci_device_id *id;
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int error = 0;
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!pci_dev->driver && drv->probe) {
34575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman		error = -ENODEV;
34675865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman
34775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman		id = pci_match_device(drv, pci_dev);
34875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman		if (id)
349d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen			error = pci_call_probe(drv, pci_dev, id);
35075865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman		if (error >= 0) {
35175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman			pci_dev->driver = drv;
35275865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman			error = 0;
35375865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman		}
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return error;
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int pci_device_probe(struct device * dev)
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int error = 0;
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pci_driver *drv;
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pci_dev *pci_dev;
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drv = to_pci_driver(dev->driver);
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pci_dev = to_pci_dev(dev);
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pci_dev_get(pci_dev);
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	error = __pci_device_probe(drv, pci_dev);
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (error)
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pci_dev_put(pci_dev);
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return error;
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int pci_device_remove(struct device * dev)
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pci_dev * pci_dev = to_pci_dev(dev);
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pci_driver * drv = pci_dev->driver;
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (drv) {
380f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern		if (drv->remove) {
381f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern			pm_runtime_get_sync(dev);
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			drv->remove(pci_dev);
383f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern			pm_runtime_put_noidle(dev);
384f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern		}
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pci_dev->driver = NULL;
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
388f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	/* Undo the runtime PM settings in local_pci_probe() */
389f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	pm_runtime_disable(dev);
390f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	pm_runtime_set_suspended(dev);
391f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern	pm_runtime_put_noidle(dev);
392f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
3942449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li	 * If the device is still on, set the power state as "unknown",
3952449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li	 * since it might change by the next time we load the driver.
3962449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li	 */
3972449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li	if (pci_dev->current_state == PCI_D0)
3982449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li		pci_dev->current_state = PCI_UNKNOWN;
3992449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li
4002449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li	/*
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * We would love to complain here if pci_dev->is_enabled is set, that
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * the driver should have called pci_disable_device(), but the
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * unfortunate fact is there are too many odd BIOS and bridge setups
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * that don't like drivers doing that all of the time.
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Oh well, we can dream of sane hardware when we sleep, no matter how
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * horrible the crap we have to deal with is when we are awake...
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pci_dev_put(pci_dev);
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
413bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic void pci_device_shutdown(struct device *dev)
414bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{
415bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	struct pci_dev *pci_dev = to_pci_dev(dev);
416bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	struct pci_driver *drv = pci_dev->driver;
417bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
418bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	if (drv && drv->shutdown)
419bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki		drv->shutdown(pci_dev);
420bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	pci_msi_shutdown(pci_dev);
421bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	pci_msix_shutdown(pci_dev);
4225b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki
4235b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki	/*
4245b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki	 * Devices may be enabled to wake up by runtime PM, but they need not
4255b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki	 * be supposed to wake up the system from its "power off" state (e.g.
4265b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki	 * ACPI S5).  Therefore disable wakeup for all devices that aren't
4275b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki	 * supposed to wake up the system at this point.  The state argument
4285b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki	 * will be ignored by pci_enable_wake().
4295b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki	 */
4305b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki	if (!device_may_wakeup(dev))
4315b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki		pci_enable_wake(pci_dev, PCI_UNKNOWN, false);
432bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}
433bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
434aa33860158114d0df3c7997bc1dd41c0168e1c2aRafael J. Wysocki#ifdef CONFIG_PM
4356cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
4366cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki/* Auxiliary functions used for system resume and run-time resume. */
4376cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
4386cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki/**
4396cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki * pci_restore_standard_config - restore standard config registers of PCI device
4406cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki * @pci_dev: PCI device to handle
4416cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki */
4426cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysockistatic int pci_restore_standard_config(struct pci_dev *pci_dev)
4436cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki{
4446cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	pci_update_current_state(pci_dev, PCI_UNKNOWN);
4456cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
4466cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	if (pci_dev->current_state != PCI_D0) {
4476cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki		int error = pci_set_power_state(pci_dev, PCI_D0);
4486cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki		if (error)
4496cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki			return error;
4506cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	}
4516cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
4521d3c16a818e992c199844954d95c17fd7ce6cbbaJon Mason	pci_restore_state(pci_dev);
4531d3c16a818e992c199844954d95c17fd7ce6cbbaJon Mason	return 0;
4546cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki}
4556cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
4566cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysockistatic void pci_pm_default_resume_early(struct pci_dev *pci_dev)
4576cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki{
4586cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	pci_restore_standard_config(pci_dev);
4596cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	pci_fixup_device(pci_fixup_resume_early, pci_dev);
4606cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki}
4616cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
4626cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#endif
4636cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
464bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#ifdef CONFIG_PM_SLEEP
465bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
466bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki/*
467bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki * Default "suspend" method for devices that have no driver provided suspend,
468fa58d305d9925b01830e535896a7227a868a9e15Rafael J. Wysocki * or not even a driver at all (second part).
469bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki */
470bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysockistatic void pci_pm_set_unknown_state(struct pci_dev *pci_dev)
471bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{
472bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	/*
473bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	 * mark its power state as "unknown", since we don't know if
474bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	 * e.g. the BIOS will change its device state when we suspend.
475bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	 */
476bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	if (pci_dev->current_state == PCI_D0)
477bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki		pci_dev->current_state = PCI_UNKNOWN;
478bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}
479bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
480bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki/*
481bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki * Default "resume" method for devices that have no driver provided resume,
482355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki * or not even a driver at all (second part).
483355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki */
484bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysockistatic int pci_pm_reenable_device(struct pci_dev *pci_dev)
485355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki{
486355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki	int retval;
487355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki
488bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	/* if the device was enabled before suspend, reenable */
489bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	retval = pci_reenable_device(pci_dev);
490bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	/*
491bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	 * if the device was busmaster before the suspend, make it busmaster
492bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	 * again
493bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	 */
494bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	if (pci_dev->is_busmaster)
495bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki		pci_set_master(pci_dev);
496bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
497bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	return retval;
498bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}
499bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
500bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_legacy_suspend(struct device *dev, pm_message_t state)
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pci_dev * pci_dev = to_pci_dev(dev);
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pci_driver * drv = pci_dev->driver;
50446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
505026694920579590c73b5c56705d543568ed5ad41Andrew Morton	if (drv && drv->suspend) {
50699dadce8756bf08f5f8baf749533d044f6b3ff25Rafael J. Wysocki		pci_power_t prev = pci_dev->current_state;
50746939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		int error;
508aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki
50957ef80266e14ecc363380268fedc64e519047b4aFrans Pop		error = drv->suspend(pci_dev, state);
51057ef80266e14ecc363380268fedc64e519047b4aFrans Pop		suspend_report_result(drv->suspend, error);
51157ef80266e14ecc363380268fedc64e519047b4aFrans Pop		if (error)
51257ef80266e14ecc363380268fedc64e519047b4aFrans Pop			return error;
513aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki
51446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
51599dadce8756bf08f5f8baf749533d044f6b3ff25Rafael J. Wysocki		    && pci_dev->current_state != PCI_UNKNOWN) {
51699dadce8756bf08f5f8baf749533d044f6b3ff25Rafael J. Wysocki			WARN_ONCE(pci_dev->current_state != prev,
51799dadce8756bf08f5f8baf749533d044f6b3ff25Rafael J. Wysocki				"PCI PM: Device state not saved by %pF\n",
51899dadce8756bf08f5f8baf749533d044f6b3ff25Rafael J. Wysocki				drv->suspend);
51999dadce8756bf08f5f8baf749533d044f6b3ff25Rafael J. Wysocki		}
520026694920579590c73b5c56705d543568ed5ad41Andrew Morton	}
521ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki
522ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki	pci_fixup_device(pci_fixup_suspend, pci_dev);
523ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki
52446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	return 0;
5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
527bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
528cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds{
529cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds	struct pci_dev * pci_dev = to_pci_dev(dev);
530cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds	struct pci_driver * drv = pci_dev->driver;
531cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds
532cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds	if (drv && drv->suspend_late) {
53346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		pci_power_t prev = pci_dev->current_state;
53446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		int error;
53546939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
53657ef80266e14ecc363380268fedc64e519047b4aFrans Pop		error = drv->suspend_late(pci_dev, state);
53757ef80266e14ecc363380268fedc64e519047b4aFrans Pop		suspend_report_result(drv->suspend_late, error);
53846939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		if (error)
53946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki			return error;
54046939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
54146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
54246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		    && pci_dev->current_state != PCI_UNKNOWN) {
54346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki			WARN_ONCE(pci_dev->current_state != prev,
54446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki				"PCI PM: Device state not saved by %pF\n",
54546939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki				drv->suspend_late);
54646939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki			return 0;
54746939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		}
548cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds	}
54946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
55046939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	if (!pci_dev->state_saved)
55146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		pci_save_state(pci_dev);
55246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
55346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	pci_pm_set_unknown_state(pci_dev);
55446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
55546939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	return 0;
556cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds}
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
558f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysockistatic int pci_legacy_resume_early(struct device *dev)
559f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki{
560f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki	struct pci_dev * pci_dev = to_pci_dev(dev);
561f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki	struct pci_driver * drv = pci_dev->driver;
562f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki
563aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki	return drv && drv->resume_early ?
564aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki			drv->resume_early(pci_dev) : 0;
565f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki}
566f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki
567bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_legacy_resume(struct device *dev)
5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pci_dev * pci_dev = to_pci_dev(dev);
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pci_driver * drv = pci_dev->driver;
5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
572ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki	pci_fixup_device(pci_fixup_resume, pci_dev);
573ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki
574aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki	return drv && drv->resume ?
575aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki			drv->resume(pci_dev) : pci_pm_reenable_device(pci_dev);
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
578571ff7584bb9e05fca0eb79752ae55a46faf3a98Rafael J. Wysocki/* Auxiliary functions used by the new power management framework */
579571ff7584bb9e05fca0eb79752ae55a46faf3a98Rafael J. Wysocki
5805294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysockistatic void pci_pm_default_resume(struct pci_dev *pci_dev)
581571ff7584bb9e05fca0eb79752ae55a46faf3a98Rafael J. Wysocki{
582734104292ff77dc71fe626b4ebd91b314547ca1bRafael J. Wysocki	pci_fixup_device(pci_fixup_resume, pci_dev);
583734104292ff77dc71fe626b4ebd91b314547ca1bRafael J. Wysocki
5845294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	if (!pci_is_bridge(pci_dev))
5855294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		pci_enable_wake(pci_dev, PCI_D0, false);
586571ff7584bb9e05fca0eb79752ae55a46faf3a98Rafael J. Wysocki}
587571ff7584bb9e05fca0eb79752ae55a46faf3a98Rafael J. Wysocki
5885294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysockistatic void pci_pm_default_suspend(struct pci_dev *pci_dev)
589734104292ff77dc71fe626b4ebd91b314547ca1bRafael J. Wysocki{
5905294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	/* Disable non-bridge devices without PM support */
591cbbc2f6b0d438f80831c20124137ea92f0e5149bRafael J. Wysocki	if (!pci_is_bridge(pci_dev))
592cbbc2f6b0d438f80831c20124137ea92f0e5149bRafael J. Wysocki		pci_disable_enabled_device(pci_dev);
593734104292ff77dc71fe626b4ebd91b314547ca1bRafael J. Wysocki}
594734104292ff77dc71fe626b4ebd91b314547ca1bRafael J. Wysocki
59507e836e8d1f3688311d97fe1bf46980b0f9ae9c1Rafael J. Wysockistatic bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
59607e836e8d1f3688311d97fe1bf46980b0f9ae9c1Rafael J. Wysocki{
59707e836e8d1f3688311d97fe1bf46980b0f9ae9c1Rafael J. Wysocki	struct pci_driver *drv = pci_dev->driver;
598bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki	bool ret = drv && (drv->suspend || drv->suspend_late || drv->resume
59907e836e8d1f3688311d97fe1bf46980b0f9ae9c1Rafael J. Wysocki		|| drv->resume_early);
600bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki
601bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki	/*
602bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki	 * Legacy PM support is used by default, so warn if the new framework is
603bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki	 * supported as well.  Drivers are supposed to support either the
604bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki	 * former, or the latter, but not both at the same time.
605bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki	 */
60682440a8253e09047410ff4df5c202be15645573fDavid Fries	WARN(ret && drv->driver.pm, "driver %s device %04x:%04x\n",
60782440a8253e09047410ff4df5c202be15645573fDavid Fries		drv->name, pci_dev->vendor, pci_dev->device);
608bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki
609bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki	return ret;
61007e836e8d1f3688311d97fe1bf46980b0f9ae9c1Rafael J. Wysocki}
61107e836e8d1f3688311d97fe1bf46980b0f9ae9c1Rafael J. Wysocki
612571ff7584bb9e05fca0eb79752ae55a46faf3a98Rafael J. Wysocki/* New power management framework */
613571ff7584bb9e05fca0eb79752ae55a46faf3a98Rafael J. Wysocki
614bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_prepare(struct device *dev)
615bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{
616bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	struct device_driver *drv = dev->driver;
617bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	int error = 0;
618bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
6196cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	/*
620eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki	 * If a PCI device configured to wake up the system from sleep states
621eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki	 * has been suspended at run time and there's a resume request pending
622eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki	 * for it, this is equivalent to the device signaling wakeup, so the
623eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki	 * system suspend operation should be aborted.
624eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki	 */
625eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki	pm_runtime_get_noresume(dev);
626eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki	if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
627eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki		pm_wakeup_event(dev, 0);
628eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki
629eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki	if (pm_wakeup_pending()) {
630eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki		pm_runtime_put_sync(dev);
631eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki		return -EBUSY;
632eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki	}
633eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki
634eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki	/*
6356cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	 * PCI devices suspended at run time need to be resumed at this
6366cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	 * point, because in general it is necessary to reconfigure them for
6376cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	 * system suspend.  Namely, if the device is supposed to wake up the
6386cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	 * system from the sleep state, we may need to reconfigure it for this
6396cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	 * purpose.  In turn, if the device is not supposed to wake up the
6406cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	 * system from the sleep state, we'll have to prevent it from signaling
6416cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	 * wake-up.
6426cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	 */
643eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki	pm_runtime_resume(dev);
6446cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
645bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	if (drv && drv->pm && drv->pm->prepare)
646bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki		error = drv->pm->prepare(dev);
647bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
648bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	return error;
649bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}
650bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
651bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic void pci_pm_complete(struct device *dev)
652bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{
653bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	struct device_driver *drv = dev->driver;
654bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
655bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	if (drv && drv->pm && drv->pm->complete)
656bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki		drv->pm->complete(dev);
657a5f76d5eba157bf637beb2dd18026db2917c512eRafael J. Wysocki
658a5f76d5eba157bf637beb2dd18026db2917c512eRafael J. Wysocki	pm_runtime_put_sync(dev);
659bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}
660bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
6616cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#else /* !CONFIG_PM_SLEEP */
6626cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
6636cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#define pci_pm_prepare	NULL
6646cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#define pci_pm_complete	NULL
6656cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
6666cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#endif /* !CONFIG_PM_SLEEP */
6676cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
668bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#ifdef CONFIG_SUSPEND
669bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
670bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_suspend(struct device *dev)
671bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{
672bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	struct pci_dev *pci_dev = to_pci_dev(dev);
6738150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhov	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
674bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
675ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki	if (pci_has_legacy_pm_support(pci_dev))
676ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki		return pci_legacy_suspend(dev, PMSG_SUSPEND);
677bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki
6785294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	if (!pm) {
6795294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		pci_pm_default_suspend(pci_dev);
6805294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		goto Fixup;
6815294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	}
6825294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki
6835294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	if (pm->suspend) {
6845294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		pci_power_t prev = pci_dev->current_state;
6855294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		int error;
6865294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki
687ddb7c9d29fac34626aef2af9f19787a888e4ca9cRafael J. Wysocki		error = pm->suspend(dev);
688ddb7c9d29fac34626aef2af9f19787a888e4ca9cRafael J. Wysocki		suspend_report_result(pm->suspend, error);
6895294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		if (error)
6905294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki			return error;
6915294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki
69246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
6935294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		    && pci_dev->current_state != PCI_UNKNOWN) {
6945294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki			WARN_ONCE(pci_dev->current_state != prev,
6955294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki				"PCI PM: State of device not saved by %pF\n",
6965294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki				pm->suspend);
6975294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		}
698bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	}
699fa58d305d9925b01830e535896a7227a868a9e15Rafael J. Wysocki
7005294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki Fixup:
7015294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	pci_fixup_device(pci_fixup_suspend, pci_dev);
7025294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki
7035294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	return 0;
704bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}
705bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
706bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_suspend_noirq(struct device *dev)
707c8958177224622411b9979eabb5610e30b06034bGreg Kroah-Hartman{
708355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki	struct pci_dev *pci_dev = to_pci_dev(dev);
7098150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhov	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
710c8958177224622411b9979eabb5610e30b06034bGreg Kroah-Hartman
711bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki	if (pci_has_legacy_pm_support(pci_dev))
712bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki		return pci_legacy_suspend_late(dev, PMSG_SUSPEND);
713bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki
714931ff68a5a53fa84bcdf9b1b179a80e54e034bd0Rafael J. Wysocki	if (!pm) {
715931ff68a5a53fa84bcdf9b1b179a80e54e034bd0Rafael J. Wysocki		pci_save_state(pci_dev);
71646939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		return 0;
717931ff68a5a53fa84bcdf9b1b179a80e54e034bd0Rafael J. Wysocki	}
71846939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
71946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	if (pm->suspend_noirq) {
72046939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		pci_power_t prev = pci_dev->current_state;
72146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		int error;
72246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
72346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		error = pm->suspend_noirq(dev);
72446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		suspend_report_result(pm->suspend_noirq, error);
72546939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		if (error)
72646939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki			return error;
72746939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
72846939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
72946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		    && pci_dev->current_state != PCI_UNKNOWN) {
73046939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki			WARN_ONCE(pci_dev->current_state != prev,
73146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki				"PCI PM: State of device not saved by %pF\n",
73246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki				pm->suspend_noirq);
73346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki			return 0;
73446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		}
735bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	}
736bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
73746939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	if (!pci_dev->state_saved) {
73846939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		pci_save_state(pci_dev);
73946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		if (!pci_is_bridge(pci_dev))
74046939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki			pci_prepare_to_sleep(pci_dev);
74146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	}
742d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki
74346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	pci_pm_set_unknown_state(pci_dev);
74446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
7450659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern	/*
7460659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern	 * Some BIOSes from ASUS have a bug: If a USB EHCI host controller's
7470659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern	 * PCI COMMAND register isn't 0, the BIOS assumes that the controller
7480659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern	 * hasn't been quiesced and tries to turn it off.  If the controller
7490659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern	 * is already in D3, this can hang or cause memory corruption.
7500659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern	 *
7510659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern	 * Since the value of the COMMAND register doesn't matter once the
7520659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern	 * device has been suspended, we can safely set it to 0 here.
7530659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern	 */
7540659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern	if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI)
7550659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern		pci_write_config_word(pci_dev, PCI_COMMAND, 0);
7560659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern
75746939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	return 0;
758c8958177224622411b9979eabb5610e30b06034bGreg Kroah-Hartman}
7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
760f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysockistatic int pci_pm_resume_noirq(struct device *dev)
761bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{
762bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	struct pci_dev *pci_dev = to_pci_dev(dev);
763bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	struct device_driver *drv = dev->driver;
764355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki	int error = 0;
765bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
7666cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	pci_pm_default_resume_early(pci_dev);
767aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki
768ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki	if (pci_has_legacy_pm_support(pci_dev))
769f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki		return pci_legacy_resume_early(dev);
770bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki
771f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki	if (drv && drv->pm && drv->pm->resume_noirq)
772f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki		error = drv->pm->resume_noirq(dev);
773bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
774bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	return error;
775bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}
776bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
777f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysockistatic int pci_pm_resume(struct device *dev)
778bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{
779355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki	struct pci_dev *pci_dev = to_pci_dev(dev);
7808150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhov	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
781bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	int error = 0;
782bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
783418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki	/*
784418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki	 * This is necessary for the suspend error path in which resume is
785418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki	 * called without restoring the standard config registers of the device.
786418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki	 */
787418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki	if (pci_dev->state_saved)
788418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki		pci_restore_standard_config(pci_dev);
789418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki
790ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki	if (pci_has_legacy_pm_support(pci_dev))
791f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki		return pci_legacy_resume(dev);
792bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki
7935294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	pci_pm_default_resume(pci_dev);
794734104292ff77dc71fe626b4ebd91b314547ca1bRafael J. Wysocki
7955294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	if (pm) {
7965294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		if (pm->resume)
7975294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki			error = pm->resume(dev);
7985294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	} else {
7995294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		pci_pm_reenable_device(pci_dev);
8005294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	}
801bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
802999cce4a52d5abdda5d2cec6bac241899bc19e4cRafael J. Wysocki	return error;
803bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}
804bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
805bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#else /* !CONFIG_SUSPEND */
806bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
807bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_suspend		NULL
808bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_suspend_noirq	NULL
809bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_resume		NULL
810bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_resume_noirq	NULL
811bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
812bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#endif /* !CONFIG_SUSPEND */
813bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
8141f112cee07b314e244ee9e71d9c1e6950dc13327Rafael J. Wysocki#ifdef CONFIG_HIBERNATE_CALLBACKS
815bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
816bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_freeze(struct device *dev)
817bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{
818bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	struct pci_dev *pci_dev = to_pci_dev(dev);
8198150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhov	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
820bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
821ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki	if (pci_has_legacy_pm_support(pci_dev))
822ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki		return pci_legacy_suspend(dev, PMSG_FREEZE);
823bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki
8245294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	if (!pm) {
8255294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		pci_pm_default_suspend(pci_dev);
8265294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		return 0;
827bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	}
828bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
8295294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	if (pm->freeze) {
8305294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		int error;
8315294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki
8325294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		error = pm->freeze(dev);
8335294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		suspend_report_result(pm->freeze, error);
8345294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		if (error)
8355294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki			return error;
8365294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	}
8375294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki
8385294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	return 0;
839bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}
840bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
841bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_freeze_noirq(struct device *dev)
842bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{
843355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki	struct pci_dev *pci_dev = to_pci_dev(dev);
844adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki	struct device_driver *drv = dev->driver;
845bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
846bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki	if (pci_has_legacy_pm_support(pci_dev))
847bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki		return pci_legacy_suspend_late(dev, PMSG_FREEZE);
848bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki
849d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki	if (drv && drv->pm && drv->pm->freeze_noirq) {
85046939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		int error;
85146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
852d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki		error = drv->pm->freeze_noirq(dev);
853d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki		suspend_report_result(drv->pm->freeze_noirq, error);
85446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		if (error)
85546939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki			return error;
856bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	}
857bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
85846939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	if (!pci_dev->state_saved)
85946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		pci_save_state(pci_dev);
860d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki
86146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	pci_pm_set_unknown_state(pci_dev);
86246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
86346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	return 0;
864bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}
865bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
866f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysockistatic int pci_pm_thaw_noirq(struct device *dev)
867bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{
868355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki	struct pci_dev *pci_dev = to_pci_dev(dev);
869bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	struct device_driver *drv = dev->driver;
870bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	int error = 0;
871bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
872ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki	if (pci_has_legacy_pm_support(pci_dev))
873f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki		return pci_legacy_resume_early(dev);
874bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki
875f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki	pci_update_current_state(pci_dev, PCI_D0);
876d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki
877f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki	if (drv && drv->pm && drv->pm->thaw_noirq)
878f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki		error = drv->pm->thaw_noirq(dev);
879bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
880bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	return error;
881bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}
882bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
883f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysockistatic int pci_pm_thaw(struct device *dev)
884bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{
885355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki	struct pci_dev *pci_dev = to_pci_dev(dev);
8868150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhov	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
887bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	int error = 0;
888bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
889ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki	if (pci_has_legacy_pm_support(pci_dev))
890f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki		return pci_legacy_resume(dev);
891bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki
8925294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	if (pm) {
8935294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		if (pm->thaw)
8945294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki			error = pm->thaw(dev);
8955294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	} else {
8965294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		pci_pm_reenable_device(pci_dev);
8975294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	}
898bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
8994b77b0a2ba27d64f58f16d8d4d48d8319dda36ffRafael J. Wysocki	pci_dev->state_saved = false;
9004b77b0a2ba27d64f58f16d8d4d48d8319dda36ffRafael J. Wysocki
901bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	return error;
902bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}
903bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
904bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_poweroff(struct device *dev)
905bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{
906355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki	struct pci_dev *pci_dev = to_pci_dev(dev);
9078150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhov	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
908bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
909ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki	if (pci_has_legacy_pm_support(pci_dev))
910ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki		return pci_legacy_suspend(dev, PMSG_HIBERNATE);
911bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki
9125294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	if (!pm) {
9135294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		pci_pm_default_suspend(pci_dev);
9145294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		goto Fixup;
9155294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	}
9165294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki
9175294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	if (pm->poweroff) {
91846939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		int error;
91946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
920ddb7c9d29fac34626aef2af9f19787a888e4ca9cRafael J. Wysocki		error = pm->poweroff(dev);
921ddb7c9d29fac34626aef2af9f19787a888e4ca9cRafael J. Wysocki		suspend_report_result(pm->poweroff, error);
92246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		if (error)
92346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki			return error;
924bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	}
925bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
9265294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki Fixup:
9275294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	pci_fixup_device(pci_fixup_suspend, pci_dev);
928c9b9972b3c88272be02d971346285d1c67fbb95fRafael J. Wysocki
92946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	return 0;
930bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}
931bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
932bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_poweroff_noirq(struct device *dev)
933bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{
93446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	struct pci_dev *pci_dev = to_pci_dev(dev);
935adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki	struct device_driver *drv = dev->driver;
936bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
937bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki	if (pci_has_legacy_pm_support(to_pci_dev(dev)))
938bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki		return pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
939bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki
94046939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	if (!drv || !drv->pm)
94146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		return 0;
94246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
94346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	if (drv->pm->poweroff_noirq) {
94446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		int error;
94546939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
946d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki		error = drv->pm->poweroff_noirq(dev);
947d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki		suspend_report_result(drv->pm->poweroff_noirq, error);
94846939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		if (error)
94946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki			return error;
950bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	}
951bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
95246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
95346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki		pci_prepare_to_sleep(pci_dev);
95446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki
95546939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki	return 0;
956bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}
957bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
958f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysockistatic int pci_pm_restore_noirq(struct device *dev)
959bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{
960bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	struct pci_dev *pci_dev = to_pci_dev(dev);
961bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	struct device_driver *drv = dev->driver;
962355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki	int error = 0;
963bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
9646cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	pci_pm_default_resume_early(pci_dev);
965aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki
966ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki	if (pci_has_legacy_pm_support(pci_dev))
967f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki		return pci_legacy_resume_early(dev);
968bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki
969f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki	if (drv && drv->pm && drv->pm->restore_noirq)
970f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki		error = drv->pm->restore_noirq(dev);
971bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
972bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	return error;
973bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}
974bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
975f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysockistatic int pci_pm_restore(struct device *dev)
976bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{
977bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	struct pci_dev *pci_dev = to_pci_dev(dev);
9788150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhov	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
979bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	int error = 0;
980bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
981418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki	/*
982418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki	 * This is necessary for the hibernation error path in which restore is
983418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki	 * called without restoring the standard config registers of the device.
984418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki	 */
985418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki	if (pci_dev->state_saved)
986418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki		pci_restore_standard_config(pci_dev);
987418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki
988ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki	if (pci_has_legacy_pm_support(pci_dev))
989f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki		return pci_legacy_resume(dev);
990bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki
9915294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	pci_pm_default_resume(pci_dev);
992734104292ff77dc71fe626b4ebd91b314547ca1bRafael J. Wysocki
9935294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	if (pm) {
9945294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		if (pm->restore)
9955294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki			error = pm->restore(dev);
9965294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	} else {
9975294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki		pci_pm_reenable_device(pci_dev);
9985294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki	}
999bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
1000bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	return error;
1001c8958177224622411b9979eabb5610e30b06034bGreg Kroah-Hartman}
10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10031f112cee07b314e244ee9e71d9c1e6950dc13327Rafael J. Wysocki#else /* !CONFIG_HIBERNATE_CALLBACKS */
1004bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
1005bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_freeze		NULL
1006bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_freeze_noirq	NULL
1007bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_thaw		NULL
1008bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_thaw_noirq	NULL
1009bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_poweroff		NULL
1010bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_poweroff_noirq	NULL
1011bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_restore		NULL
1012bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_restore_noirq	NULL
1013bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
10141f112cee07b314e244ee9e71d9c1e6950dc13327Rafael J. Wysocki#endif /* !CONFIG_HIBERNATE_CALLBACKS */
1015bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
10166cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#ifdef CONFIG_PM_RUNTIME
10176cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10186cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysockistatic int pci_pm_runtime_suspend(struct device *dev)
10196cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki{
10206cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	struct pci_dev *pci_dev = to_pci_dev(dev);
10216cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
10226cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	pci_power_t prev = pci_dev->current_state;
10236cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	int error;
10246cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10256cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	if (!pm || !pm->runtime_suspend)
10266cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki		return -ENOSYS;
10276cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10286cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	error = pm->runtime_suspend(dev);
10296cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	suspend_report_result(pm->runtime_suspend, error);
10306cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	if (error)
10316cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki		return error;
10326cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10336cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	pci_fixup_device(pci_fixup_suspend, pci_dev);
10346cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10356cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
10366cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	    && pci_dev->current_state != PCI_UNKNOWN) {
10376cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki		WARN_ONCE(pci_dev->current_state != prev,
10386cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki			"PCI PM: State of device not saved by %pF\n",
10396cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki			pm->runtime_suspend);
10406cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki		return 0;
10416cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	}
10426cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10436cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	if (!pci_dev->state_saved)
10446cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki		pci_save_state(pci_dev);
10456cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10466cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	pci_finish_runtime_suspend(pci_dev);
10476cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10486cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	return 0;
10496cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki}
10506cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10516cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysockistatic int pci_pm_runtime_resume(struct device *dev)
10526cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki{
10536cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	struct pci_dev *pci_dev = to_pci_dev(dev);
10546cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
10556cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10566cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	if (!pm || !pm->runtime_resume)
10576cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki		return -ENOSYS;
10586cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10596cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	pci_pm_default_resume_early(pci_dev);
10606cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	__pci_enable_wake(pci_dev, PCI_D0, true, false);
10616cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	pci_fixup_device(pci_fixup_resume, pci_dev);
10626cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10636cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	return pm->runtime_resume(dev);
10646cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki}
10656cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10666cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysockistatic int pci_pm_runtime_idle(struct device *dev)
10676cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki{
10686cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
10696cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10706cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	if (!pm)
10716cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki		return -ENOSYS;
10726cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10736cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	if (pm->runtime_idle) {
10746cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki		int ret = pm->runtime_idle(dev);
10756cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki		if (ret)
10766cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki			return ret;
10776cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	}
10786cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10796cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	pm_runtime_suspend(dev);
10806cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10816cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	return 0;
10826cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki}
10836cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10846cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#else /* !CONFIG_PM_RUNTIME */
10856cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10866cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#define pci_pm_runtime_suspend	NULL
10876cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#define pci_pm_runtime_resume	NULL
10886cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#define pci_pm_runtime_idle	NULL
10896cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10906cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#endif /* !CONFIG_PM_RUNTIME */
10916cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
1092aa33860158114d0df3c7997bc1dd41c0168e1c2aRafael J. Wysocki#ifdef CONFIG_PM
10936cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki
10948150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhovconst struct dev_pm_ops pci_dev_pm_ops = {
1095adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki	.prepare = pci_pm_prepare,
1096adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki	.complete = pci_pm_complete,
1097adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki	.suspend = pci_pm_suspend,
1098adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki	.resume = pci_pm_resume,
1099adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki	.freeze = pci_pm_freeze,
1100adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki	.thaw = pci_pm_thaw,
1101adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki	.poweroff = pci_pm_poweroff,
1102adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki	.restore = pci_pm_restore,
1103bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	.suspend_noirq = pci_pm_suspend_noirq,
1104bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	.resume_noirq = pci_pm_resume_noirq,
1105bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	.freeze_noirq = pci_pm_freeze_noirq,
1106bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	.thaw_noirq = pci_pm_thaw_noirq,
1107bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	.poweroff_noirq = pci_pm_poweroff_noirq,
1108bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	.restore_noirq = pci_pm_restore_noirq,
11096cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	.runtime_suspend = pci_pm_runtime_suspend,
11106cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	.runtime_resume = pci_pm_runtime_resume,
11116cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki	.runtime_idle = pci_pm_runtime_idle,
1112bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki};
1113bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
1114adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki#define PCI_PM_OPS_PTR	(&pci_dev_pm_ops)
1115bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
11166cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#else /* !COMFIG_PM_OPS */
1117bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
1118bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define PCI_PM_OPS_PTR	NULL
1119bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
11206cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#endif /* !COMFIG_PM_OPS */
1121bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki
11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
1123863b18f4b5e7d9e6903b353328cf6fa084dbb619Laurent riffard * __pci_register_driver - register a new pci driver
11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @drv: the driver structure to register
1125863b18f4b5e7d9e6903b353328cf6fa084dbb619Laurent riffard * @owner: owner module of drv
1126f95d882d81ee731be2a4a3b34f86810e29b68836Randy Dunlap * @mod_name: module name string
11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Adds the driver structure to the list of registered drivers.
11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns a negative value on error, otherwise 0.
1130eaae4b3a84a3781543a32bcaf0a33306ae915574Steven Cole * If no error occurred, the driver remains registered even if
11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * no device was claimed during registration.
11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1133725522b5453dd680412f2b6463a988e4fd148757Greg Kroah-Hartmanint __pci_register_driver(struct pci_driver *drv, struct module *owner,
1134725522b5453dd680412f2b6463a988e4fd148757Greg Kroah-Hartman			  const char *mod_name)
11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int error;
11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* initialize common driver fields */
11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drv->driver.name = drv->name;
11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drv->driver.bus = &pci_bus_type;
1141863b18f4b5e7d9e6903b353328cf6fa084dbb619Laurent riffard	drv->driver.owner = owner;
1142725522b5453dd680412f2b6463a988e4fd148757Greg Kroah-Hartman	drv->driver.mod_name = mod_name;
114350b0075520a0acba9cabab5203bbce918b966d9aAlan Cox
114475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman	spin_lock_init(&drv->dynids.lock);
114575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman	INIT_LIST_HEAD(&drv->dynids.list);
11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* register with core */
11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	error = driver_register(&drv->driver);
114950bf14b3ff05fb6e10688021b96f95d30a300f8dAkinobu Mita	if (error)
11500994375e9614f78657031e04e30019b9cdb62795Chris Wright		goto out;
11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1152ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern	error = pci_create_newid_files(drv);
115350bf14b3ff05fb6e10688021b96f95d30a300f8dAkinobu Mita	if (error)
11540994375e9614f78657031e04e30019b9cdb62795Chris Wright		goto out_newid;
11550994375e9614f78657031e04e30019b9cdb62795Chris Wrightout:
11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return error;
11570994375e9614f78657031e04e30019b9cdb62795Chris Wright
11580994375e9614f78657031e04e30019b9cdb62795Chris Wrightout_newid:
11590994375e9614f78657031e04e30019b9cdb62795Chris Wright	driver_unregister(&drv->driver);
11600994375e9614f78657031e04e30019b9cdb62795Chris Wright	goto out;
11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_unregister_driver - unregister a pci driver
11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @drv: the driver structure to unregister
11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Deletes the driver structure from the list of registered PCI drivers,
11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * gives it a chance to clean up by calling its remove() function for
11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * each device it was responsible for, and marks those devices as
11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * driverless.
11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspci_unregister_driver(struct pci_driver *drv)
11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1176ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern	pci_remove_newid_files(drv);
11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	driver_unregister(&drv->driver);
11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pci_free_dynids(drv);
11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pci_driver pci_compat_driver = {
11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.name = "compat"
11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_dev_driver - get the pci_driver of a device
11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @dev: the device to query
11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns the appropriate pci_driver structure or %NULL if there is no
11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * registered driver for the device.
11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct pci_driver *
11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspci_dev_driver(const struct pci_dev *dev)
11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dev->driver)
11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return dev->driver;
11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else {
11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int i;
11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for(i=0; i<=PCI_ROM_RESOURCE; i++)
12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (dev->resource[i].flags & IORESOURCE_BUSY)
12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return &pci_compat_driver;
12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return NULL;
12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_bus_match - Tell if a PCI device structure has a matching PCI device id structure
12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @dev: the PCI device structure to match against
12098f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @drv: the device driver to search for matching PCI device id structures
12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Used by a driver to check whether a PCI device present in the
12128f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * system is in its list of supported devices. Returns the matching
12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_device_id structure or %NULL if there is no match.
12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
121575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartmanstatic int pci_bus_match(struct device *dev, struct device_driver *drv)
12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
121775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman	struct pci_dev *pci_dev = to_pci_dev(dev);
121875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman	struct pci_driver *pci_drv = to_pci_driver(drv);
12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	const struct pci_device_id *found_id;
12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
122175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman	found_id = pci_match_device(pci_drv, pci_dev);
12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (found_id)
12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 1;
12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
122575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman	return 0;
12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_dev_get - increments the reference count of the pci device structure
12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @dev: the device being referenced
12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Each live reference to a device should be refcounted.
12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Drivers for PCI devices should normally record such references in
12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * their probe() methods, when they bind to a device, and release
12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * them by calling pci_dev_put(), in their disconnect() methods.
12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A pointer to the device with the incremented reference counter is returned.
12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct pci_dev *pci_dev_get(struct pci_dev *dev)
12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dev)
12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		get_device(&dev->dev);
12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return dev;
12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_dev_put - release a use of the pci device structure
12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @dev: device that's been disconnected
12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Must be called when a user of a device is finished with it.  When the last
12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * user of the device calls this function, the memory of the device is freed.
12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid pci_dev_put(struct pci_dev *dev)
12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dev)
12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		put_device(&dev->dev);
12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef CONFIG_HOTPLUG
12617eff2e7a8b65c25920207324e56611150eb1cd9aKay Sieversint pci_uevent(struct device *dev, struct kobj_uevent_env *env)
12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return -ENODEV;
12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct bus_type pci_bus_type = {
12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.name		= "pci",
12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.match		= pci_bus_match,
1270312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers	.uevent		= pci_uevent,
1271b15d686a2b589c9e4f1ea116553e9c3c3d030daeRussell King	.probe		= pci_device_probe,
1272b15d686a2b589c9e4f1ea116553e9c3c3d030daeRussell King	.remove		= pci_device_remove,
1273cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds	.shutdown	= pci_device_shutdown,
12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.dev_attrs	= pci_dev_attrs,
1275705b1aaa823e800490f157cd9366ad8cff385f5fAlex Chiang	.bus_attrs	= pci_bus_attrs,
1276bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki	.pm		= PCI_PM_OPS_PTR,
12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init pci_driver_init(void)
12801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return bus_register(&pci_bus_type);
12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspostcore_initcall(pci_driver_init);
12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12869dba910e9de2c4aa15ec1286f10052c107ef48caTejun HeoEXPORT_SYMBOL_GPL(pci_add_dynid);
128775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-HartmanEXPORT_SYMBOL(pci_match_id);
1288863b18f4b5e7d9e6903b353328cf6fa084dbb619Laurent riffardEXPORT_SYMBOL(__pci_register_driver);
12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(pci_unregister_driver);
12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(pci_dev_driver);
12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(pci_bus_type);
12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(pci_dev_get);
12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(pci_dev_put);
1294