xref: /openbmc/linux/drivers/pci/pci-driver.c (revision 89cdbc3546354c359558a1809133902028c57da4)
18cfab3cfSBjorn Helgaas // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
32b937303SGreg Kroah-Hartman  * (C) Copyright 2002-2004, 2007 Greg Kroah-Hartman <greg@kroah.com>
42b937303SGreg Kroah-Hartman  * (C) Copyright 2007 Novell Inc.
51da177e4SLinus Torvalds  */
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds #include <linux/pci.h>
81da177e4SLinus Torvalds #include <linux/module.h>
91da177e4SLinus Torvalds #include <linux/init.h>
101da177e4SLinus Torvalds #include <linux/device.h>
11d42c6997SAndi Kleen #include <linux/mempolicy.h>
124e57b681STim Schmielau #include <linux/string.h>
134e57b681STim Schmielau #include <linux/slab.h>
148c65b4a6STim Schmielau #include <linux/sched.h>
15873392caSRusty Russell #include <linux/cpu.h>
166cbf8214SRafael J. Wysocki #include <linux/pm_runtime.h>
17eea3fc03SRafael J. Wysocki #include <linux/suspend.h>
184fc9bbf9SKhalid Aziz #include <linux/kexec.h>
1907397df2SNipun Gupta #include <linux/of_device.h>
2007397df2SNipun Gupta #include <linux/acpi.h>
211da177e4SLinus Torvalds #include "pci.h"
22c6c889d9SBjorn Helgaas #include "pcie/portdrv.h"
231da177e4SLinus Torvalds 
2475865858SGreg Kroah-Hartman struct pci_dynid {
2575865858SGreg Kroah-Hartman 	struct list_head node;
2675865858SGreg Kroah-Hartman 	struct pci_device_id id;
2775865858SGreg Kroah-Hartman };
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds /**
309dba910eSTejun Heo  * pci_add_dynid - add a new PCI device ID to this driver and re-probe devices
319dba910eSTejun Heo  * @drv: target pci driver
329dba910eSTejun Heo  * @vendor: PCI vendor ID
339dba910eSTejun Heo  * @device: PCI device ID
349dba910eSTejun Heo  * @subvendor: PCI subvendor ID
359dba910eSTejun Heo  * @subdevice: PCI subdevice ID
369dba910eSTejun Heo  * @class: PCI class
379dba910eSTejun Heo  * @class_mask: PCI class mask
389dba910eSTejun Heo  * @driver_data: private driver data
399dba910eSTejun Heo  *
409dba910eSTejun Heo  * Adds a new dynamic pci device ID to this driver and causes the
419dba910eSTejun Heo  * driver to probe for all devices again.  @drv must have been
429dba910eSTejun Heo  * registered prior to calling this function.
439dba910eSTejun Heo  *
449dba910eSTejun Heo  * CONTEXT:
459dba910eSTejun Heo  * Does GFP_KERNEL allocation.
469dba910eSTejun Heo  *
479dba910eSTejun Heo  * RETURNS:
489dba910eSTejun Heo  * 0 on success, -errno on failure.
499dba910eSTejun Heo  */
509dba910eSTejun Heo int pci_add_dynid(struct pci_driver *drv,
519dba910eSTejun Heo 		  unsigned int vendor, unsigned int device,
529dba910eSTejun Heo 		  unsigned int subvendor, unsigned int subdevice,
539dba910eSTejun Heo 		  unsigned int class, unsigned int class_mask,
549dba910eSTejun Heo 		  unsigned long driver_data)
559dba910eSTejun Heo {
569dba910eSTejun Heo 	struct pci_dynid *dynid;
579dba910eSTejun Heo 
589dba910eSTejun Heo 	dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
599dba910eSTejun Heo 	if (!dynid)
609dba910eSTejun Heo 		return -ENOMEM;
619dba910eSTejun Heo 
629dba910eSTejun Heo 	dynid->id.vendor = vendor;
639dba910eSTejun Heo 	dynid->id.device = device;
649dba910eSTejun Heo 	dynid->id.subvendor = subvendor;
659dba910eSTejun Heo 	dynid->id.subdevice = subdevice;
669dba910eSTejun Heo 	dynid->id.class = class;
679dba910eSTejun Heo 	dynid->id.class_mask = class_mask;
689dba910eSTejun Heo 	dynid->id.driver_data = driver_data;
699dba910eSTejun Heo 
709dba910eSTejun Heo 	spin_lock(&drv->dynids.lock);
719dba910eSTejun Heo 	list_add_tail(&dynid->node, &drv->dynids.list);
729dba910eSTejun Heo 	spin_unlock(&drv->dynids.lock);
739dba910eSTejun Heo 
743b7f1016STobias Klauser 	return driver_attach(&drv->driver);
759dba910eSTejun Heo }
76b7fe9434SRyan Desfosses EXPORT_SYMBOL_GPL(pci_add_dynid);
779dba910eSTejun Heo 
789dba910eSTejun Heo static void pci_free_dynids(struct pci_driver *drv)
799dba910eSTejun Heo {
809dba910eSTejun Heo 	struct pci_dynid *dynid, *n;
819dba910eSTejun Heo 
829dba910eSTejun Heo 	spin_lock(&drv->dynids.lock);
839dba910eSTejun Heo 	list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
849dba910eSTejun Heo 		list_del(&dynid->node);
859dba910eSTejun Heo 		kfree(dynid);
869dba910eSTejun Heo 	}
879dba910eSTejun Heo 	spin_unlock(&drv->dynids.lock);
889dba910eSTejun Heo }
899dba910eSTejun Heo 
909dba910eSTejun Heo /**
919dba910eSTejun Heo  * store_new_id - sysfs frontend to pci_add_dynid()
928f7020d3SRandy Dunlap  * @driver: target device driver
938f7020d3SRandy Dunlap  * @buf: buffer for scanning device ID data
948f7020d3SRandy Dunlap  * @count: input size
951da177e4SLinus Torvalds  *
969dba910eSTejun Heo  * Allow PCI IDs to be added to an existing driver via sysfs.
971da177e4SLinus Torvalds  */
98a9427741SGreg Kroah-Hartman static ssize_t new_id_store(struct device_driver *driver, const char *buf,
993c78bc61SRyan Desfosses 			    size_t count)
1001da177e4SLinus Torvalds {
1011da177e4SLinus Torvalds 	struct pci_driver *pdrv = to_pci_driver(driver);
102b41d6cf3SJean Delvare 	const struct pci_device_id *ids = pdrv->id_table;
10320a796a9SLogan Gunthorpe 	u32 vendor, device, subvendor = PCI_ANY_ID,
1041da177e4SLinus Torvalds 		subdevice = PCI_ANY_ID, class = 0, class_mask = 0;
1051da177e4SLinus Torvalds 	unsigned long driver_data = 0;
1061da177e4SLinus Torvalds 	int fields = 0;
1078895d3bcSBandan Das 	int retval = 0;
1081da177e4SLinus Torvalds 
109b41d6cf3SJean Delvare 	fields = sscanf(buf, "%x %x %x %x %x %x %lx",
1101da177e4SLinus Torvalds 			&vendor, &device, &subvendor, &subdevice,
1111da177e4SLinus Torvalds 			&class, &class_mask, &driver_data);
1126ba18636SJean Delvare 	if (fields < 2)
1131da177e4SLinus Torvalds 		return -EINVAL;
1141da177e4SLinus Torvalds 
1158895d3bcSBandan Das 	if (fields != 7) {
1168895d3bcSBandan Das 		struct pci_dev *pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
1178895d3bcSBandan Das 		if (!pdev)
1188895d3bcSBandan Das 			return -ENOMEM;
1198895d3bcSBandan Das 
1208895d3bcSBandan Das 		pdev->vendor = vendor;
1218895d3bcSBandan Das 		pdev->device = device;
1228895d3bcSBandan Das 		pdev->subsystem_vendor = subvendor;
1238895d3bcSBandan Das 		pdev->subsystem_device = subdevice;
1248895d3bcSBandan Das 		pdev->class = class;
1258895d3bcSBandan Das 
1268895d3bcSBandan Das 		if (pci_match_id(pdrv->id_table, pdev))
1278895d3bcSBandan Das 			retval = -EEXIST;
1288895d3bcSBandan Das 
1298895d3bcSBandan Das 		kfree(pdev);
1308895d3bcSBandan Das 
1318895d3bcSBandan Das 		if (retval)
1328895d3bcSBandan Das 			return retval;
1338895d3bcSBandan Das 	}
1348895d3bcSBandan Das 
135b41d6cf3SJean Delvare 	/* Only accept driver_data values that match an existing id_table
136b41d6cf3SJean Delvare 	   entry */
1372debb4d2SChris Wright 	if (ids) {
138b41d6cf3SJean Delvare 		retval = -EINVAL;
139b41d6cf3SJean Delvare 		while (ids->vendor || ids->subvendor || ids->class_mask) {
140b41d6cf3SJean Delvare 			if (driver_data == ids->driver_data) {
141b41d6cf3SJean Delvare 				retval = 0;
142b41d6cf3SJean Delvare 				break;
143b41d6cf3SJean Delvare 			}
144b41d6cf3SJean Delvare 			ids++;
145b41d6cf3SJean Delvare 		}
146b41d6cf3SJean Delvare 		if (retval)	/* No match */
147b41d6cf3SJean Delvare 			return retval;
1482debb4d2SChris Wright 	}
149b41d6cf3SJean Delvare 
1509dba910eSTejun Heo 	retval = pci_add_dynid(pdrv, vendor, device, subvendor, subdevice,
1519dba910eSTejun Heo 			       class, class_mask, driver_data);
152b19441afSGreg Kroah-Hartman 	if (retval)
153b19441afSGreg Kroah-Hartman 		return retval;
1541da177e4SLinus Torvalds 	return count;
1551da177e4SLinus Torvalds }
156a9427741SGreg Kroah-Hartman static DRIVER_ATTR_WO(new_id);
1571da177e4SLinus Torvalds 
1580994375eSChris Wright /**
1590994375eSChris Wright  * store_remove_id - remove a PCI device ID from this driver
1600994375eSChris Wright  * @driver: target device driver
1610994375eSChris Wright  * @buf: buffer for scanning device ID data
1620994375eSChris Wright  * @count: input size
1630994375eSChris Wright  *
1640994375eSChris Wright  * Removes a dynamic pci device ID to this driver.
1650994375eSChris Wright  */
166a9427741SGreg Kroah-Hartman static ssize_t remove_id_store(struct device_driver *driver, const char *buf,
1673c78bc61SRyan Desfosses 			       size_t count)
1680994375eSChris Wright {
1690994375eSChris Wright 	struct pci_dynid *dynid, *n;
1700994375eSChris Wright 	struct pci_driver *pdrv = to_pci_driver(driver);
17120a796a9SLogan Gunthorpe 	u32 vendor, device, subvendor = PCI_ANY_ID,
1720994375eSChris Wright 		subdevice = PCI_ANY_ID, class = 0, class_mask = 0;
1730994375eSChris Wright 	int fields = 0;
1749222097fSZhen Lei 	size_t retval = -ENODEV;
1750994375eSChris Wright 
1760994375eSChris Wright 	fields = sscanf(buf, "%x %x %x %x %x %x",
1770994375eSChris Wright 			&vendor, &device, &subvendor, &subdevice,
1780994375eSChris Wright 			&class, &class_mask);
1790994375eSChris Wright 	if (fields < 2)
1800994375eSChris Wright 		return -EINVAL;
1810994375eSChris Wright 
1820994375eSChris Wright 	spin_lock(&pdrv->dynids.lock);
1830994375eSChris Wright 	list_for_each_entry_safe(dynid, n, &pdrv->dynids.list, node) {
1840994375eSChris Wright 		struct pci_device_id *id = &dynid->id;
1850994375eSChris Wright 		if ((id->vendor == vendor) &&
1860994375eSChris Wright 		    (id->device == device) &&
1870994375eSChris Wright 		    (subvendor == PCI_ANY_ID || id->subvendor == subvendor) &&
1880994375eSChris Wright 		    (subdevice == PCI_ANY_ID || id->subdevice == subdevice) &&
1890994375eSChris Wright 		    !((id->class ^ class) & class_mask)) {
1900994375eSChris Wright 			list_del(&dynid->node);
1910994375eSChris Wright 			kfree(dynid);
1929222097fSZhen Lei 			retval = count;
1930994375eSChris Wright 			break;
1940994375eSChris Wright 		}
1950994375eSChris Wright 	}
1960994375eSChris Wright 	spin_unlock(&pdrv->dynids.lock);
1970994375eSChris Wright 
1980994375eSChris Wright 	return retval;
1990994375eSChris Wright }
200a9427741SGreg Kroah-Hartman static DRIVER_ATTR_WO(remove_id);
2010994375eSChris Wright 
2022229c1fbSGreg Kroah-Hartman static struct attribute *pci_drv_attrs[] = {
2032229c1fbSGreg Kroah-Hartman 	&driver_attr_new_id.attr,
2042229c1fbSGreg Kroah-Hartman 	&driver_attr_remove_id.attr,
2052229c1fbSGreg Kroah-Hartman 	NULL,
206bfb09a86SKonstantin Khlebnikov };
2072229c1fbSGreg Kroah-Hartman ATTRIBUTE_GROUPS(pci_drv);
208ed283e9fSAlan Stern 
2091da177e4SLinus Torvalds /**
21075865858SGreg Kroah-Hartman  * pci_match_id - See if a pci device matches a given pci_id table
2111da177e4SLinus Torvalds  * @ids: array of PCI device id structures to search in
21275865858SGreg Kroah-Hartman  * @dev: the PCI device structure to match against.
2131da177e4SLinus Torvalds  *
2141da177e4SLinus Torvalds  * Used by a driver to check whether a PCI device present in the
2151da177e4SLinus Torvalds  * system is in its list of supported devices.  Returns the matching
2161da177e4SLinus Torvalds  * pci_device_id structure or %NULL if there is no match.
21775865858SGreg Kroah-Hartman  *
2188b60756aSRandy Dunlap  * Deprecated, don't use this as it will not catch any dynamic ids
21975865858SGreg Kroah-Hartman  * that a driver might want to check for.
2201da177e4SLinus Torvalds  */
22175865858SGreg Kroah-Hartman const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
22275865858SGreg Kroah-Hartman 					 struct pci_dev *dev)
2231da177e4SLinus Torvalds {
22475865858SGreg Kroah-Hartman 	if (ids) {
2251da177e4SLinus Torvalds 		while (ids->vendor || ids->subvendor || ids->class_mask) {
2261da177e4SLinus Torvalds 			if (pci_match_one_device(ids, dev))
2271da177e4SLinus Torvalds 				return ids;
2281da177e4SLinus Torvalds 			ids++;
2291da177e4SLinus Torvalds 		}
23075865858SGreg Kroah-Hartman 	}
2311da177e4SLinus Torvalds 	return NULL;
2321da177e4SLinus Torvalds }
233b7fe9434SRyan Desfosses EXPORT_SYMBOL(pci_match_id);
2341da177e4SLinus Torvalds 
235782a985dSAlex Williamson static const struct pci_device_id pci_device_id_any = {
236782a985dSAlex Williamson 	.vendor = PCI_ANY_ID,
237782a985dSAlex Williamson 	.device = PCI_ANY_ID,
238782a985dSAlex Williamson 	.subvendor = PCI_ANY_ID,
239782a985dSAlex Williamson 	.subdevice = PCI_ANY_ID,
240782a985dSAlex Williamson };
241782a985dSAlex Williamson 
2421da177e4SLinus Torvalds /**
243ae9608afSRandy Dunlap  * pci_match_device - Tell if a PCI device structure has a matching PCI device id structure
24475865858SGreg Kroah-Hartman  * @drv: the PCI driver to match against
24539ba487fSHenrik Kretzschmar  * @dev: the PCI device structure to match against
2461da177e4SLinus Torvalds  *
24775865858SGreg Kroah-Hartman  * Used by a driver to check whether a PCI device present in the
24875865858SGreg Kroah-Hartman  * system is in its list of supported devices.  Returns the matching
24975865858SGreg Kroah-Hartman  * pci_device_id structure or %NULL if there is no match.
2501da177e4SLinus Torvalds  */
251d73460d7SAdrian Bunk static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
25275865858SGreg Kroah-Hartman 						    struct pci_dev *dev)
2531da177e4SLinus Torvalds {
25475865858SGreg Kroah-Hartman 	struct pci_dynid *dynid;
255782a985dSAlex Williamson 	const struct pci_device_id *found_id = NULL;
256782a985dSAlex Williamson 
257782a985dSAlex Williamson 	/* When driver_override is set, only bind to the matching driver */
258782a985dSAlex Williamson 	if (dev->driver_override && strcmp(dev->driver_override, drv->name))
259782a985dSAlex Williamson 		return NULL;
2601da177e4SLinus Torvalds 
2617461b60aSRussell King 	/* Look at the dynamic ids first, before the static ones */
26275865858SGreg Kroah-Hartman 	spin_lock(&drv->dynids.lock);
26375865858SGreg Kroah-Hartman 	list_for_each_entry(dynid, &drv->dynids.list, node) {
26475865858SGreg Kroah-Hartman 		if (pci_match_one_device(&dynid->id, dev)) {
265782a985dSAlex Williamson 			found_id = &dynid->id;
266782a985dSAlex Williamson 			break;
2671da177e4SLinus Torvalds 		}
26875865858SGreg Kroah-Hartman 	}
26975865858SGreg Kroah-Hartman 	spin_unlock(&drv->dynids.lock);
2707461b60aSRussell King 
271782a985dSAlex Williamson 	if (!found_id)
272782a985dSAlex Williamson 		found_id = pci_match_id(drv->id_table, dev);
273782a985dSAlex Williamson 
274782a985dSAlex Williamson 	/* driver_override will always match, send a dummy id */
275782a985dSAlex Williamson 	if (!found_id && dev->driver_override)
276782a985dSAlex Williamson 		found_id = &pci_device_id_any;
277782a985dSAlex Williamson 
278782a985dSAlex Williamson 	return found_id;
2791da177e4SLinus Torvalds }
2801da177e4SLinus Torvalds 
281873392caSRusty Russell struct drv_dev_and_id {
282873392caSRusty Russell 	struct pci_driver *drv;
283873392caSRusty Russell 	struct pci_dev *dev;
284873392caSRusty Russell 	const struct pci_device_id *id;
285873392caSRusty Russell };
286873392caSRusty Russell 
287873392caSRusty Russell static long local_pci_probe(void *_ddi)
288873392caSRusty Russell {
289873392caSRusty Russell 	struct drv_dev_and_id *ddi = _ddi;
290967577b0SHuang Ying 	struct pci_dev *pci_dev = ddi->dev;
291967577b0SHuang Ying 	struct pci_driver *pci_drv = ddi->drv;
292967577b0SHuang Ying 	struct device *dev = &pci_dev->dev;
293f3ec4f87SAlan Stern 	int rc;
294873392caSRusty Russell 
295967577b0SHuang Ying 	/*
296967577b0SHuang Ying 	 * Unbound PCI devices are always put in D0, regardless of
297967577b0SHuang Ying 	 * runtime PM status.  During probe, the device is set to
298967577b0SHuang Ying 	 * active and the usage count is incremented.  If the driver
299a8360062SRafael J. Wysocki 	 * supports runtime PM, it should call pm_runtime_put_noidle(),
300a8360062SRafael J. Wysocki 	 * or any other runtime PM helper function decrementing the usage
301a8360062SRafael J. Wysocki 	 * count, in its probe routine and pm_runtime_get_noresume() in
302a8360062SRafael J. Wysocki 	 * its remove routine.
303f3ec4f87SAlan Stern 	 */
304967577b0SHuang Ying 	pm_runtime_get_sync(dev);
305967577b0SHuang Ying 	pci_dev->driver = pci_drv;
306967577b0SHuang Ying 	rc = pci_drv->probe(pci_dev, ddi->id);
307f92d74c1SStephen M. Cameron 	if (!rc)
308f92d74c1SStephen M. Cameron 		return rc;
309f92d74c1SStephen M. Cameron 	if (rc < 0) {
310967577b0SHuang Ying 		pci_dev->driver = NULL;
311967577b0SHuang Ying 		pm_runtime_put_sync(dev);
312f3ec4f87SAlan Stern 		return rc;
313873392caSRusty Russell 	}
314f92d74c1SStephen M. Cameron 	/*
315f92d74c1SStephen M. Cameron 	 * Probe function should return < 0 for failure, 0 for success
316f92d74c1SStephen M. Cameron 	 * Treat values > 0 as success, but warn.
317f92d74c1SStephen M. Cameron 	 */
3186941a0c2SBjorn Helgaas 	pci_warn(pci_dev, "Driver probe function unexpectedly returned %d\n",
3196941a0c2SBjorn Helgaas 		 rc);
320f92d74c1SStephen M. Cameron 	return 0;
321f92d74c1SStephen M. Cameron }
322873392caSRusty Russell 
3230b2c2a71SThomas Gleixner static bool pci_physfn_is_probed(struct pci_dev *dev)
3240b2c2a71SThomas Gleixner {
3250b2c2a71SThomas Gleixner #ifdef CONFIG_PCI_IOV
3260b2c2a71SThomas Gleixner 	return dev->is_virtfn && dev->physfn->is_probed;
3270b2c2a71SThomas Gleixner #else
3280b2c2a71SThomas Gleixner 	return false;
3290b2c2a71SThomas Gleixner #endif
3300b2c2a71SThomas Gleixner }
3310b2c2a71SThomas Gleixner 
332d42c6997SAndi Kleen static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
333d42c6997SAndi Kleen 			  const struct pci_device_id *id)
334d42c6997SAndi Kleen {
3350b2c2a71SThomas Gleixner 	int error, node, cpu;
336873392caSRusty Russell 	struct drv_dev_and_id ddi = { drv, dev, id };
337f70316daSMike Travis 
33812c3156fSAlexander Duyck 	/*
33912c3156fSAlexander Duyck 	 * Execute driver initialization on node where the device is
34012c3156fSAlexander Duyck 	 * attached.  This way the driver likely allocates its local memory
34112c3156fSAlexander Duyck 	 * on the right node.
34212c3156fSAlexander Duyck 	 */
343873392caSRusty Russell 	node = dev_to_node(&dev->dev);
3440b2c2a71SThomas Gleixner 	dev->is_probed = 1;
345873392caSRusty Russell 
3461ddd45f8SThomas Gleixner 	cpu_hotplug_disable();
3470b2c2a71SThomas Gleixner 
3480b2c2a71SThomas Gleixner 	/*
3490b2c2a71SThomas Gleixner 	 * Prevent nesting work_on_cpu() for the case where a Virtual Function
3500b2c2a71SThomas Gleixner 	 * device is probed from work_on_cpu() of the Physical device.
3510b2c2a71SThomas Gleixner 	 */
3520b2c2a71SThomas Gleixner 	if (node < 0 || node >= MAX_NUMNODES || !node_online(node) ||
3530b2c2a71SThomas Gleixner 	    pci_physfn_is_probed(dev))
3540b2c2a71SThomas Gleixner 		cpu = nr_cpu_ids;
3550b2c2a71SThomas Gleixner 	else
356a70f7302SRusty Russell 		cpu = cpumask_any_and(cpumask_of_node(node), cpu_online_mask);
3570b2c2a71SThomas Gleixner 
358873392caSRusty Russell 	if (cpu < nr_cpu_ids)
359873392caSRusty Russell 		error = work_on_cpu(cpu, local_pci_probe, &ddi);
360873392caSRusty Russell 	else
361873392caSRusty Russell 		error = local_pci_probe(&ddi);
36212c3156fSAlexander Duyck 
3630b2c2a71SThomas Gleixner 	dev->is_probed = 0;
3640b2c2a71SThomas Gleixner 	cpu_hotplug_enable();
365d42c6997SAndi Kleen 	return error;
366d42c6997SAndi Kleen }
367d42c6997SAndi Kleen 
3681da177e4SLinus Torvalds /**
36923ea3793SRandy Dunlap  * __pci_device_probe - check if a driver wants to claim a specific PCI device
3708f7020d3SRandy Dunlap  * @drv: driver to call to check if it wants the PCI device
3718f7020d3SRandy Dunlap  * @pci_dev: PCI device being probed
3721da177e4SLinus Torvalds  *
3731da177e4SLinus Torvalds  * returns 0 on success, else error.
3741da177e4SLinus Torvalds  * side-effect: pci_dev->driver is set to drv when drv claims pci_dev.
3751da177e4SLinus Torvalds  */
3763c78bc61SRyan Desfosses static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
3771da177e4SLinus Torvalds {
37875865858SGreg Kroah-Hartman 	const struct pci_device_id *id;
3791da177e4SLinus Torvalds 	int error = 0;
3801da177e4SLinus Torvalds 
3811da177e4SLinus Torvalds 	if (!pci_dev->driver && drv->probe) {
38275865858SGreg Kroah-Hartman 		error = -ENODEV;
38375865858SGreg Kroah-Hartman 
38475865858SGreg Kroah-Hartman 		id = pci_match_device(drv, pci_dev);
38575865858SGreg Kroah-Hartman 		if (id)
386d42c6997SAndi Kleen 			error = pci_call_probe(drv, pci_dev, id);
38775865858SGreg Kroah-Hartman 	}
3881da177e4SLinus Torvalds 	return error;
3891da177e4SLinus Torvalds }
3901da177e4SLinus Torvalds 
391890e4847SJiang Liu int __weak pcibios_alloc_irq(struct pci_dev *dev)
392890e4847SJiang Liu {
393890e4847SJiang Liu 	return 0;
394890e4847SJiang Liu }
395890e4847SJiang Liu 
396890e4847SJiang Liu void __weak pcibios_free_irq(struct pci_dev *dev)
397890e4847SJiang Liu {
398890e4847SJiang Liu }
399890e4847SJiang Liu 
4000e7df224SBodong Wang #ifdef CONFIG_PCI_IOV
4010e7df224SBodong Wang static inline bool pci_device_can_probe(struct pci_dev *pdev)
4020e7df224SBodong Wang {
4032d2f4273SAlex Williamson 	return (!pdev->is_virtfn || pdev->physfn->sriov->drivers_autoprobe ||
4042d2f4273SAlex Williamson 		pdev->driver_override);
4050e7df224SBodong Wang }
4060e7df224SBodong Wang #else
4070e7df224SBodong Wang static inline bool pci_device_can_probe(struct pci_dev *pdev)
4080e7df224SBodong Wang {
4090e7df224SBodong Wang 	return true;
4100e7df224SBodong Wang }
4110e7df224SBodong Wang #endif
4120e7df224SBodong Wang 
4131da177e4SLinus Torvalds static int pci_device_probe(struct device *dev)
4141da177e4SLinus Torvalds {
415890e4847SJiang Liu 	int error;
416890e4847SJiang Liu 	struct pci_dev *pci_dev = to_pci_dev(dev);
417890e4847SJiang Liu 	struct pci_driver *drv = to_pci_driver(dev->driver);
4181da177e4SLinus Torvalds 
41976002d8bSAlex Williamson 	if (!pci_device_can_probe(pci_dev))
42076002d8bSAlex Williamson 		return -ENODEV;
42176002d8bSAlex Williamson 
42230fdfb92SMatthew Minter 	pci_assign_irq(pci_dev);
42330fdfb92SMatthew Minter 
424890e4847SJiang Liu 	error = pcibios_alloc_irq(pci_dev);
425890e4847SJiang Liu 	if (error < 0)
426890e4847SJiang Liu 		return error;
427890e4847SJiang Liu 
4281da177e4SLinus Torvalds 	pci_dev_get(pci_dev);
4291da177e4SLinus Torvalds 	error = __pci_device_probe(drv, pci_dev);
430890e4847SJiang Liu 	if (error) {
431890e4847SJiang Liu 		pcibios_free_irq(pci_dev);
4321da177e4SLinus Torvalds 		pci_dev_put(pci_dev);
433890e4847SJiang Liu 	}
4341da177e4SLinus Torvalds 
4351da177e4SLinus Torvalds 	return error;
4361da177e4SLinus Torvalds }
4371da177e4SLinus Torvalds 
4381da177e4SLinus Torvalds static int pci_device_remove(struct device *dev)
4391da177e4SLinus Torvalds {
4401da177e4SLinus Torvalds 	struct pci_dev *pci_dev = to_pci_dev(dev);
4411da177e4SLinus Torvalds 	struct pci_driver *drv = pci_dev->driver;
4421da177e4SLinus Torvalds 
4431da177e4SLinus Torvalds 	if (drv) {
444f3ec4f87SAlan Stern 		if (drv->remove) {
445f3ec4f87SAlan Stern 			pm_runtime_get_sync(dev);
4461da177e4SLinus Torvalds 			drv->remove(pci_dev);
447f3ec4f87SAlan Stern 			pm_runtime_put_noidle(dev);
448f3ec4f87SAlan Stern 		}
449890e4847SJiang Liu 		pcibios_free_irq(pci_dev);
4501da177e4SLinus Torvalds 		pci_dev->driver = NULL;
45138972375SJakub Kicinski 		pci_iov_remove(pci_dev);
4521da177e4SLinus Torvalds 	}
4531da177e4SLinus Torvalds 
454f3ec4f87SAlan Stern 	/* Undo the runtime PM settings in local_pci_probe() */
455967577b0SHuang Ying 	pm_runtime_put_sync(dev);
456f3ec4f87SAlan Stern 
4571da177e4SLinus Torvalds 	/*
4582449e06aSShaohua Li 	 * If the device is still on, set the power state as "unknown",
4592449e06aSShaohua Li 	 * since it might change by the next time we load the driver.
4602449e06aSShaohua Li 	 */
4612449e06aSShaohua Li 	if (pci_dev->current_state == PCI_D0)
4622449e06aSShaohua Li 		pci_dev->current_state = PCI_UNKNOWN;
4632449e06aSShaohua Li 
4642449e06aSShaohua Li 	/*
4651da177e4SLinus Torvalds 	 * We would love to complain here if pci_dev->is_enabled is set, that
4661da177e4SLinus Torvalds 	 * the driver should have called pci_disable_device(), but the
4671da177e4SLinus Torvalds 	 * unfortunate fact is there are too many odd BIOS and bridge setups
4681da177e4SLinus Torvalds 	 * that don't like drivers doing that all of the time.
4691da177e4SLinus Torvalds 	 * Oh well, we can dream of sane hardware when we sleep, no matter how
4701da177e4SLinus Torvalds 	 * horrible the crap we have to deal with is when we are awake...
4711da177e4SLinus Torvalds 	 */
4721da177e4SLinus Torvalds 
4731da177e4SLinus Torvalds 	pci_dev_put(pci_dev);
4741da177e4SLinus Torvalds 	return 0;
4751da177e4SLinus Torvalds }
4761da177e4SLinus Torvalds 
477bbb44d9fSRafael J. Wysocki static void pci_device_shutdown(struct device *dev)
4781da177e4SLinus Torvalds {
4791da177e4SLinus Torvalds 	struct pci_dev *pci_dev = to_pci_dev(dev);
4801da177e4SLinus Torvalds 	struct pci_driver *drv = pci_dev->driver;
4811da177e4SLinus Torvalds 
4823ff2de9bSHuang Ying 	pm_runtime_resume(dev);
4833ff2de9bSHuang Ying 
484bbb44d9fSRafael J. Wysocki 	if (drv && drv->shutdown)
485bbb44d9fSRafael J. Wysocki 		drv->shutdown(pci_dev);
4865b415f1eSRafael J. Wysocki 
4875b415f1eSRafael J. Wysocki 	/*
4884fc9bbf9SKhalid Aziz 	 * If this is a kexec reboot, turn off Bus Master bit on the
4894fc9bbf9SKhalid Aziz 	 * device to tell it to not continue to do DMA. Don't touch
4904fc9bbf9SKhalid Aziz 	 * devices in D3cold or unknown states.
4914fc9bbf9SKhalid Aziz 	 * If it is not a kexec reboot, firmware will hit the PCI
4924fc9bbf9SKhalid Aziz 	 * devices with big hammer and stop their DMA any way.
493b566a22cSKhalid Aziz 	 */
4944fc9bbf9SKhalid Aziz 	if (kexec_in_progress && (pci_dev->current_state <= PCI_D3hot))
4957897e602SKonstantin Khlebnikov 		pci_clear_master(pci_dev);
496bbb44d9fSRafael J. Wysocki }
497bbb44d9fSRafael J. Wysocki 
498aa338601SRafael J. Wysocki #ifdef CONFIG_PM
4996cbf8214SRafael J. Wysocki 
5006cbf8214SRafael J. Wysocki /* Auxiliary functions used for system resume and run-time resume. */
5016cbf8214SRafael J. Wysocki 
5026cbf8214SRafael J. Wysocki /**
5036cbf8214SRafael J. Wysocki  * pci_restore_standard_config - restore standard config registers of PCI device
5046cbf8214SRafael J. Wysocki  * @pci_dev: PCI device to handle
5056cbf8214SRafael J. Wysocki  */
5066cbf8214SRafael J. Wysocki static int pci_restore_standard_config(struct pci_dev *pci_dev)
5076cbf8214SRafael J. Wysocki {
5086cbf8214SRafael J. Wysocki 	pci_update_current_state(pci_dev, PCI_UNKNOWN);
5096cbf8214SRafael J. Wysocki 
5106cbf8214SRafael J. Wysocki 	if (pci_dev->current_state != PCI_D0) {
5116cbf8214SRafael J. Wysocki 		int error = pci_set_power_state(pci_dev, PCI_D0);
5126cbf8214SRafael J. Wysocki 		if (error)
5136cbf8214SRafael J. Wysocki 			return error;
5146cbf8214SRafael J. Wysocki 	}
5156cbf8214SRafael J. Wysocki 
5161d3c16a8SJon Mason 	pci_restore_state(pci_dev);
5170ce3fcafSRafael J. Wysocki 	pci_pme_restore(pci_dev);
5181d3c16a8SJon Mason 	return 0;
5196cbf8214SRafael J. Wysocki }
5206cbf8214SRafael J. Wysocki 
521f7b32a86SBjorn Helgaas static void pci_pm_default_resume(struct pci_dev *pci_dev)
522f7b32a86SBjorn Helgaas {
523f7b32a86SBjorn Helgaas 	pci_fixup_device(pci_fixup_resume, pci_dev);
524f7b32a86SBjorn Helgaas 	pci_enable_wake(pci_dev, PCI_D0, false);
525f7b32a86SBjorn Helgaas }
526f7b32a86SBjorn Helgaas 
5276cbf8214SRafael J. Wysocki #endif
5286cbf8214SRafael J. Wysocki 
529bbb44d9fSRafael J. Wysocki #ifdef CONFIG_PM_SLEEP
530bbb44d9fSRafael J. Wysocki 
531db288c9cSRafael J. Wysocki static void pci_pm_default_resume_early(struct pci_dev *pci_dev)
532db288c9cSRafael J. Wysocki {
533db288c9cSRafael J. Wysocki 	pci_power_up(pci_dev);
534db288c9cSRafael J. Wysocki 	pci_restore_state(pci_dev);
5350ce3fcafSRafael J. Wysocki 	pci_pme_restore(pci_dev);
536db288c9cSRafael J. Wysocki }
537db288c9cSRafael J. Wysocki 
538bbb44d9fSRafael J. Wysocki /*
539bbb44d9fSRafael J. Wysocki  * Default "suspend" method for devices that have no driver provided suspend,
540fa58d305SRafael J. Wysocki  * or not even a driver at all (second part).
541fa58d305SRafael J. Wysocki  */
542bb808945SRafael J. Wysocki static void pci_pm_set_unknown_state(struct pci_dev *pci_dev)
543bbb44d9fSRafael J. Wysocki {
5442449e06aSShaohua Li 	/*
5452449e06aSShaohua Li 	 * mark its power state as "unknown", since we don't know if
5462449e06aSShaohua Li 	 * e.g. the BIOS will change its device state when we suspend.
5472449e06aSShaohua Li 	 */
5482449e06aSShaohua Li 	if (pci_dev->current_state == PCI_D0)
5492449e06aSShaohua Li 		pci_dev->current_state = PCI_UNKNOWN;
55002669492SAndrew Morton }
551e1a2a51eSRafael J. Wysocki 
552bbb44d9fSRafael J. Wysocki /*
553bbb44d9fSRafael J. Wysocki  * Default "resume" method for devices that have no driver provided resume,
554355a72d7SRafael J. Wysocki  * or not even a driver at all (second part).
555355a72d7SRafael J. Wysocki  */
556bb808945SRafael J. Wysocki static int pci_pm_reenable_device(struct pci_dev *pci_dev)
557355a72d7SRafael J. Wysocki {
558355a72d7SRafael J. Wysocki 	int retval;
559355a72d7SRafael J. Wysocki 
560bbb44d9fSRafael J. Wysocki 	/* if the device was enabled before suspend, reenable */
561bbb44d9fSRafael J. Wysocki 	retval = pci_reenable_device(pci_dev);
562bbb44d9fSRafael J. Wysocki 	/*
563bbb44d9fSRafael J. Wysocki 	 * if the device was busmaster before the suspend, make it busmaster
564bbb44d9fSRafael J. Wysocki 	 * again
565bbb44d9fSRafael J. Wysocki 	 */
566bbb44d9fSRafael J. Wysocki 	if (pci_dev->is_busmaster)
567bbb44d9fSRafael J. Wysocki 		pci_set_master(pci_dev);
568bbb44d9fSRafael J. Wysocki 
569bbb44d9fSRafael J. Wysocki 	return retval;
570bbb44d9fSRafael J. Wysocki }
571bbb44d9fSRafael J. Wysocki 
572bbb44d9fSRafael J. Wysocki static int pci_legacy_suspend(struct device *dev, pm_message_t state)
5731da177e4SLinus Torvalds {
5741da177e4SLinus Torvalds 	struct pci_dev *pci_dev = to_pci_dev(dev);
5751da177e4SLinus Torvalds 	struct pci_driver *drv = pci_dev->driver;
57646939f8bSRafael J. Wysocki 
5771da177e4SLinus Torvalds 	if (drv && drv->suspend) {
57899dadce8SRafael J. Wysocki 		pci_power_t prev = pci_dev->current_state;
57946939f8bSRafael J. Wysocki 		int error;
580aa8c6c93SRafael J. Wysocki 
58157ef8026SFrans Pop 		error = drv->suspend(pci_dev, state);
58257ef8026SFrans Pop 		suspend_report_result(drv->suspend, error);
58357ef8026SFrans Pop 		if (error)
58457ef8026SFrans Pop 			return error;
585aa8c6c93SRafael J. Wysocki 
58646939f8bSRafael J. Wysocki 		if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
58799dadce8SRafael J. Wysocki 		    && pci_dev->current_state != PCI_UNKNOWN) {
58812bcae44SBjorn Helgaas 			pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev,
589d75f773cSSakari Ailus 				      "PCI PM: Device state not saved by %pS\n",
59099dadce8SRafael J. Wysocki 				      drv->suspend);
5911da177e4SLinus Torvalds 		}
59299dadce8SRafael J. Wysocki 	}
593ad8cfa1dSRafael J. Wysocki 
594ad8cfa1dSRafael J. Wysocki 	pci_fixup_device(pci_fixup_suspend, pci_dev);
595ad8cfa1dSRafael J. Wysocki 
59646939f8bSRafael J. Wysocki 	return 0;
5971da177e4SLinus Torvalds }
5981da177e4SLinus Torvalds 
599bbb44d9fSRafael J. Wysocki static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
600cbd69dbbSLinus Torvalds {
601cbd69dbbSLinus Torvalds 	struct pci_dev *pci_dev = to_pci_dev(dev);
602cbd69dbbSLinus Torvalds 	struct pci_driver *drv = pci_dev->driver;
603cbd69dbbSLinus Torvalds 
604cbd69dbbSLinus Torvalds 	if (drv && drv->suspend_late) {
60546939f8bSRafael J. Wysocki 		pci_power_t prev = pci_dev->current_state;
60646939f8bSRafael J. Wysocki 		int error;
60746939f8bSRafael J. Wysocki 
60857ef8026SFrans Pop 		error = drv->suspend_late(pci_dev, state);
60957ef8026SFrans Pop 		suspend_report_result(drv->suspend_late, error);
61046939f8bSRafael J. Wysocki 		if (error)
61157ef8026SFrans Pop 			return error;
61246939f8bSRafael J. Wysocki 
61346939f8bSRafael J. Wysocki 		if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
61446939f8bSRafael J. Wysocki 		    && pci_dev->current_state != PCI_UNKNOWN) {
61512bcae44SBjorn Helgaas 			pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev,
616d75f773cSSakari Ailus 				      "PCI PM: Device state not saved by %pS\n",
61746939f8bSRafael J. Wysocki 				      drv->suspend_late);
6187d2a01b8SAndreas Noever 			goto Fixup;
61946939f8bSRafael J. Wysocki 		}
62046939f8bSRafael J. Wysocki 	}
62146939f8bSRafael J. Wysocki 
62246939f8bSRafael J. Wysocki 	if (!pci_dev->state_saved)
62346939f8bSRafael J. Wysocki 		pci_save_state(pci_dev);
62446939f8bSRafael J. Wysocki 
62546939f8bSRafael J. Wysocki 	pci_pm_set_unknown_state(pci_dev);
62646939f8bSRafael J. Wysocki 
6277d2a01b8SAndreas Noever Fixup:
6287d2a01b8SAndreas Noever 	pci_fixup_device(pci_fixup_suspend_late, pci_dev);
6297d2a01b8SAndreas Noever 
63046939f8bSRafael J. Wysocki 	return 0;
631cbd69dbbSLinus Torvalds }
6321da177e4SLinus Torvalds 
633bbb44d9fSRafael J. Wysocki static int pci_legacy_resume(struct device *dev)
6341da177e4SLinus Torvalds {
6351da177e4SLinus Torvalds 	struct pci_dev *pci_dev = to_pci_dev(dev);
6361da177e4SLinus Torvalds 	struct pci_driver *drv = pci_dev->driver;
6371da177e4SLinus Torvalds 
638ad8cfa1dSRafael J. Wysocki 	pci_fixup_device(pci_fixup_resume, pci_dev);
639ad8cfa1dSRafael J. Wysocki 
640aa8c6c93SRafael J. Wysocki 	return drv && drv->resume ?
641aa8c6c93SRafael J. Wysocki 			drv->resume(pci_dev) : pci_pm_reenable_device(pci_dev);
6421da177e4SLinus Torvalds }
6431da177e4SLinus Torvalds 
644571ff758SRafael J. Wysocki /* Auxiliary functions used by the new power management framework */
645571ff758SRafael J. Wysocki 
6465294e256SRafael J. Wysocki static void pci_pm_default_suspend(struct pci_dev *pci_dev)
64773410429SRafael J. Wysocki {
6485294e256SRafael J. Wysocki 	/* Disable non-bridge devices without PM support */
649326c1cdaSYijing Wang 	if (!pci_has_subordinate(pci_dev))
65073410429SRafael J. Wysocki 		pci_disable_enabled_device(pci_dev);
65173410429SRafael J. Wysocki }
65273410429SRafael J. Wysocki 
65307e836e8SRafael J. Wysocki static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
65407e836e8SRafael J. Wysocki {
65507e836e8SRafael J. Wysocki 	struct pci_driver *drv = pci_dev->driver;
656*89cdbc35SBjorn Helgaas 	bool ret = drv && (drv->suspend || drv->suspend_late || drv->resume);
657bb808945SRafael J. Wysocki 
658bb808945SRafael J. Wysocki 	/*
659bb808945SRafael J. Wysocki 	 * Legacy PM support is used by default, so warn if the new framework is
660bb808945SRafael J. Wysocki 	 * supported as well.  Drivers are supposed to support either the
661bb808945SRafael J. Wysocki 	 * former, or the latter, but not both at the same time.
662bb808945SRafael J. Wysocki 	 */
66312bcae44SBjorn Helgaas 	pci_WARN(pci_dev, ret && drv->driver.pm, "device %04x:%04x\n",
66412bcae44SBjorn Helgaas 		 pci_dev->vendor, pci_dev->device);
665bb808945SRafael J. Wysocki 
666bb808945SRafael J. Wysocki 	return ret;
66707e836e8SRafael J. Wysocki }
66807e836e8SRafael J. Wysocki 
669571ff758SRafael J. Wysocki /* New power management framework */
670571ff758SRafael J. Wysocki 
671bbb44d9fSRafael J. Wysocki static int pci_pm_prepare(struct device *dev)
672bbb44d9fSRafael J. Wysocki {
6730c7376adSRafael J. Wysocki 	struct pci_dev *pci_dev = to_pci_dev(dev);
6746da2f2ccSBjorn Helgaas 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
675bbb44d9fSRafael J. Wysocki 
6766da2f2ccSBjorn Helgaas 	if (pm && pm->prepare) {
6776da2f2ccSBjorn Helgaas 		int error = pm->prepare(dev);
67808810a41SRafael J. Wysocki 		if (error < 0)
679bbb44d9fSRafael J. Wysocki 			return error;
68008810a41SRafael J. Wysocki 
68108810a41SRafael J. Wysocki 		if (!error && dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_PREPARE))
68208810a41SRafael J. Wysocki 			return 0;
683bbb44d9fSRafael J. Wysocki 	}
6840c7376adSRafael J. Wysocki 	if (pci_dev_need_resume(pci_dev))
6850c7376adSRafael J. Wysocki 		return 0;
6860c7376adSRafael J. Wysocki 
6870c7376adSRafael J. Wysocki 	/*
6880c7376adSRafael J. Wysocki 	 * The PME setting needs to be adjusted here in case the direct-complete
6890c7376adSRafael J. Wysocki 	 * optimization is used with respect to this device.
6900c7376adSRafael J. Wysocki 	 */
6910c7376adSRafael J. Wysocki 	pci_dev_adjust_pme(pci_dev);
6920c7376adSRafael J. Wysocki 	return 1;
693bac2a909SRafael J. Wysocki }
694bbb44d9fSRafael J. Wysocki 
6952cef548aSRafael J. Wysocki static void pci_pm_complete(struct device *dev)
6962cef548aSRafael J. Wysocki {
697a0d2a959SLukas Wunner 	struct pci_dev *pci_dev = to_pci_dev(dev);
698a0d2a959SLukas Wunner 
699a0d2a959SLukas Wunner 	pci_dev_complete_resume(pci_dev);
700a0d2a959SLukas Wunner 	pm_generic_complete(dev);
701a0d2a959SLukas Wunner 
702a0d2a959SLukas Wunner 	/* Resume device if platform firmware has put it in reset-power-on */
703bd755d77SRafael J. Wysocki 	if (pm_runtime_suspended(dev) && pm_resume_via_firmware()) {
704a0d2a959SLukas Wunner 		pci_power_t pre_sleep_state = pci_dev->current_state;
705a0d2a959SLukas Wunner 
706b51033e0SRafael J. Wysocki 		pci_refresh_power_state(pci_dev);
707b51033e0SRafael J. Wysocki 		/*
708b51033e0SRafael J. Wysocki 		 * On platforms with ACPI this check may also trigger for
709b51033e0SRafael J. Wysocki 		 * devices sharing power resources if one of those power
710b51033e0SRafael J. Wysocki 		 * resources has been activated as a result of a change of the
711b51033e0SRafael J. Wysocki 		 * power state of another device sharing it.  However, in that
712b51033e0SRafael J. Wysocki 		 * case it is also better to resume the device, in general.
713b51033e0SRafael J. Wysocki 		 */
714a0d2a959SLukas Wunner 		if (pci_dev->current_state < pre_sleep_state)
715a0d2a959SLukas Wunner 			pm_request_resume(dev);
716a0d2a959SLukas Wunner 	}
7172cef548aSRafael J. Wysocki }
718bbb44d9fSRafael J. Wysocki 
7196cbf8214SRafael J. Wysocki #else /* !CONFIG_PM_SLEEP */
7206cbf8214SRafael J. Wysocki 
7216cbf8214SRafael J. Wysocki #define pci_pm_prepare	NULL
7222cef548aSRafael J. Wysocki #define pci_pm_complete	NULL
7236cbf8214SRafael J. Wysocki 
7246cbf8214SRafael J. Wysocki #endif /* !CONFIG_PM_SLEEP */
7256cbf8214SRafael J. Wysocki 
726bbb44d9fSRafael J. Wysocki #ifdef CONFIG_SUSPEND
727a39bd851SBjorn Helgaas static void pcie_pme_root_status_cleanup(struct pci_dev *pci_dev)
728a39bd851SBjorn Helgaas {
729a39bd851SBjorn Helgaas 	/*
730a39bd851SBjorn Helgaas 	 * Some BIOSes forget to clear Root PME Status bits after system
731a39bd851SBjorn Helgaas 	 * wakeup, which breaks ACPI-based runtime wakeup on PCI Express.
732a39bd851SBjorn Helgaas 	 * Clear those bits now just in case (shouldn't hurt).
733a39bd851SBjorn Helgaas 	 */
734a39bd851SBjorn Helgaas 	if (pci_is_pcie(pci_dev) &&
7353620c714SBjorn Helgaas 	    (pci_pcie_type(pci_dev) == PCI_EXP_TYPE_ROOT_PORT ||
7363620c714SBjorn Helgaas 	     pci_pcie_type(pci_dev) == PCI_EXP_TYPE_RC_EC))
737a39bd851SBjorn Helgaas 		pcie_clear_root_pme_status(pci_dev);
738a39bd851SBjorn Helgaas }
739bbb44d9fSRafael J. Wysocki 
740bbb44d9fSRafael J. Wysocki static int pci_pm_suspend(struct device *dev)
741bbb44d9fSRafael J. Wysocki {
742bbb44d9fSRafael J. Wysocki 	struct pci_dev *pci_dev = to_pci_dev(dev);
7438150f32bSDmitry Torokhov 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
744bbb44d9fSRafael J. Wysocki 
745d491f2b7SRafael J. Wysocki 	pci_dev->skip_bus_pm = false;
746d491f2b7SRafael J. Wysocki 
747ad8cfa1dSRafael J. Wysocki 	if (pci_has_legacy_pm_support(pci_dev))
748ad8cfa1dSRafael J. Wysocki 		return pci_legacy_suspend(dev, PMSG_SUSPEND);
749bb808945SRafael J. Wysocki 
7505294e256SRafael J. Wysocki 	if (!pm) {
7515294e256SRafael J. Wysocki 		pci_pm_default_suspend(pci_dev);
752c4b65157SRafael J. Wysocki 		return 0;
753bbb44d9fSRafael J. Wysocki 	}
754fa58d305SRafael J. Wysocki 
7557cd0602dSRafael J. Wysocki 	/*
756c4b65157SRafael J. Wysocki 	 * PCI devices suspended at run time may need to be resumed at this
757c4b65157SRafael J. Wysocki 	 * point, because in general it may be necessary to reconfigure them for
758c4b65157SRafael J. Wysocki 	 * system suspend.  Namely, if the device is expected to wake up the
759c4b65157SRafael J. Wysocki 	 * system from the sleep state, it may have to be reconfigured for this
760c4b65157SRafael J. Wysocki 	 * purpose, or if the device is not expected to wake up the system from
761c4b65157SRafael J. Wysocki 	 * the sleep state, it should be prevented from signaling wakeup events
762c4b65157SRafael J. Wysocki 	 * going forward.
763c4b65157SRafael J. Wysocki 	 *
764c4b65157SRafael J. Wysocki 	 * Also if the driver of the device does not indicate that its system
765c4b65157SRafael J. Wysocki 	 * suspend callbacks can cope with runtime-suspended devices, it is
766c4b65157SRafael J. Wysocki 	 * better to resume the device from runtime suspend here.
7677cd0602dSRafael J. Wysocki 	 */
768c4b65157SRafael J. Wysocki 	if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) ||
7690c7376adSRafael J. Wysocki 	    pci_dev_need_resume(pci_dev)) {
7707cd0602dSRafael J. Wysocki 		pm_runtime_resume(dev);
77182fee4d6SRafael J. Wysocki 		pci_dev->state_saved = false;
7720c7376adSRafael J. Wysocki 	} else {
7730c7376adSRafael J. Wysocki 		pci_dev_adjust_pme(pci_dev);
774656088aaSRafael J. Wysocki 	}
775656088aaSRafael J. Wysocki 
7765294e256SRafael J. Wysocki 	if (pm->suspend) {
7775294e256SRafael J. Wysocki 		pci_power_t prev = pci_dev->current_state;
7785294e256SRafael J. Wysocki 		int error;
7795294e256SRafael J. Wysocki 
7805294e256SRafael J. Wysocki 		error = pm->suspend(dev);
7815294e256SRafael J. Wysocki 		suspend_report_result(pm->suspend, error);
7825294e256SRafael J. Wysocki 		if (error)
783bbb44d9fSRafael J. Wysocki 			return error;
7845294e256SRafael J. Wysocki 
78546939f8bSRafael J. Wysocki 		if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
7865294e256SRafael J. Wysocki 		    && pci_dev->current_state != PCI_UNKNOWN) {
78712bcae44SBjorn Helgaas 			pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev,
788d75f773cSSakari Ailus 				      "PCI PM: State of device not saved by %pS\n",
7895294e256SRafael J. Wysocki 				      pm->suspend);
7905294e256SRafael J. Wysocki 		}
7915294e256SRafael J. Wysocki 	}
7925294e256SRafael J. Wysocki 
7935294e256SRafael J. Wysocki 	return 0;
794bbb44d9fSRafael J. Wysocki }
795bbb44d9fSRafael J. Wysocki 
796c4b65157SRafael J. Wysocki static int pci_pm_suspend_late(struct device *dev)
797c4b65157SRafael J. Wysocki {
798c4b65157SRafael J. Wysocki 	if (dev_pm_smart_suspend_and_suspended(dev))
799c4b65157SRafael J. Wysocki 		return 0;
800c4b65157SRafael J. Wysocki 
801c4b65157SRafael J. Wysocki 	pci_fixup_device(pci_fixup_suspend, to_pci_dev(dev));
802c4b65157SRafael J. Wysocki 
803c4b65157SRafael J. Wysocki 	return pm_generic_suspend_late(dev);
804c4b65157SRafael J. Wysocki }
805c4b65157SRafael J. Wysocki 
806bbb44d9fSRafael J. Wysocki static int pci_pm_suspend_noirq(struct device *dev)
807c8958177SGreg KH {
808355a72d7SRafael J. Wysocki 	struct pci_dev *pci_dev = to_pci_dev(dev);
8098150f32bSDmitry Torokhov 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
810c8958177SGreg KH 
811bd755d77SRafael J. Wysocki 	if (dev_pm_smart_suspend_and_suspended(dev)) {
812bd755d77SRafael J. Wysocki 		dev->power.may_skip_resume = true;
813c4b65157SRafael J. Wysocki 		return 0;
814bd755d77SRafael J. Wysocki 	}
815c4b65157SRafael J. Wysocki 
816bb808945SRafael J. Wysocki 	if (pci_has_legacy_pm_support(pci_dev))
817bb808945SRafael J. Wysocki 		return pci_legacy_suspend_late(dev, PMSG_SUSPEND);
818bb808945SRafael J. Wysocki 
819931ff68aSRafael J. Wysocki 	if (!pm) {
820931ff68aSRafael J. Wysocki 		pci_save_state(pci_dev);
8217d2a01b8SAndreas Noever 		goto Fixup;
822931ff68aSRafael J. Wysocki 	}
82346939f8bSRafael J. Wysocki 
82446939f8bSRafael J. Wysocki 	if (pm->suspend_noirq) {
82546939f8bSRafael J. Wysocki 		pci_power_t prev = pci_dev->current_state;
82646939f8bSRafael J. Wysocki 		int error;
82746939f8bSRafael J. Wysocki 
82846939f8bSRafael J. Wysocki 		error = pm->suspend_noirq(dev);
82946939f8bSRafael J. Wysocki 		suspend_report_result(pm->suspend_noirq, error);
83046939f8bSRafael J. Wysocki 		if (error)
83146939f8bSRafael J. Wysocki 			return error;
83246939f8bSRafael J. Wysocki 
83346939f8bSRafael J. Wysocki 		if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
83446939f8bSRafael J. Wysocki 		    && pci_dev->current_state != PCI_UNKNOWN) {
83512bcae44SBjorn Helgaas 			pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev,
836d75f773cSSakari Ailus 				      "PCI PM: State of device not saved by %pS\n",
83746939f8bSRafael J. Wysocki 				      pm->suspend_noirq);
8387d2a01b8SAndreas Noever 			goto Fixup;
83946939f8bSRafael J. Wysocki 		}
840c8958177SGreg KH 	}
841d67e37d7SRafael J. Wysocki 
842d491f2b7SRafael J. Wysocki 	if (pci_dev->skip_bus_pm) {
843d491f2b7SRafael J. Wysocki 		/*
8443e26c5feSRafael J. Wysocki 		 * Either the device is a bridge with a child in D0 below it, or
8453e26c5feSRafael J. Wysocki 		 * the function is running for the second time in a row without
846d491f2b7SRafael J. Wysocki 		 * going through full resume, which is possible only during
8473e26c5feSRafael J. Wysocki 		 * suspend-to-idle in a spurious wakeup case.  The device should
8483e26c5feSRafael J. Wysocki 		 * be in D0 at this point, but if it is a bridge, it may be
8493e26c5feSRafael J. Wysocki 		 * necessary to save its state.
850d491f2b7SRafael J. Wysocki 		 */
8513e26c5feSRafael J. Wysocki 		if (!pci_dev->state_saved)
8523e26c5feSRafael J. Wysocki 			pci_save_state(pci_dev);
8533e26c5feSRafael J. Wysocki 	} else if (!pci_dev->state_saved) {
85446939f8bSRafael J. Wysocki 		pci_save_state(pci_dev);
8559d26d3a8SMika Westerberg 		if (pci_power_manageable(pci_dev))
85646939f8bSRafael J. Wysocki 			pci_prepare_to_sleep(pci_dev);
85746939f8bSRafael J. Wysocki 	}
85846939f8bSRafael J. Wysocki 
8596941a0c2SBjorn Helgaas 	pci_dbg(pci_dev, "PCI PM: Suspend power state: %s\n",
860ca67ab5cSRafael J. Wysocki 		pci_power_name(pci_dev->current_state));
861ca67ab5cSRafael J. Wysocki 
8623e26c5feSRafael J. Wysocki 	if (pci_dev->current_state == PCI_D0) {
8633e26c5feSRafael J. Wysocki 		pci_dev->skip_bus_pm = true;
8643e26c5feSRafael J. Wysocki 		/*
8653e26c5feSRafael J. Wysocki 		 * Per PCI PM r1.2, table 6-1, a bridge must be in D0 if any
8663e26c5feSRafael J. Wysocki 		 * downstream device is in D0, so avoid changing the power state
8673e26c5feSRafael J. Wysocki 		 * of the parent bridge by setting the skip_bus_pm flag for it.
8683e26c5feSRafael J. Wysocki 		 */
8693e26c5feSRafael J. Wysocki 		if (pci_dev->bus->self)
8703e26c5feSRafael J. Wysocki 			pci_dev->bus->self->skip_bus_pm = true;
8713e26c5feSRafael J. Wysocki 	}
8723e26c5feSRafael J. Wysocki 
873471a739aSRafael J. Wysocki 	if (pci_dev->skip_bus_pm && pm_suspend_no_platform()) {
8746941a0c2SBjorn Helgaas 		pci_dbg(pci_dev, "PCI PM: Skipped\n");
8753e26c5feSRafael J. Wysocki 		goto Fixup;
8763e26c5feSRafael J. Wysocki 	}
8773e26c5feSRafael J. Wysocki 
878bb808945SRafael J. Wysocki 	pci_pm_set_unknown_state(pci_dev);
879bbb44d9fSRafael J. Wysocki 
880dbf0e4c7SAlan Stern 	/*
881dbf0e4c7SAlan Stern 	 * Some BIOSes from ASUS have a bug: If a USB EHCI host controller's
882dbf0e4c7SAlan Stern 	 * PCI COMMAND register isn't 0, the BIOS assumes that the controller
883dbf0e4c7SAlan Stern 	 * hasn't been quiesced and tries to turn it off.  If the controller
884dbf0e4c7SAlan Stern 	 * is already in D3, this can hang or cause memory corruption.
885dbf0e4c7SAlan Stern 	 *
886dbf0e4c7SAlan Stern 	 * Since the value of the COMMAND register doesn't matter once the
887dbf0e4c7SAlan Stern 	 * device has been suspended, we can safely set it to 0 here.
888dbf0e4c7SAlan Stern 	 */
889dbf0e4c7SAlan Stern 	if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI)
890dbf0e4c7SAlan Stern 		pci_write_config_word(pci_dev, PCI_COMMAND, 0);
891dbf0e4c7SAlan Stern 
8927d2a01b8SAndreas Noever Fixup:
8937d2a01b8SAndreas Noever 	pci_fixup_device(pci_fixup_suspend_late, pci_dev);
8947d2a01b8SAndreas Noever 
895bd755d77SRafael J. Wysocki 	/*
896bd755d77SRafael J. Wysocki 	 * If the target system sleep state is suspend-to-idle, it is sufficient
897bd755d77SRafael J. Wysocki 	 * to check whether or not the device's wakeup settings are good for
898bd755d77SRafael J. Wysocki 	 * runtime PM.  Otherwise, the pm_resume_via_firmware() check will cause
899bd755d77SRafael J. Wysocki 	 * pci_pm_complete() to take care of fixing up the device's state
900bd755d77SRafael J. Wysocki 	 * anyway, if need be.
901bd755d77SRafael J. Wysocki 	 */
902bd755d77SRafael J. Wysocki 	dev->power.may_skip_resume = device_may_wakeup(dev) ||
903bd755d77SRafael J. Wysocki 					!device_can_wakeup(dev);
904bd755d77SRafael J. Wysocki 
90546939f8bSRafael J. Wysocki 	return 0;
906bbb44d9fSRafael J. Wysocki }
907bbb44d9fSRafael J. Wysocki 
908bbb44d9fSRafael J. Wysocki static int pci_pm_resume_noirq(struct device *dev)
909bbb44d9fSRafael J. Wysocki {
910355a72d7SRafael J. Wysocki 	struct pci_dev *pci_dev = to_pci_dev(dev);
9116da2f2ccSBjorn Helgaas 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
912bbb44d9fSRafael J. Wysocki 
913bd755d77SRafael J. Wysocki 	if (dev_pm_may_skip_resume(dev))
914bd755d77SRafael J. Wysocki 		return 0;
915bd755d77SRafael J. Wysocki 
916c4b65157SRafael J. Wysocki 	/*
917c4b65157SRafael J. Wysocki 	 * Devices with DPM_FLAG_SMART_SUSPEND may be left in runtime suspend
918c4b65157SRafael J. Wysocki 	 * during system suspend, so update their runtime PM status to "active"
919c4b65157SRafael J. Wysocki 	 * as they are going to be put into D0 shortly.
920c4b65157SRafael J. Wysocki 	 */
921c4b65157SRafael J. Wysocki 	if (dev_pm_smart_suspend_and_suspended(dev))
922c4b65157SRafael J. Wysocki 		pm_runtime_set_active(dev);
923c4b65157SRafael J. Wysocki 
9243e26c5feSRafael J. Wysocki 	/*
9253e26c5feSRafael J. Wysocki 	 * In the suspend-to-idle case, devices left in D0 during suspend will
9263e26c5feSRafael J. Wysocki 	 * stay in D0, so it is not necessary to restore or update their
927471a739aSRafael J. Wysocki 	 * configuration here and attempting to put them into D0 again is
928471a739aSRafael J. Wysocki 	 * pointless, so avoid doing that.
9293e26c5feSRafael J. Wysocki 	 */
930471a739aSRafael J. Wysocki 	if (!(pci_dev->skip_bus_pm && pm_suspend_no_platform()))
9316cbf8214SRafael J. Wysocki 		pci_pm_default_resume_early(pci_dev);
932aa8c6c93SRafael J. Wysocki 
9333e26c5feSRafael J. Wysocki 	pci_fixup_device(pci_fixup_resume_early, pci_dev);
934ec6a75efSBjorn Helgaas 	pcie_pme_root_status_cleanup(pci_dev);
9353e26c5feSRafael J. Wysocki 
936ad8cfa1dSRafael J. Wysocki 	if (pci_has_legacy_pm_support(pci_dev))
937*89cdbc35SBjorn Helgaas 		return 0;
938bb808945SRafael J. Wysocki 
9396da2f2ccSBjorn Helgaas 	if (pm && pm->resume_noirq)
9406da2f2ccSBjorn Helgaas 		return pm->resume_noirq(dev);
941bbb44d9fSRafael J. Wysocki 
9426da2f2ccSBjorn Helgaas 	return 0;
943bbb44d9fSRafael J. Wysocki }
944bbb44d9fSRafael J. Wysocki 
945f6dc1e5eSRafael J. Wysocki static int pci_pm_resume(struct device *dev)
946f6dc1e5eSRafael J. Wysocki {
947f6dc1e5eSRafael J. Wysocki 	struct pci_dev *pci_dev = to_pci_dev(dev);
9488150f32bSDmitry Torokhov 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
949f6dc1e5eSRafael J. Wysocki 
950418e4da3SRafael J. Wysocki 	/*
951418e4da3SRafael J. Wysocki 	 * This is necessary for the suspend error path in which resume is
952418e4da3SRafael J. Wysocki 	 * called without restoring the standard config registers of the device.
953418e4da3SRafael J. Wysocki 	 */
954418e4da3SRafael J. Wysocki 	if (pci_dev->state_saved)
955418e4da3SRafael J. Wysocki 		pci_restore_standard_config(pci_dev);
956418e4da3SRafael J. Wysocki 
957f6dc1e5eSRafael J. Wysocki 	if (pci_has_legacy_pm_support(pci_dev))
958f6dc1e5eSRafael J. Wysocki 		return pci_legacy_resume(dev);
959f6dc1e5eSRafael J. Wysocki 
9605294e256SRafael J. Wysocki 	pci_pm_default_resume(pci_dev);
961f6dc1e5eSRafael J. Wysocki 
9625294e256SRafael J. Wysocki 	if (pm) {
9635294e256SRafael J. Wysocki 		if (pm->resume)
9646da2f2ccSBjorn Helgaas 			return pm->resume(dev);
9655294e256SRafael J. Wysocki 	} else {
9665294e256SRafael J. Wysocki 		pci_pm_reenable_device(pci_dev);
9675294e256SRafael J. Wysocki 	}
968f6dc1e5eSRafael J. Wysocki 
9696da2f2ccSBjorn Helgaas 	return 0;
970f6dc1e5eSRafael J. Wysocki }
971f6dc1e5eSRafael J. Wysocki 
972bbb44d9fSRafael J. Wysocki #else /* !CONFIG_SUSPEND */
973bbb44d9fSRafael J. Wysocki 
974bbb44d9fSRafael J. Wysocki #define pci_pm_suspend		NULL
975c4b65157SRafael J. Wysocki #define pci_pm_suspend_late	NULL
976bbb44d9fSRafael J. Wysocki #define pci_pm_suspend_noirq	NULL
977bbb44d9fSRafael J. Wysocki #define pci_pm_resume		NULL
978bbb44d9fSRafael J. Wysocki #define pci_pm_resume_noirq	NULL
979bbb44d9fSRafael J. Wysocki 
980bbb44d9fSRafael J. Wysocki #endif /* !CONFIG_SUSPEND */
981bbb44d9fSRafael J. Wysocki 
9821f112ceeSRafael J. Wysocki #ifdef CONFIG_HIBERNATE_CALLBACKS
983bbb44d9fSRafael J. Wysocki 
984699c1985SSebastian Ott /*
985699c1985SSebastian Ott  * pcibios_pm_ops - provide arch-specific hooks when a PCI device is doing
986699c1985SSebastian Ott  * a hibernate transition
987699c1985SSebastian Ott  */
988699c1985SSebastian Ott struct dev_pm_ops __weak pcibios_pm_ops;
989699c1985SSebastian Ott 
990bbb44d9fSRafael J. Wysocki static int pci_pm_freeze(struct device *dev)
991bbb44d9fSRafael J. Wysocki {
992bbb44d9fSRafael J. Wysocki 	struct pci_dev *pci_dev = to_pci_dev(dev);
9938150f32bSDmitry Torokhov 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
994bbb44d9fSRafael J. Wysocki 
995ad8cfa1dSRafael J. Wysocki 	if (pci_has_legacy_pm_support(pci_dev))
996ad8cfa1dSRafael J. Wysocki 		return pci_legacy_suspend(dev, PMSG_FREEZE);
997bb808945SRafael J. Wysocki 
9985294e256SRafael J. Wysocki 	if (!pm) {
9995294e256SRafael J. Wysocki 		pci_pm_default_suspend(pci_dev);
10005294e256SRafael J. Wysocki 		return 0;
1001bbb44d9fSRafael J. Wysocki 	}
1002d67e37d7SRafael J. Wysocki 
10037cd0602dSRafael J. Wysocki 	/*
1004501debd4SRafael J. Wysocki 	 * Resume all runtime-suspended devices before creating a snapshot
1005501debd4SRafael J. Wysocki 	 * image of system memory, because the restore kernel generally cannot
1006501debd4SRafael J. Wysocki 	 * be expected to always handle them consistently and they need to be
1007501debd4SRafael J. Wysocki 	 * put into the runtime-active metastate during system resume anyway,
1008501debd4SRafael J. Wysocki 	 * so it is better to ensure that the state saved in the image will be
1009501debd4SRafael J. Wysocki 	 * always consistent with that.
10107cd0602dSRafael J. Wysocki 	 */
10117cd0602dSRafael J. Wysocki 	pm_runtime_resume(dev);
101282fee4d6SRafael J. Wysocki 	pci_dev->state_saved = false;
1013ae860a19SMika Westerberg 
10145294e256SRafael J. Wysocki 	if (pm->freeze) {
10155294e256SRafael J. Wysocki 		int error;
10165294e256SRafael J. Wysocki 
10175294e256SRafael J. Wysocki 		error = pm->freeze(dev);
10185294e256SRafael J. Wysocki 		suspend_report_result(pm->freeze, error);
10195294e256SRafael J. Wysocki 		if (error)
1020bbb44d9fSRafael J. Wysocki 			return error;
1021bbb44d9fSRafael J. Wysocki 	}
1022bbb44d9fSRafael J. Wysocki 
10235294e256SRafael J. Wysocki 	return 0;
10245294e256SRafael J. Wysocki }
10255294e256SRafael J. Wysocki 
1026bbb44d9fSRafael J. Wysocki static int pci_pm_freeze_noirq(struct device *dev)
1027bbb44d9fSRafael J. Wysocki {
1028355a72d7SRafael J. Wysocki 	struct pci_dev *pci_dev = to_pci_dev(dev);
10296da2f2ccSBjorn Helgaas 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
1030bbb44d9fSRafael J. Wysocki 
1031bb808945SRafael J. Wysocki 	if (pci_has_legacy_pm_support(pci_dev))
1032bb808945SRafael J. Wysocki 		return pci_legacy_suspend_late(dev, PMSG_FREEZE);
1033bb808945SRafael J. Wysocki 
10346da2f2ccSBjorn Helgaas 	if (pm && pm->freeze_noirq) {
103546939f8bSRafael J. Wysocki 		int error;
103646939f8bSRafael J. Wysocki 
10376da2f2ccSBjorn Helgaas 		error = pm->freeze_noirq(dev);
10386da2f2ccSBjorn Helgaas 		suspend_report_result(pm->freeze_noirq, error);
103946939f8bSRafael J. Wysocki 		if (error)
104046939f8bSRafael J. Wysocki 			return error;
1041bbb44d9fSRafael J. Wysocki 	}
1042d67e37d7SRafael J. Wysocki 
104346939f8bSRafael J. Wysocki 	if (!pci_dev->state_saved)
104446939f8bSRafael J. Wysocki 		pci_save_state(pci_dev);
104546939f8bSRafael J. Wysocki 
1046bb808945SRafael J. Wysocki 	pci_pm_set_unknown_state(pci_dev);
1047bbb44d9fSRafael J. Wysocki 
1048699c1985SSebastian Ott 	if (pcibios_pm_ops.freeze_noirq)
1049699c1985SSebastian Ott 		return pcibios_pm_ops.freeze_noirq(dev);
1050699c1985SSebastian Ott 
105146939f8bSRafael J. Wysocki 	return 0;
1052bbb44d9fSRafael J. Wysocki }
1053bbb44d9fSRafael J. Wysocki 
1054bbb44d9fSRafael J. Wysocki static int pci_pm_thaw_noirq(struct device *dev)
1055bbb44d9fSRafael J. Wysocki {
1056355a72d7SRafael J. Wysocki 	struct pci_dev *pci_dev = to_pci_dev(dev);
10576da2f2ccSBjorn Helgaas 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
10586da2f2ccSBjorn Helgaas 	int error;
1059bbb44d9fSRafael J. Wysocki 
1060699c1985SSebastian Ott 	if (pcibios_pm_ops.thaw_noirq) {
1061699c1985SSebastian Ott 		error = pcibios_pm_ops.thaw_noirq(dev);
1062699c1985SSebastian Ott 		if (error)
1063699c1985SSebastian Ott 			return error;
1064699c1985SSebastian Ott 	}
1065699c1985SSebastian Ott 
10665839ee73SRafael J. Wysocki 	/*
1067*89cdbc35SBjorn Helgaas 	 * The pm->thaw_noirq() callback assumes the device has been
1068*89cdbc35SBjorn Helgaas 	 * returned to D0 and its config state has been restored.
1069f2c33ccaSDexuan Cui 	 *
1070f2c33ccaSDexuan Cui 	 * In addition, pci_restore_state() restores MSI-X state in MMIO
1071f2c33ccaSDexuan Cui 	 * space, which requires the device to be in D0, so return it to D0
1072f2c33ccaSDexuan Cui 	 * in case the driver's "freeze" callbacks put it into a low-power
1073f2c33ccaSDexuan Cui 	 * state.
10745839ee73SRafael J. Wysocki 	 */
10755839ee73SRafael J. Wysocki 	pci_set_power_state(pci_dev, PCI_D0);
1076e60514bdSChen Yu 	pci_restore_state(pci_dev);
1077d67e37d7SRafael J. Wysocki 
1078f2c33ccaSDexuan Cui 	if (pci_has_legacy_pm_support(pci_dev))
1079*89cdbc35SBjorn Helgaas 		return 0;
1080f2c33ccaSDexuan Cui 
10816da2f2ccSBjorn Helgaas 	if (pm && pm->thaw_noirq)
10826da2f2ccSBjorn Helgaas 		return pm->thaw_noirq(dev);
1083bbb44d9fSRafael J. Wysocki 
10846da2f2ccSBjorn Helgaas 	return 0;
1085bbb44d9fSRafael J. Wysocki }
1086bbb44d9fSRafael J. Wysocki 
1087f6dc1e5eSRafael J. Wysocki static int pci_pm_thaw(struct device *dev)
1088f6dc1e5eSRafael J. Wysocki {
1089f6dc1e5eSRafael J. Wysocki 	struct pci_dev *pci_dev = to_pci_dev(dev);
10908150f32bSDmitry Torokhov 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
1091f6dc1e5eSRafael J. Wysocki 	int error = 0;
1092f6dc1e5eSRafael J. Wysocki 
1093f6dc1e5eSRafael J. Wysocki 	if (pci_has_legacy_pm_support(pci_dev))
1094f6dc1e5eSRafael J. Wysocki 		return pci_legacy_resume(dev);
1095f6dc1e5eSRafael J. Wysocki 
10965294e256SRafael J. Wysocki 	if (pm) {
10975294e256SRafael J. Wysocki 		if (pm->thaw)
10985294e256SRafael J. Wysocki 			error = pm->thaw(dev);
10995294e256SRafael J. Wysocki 	} else {
1100f6dc1e5eSRafael J. Wysocki 		pci_pm_reenable_device(pci_dev);
11015294e256SRafael J. Wysocki 	}
1102f6dc1e5eSRafael J. Wysocki 
11034b77b0a2SRafael J. Wysocki 	pci_dev->state_saved = false;
11044b77b0a2SRafael J. Wysocki 
1105f6dc1e5eSRafael J. Wysocki 	return error;
1106f6dc1e5eSRafael J. Wysocki }
1107f6dc1e5eSRafael J. Wysocki 
1108bbb44d9fSRafael J. Wysocki static int pci_pm_poweroff(struct device *dev)
1109bbb44d9fSRafael J. Wysocki {
1110355a72d7SRafael J. Wysocki 	struct pci_dev *pci_dev = to_pci_dev(dev);
11118150f32bSDmitry Torokhov 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
1112bbb44d9fSRafael J. Wysocki 
1113ad8cfa1dSRafael J. Wysocki 	if (pci_has_legacy_pm_support(pci_dev))
1114ad8cfa1dSRafael J. Wysocki 		return pci_legacy_suspend(dev, PMSG_HIBERNATE);
1115bb808945SRafael J. Wysocki 
11165294e256SRafael J. Wysocki 	if (!pm) {
11175294e256SRafael J. Wysocki 		pci_pm_default_suspend(pci_dev);
1118c4b65157SRafael J. Wysocki 		return 0;
11195294e256SRafael J. Wysocki 	}
11205294e256SRafael J. Wysocki 
11217cd0602dSRafael J. Wysocki 	/* The reason to do that is the same as in pci_pm_suspend(). */
1122c4b65157SRafael J. Wysocki 	if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) ||
11230c7376adSRafael J. Wysocki 	    pci_dev_need_resume(pci_dev)) {
11247cd0602dSRafael J. Wysocki 		pm_runtime_resume(dev);
112582fee4d6SRafael J. Wysocki 		pci_dev->state_saved = false;
11260c7376adSRafael J. Wysocki 	} else {
11270c7376adSRafael J. Wysocki 		pci_dev_adjust_pme(pci_dev);
11280c7376adSRafael J. Wysocki 	}
11290c7376adSRafael J. Wysocki 
11305294e256SRafael J. Wysocki 	if (pm->poweroff) {
113146939f8bSRafael J. Wysocki 		int error;
113246939f8bSRafael J. Wysocki 
1133ddb7c9d2SRafael J. Wysocki 		error = pm->poweroff(dev);
1134ddb7c9d2SRafael J. Wysocki 		suspend_report_result(pm->poweroff, error);
113546939f8bSRafael J. Wysocki 		if (error)
113646939f8bSRafael J. Wysocki 			return error;
113746939f8bSRafael J. Wysocki 	}
113846939f8bSRafael J. Wysocki 
113946939f8bSRafael J. Wysocki 	return 0;
114046939f8bSRafael J. Wysocki }
114146939f8bSRafael J. Wysocki 
1142c4b65157SRafael J. Wysocki static int pci_pm_poweroff_late(struct device *dev)
1143c4b65157SRafael J. Wysocki {
1144c4b65157SRafael J. Wysocki 	if (dev_pm_smart_suspend_and_suspended(dev))
1145c4b65157SRafael J. Wysocki 		return 0;
1146c4b65157SRafael J. Wysocki 
1147c4b65157SRafael J. Wysocki 	pci_fixup_device(pci_fixup_suspend, to_pci_dev(dev));
1148c4b65157SRafael J. Wysocki 
1149c4b65157SRafael J. Wysocki 	return pm_generic_poweroff_late(dev);
1150c4b65157SRafael J. Wysocki }
1151c4b65157SRafael J. Wysocki 
115246939f8bSRafael J. Wysocki static int pci_pm_poweroff_noirq(struct device *dev)
115346939f8bSRafael J. Wysocki {
115446939f8bSRafael J. Wysocki 	struct pci_dev *pci_dev = to_pci_dev(dev);
11556da2f2ccSBjorn Helgaas 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
115646939f8bSRafael J. Wysocki 
1157c4b65157SRafael J. Wysocki 	if (dev_pm_smart_suspend_and_suspended(dev))
1158c4b65157SRafael J. Wysocki 		return 0;
1159c4b65157SRafael J. Wysocki 
11606da2f2ccSBjorn Helgaas 	if (pci_has_legacy_pm_support(pci_dev))
116146939f8bSRafael J. Wysocki 		return pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
116246939f8bSRafael J. Wysocki 
11636da2f2ccSBjorn Helgaas 	if (!pm) {
11647d2a01b8SAndreas Noever 		pci_fixup_device(pci_fixup_suspend_late, pci_dev);
116546939f8bSRafael J. Wysocki 		return 0;
11667d2a01b8SAndreas Noever 	}
116746939f8bSRafael J. Wysocki 
11686da2f2ccSBjorn Helgaas 	if (pm->poweroff_noirq) {
116946939f8bSRafael J. Wysocki 		int error;
117046939f8bSRafael J. Wysocki 
11716da2f2ccSBjorn Helgaas 		error = pm->poweroff_noirq(dev);
11726da2f2ccSBjorn Helgaas 		suspend_report_result(pm->poweroff_noirq, error);
117346939f8bSRafael J. Wysocki 		if (error)
117446939f8bSRafael J. Wysocki 			return error;
1175bbb44d9fSRafael J. Wysocki 	}
1176bbb44d9fSRafael J. Wysocki 
1177326c1cdaSYijing Wang 	if (!pci_dev->state_saved && !pci_has_subordinate(pci_dev))
11785294e256SRafael J. Wysocki 		pci_prepare_to_sleep(pci_dev);
11795294e256SRafael J. Wysocki 
11800b68c8e2SRafael J. Wysocki 	/*
11810b68c8e2SRafael J. Wysocki 	 * The reason for doing this here is the same as for the analogous code
11820b68c8e2SRafael J. Wysocki 	 * in pci_pm_suspend_noirq().
11830b68c8e2SRafael J. Wysocki 	 */
11840b68c8e2SRafael J. Wysocki 	if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI)
11850b68c8e2SRafael J. Wysocki 		pci_write_config_word(pci_dev, PCI_COMMAND, 0);
11860b68c8e2SRafael J. Wysocki 
11877d2a01b8SAndreas Noever 	pci_fixup_device(pci_fixup_suspend_late, pci_dev);
11887d2a01b8SAndreas Noever 
1189699c1985SSebastian Ott 	if (pcibios_pm_ops.poweroff_noirq)
1190699c1985SSebastian Ott 		return pcibios_pm_ops.poweroff_noirq(dev);
1191699c1985SSebastian Ott 
119246939f8bSRafael J. Wysocki 	return 0;
1193bbb44d9fSRafael J. Wysocki }
1194bbb44d9fSRafael J. Wysocki 
1195bbb44d9fSRafael J. Wysocki static int pci_pm_restore_noirq(struct device *dev)
1196bbb44d9fSRafael J. Wysocki {
1197bbb44d9fSRafael J. Wysocki 	struct pci_dev *pci_dev = to_pci_dev(dev);
11986da2f2ccSBjorn Helgaas 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
11996da2f2ccSBjorn Helgaas 	int error;
1200bbb44d9fSRafael J. Wysocki 
1201699c1985SSebastian Ott 	if (pcibios_pm_ops.restore_noirq) {
1202699c1985SSebastian Ott 		error = pcibios_pm_ops.restore_noirq(dev);
1203699c1985SSebastian Ott 		if (error)
1204699c1985SSebastian Ott 			return error;
1205699c1985SSebastian Ott 	}
1206699c1985SSebastian Ott 
12076cbf8214SRafael J. Wysocki 	pci_pm_default_resume_early(pci_dev);
12083e26c5feSRafael J. Wysocki 	pci_fixup_device(pci_fixup_resume_early, pci_dev);
1209aa8c6c93SRafael J. Wysocki 
1210ad8cfa1dSRafael J. Wysocki 	if (pci_has_legacy_pm_support(pci_dev))
1211*89cdbc35SBjorn Helgaas 		return 0;
1212bb808945SRafael J. Wysocki 
12136da2f2ccSBjorn Helgaas 	if (pm && pm->restore_noirq)
12146da2f2ccSBjorn Helgaas 		return pm->restore_noirq(dev);
1215bbb44d9fSRafael J. Wysocki 
12166da2f2ccSBjorn Helgaas 	return 0;
1217bbb44d9fSRafael J. Wysocki }
1218bbb44d9fSRafael J. Wysocki 
1219f6dc1e5eSRafael J. Wysocki static int pci_pm_restore(struct device *dev)
1220f6dc1e5eSRafael J. Wysocki {
1221f6dc1e5eSRafael J. Wysocki 	struct pci_dev *pci_dev = to_pci_dev(dev);
12228150f32bSDmitry Torokhov 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
1223f6dc1e5eSRafael J. Wysocki 
1224418e4da3SRafael J. Wysocki 	/*
1225418e4da3SRafael J. Wysocki 	 * This is necessary for the hibernation error path in which restore is
1226418e4da3SRafael J. Wysocki 	 * called without restoring the standard config registers of the device.
1227418e4da3SRafael J. Wysocki 	 */
1228418e4da3SRafael J. Wysocki 	if (pci_dev->state_saved)
1229418e4da3SRafael J. Wysocki 		pci_restore_standard_config(pci_dev);
1230418e4da3SRafael J. Wysocki 
1231f6dc1e5eSRafael J. Wysocki 	if (pci_has_legacy_pm_support(pci_dev))
1232f6dc1e5eSRafael J. Wysocki 		return pci_legacy_resume(dev);
1233f6dc1e5eSRafael J. Wysocki 
12345294e256SRafael J. Wysocki 	pci_pm_default_resume(pci_dev);
1235f6dc1e5eSRafael J. Wysocki 
12365294e256SRafael J. Wysocki 	if (pm) {
12375294e256SRafael J. Wysocki 		if (pm->restore)
12386da2f2ccSBjorn Helgaas 			return pm->restore(dev);
12395294e256SRafael J. Wysocki 	} else {
12405294e256SRafael J. Wysocki 		pci_pm_reenable_device(pci_dev);
12415294e256SRafael J. Wysocki 	}
1242f6dc1e5eSRafael J. Wysocki 
12436da2f2ccSBjorn Helgaas 	return 0;
1244f6dc1e5eSRafael J. Wysocki }
1245f6dc1e5eSRafael J. Wysocki 
12461f112ceeSRafael J. Wysocki #else /* !CONFIG_HIBERNATE_CALLBACKS */
1247bbb44d9fSRafael J. Wysocki 
1248bbb44d9fSRafael J. Wysocki #define pci_pm_freeze		NULL
1249bbb44d9fSRafael J. Wysocki #define pci_pm_freeze_noirq	NULL
1250bbb44d9fSRafael J. Wysocki #define pci_pm_thaw		NULL
1251bbb44d9fSRafael J. Wysocki #define pci_pm_thaw_noirq	NULL
1252bbb44d9fSRafael J. Wysocki #define pci_pm_poweroff		NULL
1253c4b65157SRafael J. Wysocki #define pci_pm_poweroff_late	NULL
1254bbb44d9fSRafael J. Wysocki #define pci_pm_poweroff_noirq	NULL
1255bbb44d9fSRafael J. Wysocki #define pci_pm_restore		NULL
1256bbb44d9fSRafael J. Wysocki #define pci_pm_restore_noirq	NULL
1257bbb44d9fSRafael J. Wysocki 
12581f112ceeSRafael J. Wysocki #endif /* !CONFIG_HIBERNATE_CALLBACKS */
1259bbb44d9fSRafael J. Wysocki 
1260fbb988beSRafael J. Wysocki #ifdef CONFIG_PM
12616cbf8214SRafael J. Wysocki 
12626cbf8214SRafael J. Wysocki static int pci_pm_runtime_suspend(struct device *dev)
12636cbf8214SRafael J. Wysocki {
12646cbf8214SRafael J. Wysocki 	struct pci_dev *pci_dev = to_pci_dev(dev);
12656cbf8214SRafael J. Wysocki 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
12666cbf8214SRafael J. Wysocki 	pci_power_t prev = pci_dev->current_state;
12676cbf8214SRafael J. Wysocki 	int error;
12686cbf8214SRafael J. Wysocki 
1269967577b0SHuang Ying 	/*
12705775b843SRafael J. Wysocki 	 * If pci_dev->driver is not set (unbound), we leave the device in D0,
12715775b843SRafael J. Wysocki 	 * but it may go to D3cold when the bridge above it runtime suspends.
12725775b843SRafael J. Wysocki 	 * Save its config space in case that happens.
1273967577b0SHuang Ying 	 */
12745775b843SRafael J. Wysocki 	if (!pci_dev->driver) {
12755775b843SRafael J. Wysocki 		pci_save_state(pci_dev);
1276967577b0SHuang Ying 		return 0;
12775775b843SRafael J. Wysocki 	}
1278967577b0SHuang Ying 
127982fee4d6SRafael J. Wysocki 	pci_dev->state_saved = false;
1280c5eb1190SJarkko Nikula 	if (pm && pm->runtime_suspend) {
12816cbf8214SRafael J. Wysocki 		error = pm->runtime_suspend(dev);
128206bf403dSImre Deak 		/*
128306bf403dSImre Deak 		 * -EBUSY and -EAGAIN is used to request the runtime PM core
128406bf403dSImre Deak 		 * to schedule a new suspend, so log the event only with debug
128506bf403dSImre Deak 		 * log level.
128606bf403dSImre Deak 		 */
1287c5eb1190SJarkko Nikula 		if (error == -EBUSY || error == -EAGAIN) {
12886941a0c2SBjorn Helgaas 			pci_dbg(pci_dev, "can't suspend now (%ps returned %d)\n",
128906bf403dSImre Deak 				pm->runtime_suspend, error);
1290c5eb1190SJarkko Nikula 			return error;
1291c5eb1190SJarkko Nikula 		} else if (error) {
12926941a0c2SBjorn Helgaas 			pci_err(pci_dev, "can't suspend (%ps returned %d)\n",
129306bf403dSImre Deak 				pm->runtime_suspend, error);
12946cbf8214SRafael J. Wysocki 			return error;
129506bf403dSImre Deak 		}
1296c5eb1190SJarkko Nikula 	}
12976cbf8214SRafael J. Wysocki 
12986cbf8214SRafael J. Wysocki 	pci_fixup_device(pci_fixup_suspend, pci_dev);
12996cbf8214SRafael J. Wysocki 
1300c5eb1190SJarkko Nikula 	if (pm && pm->runtime_suspend
1301c5eb1190SJarkko Nikula 	    && !pci_dev->state_saved && pci_dev->current_state != PCI_D0
13026cbf8214SRafael J. Wysocki 	    && pci_dev->current_state != PCI_UNKNOWN) {
130312bcae44SBjorn Helgaas 		pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev,
1304d75f773cSSakari Ailus 			      "PCI PM: State of device not saved by %pS\n",
13056cbf8214SRafael J. Wysocki 			      pm->runtime_suspend);
13066cbf8214SRafael J. Wysocki 		return 0;
13076cbf8214SRafael J. Wysocki 	}
13086cbf8214SRafael J. Wysocki 
130942eca230SDave Airlie 	if (!pci_dev->state_saved) {
13106cbf8214SRafael J. Wysocki 		pci_save_state(pci_dev);
13116cbf8214SRafael J. Wysocki 		pci_finish_runtime_suspend(pci_dev);
131242eca230SDave Airlie 	}
13136cbf8214SRafael J. Wysocki 
13146cbf8214SRafael J. Wysocki 	return 0;
13156cbf8214SRafael J. Wysocki }
13166cbf8214SRafael J. Wysocki 
13176cbf8214SRafael J. Wysocki static int pci_pm_runtime_resume(struct device *dev)
13186cbf8214SRafael J. Wysocki {
13196cbf8214SRafael J. Wysocki 	struct pci_dev *pci_dev = to_pci_dev(dev);
13206cbf8214SRafael J. Wysocki 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
13216da2f2ccSBjorn Helgaas 	int error = 0;
13226cbf8214SRafael J. Wysocki 
1323967577b0SHuang Ying 	/*
13245775b843SRafael J. Wysocki 	 * Restoring config space is necessary even if the device is not bound
13255775b843SRafael J. Wysocki 	 * to a driver because although we left it in D0, it may have gone to
13265775b843SRafael J. Wysocki 	 * D3cold when the bridge above it runtime suspended.
1327967577b0SHuang Ying 	 */
13285775b843SRafael J. Wysocki 	pci_restore_standard_config(pci_dev);
13295775b843SRafael J. Wysocki 
1330967577b0SHuang Ying 	if (!pci_dev->driver)
1331967577b0SHuang Ying 		return 0;
1332967577b0SHuang Ying 
1333db288c9cSRafael J. Wysocki 	pci_fixup_device(pci_fixup_resume_early, pci_dev);
1334f7b32a86SBjorn Helgaas 	pci_pm_default_resume(pci_dev);
13356cbf8214SRafael J. Wysocki 
1336c5eb1190SJarkko Nikula 	if (pm && pm->runtime_resume)
13376da2f2ccSBjorn Helgaas 		error = pm->runtime_resume(dev);
1338448bd857SHuang Ying 
1339448bd857SHuang Ying 	pci_dev->runtime_d3cold = false;
1340448bd857SHuang Ying 
13416da2f2ccSBjorn Helgaas 	return error;
13426cbf8214SRafael J. Wysocki }
13436cbf8214SRafael J. Wysocki 
13446cbf8214SRafael J. Wysocki static int pci_pm_runtime_idle(struct device *dev)
13456cbf8214SRafael J. Wysocki {
1346967577b0SHuang Ying 	struct pci_dev *pci_dev = to_pci_dev(dev);
13476cbf8214SRafael J. Wysocki 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
13486cbf8214SRafael J. Wysocki 
1349967577b0SHuang Ying 	/*
1350967577b0SHuang Ying 	 * If pci_dev->driver is not set (unbound), the device should
1351967577b0SHuang Ying 	 * always remain in D0 regardless of the runtime PM status
1352967577b0SHuang Ying 	 */
1353967577b0SHuang Ying 	if (!pci_dev->driver)
135445f0a85cSRafael J. Wysocki 		return 0;
1355967577b0SHuang Ying 
13566cbf8214SRafael J. Wysocki 	if (!pm)
13576cbf8214SRafael J. Wysocki 		return -ENOSYS;
13586cbf8214SRafael J. Wysocki 
135945f0a85cSRafael J. Wysocki 	if (pm->runtime_idle)
13606da2f2ccSBjorn Helgaas 		return pm->runtime_idle(dev);
13616cbf8214SRafael J. Wysocki 
13626da2f2ccSBjorn Helgaas 	return 0;
13636cbf8214SRafael J. Wysocki }
13646cbf8214SRafael J. Wysocki 
1365f91da04dSSachin Kamat static const struct dev_pm_ops pci_dev_pm_ops = {
1366bbb44d9fSRafael J. Wysocki 	.prepare = pci_pm_prepare,
13672cef548aSRafael J. Wysocki 	.complete = pci_pm_complete,
1368bbb44d9fSRafael J. Wysocki 	.suspend = pci_pm_suspend,
1369c4b65157SRafael J. Wysocki 	.suspend_late = pci_pm_suspend_late,
1370bbb44d9fSRafael J. Wysocki 	.resume = pci_pm_resume,
1371bbb44d9fSRafael J. Wysocki 	.freeze = pci_pm_freeze,
1372bbb44d9fSRafael J. Wysocki 	.thaw = pci_pm_thaw,
1373bbb44d9fSRafael J. Wysocki 	.poweroff = pci_pm_poweroff,
1374c4b65157SRafael J. Wysocki 	.poweroff_late = pci_pm_poweroff_late,
1375bbb44d9fSRafael J. Wysocki 	.restore = pci_pm_restore,
1376bbb44d9fSRafael J. Wysocki 	.suspend_noirq = pci_pm_suspend_noirq,
1377bbb44d9fSRafael J. Wysocki 	.resume_noirq = pci_pm_resume_noirq,
1378bbb44d9fSRafael J. Wysocki 	.freeze_noirq = pci_pm_freeze_noirq,
1379bbb44d9fSRafael J. Wysocki 	.thaw_noirq = pci_pm_thaw_noirq,
1380bbb44d9fSRafael J. Wysocki 	.poweroff_noirq = pci_pm_poweroff_noirq,
1381bbb44d9fSRafael J. Wysocki 	.restore_noirq = pci_pm_restore_noirq,
13826cbf8214SRafael J. Wysocki 	.runtime_suspend = pci_pm_runtime_suspend,
13836cbf8214SRafael J. Wysocki 	.runtime_resume = pci_pm_runtime_resume,
13846cbf8214SRafael J. Wysocki 	.runtime_idle = pci_pm_runtime_idle,
1385bbb44d9fSRafael J. Wysocki };
1386bbb44d9fSRafael J. Wysocki 
1387adf09493SRafael J. Wysocki #define PCI_PM_OPS_PTR	(&pci_dev_pm_ops)
1388bbb44d9fSRafael J. Wysocki 
1389fbb988beSRafael J. Wysocki #else /* !CONFIG_PM */
1390fbb988beSRafael J. Wysocki 
1391fbb988beSRafael J. Wysocki #define pci_pm_runtime_suspend	NULL
1392fbb988beSRafael J. Wysocki #define pci_pm_runtime_resume	NULL
1393fbb988beSRafael J. Wysocki #define pci_pm_runtime_idle	NULL
1394bbb44d9fSRafael J. Wysocki 
1395bbb44d9fSRafael J. Wysocki #define PCI_PM_OPS_PTR	NULL
1396bbb44d9fSRafael J. Wysocki 
1397fbb988beSRafael J. Wysocki #endif /* !CONFIG_PM */
13981da177e4SLinus Torvalds 
13991da177e4SLinus Torvalds /**
1400863b18f4SLaurent riffard  * __pci_register_driver - register a new pci driver
14011da177e4SLinus Torvalds  * @drv: the driver structure to register
1402863b18f4SLaurent riffard  * @owner: owner module of drv
1403f95d882dSRandy Dunlap  * @mod_name: module name string
14041da177e4SLinus Torvalds  *
14051da177e4SLinus Torvalds  * Adds the driver structure to the list of registered drivers.
14061da177e4SLinus Torvalds  * Returns a negative value on error, otherwise 0.
1407eaae4b3aSSteven Cole  * If no error occurred, the driver remains registered even if
14081da177e4SLinus Torvalds  * no device was claimed during registration.
14091da177e4SLinus Torvalds  */
1410725522b5SGreg Kroah-Hartman int __pci_register_driver(struct pci_driver *drv, struct module *owner,
1411725522b5SGreg Kroah-Hartman 			  const char *mod_name)
14121da177e4SLinus Torvalds {
14131da177e4SLinus Torvalds 	/* initialize common driver fields */
14141da177e4SLinus Torvalds 	drv->driver.name = drv->name;
14151da177e4SLinus Torvalds 	drv->driver.bus = &pci_bus_type;
1416863b18f4SLaurent riffard 	drv->driver.owner = owner;
1417725522b5SGreg Kroah-Hartman 	drv->driver.mod_name = mod_name;
141892d50fc1SGreg Kroah-Hartman 	drv->driver.groups = drv->groups;
141950b00755SAlan Cox 
142075865858SGreg Kroah-Hartman 	spin_lock_init(&drv->dynids.lock);
142175865858SGreg Kroah-Hartman 	INIT_LIST_HEAD(&drv->dynids.list);
14221da177e4SLinus Torvalds 
14231da177e4SLinus Torvalds 	/* register with core */
1424bfb09a86SKonstantin Khlebnikov 	return driver_register(&drv->driver);
14251da177e4SLinus Torvalds }
1426b7fe9434SRyan Desfosses EXPORT_SYMBOL(__pci_register_driver);
14271da177e4SLinus Torvalds 
14281da177e4SLinus Torvalds /**
14291da177e4SLinus Torvalds  * pci_unregister_driver - unregister a pci driver
14301da177e4SLinus Torvalds  * @drv: the driver structure to unregister
14311da177e4SLinus Torvalds  *
14321da177e4SLinus Torvalds  * Deletes the driver structure from the list of registered PCI drivers,
14331da177e4SLinus Torvalds  * gives it a chance to clean up by calling its remove() function for
14341da177e4SLinus Torvalds  * each device it was responsible for, and marks those devices as
14351da177e4SLinus Torvalds  * driverless.
14361da177e4SLinus Torvalds  */
14371da177e4SLinus Torvalds 
14383c78bc61SRyan Desfosses void pci_unregister_driver(struct pci_driver *drv)
14391da177e4SLinus Torvalds {
14401da177e4SLinus Torvalds 	driver_unregister(&drv->driver);
14411da177e4SLinus Torvalds 	pci_free_dynids(drv);
14421da177e4SLinus Torvalds }
1443b7fe9434SRyan Desfosses EXPORT_SYMBOL(pci_unregister_driver);
14441da177e4SLinus Torvalds 
14451da177e4SLinus Torvalds static struct pci_driver pci_compat_driver = {
14461da177e4SLinus Torvalds 	.name = "compat"
14471da177e4SLinus Torvalds };
14481da177e4SLinus Torvalds 
14491da177e4SLinus Torvalds /**
14501da177e4SLinus Torvalds  * pci_dev_driver - get the pci_driver of a device
14511da177e4SLinus Torvalds  * @dev: the device to query
14521da177e4SLinus Torvalds  *
14531da177e4SLinus Torvalds  * Returns the appropriate pci_driver structure or %NULL if there is no
14541da177e4SLinus Torvalds  * registered driver for the device.
14551da177e4SLinus Torvalds  */
14563c78bc61SRyan Desfosses struct pci_driver *pci_dev_driver(const struct pci_dev *dev)
14571da177e4SLinus Torvalds {
14581da177e4SLinus Torvalds 	if (dev->driver)
14591da177e4SLinus Torvalds 		return dev->driver;
14601da177e4SLinus Torvalds 	else {
14611da177e4SLinus Torvalds 		int i;
14621da177e4SLinus Torvalds 		for (i = 0; i <= PCI_ROM_RESOURCE; i++)
14631da177e4SLinus Torvalds 			if (dev->resource[i].flags & IORESOURCE_BUSY)
14641da177e4SLinus Torvalds 				return &pci_compat_driver;
14651da177e4SLinus Torvalds 	}
14661da177e4SLinus Torvalds 	return NULL;
14671da177e4SLinus Torvalds }
1468b7fe9434SRyan Desfosses EXPORT_SYMBOL(pci_dev_driver);
14691da177e4SLinus Torvalds 
14701da177e4SLinus Torvalds /**
14711da177e4SLinus Torvalds  * pci_bus_match - Tell if a PCI device structure has a matching PCI device id structure
14721da177e4SLinus Torvalds  * @dev: the PCI device structure to match against
14738f7020d3SRandy Dunlap  * @drv: the device driver to search for matching PCI device id structures
14741da177e4SLinus Torvalds  *
14751da177e4SLinus Torvalds  * Used by a driver to check whether a PCI device present in the
14761da177e4SLinus Torvalds  * system is in its list of supported devices. Returns the matching
14771da177e4SLinus Torvalds  * pci_device_id structure or %NULL if there is no match.
14781da177e4SLinus Torvalds  */
14791da177e4SLinus Torvalds static int pci_bus_match(struct device *dev, struct device_driver *drv)
14801da177e4SLinus Torvalds {
148175865858SGreg Kroah-Hartman 	struct pci_dev *pci_dev = to_pci_dev(dev);
148258d9a38fSYinghai Lu 	struct pci_driver *pci_drv;
14831da177e4SLinus Torvalds 	const struct pci_device_id *found_id;
14841da177e4SLinus Torvalds 
148558d9a38fSYinghai Lu 	if (!pci_dev->match_driver)
148658d9a38fSYinghai Lu 		return 0;
148758d9a38fSYinghai Lu 
148858d9a38fSYinghai Lu 	pci_drv = to_pci_driver(drv);
148975865858SGreg Kroah-Hartman 	found_id = pci_match_device(pci_drv, pci_dev);
14901da177e4SLinus Torvalds 	if (found_id)
14911da177e4SLinus Torvalds 		return 1;
14921da177e4SLinus Torvalds 
149375865858SGreg Kroah-Hartman 	return 0;
14941da177e4SLinus Torvalds }
14951da177e4SLinus Torvalds 
14961da177e4SLinus Torvalds /**
14971da177e4SLinus Torvalds  * pci_dev_get - increments the reference count of the pci device structure
14981da177e4SLinus Torvalds  * @dev: the device being referenced
14991da177e4SLinus Torvalds  *
15001da177e4SLinus Torvalds  * Each live reference to a device should be refcounted.
15011da177e4SLinus Torvalds  *
15021da177e4SLinus Torvalds  * Drivers for PCI devices should normally record such references in
15031da177e4SLinus Torvalds  * their probe() methods, when they bind to a device, and release
15041da177e4SLinus Torvalds  * them by calling pci_dev_put(), in their disconnect() methods.
15051da177e4SLinus Torvalds  *
15061da177e4SLinus Torvalds  * A pointer to the device with the incremented reference counter is returned.
15071da177e4SLinus Torvalds  */
15081da177e4SLinus Torvalds struct pci_dev *pci_dev_get(struct pci_dev *dev)
15091da177e4SLinus Torvalds {
15101da177e4SLinus Torvalds 	if (dev)
15111da177e4SLinus Torvalds 		get_device(&dev->dev);
15121da177e4SLinus Torvalds 	return dev;
15131da177e4SLinus Torvalds }
1514b7fe9434SRyan Desfosses EXPORT_SYMBOL(pci_dev_get);
15151da177e4SLinus Torvalds 
15161da177e4SLinus Torvalds /**
15171da177e4SLinus Torvalds  * pci_dev_put - release a use of the pci device structure
15181da177e4SLinus Torvalds  * @dev: device that's been disconnected
15191da177e4SLinus Torvalds  *
15201da177e4SLinus Torvalds  * Must be called when a user of a device is finished with it.  When the last
15211da177e4SLinus Torvalds  * user of the device calls this function, the memory of the device is freed.
15221da177e4SLinus Torvalds  */
15231da177e4SLinus Torvalds void pci_dev_put(struct pci_dev *dev)
15241da177e4SLinus Torvalds {
15251da177e4SLinus Torvalds 	if (dev)
15261da177e4SLinus Torvalds 		put_device(&dev->dev);
15271da177e4SLinus Torvalds }
1528b7fe9434SRyan Desfosses EXPORT_SYMBOL(pci_dev_put);
15291da177e4SLinus Torvalds 
15308ccc9aa1SBill Pemberton static int pci_uevent(struct device *dev, struct kobj_uevent_env *env)
15318ccc9aa1SBill Pemberton {
15328ccc9aa1SBill Pemberton 	struct pci_dev *pdev;
15338ccc9aa1SBill Pemberton 
15348ccc9aa1SBill Pemberton 	if (!dev)
15358ccc9aa1SBill Pemberton 		return -ENODEV;
15368ccc9aa1SBill Pemberton 
15378ccc9aa1SBill Pemberton 	pdev = to_pci_dev(dev);
15388ccc9aa1SBill Pemberton 
15398ccc9aa1SBill Pemberton 	if (add_uevent_var(env, "PCI_CLASS=%04X", pdev->class))
15408ccc9aa1SBill Pemberton 		return -ENOMEM;
15418ccc9aa1SBill Pemberton 
15428ccc9aa1SBill Pemberton 	if (add_uevent_var(env, "PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
15438ccc9aa1SBill Pemberton 		return -ENOMEM;
15448ccc9aa1SBill Pemberton 
15458ccc9aa1SBill Pemberton 	if (add_uevent_var(env, "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
15468ccc9aa1SBill Pemberton 			   pdev->subsystem_device))
15478ccc9aa1SBill Pemberton 		return -ENOMEM;
15488ccc9aa1SBill Pemberton 
15498ccc9aa1SBill Pemberton 	if (add_uevent_var(env, "PCI_SLOT_NAME=%s", pci_name(pdev)))
15508ccc9aa1SBill Pemberton 		return -ENOMEM;
15518ccc9aa1SBill Pemberton 
1552145b3fe5SRicardo Ribalda Delgado 	if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02X",
15538ccc9aa1SBill Pemberton 			   pdev->vendor, pdev->device,
15548ccc9aa1SBill Pemberton 			   pdev->subsystem_vendor, pdev->subsystem_device,
15558ccc9aa1SBill Pemberton 			   (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
15568ccc9aa1SBill Pemberton 			   (u8)(pdev->class)))
15578ccc9aa1SBill Pemberton 		return -ENOMEM;
1558efdd4070SBjorn Helgaas 
15598ccc9aa1SBill Pemberton 	return 0;
15608ccc9aa1SBill Pemberton }
15618ccc9aa1SBill Pemberton 
15622e28bc84SOza Pawandeep #if defined(CONFIG_PCIEPORTBUS) || defined(CONFIG_EEH)
15633ecac020SMichael Ellerman /**
15643ecac020SMichael Ellerman  * pci_uevent_ers - emit a uevent during recovery path of PCI device
15653ecac020SMichael Ellerman  * @pdev: PCI device undergoing error recovery
15663ecac020SMichael Ellerman  * @err_type: type of error event
15673ecac020SMichael Ellerman  */
15683ecac020SMichael Ellerman void pci_uevent_ers(struct pci_dev *pdev, enum pci_ers_result err_type)
15693ecac020SMichael Ellerman {
15703ecac020SMichael Ellerman 	int idx = 0;
15713ecac020SMichael Ellerman 	char *envp[3];
15723ecac020SMichael Ellerman 
15733ecac020SMichael Ellerman 	switch (err_type) {
15743ecac020SMichael Ellerman 	case PCI_ERS_RESULT_NONE:
15753ecac020SMichael Ellerman 	case PCI_ERS_RESULT_CAN_RECOVER:
15763ecac020SMichael Ellerman 		envp[idx++] = "ERROR_EVENT=BEGIN_RECOVERY";
15773ecac020SMichael Ellerman 		envp[idx++] = "DEVICE_ONLINE=0";
15783ecac020SMichael Ellerman 		break;
15793ecac020SMichael Ellerman 	case PCI_ERS_RESULT_RECOVERED:
15803ecac020SMichael Ellerman 		envp[idx++] = "ERROR_EVENT=SUCCESSFUL_RECOVERY";
15813ecac020SMichael Ellerman 		envp[idx++] = "DEVICE_ONLINE=1";
15823ecac020SMichael Ellerman 		break;
15833ecac020SMichael Ellerman 	case PCI_ERS_RESULT_DISCONNECT:
15843ecac020SMichael Ellerman 		envp[idx++] = "ERROR_EVENT=FAILED_RECOVERY";
15853ecac020SMichael Ellerman 		envp[idx++] = "DEVICE_ONLINE=0";
15863ecac020SMichael Ellerman 		break;
15873ecac020SMichael Ellerman 	default:
15883ecac020SMichael Ellerman 		break;
15893ecac020SMichael Ellerman 	}
15903ecac020SMichael Ellerman 
15913ecac020SMichael Ellerman 	if (idx > 0) {
15923ecac020SMichael Ellerman 		envp[idx++] = NULL;
15933ecac020SMichael Ellerman 		kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, envp);
15943ecac020SMichael Ellerman 	}
15953ecac020SMichael Ellerman }
15963ecac020SMichael Ellerman #endif
15973ecac020SMichael Ellerman 
159802e0bea6SPhil Sutter static int pci_bus_num_vf(struct device *dev)
159902e0bea6SPhil Sutter {
160002e0bea6SPhil Sutter 	return pci_num_vf(to_pci_dev(dev));
160102e0bea6SPhil Sutter }
160202e0bea6SPhil Sutter 
160307397df2SNipun Gupta /**
160407397df2SNipun Gupta  * pci_dma_configure - Setup DMA configuration
160507397df2SNipun Gupta  * @dev: ptr to dev structure
160607397df2SNipun Gupta  *
160707397df2SNipun Gupta  * Function to update PCI devices's DMA configuration using the same
160807397df2SNipun Gupta  * info from the OF node or ACPI node of host bridge's parent (if any).
160907397df2SNipun Gupta  */
161007397df2SNipun Gupta static int pci_dma_configure(struct device *dev)
161107397df2SNipun Gupta {
161207397df2SNipun Gupta 	struct device *bridge;
161307397df2SNipun Gupta 	int ret = 0;
161407397df2SNipun Gupta 
161507397df2SNipun Gupta 	bridge = pci_get_host_bridge_device(to_pci_dev(dev));
161607397df2SNipun Gupta 
161707397df2SNipun Gupta 	if (IS_ENABLED(CONFIG_OF) && bridge->parent &&
161807397df2SNipun Gupta 	    bridge->parent->of_node) {
16193d6ce86eSChristoph Hellwig 		ret = of_dma_configure(dev, bridge->parent->of_node, true);
162007397df2SNipun Gupta 	} else if (has_acpi_companion(bridge)) {
162107397df2SNipun Gupta 		struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
162207397df2SNipun Gupta 
1623e5361ca2SRobin Murphy 		ret = acpi_dma_configure(dev, acpi_get_dma_attr(adev));
162407397df2SNipun Gupta 	}
162507397df2SNipun Gupta 
162607397df2SNipun Gupta 	pci_put_host_bridge_device(bridge);
162707397df2SNipun Gupta 	return ret;
162807397df2SNipun Gupta }
162907397df2SNipun Gupta 
16301da177e4SLinus Torvalds struct bus_type pci_bus_type = {
16311da177e4SLinus Torvalds 	.name		= "pci",
16321da177e4SLinus Torvalds 	.match		= pci_bus_match,
1633312c004dSKay Sievers 	.uevent		= pci_uevent,
1634b15d686aSRussell King 	.probe		= pci_device_probe,
1635b15d686aSRussell King 	.remove		= pci_device_remove,
1636cbd69dbbSLinus Torvalds 	.shutdown	= pci_device_shutdown,
16375136b2daSGreg Kroah-Hartman 	.dev_groups	= pci_dev_groups,
16380f49ba55SGreg Kroah-Hartman 	.bus_groups	= pci_bus_groups,
16392229c1fbSGreg Kroah-Hartman 	.drv_groups	= pci_drv_groups,
1640bbb44d9fSRafael J. Wysocki 	.pm		= PCI_PM_OPS_PTR,
164102e0bea6SPhil Sutter 	.num_vf		= pci_bus_num_vf,
164207397df2SNipun Gupta 	.dma_configure	= pci_dma_configure,
16431da177e4SLinus Torvalds };
1644b7fe9434SRyan Desfosses EXPORT_SYMBOL(pci_bus_type);
16451da177e4SLinus Torvalds 
1646c6c889d9SBjorn Helgaas #ifdef CONFIG_PCIEPORTBUS
1647c6c889d9SBjorn Helgaas static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
1648c6c889d9SBjorn Helgaas {
1649c6c889d9SBjorn Helgaas 	struct pcie_device *pciedev;
1650c6c889d9SBjorn Helgaas 	struct pcie_port_service_driver *driver;
1651c6c889d9SBjorn Helgaas 
1652c6c889d9SBjorn Helgaas 	if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type)
1653c6c889d9SBjorn Helgaas 		return 0;
1654c6c889d9SBjorn Helgaas 
1655c6c889d9SBjorn Helgaas 	pciedev = to_pcie_device(dev);
1656c6c889d9SBjorn Helgaas 	driver = to_service_driver(drv);
1657c6c889d9SBjorn Helgaas 
1658c6c889d9SBjorn Helgaas 	if (driver->service != pciedev->service)
1659c6c889d9SBjorn Helgaas 		return 0;
1660c6c889d9SBjorn Helgaas 
1661c6c889d9SBjorn Helgaas 	if (driver->port_type != PCIE_ANY_PORT &&
1662c6c889d9SBjorn Helgaas 	    driver->port_type != pci_pcie_type(pciedev->port))
1663c6c889d9SBjorn Helgaas 		return 0;
1664c6c889d9SBjorn Helgaas 
1665c6c889d9SBjorn Helgaas 	return 1;
1666c6c889d9SBjorn Helgaas }
1667c6c889d9SBjorn Helgaas 
1668c6c889d9SBjorn Helgaas struct bus_type pcie_port_bus_type = {
1669c6c889d9SBjorn Helgaas 	.name		= "pci_express",
1670c6c889d9SBjorn Helgaas 	.match		= pcie_port_bus_match,
1671c6c889d9SBjorn Helgaas };
1672c6c889d9SBjorn Helgaas EXPORT_SYMBOL_GPL(pcie_port_bus_type);
1673c6c889d9SBjorn Helgaas #endif
1674c6c889d9SBjorn Helgaas 
16751da177e4SLinus Torvalds static int __init pci_driver_init(void)
16761da177e4SLinus Torvalds {
1677c6c889d9SBjorn Helgaas 	int ret;
1678c6c889d9SBjorn Helgaas 
1679c6c889d9SBjorn Helgaas 	ret = bus_register(&pci_bus_type);
1680c6c889d9SBjorn Helgaas 	if (ret)
1681c6c889d9SBjorn Helgaas 		return ret;
1682c6c889d9SBjorn Helgaas 
1683c6c889d9SBjorn Helgaas #ifdef CONFIG_PCIEPORTBUS
1684c6c889d9SBjorn Helgaas 	ret = bus_register(&pcie_port_bus_type);
1685c6c889d9SBjorn Helgaas 	if (ret)
1686c6c889d9SBjorn Helgaas 		return ret;
1687c6c889d9SBjorn Helgaas #endif
1688a8651194SChristoph Hellwig 	dma_debug_add_bus(&pci_bus_type);
1689c6c889d9SBjorn Helgaas 	return 0;
16901da177e4SLinus Torvalds }
16911da177e4SLinus Torvalds postcore_initcall(pci_driver_init);
1692