162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * (C) Copyright 2002-2004, 2007 Greg Kroah-Hartman <greg@kroah.com>
462306a36Sopenharmony_ci * (C) Copyright 2007 Novell Inc.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/pci.h>
862306a36Sopenharmony_ci#include <linux/module.h>
962306a36Sopenharmony_ci#include <linux/init.h>
1062306a36Sopenharmony_ci#include <linux/device.h>
1162306a36Sopenharmony_ci#include <linux/mempolicy.h>
1262306a36Sopenharmony_ci#include <linux/string.h>
1362306a36Sopenharmony_ci#include <linux/slab.h>
1462306a36Sopenharmony_ci#include <linux/sched.h>
1562306a36Sopenharmony_ci#include <linux/sched/isolation.h>
1662306a36Sopenharmony_ci#include <linux/cpu.h>
1762306a36Sopenharmony_ci#include <linux/pm_runtime.h>
1862306a36Sopenharmony_ci#include <linux/suspend.h>
1962306a36Sopenharmony_ci#include <linux/kexec.h>
2062306a36Sopenharmony_ci#include <linux/of_device.h>
2162306a36Sopenharmony_ci#include <linux/acpi.h>
2262306a36Sopenharmony_ci#include <linux/dma-map-ops.h>
2362306a36Sopenharmony_ci#include <linux/iommu.h>
2462306a36Sopenharmony_ci#include "pci.h"
2562306a36Sopenharmony_ci#include "pcie/portdrv.h"
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistruct pci_dynid {
2862306a36Sopenharmony_ci	struct list_head node;
2962306a36Sopenharmony_ci	struct pci_device_id id;
3062306a36Sopenharmony_ci};
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/**
3362306a36Sopenharmony_ci * pci_add_dynid - add a new PCI device ID to this driver and re-probe devices
3462306a36Sopenharmony_ci * @drv: target pci driver
3562306a36Sopenharmony_ci * @vendor: PCI vendor ID
3662306a36Sopenharmony_ci * @device: PCI device ID
3762306a36Sopenharmony_ci * @subvendor: PCI subvendor ID
3862306a36Sopenharmony_ci * @subdevice: PCI subdevice ID
3962306a36Sopenharmony_ci * @class: PCI class
4062306a36Sopenharmony_ci * @class_mask: PCI class mask
4162306a36Sopenharmony_ci * @driver_data: private driver data
4262306a36Sopenharmony_ci *
4362306a36Sopenharmony_ci * Adds a new dynamic pci device ID to this driver and causes the
4462306a36Sopenharmony_ci * driver to probe for all devices again.  @drv must have been
4562306a36Sopenharmony_ci * registered prior to calling this function.
4662306a36Sopenharmony_ci *
4762306a36Sopenharmony_ci * CONTEXT:
4862306a36Sopenharmony_ci * Does GFP_KERNEL allocation.
4962306a36Sopenharmony_ci *
5062306a36Sopenharmony_ci * RETURNS:
5162306a36Sopenharmony_ci * 0 on success, -errno on failure.
5262306a36Sopenharmony_ci */
5362306a36Sopenharmony_ciint pci_add_dynid(struct pci_driver *drv,
5462306a36Sopenharmony_ci		  unsigned int vendor, unsigned int device,
5562306a36Sopenharmony_ci		  unsigned int subvendor, unsigned int subdevice,
5662306a36Sopenharmony_ci		  unsigned int class, unsigned int class_mask,
5762306a36Sopenharmony_ci		  unsigned long driver_data)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	struct pci_dynid *dynid;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
6262306a36Sopenharmony_ci	if (!dynid)
6362306a36Sopenharmony_ci		return -ENOMEM;
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	dynid->id.vendor = vendor;
6662306a36Sopenharmony_ci	dynid->id.device = device;
6762306a36Sopenharmony_ci	dynid->id.subvendor = subvendor;
6862306a36Sopenharmony_ci	dynid->id.subdevice = subdevice;
6962306a36Sopenharmony_ci	dynid->id.class = class;
7062306a36Sopenharmony_ci	dynid->id.class_mask = class_mask;
7162306a36Sopenharmony_ci	dynid->id.driver_data = driver_data;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	spin_lock(&drv->dynids.lock);
7462306a36Sopenharmony_ci	list_add_tail(&dynid->node, &drv->dynids.list);
7562306a36Sopenharmony_ci	spin_unlock(&drv->dynids.lock);
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	return driver_attach(&drv->driver);
7862306a36Sopenharmony_ci}
7962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_add_dynid);
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_cistatic void pci_free_dynids(struct pci_driver *drv)
8262306a36Sopenharmony_ci{
8362306a36Sopenharmony_ci	struct pci_dynid *dynid, *n;
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	spin_lock(&drv->dynids.lock);
8662306a36Sopenharmony_ci	list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
8762306a36Sopenharmony_ci		list_del(&dynid->node);
8862306a36Sopenharmony_ci		kfree(dynid);
8962306a36Sopenharmony_ci	}
9062306a36Sopenharmony_ci	spin_unlock(&drv->dynids.lock);
9162306a36Sopenharmony_ci}
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci/**
9462306a36Sopenharmony_ci * pci_match_id - See if a PCI device matches a given pci_id table
9562306a36Sopenharmony_ci * @ids: array of PCI device ID structures to search in
9662306a36Sopenharmony_ci * @dev: the PCI device structure to match against.
9762306a36Sopenharmony_ci *
9862306a36Sopenharmony_ci * Used by a driver to check whether a PCI device is in its list of
9962306a36Sopenharmony_ci * supported devices.  Returns the matching pci_device_id structure or
10062306a36Sopenharmony_ci * %NULL if there is no match.
10162306a36Sopenharmony_ci *
10262306a36Sopenharmony_ci * Deprecated; don't use this as it will not catch any dynamic IDs
10362306a36Sopenharmony_ci * that a driver might want to check for.
10462306a36Sopenharmony_ci */
10562306a36Sopenharmony_ciconst struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
10662306a36Sopenharmony_ci					 struct pci_dev *dev)
10762306a36Sopenharmony_ci{
10862306a36Sopenharmony_ci	if (ids) {
10962306a36Sopenharmony_ci		while (ids->vendor || ids->subvendor || ids->class_mask) {
11062306a36Sopenharmony_ci			if (pci_match_one_device(ids, dev))
11162306a36Sopenharmony_ci				return ids;
11262306a36Sopenharmony_ci			ids++;
11362306a36Sopenharmony_ci		}
11462306a36Sopenharmony_ci	}
11562306a36Sopenharmony_ci	return NULL;
11662306a36Sopenharmony_ci}
11762306a36Sopenharmony_ciEXPORT_SYMBOL(pci_match_id);
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_cistatic const struct pci_device_id pci_device_id_any = {
12062306a36Sopenharmony_ci	.vendor = PCI_ANY_ID,
12162306a36Sopenharmony_ci	.device = PCI_ANY_ID,
12262306a36Sopenharmony_ci	.subvendor = PCI_ANY_ID,
12362306a36Sopenharmony_ci	.subdevice = PCI_ANY_ID,
12462306a36Sopenharmony_ci};
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci/**
12762306a36Sopenharmony_ci * pci_match_device - See if a device matches a driver's list of IDs
12862306a36Sopenharmony_ci * @drv: the PCI driver to match against
12962306a36Sopenharmony_ci * @dev: the PCI device structure to match against
13062306a36Sopenharmony_ci *
13162306a36Sopenharmony_ci * Used by a driver to check whether a PCI device is in its list of
13262306a36Sopenharmony_ci * supported devices or in the dynids list, which may have been augmented
13362306a36Sopenharmony_ci * via the sysfs "new_id" file.  Returns the matching pci_device_id
13462306a36Sopenharmony_ci * structure or %NULL if there is no match.
13562306a36Sopenharmony_ci */
13662306a36Sopenharmony_cistatic const struct pci_device_id *pci_match_device(struct pci_driver *drv,
13762306a36Sopenharmony_ci						    struct pci_dev *dev)
13862306a36Sopenharmony_ci{
13962306a36Sopenharmony_ci	struct pci_dynid *dynid;
14062306a36Sopenharmony_ci	const struct pci_device_id *found_id = NULL, *ids;
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	/* When driver_override is set, only bind to the matching driver */
14362306a36Sopenharmony_ci	if (dev->driver_override && strcmp(dev->driver_override, drv->name))
14462306a36Sopenharmony_ci		return NULL;
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	/* Look at the dynamic ids first, before the static ones */
14762306a36Sopenharmony_ci	spin_lock(&drv->dynids.lock);
14862306a36Sopenharmony_ci	list_for_each_entry(dynid, &drv->dynids.list, node) {
14962306a36Sopenharmony_ci		if (pci_match_one_device(&dynid->id, dev)) {
15062306a36Sopenharmony_ci			found_id = &dynid->id;
15162306a36Sopenharmony_ci			break;
15262306a36Sopenharmony_ci		}
15362306a36Sopenharmony_ci	}
15462306a36Sopenharmony_ci	spin_unlock(&drv->dynids.lock);
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	if (found_id)
15762306a36Sopenharmony_ci		return found_id;
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	for (ids = drv->id_table; (found_id = pci_match_id(ids, dev));
16062306a36Sopenharmony_ci	     ids = found_id + 1) {
16162306a36Sopenharmony_ci		/*
16262306a36Sopenharmony_ci		 * The match table is split based on driver_override.
16362306a36Sopenharmony_ci		 * In case override_only was set, enforce driver_override
16462306a36Sopenharmony_ci		 * matching.
16562306a36Sopenharmony_ci		 */
16662306a36Sopenharmony_ci		if (found_id->override_only) {
16762306a36Sopenharmony_ci			if (dev->driver_override)
16862306a36Sopenharmony_ci				return found_id;
16962306a36Sopenharmony_ci		} else {
17062306a36Sopenharmony_ci			return found_id;
17162306a36Sopenharmony_ci		}
17262306a36Sopenharmony_ci	}
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci	/* driver_override will always match, send a dummy id */
17562306a36Sopenharmony_ci	if (dev->driver_override)
17662306a36Sopenharmony_ci		return &pci_device_id_any;
17762306a36Sopenharmony_ci	return NULL;
17862306a36Sopenharmony_ci}
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci/**
18162306a36Sopenharmony_ci * new_id_store - sysfs frontend to pci_add_dynid()
18262306a36Sopenharmony_ci * @driver: target device driver
18362306a36Sopenharmony_ci * @buf: buffer for scanning device ID data
18462306a36Sopenharmony_ci * @count: input size
18562306a36Sopenharmony_ci *
18662306a36Sopenharmony_ci * Allow PCI IDs to be added to an existing driver via sysfs.
18762306a36Sopenharmony_ci */
18862306a36Sopenharmony_cistatic ssize_t new_id_store(struct device_driver *driver, const char *buf,
18962306a36Sopenharmony_ci			    size_t count)
19062306a36Sopenharmony_ci{
19162306a36Sopenharmony_ci	struct pci_driver *pdrv = to_pci_driver(driver);
19262306a36Sopenharmony_ci	const struct pci_device_id *ids = pdrv->id_table;
19362306a36Sopenharmony_ci	u32 vendor, device, subvendor = PCI_ANY_ID,
19462306a36Sopenharmony_ci		subdevice = PCI_ANY_ID, class = 0, class_mask = 0;
19562306a36Sopenharmony_ci	unsigned long driver_data = 0;
19662306a36Sopenharmony_ci	int fields;
19762306a36Sopenharmony_ci	int retval = 0;
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci	fields = sscanf(buf, "%x %x %x %x %x %x %lx",
20062306a36Sopenharmony_ci			&vendor, &device, &subvendor, &subdevice,
20162306a36Sopenharmony_ci			&class, &class_mask, &driver_data);
20262306a36Sopenharmony_ci	if (fields < 2)
20362306a36Sopenharmony_ci		return -EINVAL;
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci	if (fields != 7) {
20662306a36Sopenharmony_ci		struct pci_dev *pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
20762306a36Sopenharmony_ci		if (!pdev)
20862306a36Sopenharmony_ci			return -ENOMEM;
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci		pdev->vendor = vendor;
21162306a36Sopenharmony_ci		pdev->device = device;
21262306a36Sopenharmony_ci		pdev->subsystem_vendor = subvendor;
21362306a36Sopenharmony_ci		pdev->subsystem_device = subdevice;
21462306a36Sopenharmony_ci		pdev->class = class;
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci		if (pci_match_device(pdrv, pdev))
21762306a36Sopenharmony_ci			retval = -EEXIST;
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci		kfree(pdev);
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci		if (retval)
22262306a36Sopenharmony_ci			return retval;
22362306a36Sopenharmony_ci	}
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	/* Only accept driver_data values that match an existing id_table
22662306a36Sopenharmony_ci	   entry */
22762306a36Sopenharmony_ci	if (ids) {
22862306a36Sopenharmony_ci		retval = -EINVAL;
22962306a36Sopenharmony_ci		while (ids->vendor || ids->subvendor || ids->class_mask) {
23062306a36Sopenharmony_ci			if (driver_data == ids->driver_data) {
23162306a36Sopenharmony_ci				retval = 0;
23262306a36Sopenharmony_ci				break;
23362306a36Sopenharmony_ci			}
23462306a36Sopenharmony_ci			ids++;
23562306a36Sopenharmony_ci		}
23662306a36Sopenharmony_ci		if (retval)	/* No match */
23762306a36Sopenharmony_ci			return retval;
23862306a36Sopenharmony_ci	}
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	retval = pci_add_dynid(pdrv, vendor, device, subvendor, subdevice,
24162306a36Sopenharmony_ci			       class, class_mask, driver_data);
24262306a36Sopenharmony_ci	if (retval)
24362306a36Sopenharmony_ci		return retval;
24462306a36Sopenharmony_ci	return count;
24562306a36Sopenharmony_ci}
24662306a36Sopenharmony_cistatic DRIVER_ATTR_WO(new_id);
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci/**
24962306a36Sopenharmony_ci * remove_id_store - remove a PCI device ID from this driver
25062306a36Sopenharmony_ci * @driver: target device driver
25162306a36Sopenharmony_ci * @buf: buffer for scanning device ID data
25262306a36Sopenharmony_ci * @count: input size
25362306a36Sopenharmony_ci *
25462306a36Sopenharmony_ci * Removes a dynamic pci device ID to this driver.
25562306a36Sopenharmony_ci */
25662306a36Sopenharmony_cistatic ssize_t remove_id_store(struct device_driver *driver, const char *buf,
25762306a36Sopenharmony_ci			       size_t count)
25862306a36Sopenharmony_ci{
25962306a36Sopenharmony_ci	struct pci_dynid *dynid, *n;
26062306a36Sopenharmony_ci	struct pci_driver *pdrv = to_pci_driver(driver);
26162306a36Sopenharmony_ci	u32 vendor, device, subvendor = PCI_ANY_ID,
26262306a36Sopenharmony_ci		subdevice = PCI_ANY_ID, class = 0, class_mask = 0;
26362306a36Sopenharmony_ci	int fields;
26462306a36Sopenharmony_ci	size_t retval = -ENODEV;
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci	fields = sscanf(buf, "%x %x %x %x %x %x",
26762306a36Sopenharmony_ci			&vendor, &device, &subvendor, &subdevice,
26862306a36Sopenharmony_ci			&class, &class_mask);
26962306a36Sopenharmony_ci	if (fields < 2)
27062306a36Sopenharmony_ci		return -EINVAL;
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci	spin_lock(&pdrv->dynids.lock);
27362306a36Sopenharmony_ci	list_for_each_entry_safe(dynid, n, &pdrv->dynids.list, node) {
27462306a36Sopenharmony_ci		struct pci_device_id *id = &dynid->id;
27562306a36Sopenharmony_ci		if ((id->vendor == vendor) &&
27662306a36Sopenharmony_ci		    (id->device == device) &&
27762306a36Sopenharmony_ci		    (subvendor == PCI_ANY_ID || id->subvendor == subvendor) &&
27862306a36Sopenharmony_ci		    (subdevice == PCI_ANY_ID || id->subdevice == subdevice) &&
27962306a36Sopenharmony_ci		    !((id->class ^ class) & class_mask)) {
28062306a36Sopenharmony_ci			list_del(&dynid->node);
28162306a36Sopenharmony_ci			kfree(dynid);
28262306a36Sopenharmony_ci			retval = count;
28362306a36Sopenharmony_ci			break;
28462306a36Sopenharmony_ci		}
28562306a36Sopenharmony_ci	}
28662306a36Sopenharmony_ci	spin_unlock(&pdrv->dynids.lock);
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	return retval;
28962306a36Sopenharmony_ci}
29062306a36Sopenharmony_cistatic DRIVER_ATTR_WO(remove_id);
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_cistatic struct attribute *pci_drv_attrs[] = {
29362306a36Sopenharmony_ci	&driver_attr_new_id.attr,
29462306a36Sopenharmony_ci	&driver_attr_remove_id.attr,
29562306a36Sopenharmony_ci	NULL,
29662306a36Sopenharmony_ci};
29762306a36Sopenharmony_ciATTRIBUTE_GROUPS(pci_drv);
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_cistruct drv_dev_and_id {
30062306a36Sopenharmony_ci	struct pci_driver *drv;
30162306a36Sopenharmony_ci	struct pci_dev *dev;
30262306a36Sopenharmony_ci	const struct pci_device_id *id;
30362306a36Sopenharmony_ci};
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_cistatic long local_pci_probe(void *_ddi)
30662306a36Sopenharmony_ci{
30762306a36Sopenharmony_ci	struct drv_dev_and_id *ddi = _ddi;
30862306a36Sopenharmony_ci	struct pci_dev *pci_dev = ddi->dev;
30962306a36Sopenharmony_ci	struct pci_driver *pci_drv = ddi->drv;
31062306a36Sopenharmony_ci	struct device *dev = &pci_dev->dev;
31162306a36Sopenharmony_ci	int rc;
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	/*
31462306a36Sopenharmony_ci	 * Unbound PCI devices are always put in D0, regardless of
31562306a36Sopenharmony_ci	 * runtime PM status.  During probe, the device is set to
31662306a36Sopenharmony_ci	 * active and the usage count is incremented.  If the driver
31762306a36Sopenharmony_ci	 * supports runtime PM, it should call pm_runtime_put_noidle(),
31862306a36Sopenharmony_ci	 * or any other runtime PM helper function decrementing the usage
31962306a36Sopenharmony_ci	 * count, in its probe routine and pm_runtime_get_noresume() in
32062306a36Sopenharmony_ci	 * its remove routine.
32162306a36Sopenharmony_ci	 */
32262306a36Sopenharmony_ci	pm_runtime_get_sync(dev);
32362306a36Sopenharmony_ci	pci_dev->driver = pci_drv;
32462306a36Sopenharmony_ci	rc = pci_drv->probe(pci_dev, ddi->id);
32562306a36Sopenharmony_ci	if (!rc)
32662306a36Sopenharmony_ci		return rc;
32762306a36Sopenharmony_ci	if (rc < 0) {
32862306a36Sopenharmony_ci		pci_dev->driver = NULL;
32962306a36Sopenharmony_ci		pm_runtime_put_sync(dev);
33062306a36Sopenharmony_ci		return rc;
33162306a36Sopenharmony_ci	}
33262306a36Sopenharmony_ci	/*
33362306a36Sopenharmony_ci	 * Probe function should return < 0 for failure, 0 for success
33462306a36Sopenharmony_ci	 * Treat values > 0 as success, but warn.
33562306a36Sopenharmony_ci	 */
33662306a36Sopenharmony_ci	pci_warn(pci_dev, "Driver probe function unexpectedly returned %d\n",
33762306a36Sopenharmony_ci		 rc);
33862306a36Sopenharmony_ci	return 0;
33962306a36Sopenharmony_ci}
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_cistatic bool pci_physfn_is_probed(struct pci_dev *dev)
34262306a36Sopenharmony_ci{
34362306a36Sopenharmony_ci#ifdef CONFIG_PCI_IOV
34462306a36Sopenharmony_ci	return dev->is_virtfn && dev->physfn->is_probed;
34562306a36Sopenharmony_ci#else
34662306a36Sopenharmony_ci	return false;
34762306a36Sopenharmony_ci#endif
34862306a36Sopenharmony_ci}
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_cistatic int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
35162306a36Sopenharmony_ci			  const struct pci_device_id *id)
35262306a36Sopenharmony_ci{
35362306a36Sopenharmony_ci	int error, node, cpu;
35462306a36Sopenharmony_ci	struct drv_dev_and_id ddi = { drv, dev, id };
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci	/*
35762306a36Sopenharmony_ci	 * Execute driver initialization on node where the device is
35862306a36Sopenharmony_ci	 * attached.  This way the driver likely allocates its local memory
35962306a36Sopenharmony_ci	 * on the right node.
36062306a36Sopenharmony_ci	 */
36162306a36Sopenharmony_ci	node = dev_to_node(&dev->dev);
36262306a36Sopenharmony_ci	dev->is_probed = 1;
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci	cpu_hotplug_disable();
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci	/*
36762306a36Sopenharmony_ci	 * Prevent nesting work_on_cpu() for the case where a Virtual Function
36862306a36Sopenharmony_ci	 * device is probed from work_on_cpu() of the Physical device.
36962306a36Sopenharmony_ci	 */
37062306a36Sopenharmony_ci	if (node < 0 || node >= MAX_NUMNODES || !node_online(node) ||
37162306a36Sopenharmony_ci	    pci_physfn_is_probed(dev)) {
37262306a36Sopenharmony_ci		cpu = nr_cpu_ids;
37362306a36Sopenharmony_ci	} else {
37462306a36Sopenharmony_ci		cpumask_var_t wq_domain_mask;
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci		if (!zalloc_cpumask_var(&wq_domain_mask, GFP_KERNEL)) {
37762306a36Sopenharmony_ci			error = -ENOMEM;
37862306a36Sopenharmony_ci			goto out;
37962306a36Sopenharmony_ci		}
38062306a36Sopenharmony_ci		cpumask_and(wq_domain_mask,
38162306a36Sopenharmony_ci			    housekeeping_cpumask(HK_TYPE_WQ),
38262306a36Sopenharmony_ci			    housekeeping_cpumask(HK_TYPE_DOMAIN));
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci		cpu = cpumask_any_and(cpumask_of_node(node),
38562306a36Sopenharmony_ci				      wq_domain_mask);
38662306a36Sopenharmony_ci		free_cpumask_var(wq_domain_mask);
38762306a36Sopenharmony_ci	}
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci	if (cpu < nr_cpu_ids)
39062306a36Sopenharmony_ci		error = work_on_cpu(cpu, local_pci_probe, &ddi);
39162306a36Sopenharmony_ci	else
39262306a36Sopenharmony_ci		error = local_pci_probe(&ddi);
39362306a36Sopenharmony_ciout:
39462306a36Sopenharmony_ci	dev->is_probed = 0;
39562306a36Sopenharmony_ci	cpu_hotplug_enable();
39662306a36Sopenharmony_ci	return error;
39762306a36Sopenharmony_ci}
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci/**
40062306a36Sopenharmony_ci * __pci_device_probe - check if a driver wants to claim a specific PCI device
40162306a36Sopenharmony_ci * @drv: driver to call to check if it wants the PCI device
40262306a36Sopenharmony_ci * @pci_dev: PCI device being probed
40362306a36Sopenharmony_ci *
40462306a36Sopenharmony_ci * returns 0 on success, else error.
40562306a36Sopenharmony_ci * side-effect: pci_dev->driver is set to drv when drv claims pci_dev.
40662306a36Sopenharmony_ci */
40762306a36Sopenharmony_cistatic int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
40862306a36Sopenharmony_ci{
40962306a36Sopenharmony_ci	const struct pci_device_id *id;
41062306a36Sopenharmony_ci	int error = 0;
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci	if (drv->probe) {
41362306a36Sopenharmony_ci		error = -ENODEV;
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci		id = pci_match_device(drv, pci_dev);
41662306a36Sopenharmony_ci		if (id)
41762306a36Sopenharmony_ci			error = pci_call_probe(drv, pci_dev, id);
41862306a36Sopenharmony_ci	}
41962306a36Sopenharmony_ci	return error;
42062306a36Sopenharmony_ci}
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ciint __weak pcibios_alloc_irq(struct pci_dev *dev)
42362306a36Sopenharmony_ci{
42462306a36Sopenharmony_ci	return 0;
42562306a36Sopenharmony_ci}
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_civoid __weak pcibios_free_irq(struct pci_dev *dev)
42862306a36Sopenharmony_ci{
42962306a36Sopenharmony_ci}
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_ci#ifdef CONFIG_PCI_IOV
43262306a36Sopenharmony_cistatic inline bool pci_device_can_probe(struct pci_dev *pdev)
43362306a36Sopenharmony_ci{
43462306a36Sopenharmony_ci	return (!pdev->is_virtfn || pdev->physfn->sriov->drivers_autoprobe ||
43562306a36Sopenharmony_ci		pdev->driver_override);
43662306a36Sopenharmony_ci}
43762306a36Sopenharmony_ci#else
43862306a36Sopenharmony_cistatic inline bool pci_device_can_probe(struct pci_dev *pdev)
43962306a36Sopenharmony_ci{
44062306a36Sopenharmony_ci	return true;
44162306a36Sopenharmony_ci}
44262306a36Sopenharmony_ci#endif
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_cistatic int pci_device_probe(struct device *dev)
44562306a36Sopenharmony_ci{
44662306a36Sopenharmony_ci	int error;
44762306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
44862306a36Sopenharmony_ci	struct pci_driver *drv = to_pci_driver(dev->driver);
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci	if (!pci_device_can_probe(pci_dev))
45162306a36Sopenharmony_ci		return -ENODEV;
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_ci	pci_assign_irq(pci_dev);
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci	error = pcibios_alloc_irq(pci_dev);
45662306a36Sopenharmony_ci	if (error < 0)
45762306a36Sopenharmony_ci		return error;
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_ci	pci_dev_get(pci_dev);
46062306a36Sopenharmony_ci	error = __pci_device_probe(drv, pci_dev);
46162306a36Sopenharmony_ci	if (error) {
46262306a36Sopenharmony_ci		pcibios_free_irq(pci_dev);
46362306a36Sopenharmony_ci		pci_dev_put(pci_dev);
46462306a36Sopenharmony_ci	}
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ci	return error;
46762306a36Sopenharmony_ci}
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_cistatic void pci_device_remove(struct device *dev)
47062306a36Sopenharmony_ci{
47162306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
47262306a36Sopenharmony_ci	struct pci_driver *drv = pci_dev->driver;
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_ci	if (drv->remove) {
47562306a36Sopenharmony_ci		pm_runtime_get_sync(dev);
47662306a36Sopenharmony_ci		/*
47762306a36Sopenharmony_ci		 * If the driver provides a .runtime_idle() callback and it has
47862306a36Sopenharmony_ci		 * started to run already, it may continue to run in parallel
47962306a36Sopenharmony_ci		 * with the code below, so wait until all of the runtime PM
48062306a36Sopenharmony_ci		 * activity has completed.
48162306a36Sopenharmony_ci		 */
48262306a36Sopenharmony_ci		pm_runtime_barrier(dev);
48362306a36Sopenharmony_ci		drv->remove(pci_dev);
48462306a36Sopenharmony_ci		pm_runtime_put_noidle(dev);
48562306a36Sopenharmony_ci	}
48662306a36Sopenharmony_ci	pcibios_free_irq(pci_dev);
48762306a36Sopenharmony_ci	pci_dev->driver = NULL;
48862306a36Sopenharmony_ci	pci_iov_remove(pci_dev);
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci	/* Undo the runtime PM settings in local_pci_probe() */
49162306a36Sopenharmony_ci	pm_runtime_put_sync(dev);
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci	/*
49462306a36Sopenharmony_ci	 * If the device is still on, set the power state as "unknown",
49562306a36Sopenharmony_ci	 * since it might change by the next time we load the driver.
49662306a36Sopenharmony_ci	 */
49762306a36Sopenharmony_ci	if (pci_dev->current_state == PCI_D0)
49862306a36Sopenharmony_ci		pci_dev->current_state = PCI_UNKNOWN;
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci	/*
50162306a36Sopenharmony_ci	 * We would love to complain here if pci_dev->is_enabled is set, that
50262306a36Sopenharmony_ci	 * the driver should have called pci_disable_device(), but the
50362306a36Sopenharmony_ci	 * unfortunate fact is there are too many odd BIOS and bridge setups
50462306a36Sopenharmony_ci	 * that don't like drivers doing that all of the time.
50562306a36Sopenharmony_ci	 * Oh well, we can dream of sane hardware when we sleep, no matter how
50662306a36Sopenharmony_ci	 * horrible the crap we have to deal with is when we are awake...
50762306a36Sopenharmony_ci	 */
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci	pci_dev_put(pci_dev);
51062306a36Sopenharmony_ci}
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_cistatic void pci_device_shutdown(struct device *dev)
51362306a36Sopenharmony_ci{
51462306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
51562306a36Sopenharmony_ci	struct pci_driver *drv = pci_dev->driver;
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci	pm_runtime_resume(dev);
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci	if (drv && drv->shutdown)
52062306a36Sopenharmony_ci		drv->shutdown(pci_dev);
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci	/*
52362306a36Sopenharmony_ci	 * If this is a kexec reboot, turn off Bus Master bit on the
52462306a36Sopenharmony_ci	 * device to tell it to not continue to do DMA. Don't touch
52562306a36Sopenharmony_ci	 * devices in D3cold or unknown states.
52662306a36Sopenharmony_ci	 * If it is not a kexec reboot, firmware will hit the PCI
52762306a36Sopenharmony_ci	 * devices with big hammer and stop their DMA any way.
52862306a36Sopenharmony_ci	 */
52962306a36Sopenharmony_ci	if (kexec_in_progress && (pci_dev->current_state <= PCI_D3hot))
53062306a36Sopenharmony_ci		pci_clear_master(pci_dev);
53162306a36Sopenharmony_ci}
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci#ifdef CONFIG_PM_SLEEP
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci/* Auxiliary functions used for system resume */
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci/**
53862306a36Sopenharmony_ci * pci_restore_standard_config - restore standard config registers of PCI device
53962306a36Sopenharmony_ci * @pci_dev: PCI device to handle
54062306a36Sopenharmony_ci */
54162306a36Sopenharmony_cistatic int pci_restore_standard_config(struct pci_dev *pci_dev)
54262306a36Sopenharmony_ci{
54362306a36Sopenharmony_ci	pci_update_current_state(pci_dev, PCI_UNKNOWN);
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci	if (pci_dev->current_state != PCI_D0) {
54662306a36Sopenharmony_ci		int error = pci_set_power_state(pci_dev, PCI_D0);
54762306a36Sopenharmony_ci		if (error)
54862306a36Sopenharmony_ci			return error;
54962306a36Sopenharmony_ci	}
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci	pci_restore_state(pci_dev);
55262306a36Sopenharmony_ci	pci_pme_restore(pci_dev);
55362306a36Sopenharmony_ci	return 0;
55462306a36Sopenharmony_ci}
55562306a36Sopenharmony_ci#endif /* CONFIG_PM_SLEEP */
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci#ifdef CONFIG_PM
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci/* Auxiliary functions used for system resume and run-time resume */
56062306a36Sopenharmony_ci
56162306a36Sopenharmony_cistatic void pci_pm_default_resume(struct pci_dev *pci_dev)
56262306a36Sopenharmony_ci{
56362306a36Sopenharmony_ci	pci_fixup_device(pci_fixup_resume, pci_dev);
56462306a36Sopenharmony_ci	pci_enable_wake(pci_dev, PCI_D0, false);
56562306a36Sopenharmony_ci}
56662306a36Sopenharmony_ci
56762306a36Sopenharmony_cistatic void pci_pm_power_up_and_verify_state(struct pci_dev *pci_dev)
56862306a36Sopenharmony_ci{
56962306a36Sopenharmony_ci	pci_power_up(pci_dev);
57062306a36Sopenharmony_ci	pci_update_current_state(pci_dev, PCI_D0);
57162306a36Sopenharmony_ci}
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_cistatic void pci_pm_default_resume_early(struct pci_dev *pci_dev)
57462306a36Sopenharmony_ci{
57562306a36Sopenharmony_ci	pci_pm_power_up_and_verify_state(pci_dev);
57662306a36Sopenharmony_ci	pci_restore_state(pci_dev);
57762306a36Sopenharmony_ci	pci_pme_restore(pci_dev);
57862306a36Sopenharmony_ci}
57962306a36Sopenharmony_ci
58062306a36Sopenharmony_cistatic void pci_pm_bridge_power_up_actions(struct pci_dev *pci_dev)
58162306a36Sopenharmony_ci{
58262306a36Sopenharmony_ci	int ret;
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci	ret = pci_bridge_wait_for_secondary_bus(pci_dev, "resume");
58562306a36Sopenharmony_ci	if (ret) {
58662306a36Sopenharmony_ci		/*
58762306a36Sopenharmony_ci		 * The downstream link failed to come up, so mark the
58862306a36Sopenharmony_ci		 * devices below as disconnected to make sure we don't
58962306a36Sopenharmony_ci		 * attempt to resume them.
59062306a36Sopenharmony_ci		 */
59162306a36Sopenharmony_ci		pci_walk_bus(pci_dev->subordinate, pci_dev_set_disconnected,
59262306a36Sopenharmony_ci			     NULL);
59362306a36Sopenharmony_ci		return;
59462306a36Sopenharmony_ci	}
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ci	/*
59762306a36Sopenharmony_ci	 * When powering on a bridge from D3cold, the whole hierarchy may be
59862306a36Sopenharmony_ci	 * powered on into D0uninitialized state, resume them to give them a
59962306a36Sopenharmony_ci	 * chance to suspend again
60062306a36Sopenharmony_ci	 */
60162306a36Sopenharmony_ci	pci_resume_bus(pci_dev->subordinate);
60262306a36Sopenharmony_ci}
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci#endif /* CONFIG_PM */
60562306a36Sopenharmony_ci
60662306a36Sopenharmony_ci#ifdef CONFIG_PM_SLEEP
60762306a36Sopenharmony_ci
60862306a36Sopenharmony_ci/*
60962306a36Sopenharmony_ci * Default "suspend" method for devices that have no driver provided suspend,
61062306a36Sopenharmony_ci * or not even a driver at all (second part).
61162306a36Sopenharmony_ci */
61262306a36Sopenharmony_cistatic void pci_pm_set_unknown_state(struct pci_dev *pci_dev)
61362306a36Sopenharmony_ci{
61462306a36Sopenharmony_ci	/*
61562306a36Sopenharmony_ci	 * mark its power state as "unknown", since we don't know if
61662306a36Sopenharmony_ci	 * e.g. the BIOS will change its device state when we suspend.
61762306a36Sopenharmony_ci	 */
61862306a36Sopenharmony_ci	if (pci_dev->current_state == PCI_D0)
61962306a36Sopenharmony_ci		pci_dev->current_state = PCI_UNKNOWN;
62062306a36Sopenharmony_ci}
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci/*
62362306a36Sopenharmony_ci * Default "resume" method for devices that have no driver provided resume,
62462306a36Sopenharmony_ci * or not even a driver at all (second part).
62562306a36Sopenharmony_ci */
62662306a36Sopenharmony_cistatic int pci_pm_reenable_device(struct pci_dev *pci_dev)
62762306a36Sopenharmony_ci{
62862306a36Sopenharmony_ci	int retval;
62962306a36Sopenharmony_ci
63062306a36Sopenharmony_ci	/* if the device was enabled before suspend, re-enable */
63162306a36Sopenharmony_ci	retval = pci_reenable_device(pci_dev);
63262306a36Sopenharmony_ci	/*
63362306a36Sopenharmony_ci	 * if the device was busmaster before the suspend, make it busmaster
63462306a36Sopenharmony_ci	 * again
63562306a36Sopenharmony_ci	 */
63662306a36Sopenharmony_ci	if (pci_dev->is_busmaster)
63762306a36Sopenharmony_ci		pci_set_master(pci_dev);
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_ci	return retval;
64062306a36Sopenharmony_ci}
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_cistatic int pci_legacy_suspend(struct device *dev, pm_message_t state)
64362306a36Sopenharmony_ci{
64462306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
64562306a36Sopenharmony_ci	struct pci_driver *drv = pci_dev->driver;
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_ci	if (drv && drv->suspend) {
64862306a36Sopenharmony_ci		pci_power_t prev = pci_dev->current_state;
64962306a36Sopenharmony_ci		int error;
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_ci		error = drv->suspend(pci_dev, state);
65262306a36Sopenharmony_ci		suspend_report_result(dev, drv->suspend, error);
65362306a36Sopenharmony_ci		if (error)
65462306a36Sopenharmony_ci			return error;
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_ci		if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
65762306a36Sopenharmony_ci		    && pci_dev->current_state != PCI_UNKNOWN) {
65862306a36Sopenharmony_ci			pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev,
65962306a36Sopenharmony_ci				      "PCI PM: Device state not saved by %pS\n",
66062306a36Sopenharmony_ci				      drv->suspend);
66162306a36Sopenharmony_ci		}
66262306a36Sopenharmony_ci	}
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci	pci_fixup_device(pci_fixup_suspend, pci_dev);
66562306a36Sopenharmony_ci
66662306a36Sopenharmony_ci	return 0;
66762306a36Sopenharmony_ci}
66862306a36Sopenharmony_ci
66962306a36Sopenharmony_cistatic int pci_legacy_suspend_late(struct device *dev)
67062306a36Sopenharmony_ci{
67162306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
67262306a36Sopenharmony_ci
67362306a36Sopenharmony_ci	if (!pci_dev->state_saved)
67462306a36Sopenharmony_ci		pci_save_state(pci_dev);
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci	pci_pm_set_unknown_state(pci_dev);
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_ci	pci_fixup_device(pci_fixup_suspend_late, pci_dev);
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	return 0;
68162306a36Sopenharmony_ci}
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_cistatic int pci_legacy_resume(struct device *dev)
68462306a36Sopenharmony_ci{
68562306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
68662306a36Sopenharmony_ci	struct pci_driver *drv = pci_dev->driver;
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci	pci_fixup_device(pci_fixup_resume, pci_dev);
68962306a36Sopenharmony_ci
69062306a36Sopenharmony_ci	return drv && drv->resume ?
69162306a36Sopenharmony_ci			drv->resume(pci_dev) : pci_pm_reenable_device(pci_dev);
69262306a36Sopenharmony_ci}
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci/* Auxiliary functions used by the new power management framework */
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_cistatic void pci_pm_default_suspend(struct pci_dev *pci_dev)
69762306a36Sopenharmony_ci{
69862306a36Sopenharmony_ci	/* Disable non-bridge devices without PM support */
69962306a36Sopenharmony_ci	if (!pci_has_subordinate(pci_dev))
70062306a36Sopenharmony_ci		pci_disable_enabled_device(pci_dev);
70162306a36Sopenharmony_ci}
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_cistatic bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
70462306a36Sopenharmony_ci{
70562306a36Sopenharmony_ci	struct pci_driver *drv = pci_dev->driver;
70662306a36Sopenharmony_ci	bool ret = drv && (drv->suspend || drv->resume);
70762306a36Sopenharmony_ci
70862306a36Sopenharmony_ci	/*
70962306a36Sopenharmony_ci	 * Legacy PM support is used by default, so warn if the new framework is
71062306a36Sopenharmony_ci	 * supported as well.  Drivers are supposed to support either the
71162306a36Sopenharmony_ci	 * former, or the latter, but not both at the same time.
71262306a36Sopenharmony_ci	 */
71362306a36Sopenharmony_ci	pci_WARN(pci_dev, ret && drv->driver.pm, "device %04x:%04x\n",
71462306a36Sopenharmony_ci		 pci_dev->vendor, pci_dev->device);
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci	return ret;
71762306a36Sopenharmony_ci}
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_ci/* New power management framework */
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_cistatic int pci_pm_prepare(struct device *dev)
72262306a36Sopenharmony_ci{
72362306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
72462306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
72562306a36Sopenharmony_ci
72662306a36Sopenharmony_ci	if (pm && pm->prepare) {
72762306a36Sopenharmony_ci		int error = pm->prepare(dev);
72862306a36Sopenharmony_ci		if (error < 0)
72962306a36Sopenharmony_ci			return error;
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci		if (!error && dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_PREPARE))
73262306a36Sopenharmony_ci			return 0;
73362306a36Sopenharmony_ci	}
73462306a36Sopenharmony_ci	if (pci_dev_need_resume(pci_dev))
73562306a36Sopenharmony_ci		return 0;
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci	/*
73862306a36Sopenharmony_ci	 * The PME setting needs to be adjusted here in case the direct-complete
73962306a36Sopenharmony_ci	 * optimization is used with respect to this device.
74062306a36Sopenharmony_ci	 */
74162306a36Sopenharmony_ci	pci_dev_adjust_pme(pci_dev);
74262306a36Sopenharmony_ci	return 1;
74362306a36Sopenharmony_ci}
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_cistatic void pci_pm_complete(struct device *dev)
74662306a36Sopenharmony_ci{
74762306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_ci	pci_dev_complete_resume(pci_dev);
75062306a36Sopenharmony_ci	pm_generic_complete(dev);
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_ci	/* Resume device if platform firmware has put it in reset-power-on */
75362306a36Sopenharmony_ci	if (pm_runtime_suspended(dev) && pm_resume_via_firmware()) {
75462306a36Sopenharmony_ci		pci_power_t pre_sleep_state = pci_dev->current_state;
75562306a36Sopenharmony_ci
75662306a36Sopenharmony_ci		pci_refresh_power_state(pci_dev);
75762306a36Sopenharmony_ci		/*
75862306a36Sopenharmony_ci		 * On platforms with ACPI this check may also trigger for
75962306a36Sopenharmony_ci		 * devices sharing power resources if one of those power
76062306a36Sopenharmony_ci		 * resources has been activated as a result of a change of the
76162306a36Sopenharmony_ci		 * power state of another device sharing it.  However, in that
76262306a36Sopenharmony_ci		 * case it is also better to resume the device, in general.
76362306a36Sopenharmony_ci		 */
76462306a36Sopenharmony_ci		if (pci_dev->current_state < pre_sleep_state)
76562306a36Sopenharmony_ci			pm_request_resume(dev);
76662306a36Sopenharmony_ci	}
76762306a36Sopenharmony_ci}
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci#else /* !CONFIG_PM_SLEEP */
77062306a36Sopenharmony_ci
77162306a36Sopenharmony_ci#define pci_pm_prepare	NULL
77262306a36Sopenharmony_ci#define pci_pm_complete	NULL
77362306a36Sopenharmony_ci
77462306a36Sopenharmony_ci#endif /* !CONFIG_PM_SLEEP */
77562306a36Sopenharmony_ci
77662306a36Sopenharmony_ci#ifdef CONFIG_SUSPEND
77762306a36Sopenharmony_cistatic void pcie_pme_root_status_cleanup(struct pci_dev *pci_dev)
77862306a36Sopenharmony_ci{
77962306a36Sopenharmony_ci	/*
78062306a36Sopenharmony_ci	 * Some BIOSes forget to clear Root PME Status bits after system
78162306a36Sopenharmony_ci	 * wakeup, which breaks ACPI-based runtime wakeup on PCI Express.
78262306a36Sopenharmony_ci	 * Clear those bits now just in case (shouldn't hurt).
78362306a36Sopenharmony_ci	 */
78462306a36Sopenharmony_ci	if (pci_is_pcie(pci_dev) &&
78562306a36Sopenharmony_ci	    (pci_pcie_type(pci_dev) == PCI_EXP_TYPE_ROOT_PORT ||
78662306a36Sopenharmony_ci	     pci_pcie_type(pci_dev) == PCI_EXP_TYPE_RC_EC))
78762306a36Sopenharmony_ci		pcie_clear_root_pme_status(pci_dev);
78862306a36Sopenharmony_ci}
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_cistatic int pci_pm_suspend(struct device *dev)
79162306a36Sopenharmony_ci{
79262306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
79362306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_ci	pci_dev->skip_bus_pm = false;
79662306a36Sopenharmony_ci
79762306a36Sopenharmony_ci	/*
79862306a36Sopenharmony_ci	 * Disabling PTM allows some systems, e.g., Intel mobile chips
79962306a36Sopenharmony_ci	 * since Coffee Lake, to enter a lower-power PM state.
80062306a36Sopenharmony_ci	 */
80162306a36Sopenharmony_ci	pci_suspend_ptm(pci_dev);
80262306a36Sopenharmony_ci
80362306a36Sopenharmony_ci	if (pci_has_legacy_pm_support(pci_dev))
80462306a36Sopenharmony_ci		return pci_legacy_suspend(dev, PMSG_SUSPEND);
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_ci	if (!pm) {
80762306a36Sopenharmony_ci		pci_pm_default_suspend(pci_dev);
80862306a36Sopenharmony_ci		return 0;
80962306a36Sopenharmony_ci	}
81062306a36Sopenharmony_ci
81162306a36Sopenharmony_ci	/*
81262306a36Sopenharmony_ci	 * PCI devices suspended at run time may need to be resumed at this
81362306a36Sopenharmony_ci	 * point, because in general it may be necessary to reconfigure them for
81462306a36Sopenharmony_ci	 * system suspend.  Namely, if the device is expected to wake up the
81562306a36Sopenharmony_ci	 * system from the sleep state, it may have to be reconfigured for this
81662306a36Sopenharmony_ci	 * purpose, or if the device is not expected to wake up the system from
81762306a36Sopenharmony_ci	 * the sleep state, it should be prevented from signaling wakeup events
81862306a36Sopenharmony_ci	 * going forward.
81962306a36Sopenharmony_ci	 *
82062306a36Sopenharmony_ci	 * Also if the driver of the device does not indicate that its system
82162306a36Sopenharmony_ci	 * suspend callbacks can cope with runtime-suspended devices, it is
82262306a36Sopenharmony_ci	 * better to resume the device from runtime suspend here.
82362306a36Sopenharmony_ci	 */
82462306a36Sopenharmony_ci	if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) ||
82562306a36Sopenharmony_ci	    pci_dev_need_resume(pci_dev)) {
82662306a36Sopenharmony_ci		pm_runtime_resume(dev);
82762306a36Sopenharmony_ci		pci_dev->state_saved = false;
82862306a36Sopenharmony_ci	} else {
82962306a36Sopenharmony_ci		pci_dev_adjust_pme(pci_dev);
83062306a36Sopenharmony_ci	}
83162306a36Sopenharmony_ci
83262306a36Sopenharmony_ci	if (pm->suspend) {
83362306a36Sopenharmony_ci		pci_power_t prev = pci_dev->current_state;
83462306a36Sopenharmony_ci		int error;
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ci		error = pm->suspend(dev);
83762306a36Sopenharmony_ci		suspend_report_result(dev, pm->suspend, error);
83862306a36Sopenharmony_ci		if (error)
83962306a36Sopenharmony_ci			return error;
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_ci		if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
84262306a36Sopenharmony_ci		    && pci_dev->current_state != PCI_UNKNOWN) {
84362306a36Sopenharmony_ci			pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev,
84462306a36Sopenharmony_ci				      "PCI PM: State of device not saved by %pS\n",
84562306a36Sopenharmony_ci				      pm->suspend);
84662306a36Sopenharmony_ci		}
84762306a36Sopenharmony_ci	}
84862306a36Sopenharmony_ci
84962306a36Sopenharmony_ci	return 0;
85062306a36Sopenharmony_ci}
85162306a36Sopenharmony_ci
85262306a36Sopenharmony_cistatic int pci_pm_suspend_late(struct device *dev)
85362306a36Sopenharmony_ci{
85462306a36Sopenharmony_ci	if (dev_pm_skip_suspend(dev))
85562306a36Sopenharmony_ci		return 0;
85662306a36Sopenharmony_ci
85762306a36Sopenharmony_ci	pci_fixup_device(pci_fixup_suspend, to_pci_dev(dev));
85862306a36Sopenharmony_ci
85962306a36Sopenharmony_ci	return pm_generic_suspend_late(dev);
86062306a36Sopenharmony_ci}
86162306a36Sopenharmony_ci
86262306a36Sopenharmony_cistatic int pci_pm_suspend_noirq(struct device *dev)
86362306a36Sopenharmony_ci{
86462306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
86562306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
86662306a36Sopenharmony_ci
86762306a36Sopenharmony_ci	if (dev_pm_skip_suspend(dev))
86862306a36Sopenharmony_ci		return 0;
86962306a36Sopenharmony_ci
87062306a36Sopenharmony_ci	if (pci_has_legacy_pm_support(pci_dev))
87162306a36Sopenharmony_ci		return pci_legacy_suspend_late(dev);
87262306a36Sopenharmony_ci
87362306a36Sopenharmony_ci	if (!pm) {
87462306a36Sopenharmony_ci		pci_save_state(pci_dev);
87562306a36Sopenharmony_ci		goto Fixup;
87662306a36Sopenharmony_ci	}
87762306a36Sopenharmony_ci
87862306a36Sopenharmony_ci	if (pm->suspend_noirq) {
87962306a36Sopenharmony_ci		pci_power_t prev = pci_dev->current_state;
88062306a36Sopenharmony_ci		int error;
88162306a36Sopenharmony_ci
88262306a36Sopenharmony_ci		error = pm->suspend_noirq(dev);
88362306a36Sopenharmony_ci		suspend_report_result(dev, pm->suspend_noirq, error);
88462306a36Sopenharmony_ci		if (error)
88562306a36Sopenharmony_ci			return error;
88662306a36Sopenharmony_ci
88762306a36Sopenharmony_ci		if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
88862306a36Sopenharmony_ci		    && pci_dev->current_state != PCI_UNKNOWN) {
88962306a36Sopenharmony_ci			pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev,
89062306a36Sopenharmony_ci				      "PCI PM: State of device not saved by %pS\n",
89162306a36Sopenharmony_ci				      pm->suspend_noirq);
89262306a36Sopenharmony_ci			goto Fixup;
89362306a36Sopenharmony_ci		}
89462306a36Sopenharmony_ci	}
89562306a36Sopenharmony_ci
89662306a36Sopenharmony_ci	if (!pci_dev->state_saved) {
89762306a36Sopenharmony_ci		pci_save_state(pci_dev);
89862306a36Sopenharmony_ci
89962306a36Sopenharmony_ci		/*
90062306a36Sopenharmony_ci		 * If the device is a bridge with a child in D0 below it,
90162306a36Sopenharmony_ci		 * it needs to stay in D0, so check skip_bus_pm to avoid
90262306a36Sopenharmony_ci		 * putting it into a low-power state in that case.
90362306a36Sopenharmony_ci		 */
90462306a36Sopenharmony_ci		if (!pci_dev->skip_bus_pm && pci_power_manageable(pci_dev))
90562306a36Sopenharmony_ci			pci_prepare_to_sleep(pci_dev);
90662306a36Sopenharmony_ci	}
90762306a36Sopenharmony_ci
90862306a36Sopenharmony_ci	pci_dbg(pci_dev, "PCI PM: Suspend power state: %s\n",
90962306a36Sopenharmony_ci		pci_power_name(pci_dev->current_state));
91062306a36Sopenharmony_ci
91162306a36Sopenharmony_ci	if (pci_dev->current_state == PCI_D0) {
91262306a36Sopenharmony_ci		pci_dev->skip_bus_pm = true;
91362306a36Sopenharmony_ci		/*
91462306a36Sopenharmony_ci		 * Per PCI PM r1.2, table 6-1, a bridge must be in D0 if any
91562306a36Sopenharmony_ci		 * downstream device is in D0, so avoid changing the power state
91662306a36Sopenharmony_ci		 * of the parent bridge by setting the skip_bus_pm flag for it.
91762306a36Sopenharmony_ci		 */
91862306a36Sopenharmony_ci		if (pci_dev->bus->self)
91962306a36Sopenharmony_ci			pci_dev->bus->self->skip_bus_pm = true;
92062306a36Sopenharmony_ci	}
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_ci	if (pci_dev->skip_bus_pm && pm_suspend_no_platform()) {
92362306a36Sopenharmony_ci		pci_dbg(pci_dev, "PCI PM: Skipped\n");
92462306a36Sopenharmony_ci		goto Fixup;
92562306a36Sopenharmony_ci	}
92662306a36Sopenharmony_ci
92762306a36Sopenharmony_ci	pci_pm_set_unknown_state(pci_dev);
92862306a36Sopenharmony_ci
92962306a36Sopenharmony_ci	/*
93062306a36Sopenharmony_ci	 * Some BIOSes from ASUS have a bug: If a USB EHCI host controller's
93162306a36Sopenharmony_ci	 * PCI COMMAND register isn't 0, the BIOS assumes that the controller
93262306a36Sopenharmony_ci	 * hasn't been quiesced and tries to turn it off.  If the controller
93362306a36Sopenharmony_ci	 * is already in D3, this can hang or cause memory corruption.
93462306a36Sopenharmony_ci	 *
93562306a36Sopenharmony_ci	 * Since the value of the COMMAND register doesn't matter once the
93662306a36Sopenharmony_ci	 * device has been suspended, we can safely set it to 0 here.
93762306a36Sopenharmony_ci	 */
93862306a36Sopenharmony_ci	if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI)
93962306a36Sopenharmony_ci		pci_write_config_word(pci_dev, PCI_COMMAND, 0);
94062306a36Sopenharmony_ci
94162306a36Sopenharmony_ciFixup:
94262306a36Sopenharmony_ci	pci_fixup_device(pci_fixup_suspend_late, pci_dev);
94362306a36Sopenharmony_ci
94462306a36Sopenharmony_ci	/*
94562306a36Sopenharmony_ci	 * If the target system sleep state is suspend-to-idle, it is sufficient
94662306a36Sopenharmony_ci	 * to check whether or not the device's wakeup settings are good for
94762306a36Sopenharmony_ci	 * runtime PM.  Otherwise, the pm_resume_via_firmware() check will cause
94862306a36Sopenharmony_ci	 * pci_pm_complete() to take care of fixing up the device's state
94962306a36Sopenharmony_ci	 * anyway, if need be.
95062306a36Sopenharmony_ci	 */
95162306a36Sopenharmony_ci	if (device_can_wakeup(dev) && !device_may_wakeup(dev))
95262306a36Sopenharmony_ci		dev->power.may_skip_resume = false;
95362306a36Sopenharmony_ci
95462306a36Sopenharmony_ci	return 0;
95562306a36Sopenharmony_ci}
95662306a36Sopenharmony_ci
95762306a36Sopenharmony_cistatic int pci_pm_resume_noirq(struct device *dev)
95862306a36Sopenharmony_ci{
95962306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
96062306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
96162306a36Sopenharmony_ci	pci_power_t prev_state = pci_dev->current_state;
96262306a36Sopenharmony_ci	bool skip_bus_pm = pci_dev->skip_bus_pm;
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_ci	if (dev_pm_skip_resume(dev))
96562306a36Sopenharmony_ci		return 0;
96662306a36Sopenharmony_ci
96762306a36Sopenharmony_ci	/*
96862306a36Sopenharmony_ci	 * In the suspend-to-idle case, devices left in D0 during suspend will
96962306a36Sopenharmony_ci	 * stay in D0, so it is not necessary to restore or update their
97062306a36Sopenharmony_ci	 * configuration here and attempting to put them into D0 again is
97162306a36Sopenharmony_ci	 * pointless, so avoid doing that.
97262306a36Sopenharmony_ci	 */
97362306a36Sopenharmony_ci	if (!(skip_bus_pm && pm_suspend_no_platform()))
97462306a36Sopenharmony_ci		pci_pm_default_resume_early(pci_dev);
97562306a36Sopenharmony_ci
97662306a36Sopenharmony_ci	pci_fixup_device(pci_fixup_resume_early, pci_dev);
97762306a36Sopenharmony_ci	pcie_pme_root_status_cleanup(pci_dev);
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_ci	if (!skip_bus_pm && prev_state == PCI_D3cold)
98062306a36Sopenharmony_ci		pci_pm_bridge_power_up_actions(pci_dev);
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ci	if (pci_has_legacy_pm_support(pci_dev))
98362306a36Sopenharmony_ci		return 0;
98462306a36Sopenharmony_ci
98562306a36Sopenharmony_ci	if (pm && pm->resume_noirq)
98662306a36Sopenharmony_ci		return pm->resume_noirq(dev);
98762306a36Sopenharmony_ci
98862306a36Sopenharmony_ci	return 0;
98962306a36Sopenharmony_ci}
99062306a36Sopenharmony_ci
99162306a36Sopenharmony_cistatic int pci_pm_resume_early(struct device *dev)
99262306a36Sopenharmony_ci{
99362306a36Sopenharmony_ci	if (dev_pm_skip_resume(dev))
99462306a36Sopenharmony_ci		return 0;
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_ci	return pm_generic_resume_early(dev);
99762306a36Sopenharmony_ci}
99862306a36Sopenharmony_ci
99962306a36Sopenharmony_cistatic int pci_pm_resume(struct device *dev)
100062306a36Sopenharmony_ci{
100162306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
100262306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
100362306a36Sopenharmony_ci
100462306a36Sopenharmony_ci	/*
100562306a36Sopenharmony_ci	 * This is necessary for the suspend error path in which resume is
100662306a36Sopenharmony_ci	 * called without restoring the standard config registers of the device.
100762306a36Sopenharmony_ci	 */
100862306a36Sopenharmony_ci	if (pci_dev->state_saved)
100962306a36Sopenharmony_ci		pci_restore_standard_config(pci_dev);
101062306a36Sopenharmony_ci
101162306a36Sopenharmony_ci	pci_resume_ptm(pci_dev);
101262306a36Sopenharmony_ci
101362306a36Sopenharmony_ci	if (pci_has_legacy_pm_support(pci_dev))
101462306a36Sopenharmony_ci		return pci_legacy_resume(dev);
101562306a36Sopenharmony_ci
101662306a36Sopenharmony_ci	pci_pm_default_resume(pci_dev);
101762306a36Sopenharmony_ci
101862306a36Sopenharmony_ci	if (pm) {
101962306a36Sopenharmony_ci		if (pm->resume)
102062306a36Sopenharmony_ci			return pm->resume(dev);
102162306a36Sopenharmony_ci	} else {
102262306a36Sopenharmony_ci		pci_pm_reenable_device(pci_dev);
102362306a36Sopenharmony_ci	}
102462306a36Sopenharmony_ci
102562306a36Sopenharmony_ci	return 0;
102662306a36Sopenharmony_ci}
102762306a36Sopenharmony_ci
102862306a36Sopenharmony_ci#else /* !CONFIG_SUSPEND */
102962306a36Sopenharmony_ci
103062306a36Sopenharmony_ci#define pci_pm_suspend		NULL
103162306a36Sopenharmony_ci#define pci_pm_suspend_late	NULL
103262306a36Sopenharmony_ci#define pci_pm_suspend_noirq	NULL
103362306a36Sopenharmony_ci#define pci_pm_resume		NULL
103462306a36Sopenharmony_ci#define pci_pm_resume_early	NULL
103562306a36Sopenharmony_ci#define pci_pm_resume_noirq	NULL
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_ci#endif /* !CONFIG_SUSPEND */
103862306a36Sopenharmony_ci
103962306a36Sopenharmony_ci#ifdef CONFIG_HIBERNATE_CALLBACKS
104062306a36Sopenharmony_ci
104162306a36Sopenharmony_cistatic int pci_pm_freeze(struct device *dev)
104262306a36Sopenharmony_ci{
104362306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
104462306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
104562306a36Sopenharmony_ci
104662306a36Sopenharmony_ci	if (pci_has_legacy_pm_support(pci_dev))
104762306a36Sopenharmony_ci		return pci_legacy_suspend(dev, PMSG_FREEZE);
104862306a36Sopenharmony_ci
104962306a36Sopenharmony_ci	if (!pm) {
105062306a36Sopenharmony_ci		pci_pm_default_suspend(pci_dev);
105162306a36Sopenharmony_ci		return 0;
105262306a36Sopenharmony_ci	}
105362306a36Sopenharmony_ci
105462306a36Sopenharmony_ci	/*
105562306a36Sopenharmony_ci	 * Resume all runtime-suspended devices before creating a snapshot
105662306a36Sopenharmony_ci	 * image of system memory, because the restore kernel generally cannot
105762306a36Sopenharmony_ci	 * be expected to always handle them consistently and they need to be
105862306a36Sopenharmony_ci	 * put into the runtime-active metastate during system resume anyway,
105962306a36Sopenharmony_ci	 * so it is better to ensure that the state saved in the image will be
106062306a36Sopenharmony_ci	 * always consistent with that.
106162306a36Sopenharmony_ci	 */
106262306a36Sopenharmony_ci	pm_runtime_resume(dev);
106362306a36Sopenharmony_ci	pci_dev->state_saved = false;
106462306a36Sopenharmony_ci
106562306a36Sopenharmony_ci	if (pm->freeze) {
106662306a36Sopenharmony_ci		int error;
106762306a36Sopenharmony_ci
106862306a36Sopenharmony_ci		error = pm->freeze(dev);
106962306a36Sopenharmony_ci		suspend_report_result(dev, pm->freeze, error);
107062306a36Sopenharmony_ci		if (error)
107162306a36Sopenharmony_ci			return error;
107262306a36Sopenharmony_ci	}
107362306a36Sopenharmony_ci
107462306a36Sopenharmony_ci	return 0;
107562306a36Sopenharmony_ci}
107662306a36Sopenharmony_ci
107762306a36Sopenharmony_cistatic int pci_pm_freeze_noirq(struct device *dev)
107862306a36Sopenharmony_ci{
107962306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
108062306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
108162306a36Sopenharmony_ci
108262306a36Sopenharmony_ci	if (pci_has_legacy_pm_support(pci_dev))
108362306a36Sopenharmony_ci		return pci_legacy_suspend_late(dev);
108462306a36Sopenharmony_ci
108562306a36Sopenharmony_ci	if (pm && pm->freeze_noirq) {
108662306a36Sopenharmony_ci		int error;
108762306a36Sopenharmony_ci
108862306a36Sopenharmony_ci		error = pm->freeze_noirq(dev);
108962306a36Sopenharmony_ci		suspend_report_result(dev, pm->freeze_noirq, error);
109062306a36Sopenharmony_ci		if (error)
109162306a36Sopenharmony_ci			return error;
109262306a36Sopenharmony_ci	}
109362306a36Sopenharmony_ci
109462306a36Sopenharmony_ci	if (!pci_dev->state_saved)
109562306a36Sopenharmony_ci		pci_save_state(pci_dev);
109662306a36Sopenharmony_ci
109762306a36Sopenharmony_ci	pci_pm_set_unknown_state(pci_dev);
109862306a36Sopenharmony_ci
109962306a36Sopenharmony_ci	return 0;
110062306a36Sopenharmony_ci}
110162306a36Sopenharmony_ci
110262306a36Sopenharmony_cistatic int pci_pm_thaw_noirq(struct device *dev)
110362306a36Sopenharmony_ci{
110462306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
110562306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
110662306a36Sopenharmony_ci
110762306a36Sopenharmony_ci	/*
110862306a36Sopenharmony_ci	 * The pm->thaw_noirq() callback assumes the device has been
110962306a36Sopenharmony_ci	 * returned to D0 and its config state has been restored.
111062306a36Sopenharmony_ci	 *
111162306a36Sopenharmony_ci	 * In addition, pci_restore_state() restores MSI-X state in MMIO
111262306a36Sopenharmony_ci	 * space, which requires the device to be in D0, so return it to D0
111362306a36Sopenharmony_ci	 * in case the driver's "freeze" callbacks put it into a low-power
111462306a36Sopenharmony_ci	 * state.
111562306a36Sopenharmony_ci	 */
111662306a36Sopenharmony_ci	pci_pm_power_up_and_verify_state(pci_dev);
111762306a36Sopenharmony_ci	pci_restore_state(pci_dev);
111862306a36Sopenharmony_ci
111962306a36Sopenharmony_ci	if (pci_has_legacy_pm_support(pci_dev))
112062306a36Sopenharmony_ci		return 0;
112162306a36Sopenharmony_ci
112262306a36Sopenharmony_ci	if (pm && pm->thaw_noirq)
112362306a36Sopenharmony_ci		return pm->thaw_noirq(dev);
112462306a36Sopenharmony_ci
112562306a36Sopenharmony_ci	return 0;
112662306a36Sopenharmony_ci}
112762306a36Sopenharmony_ci
112862306a36Sopenharmony_cistatic int pci_pm_thaw(struct device *dev)
112962306a36Sopenharmony_ci{
113062306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
113162306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
113262306a36Sopenharmony_ci	int error = 0;
113362306a36Sopenharmony_ci
113462306a36Sopenharmony_ci	if (pci_has_legacy_pm_support(pci_dev))
113562306a36Sopenharmony_ci		return pci_legacy_resume(dev);
113662306a36Sopenharmony_ci
113762306a36Sopenharmony_ci	if (pm) {
113862306a36Sopenharmony_ci		if (pm->thaw)
113962306a36Sopenharmony_ci			error = pm->thaw(dev);
114062306a36Sopenharmony_ci	} else {
114162306a36Sopenharmony_ci		pci_pm_reenable_device(pci_dev);
114262306a36Sopenharmony_ci	}
114362306a36Sopenharmony_ci
114462306a36Sopenharmony_ci	pci_dev->state_saved = false;
114562306a36Sopenharmony_ci
114662306a36Sopenharmony_ci	return error;
114762306a36Sopenharmony_ci}
114862306a36Sopenharmony_ci
114962306a36Sopenharmony_cistatic int pci_pm_poweroff(struct device *dev)
115062306a36Sopenharmony_ci{
115162306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
115262306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
115362306a36Sopenharmony_ci
115462306a36Sopenharmony_ci	if (pci_has_legacy_pm_support(pci_dev))
115562306a36Sopenharmony_ci		return pci_legacy_suspend(dev, PMSG_HIBERNATE);
115662306a36Sopenharmony_ci
115762306a36Sopenharmony_ci	if (!pm) {
115862306a36Sopenharmony_ci		pci_pm_default_suspend(pci_dev);
115962306a36Sopenharmony_ci		return 0;
116062306a36Sopenharmony_ci	}
116162306a36Sopenharmony_ci
116262306a36Sopenharmony_ci	/* The reason to do that is the same as in pci_pm_suspend(). */
116362306a36Sopenharmony_ci	if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) ||
116462306a36Sopenharmony_ci	    pci_dev_need_resume(pci_dev)) {
116562306a36Sopenharmony_ci		pm_runtime_resume(dev);
116662306a36Sopenharmony_ci		pci_dev->state_saved = false;
116762306a36Sopenharmony_ci	} else {
116862306a36Sopenharmony_ci		pci_dev_adjust_pme(pci_dev);
116962306a36Sopenharmony_ci	}
117062306a36Sopenharmony_ci
117162306a36Sopenharmony_ci	if (pm->poweroff) {
117262306a36Sopenharmony_ci		int error;
117362306a36Sopenharmony_ci
117462306a36Sopenharmony_ci		error = pm->poweroff(dev);
117562306a36Sopenharmony_ci		suspend_report_result(dev, pm->poweroff, error);
117662306a36Sopenharmony_ci		if (error)
117762306a36Sopenharmony_ci			return error;
117862306a36Sopenharmony_ci	}
117962306a36Sopenharmony_ci
118062306a36Sopenharmony_ci	return 0;
118162306a36Sopenharmony_ci}
118262306a36Sopenharmony_ci
118362306a36Sopenharmony_cistatic int pci_pm_poweroff_late(struct device *dev)
118462306a36Sopenharmony_ci{
118562306a36Sopenharmony_ci	if (dev_pm_skip_suspend(dev))
118662306a36Sopenharmony_ci		return 0;
118762306a36Sopenharmony_ci
118862306a36Sopenharmony_ci	pci_fixup_device(pci_fixup_suspend, to_pci_dev(dev));
118962306a36Sopenharmony_ci
119062306a36Sopenharmony_ci	return pm_generic_poweroff_late(dev);
119162306a36Sopenharmony_ci}
119262306a36Sopenharmony_ci
119362306a36Sopenharmony_cistatic int pci_pm_poweroff_noirq(struct device *dev)
119462306a36Sopenharmony_ci{
119562306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
119662306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
119762306a36Sopenharmony_ci
119862306a36Sopenharmony_ci	if (dev_pm_skip_suspend(dev))
119962306a36Sopenharmony_ci		return 0;
120062306a36Sopenharmony_ci
120162306a36Sopenharmony_ci	if (pci_has_legacy_pm_support(pci_dev))
120262306a36Sopenharmony_ci		return pci_legacy_suspend_late(dev);
120362306a36Sopenharmony_ci
120462306a36Sopenharmony_ci	if (!pm) {
120562306a36Sopenharmony_ci		pci_fixup_device(pci_fixup_suspend_late, pci_dev);
120662306a36Sopenharmony_ci		return 0;
120762306a36Sopenharmony_ci	}
120862306a36Sopenharmony_ci
120962306a36Sopenharmony_ci	if (pm->poweroff_noirq) {
121062306a36Sopenharmony_ci		int error;
121162306a36Sopenharmony_ci
121262306a36Sopenharmony_ci		error = pm->poweroff_noirq(dev);
121362306a36Sopenharmony_ci		suspend_report_result(dev, pm->poweroff_noirq, error);
121462306a36Sopenharmony_ci		if (error)
121562306a36Sopenharmony_ci			return error;
121662306a36Sopenharmony_ci	}
121762306a36Sopenharmony_ci
121862306a36Sopenharmony_ci	if (!pci_dev->state_saved && !pci_has_subordinate(pci_dev))
121962306a36Sopenharmony_ci		pci_prepare_to_sleep(pci_dev);
122062306a36Sopenharmony_ci
122162306a36Sopenharmony_ci	/*
122262306a36Sopenharmony_ci	 * The reason for doing this here is the same as for the analogous code
122362306a36Sopenharmony_ci	 * in pci_pm_suspend_noirq().
122462306a36Sopenharmony_ci	 */
122562306a36Sopenharmony_ci	if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI)
122662306a36Sopenharmony_ci		pci_write_config_word(pci_dev, PCI_COMMAND, 0);
122762306a36Sopenharmony_ci
122862306a36Sopenharmony_ci	pci_fixup_device(pci_fixup_suspend_late, pci_dev);
122962306a36Sopenharmony_ci
123062306a36Sopenharmony_ci	return 0;
123162306a36Sopenharmony_ci}
123262306a36Sopenharmony_ci
123362306a36Sopenharmony_cistatic int pci_pm_restore_noirq(struct device *dev)
123462306a36Sopenharmony_ci{
123562306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
123662306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
123762306a36Sopenharmony_ci
123862306a36Sopenharmony_ci	pci_pm_default_resume_early(pci_dev);
123962306a36Sopenharmony_ci	pci_fixup_device(pci_fixup_resume_early, pci_dev);
124062306a36Sopenharmony_ci
124162306a36Sopenharmony_ci	if (pci_has_legacy_pm_support(pci_dev))
124262306a36Sopenharmony_ci		return 0;
124362306a36Sopenharmony_ci
124462306a36Sopenharmony_ci	if (pm && pm->restore_noirq)
124562306a36Sopenharmony_ci		return pm->restore_noirq(dev);
124662306a36Sopenharmony_ci
124762306a36Sopenharmony_ci	return 0;
124862306a36Sopenharmony_ci}
124962306a36Sopenharmony_ci
125062306a36Sopenharmony_cistatic int pci_pm_restore(struct device *dev)
125162306a36Sopenharmony_ci{
125262306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
125362306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
125462306a36Sopenharmony_ci
125562306a36Sopenharmony_ci	/*
125662306a36Sopenharmony_ci	 * This is necessary for the hibernation error path in which restore is
125762306a36Sopenharmony_ci	 * called without restoring the standard config registers of the device.
125862306a36Sopenharmony_ci	 */
125962306a36Sopenharmony_ci	if (pci_dev->state_saved)
126062306a36Sopenharmony_ci		pci_restore_standard_config(pci_dev);
126162306a36Sopenharmony_ci
126262306a36Sopenharmony_ci	if (pci_has_legacy_pm_support(pci_dev))
126362306a36Sopenharmony_ci		return pci_legacy_resume(dev);
126462306a36Sopenharmony_ci
126562306a36Sopenharmony_ci	pci_pm_default_resume(pci_dev);
126662306a36Sopenharmony_ci
126762306a36Sopenharmony_ci	if (pm) {
126862306a36Sopenharmony_ci		if (pm->restore)
126962306a36Sopenharmony_ci			return pm->restore(dev);
127062306a36Sopenharmony_ci	} else {
127162306a36Sopenharmony_ci		pci_pm_reenable_device(pci_dev);
127262306a36Sopenharmony_ci	}
127362306a36Sopenharmony_ci
127462306a36Sopenharmony_ci	return 0;
127562306a36Sopenharmony_ci}
127662306a36Sopenharmony_ci
127762306a36Sopenharmony_ci#else /* !CONFIG_HIBERNATE_CALLBACKS */
127862306a36Sopenharmony_ci
127962306a36Sopenharmony_ci#define pci_pm_freeze		NULL
128062306a36Sopenharmony_ci#define pci_pm_freeze_noirq	NULL
128162306a36Sopenharmony_ci#define pci_pm_thaw		NULL
128262306a36Sopenharmony_ci#define pci_pm_thaw_noirq	NULL
128362306a36Sopenharmony_ci#define pci_pm_poweroff		NULL
128462306a36Sopenharmony_ci#define pci_pm_poweroff_late	NULL
128562306a36Sopenharmony_ci#define pci_pm_poweroff_noirq	NULL
128662306a36Sopenharmony_ci#define pci_pm_restore		NULL
128762306a36Sopenharmony_ci#define pci_pm_restore_noirq	NULL
128862306a36Sopenharmony_ci
128962306a36Sopenharmony_ci#endif /* !CONFIG_HIBERNATE_CALLBACKS */
129062306a36Sopenharmony_ci
129162306a36Sopenharmony_ci#ifdef CONFIG_PM
129262306a36Sopenharmony_ci
129362306a36Sopenharmony_cistatic int pci_pm_runtime_suspend(struct device *dev)
129462306a36Sopenharmony_ci{
129562306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
129662306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
129762306a36Sopenharmony_ci	pci_power_t prev = pci_dev->current_state;
129862306a36Sopenharmony_ci	int error;
129962306a36Sopenharmony_ci
130062306a36Sopenharmony_ci	pci_suspend_ptm(pci_dev);
130162306a36Sopenharmony_ci
130262306a36Sopenharmony_ci	/*
130362306a36Sopenharmony_ci	 * If pci_dev->driver is not set (unbound), we leave the device in D0,
130462306a36Sopenharmony_ci	 * but it may go to D3cold when the bridge above it runtime suspends.
130562306a36Sopenharmony_ci	 * Save its config space in case that happens.
130662306a36Sopenharmony_ci	 */
130762306a36Sopenharmony_ci	if (!pci_dev->driver) {
130862306a36Sopenharmony_ci		pci_save_state(pci_dev);
130962306a36Sopenharmony_ci		return 0;
131062306a36Sopenharmony_ci	}
131162306a36Sopenharmony_ci
131262306a36Sopenharmony_ci	pci_dev->state_saved = false;
131362306a36Sopenharmony_ci	if (pm && pm->runtime_suspend) {
131462306a36Sopenharmony_ci		error = pm->runtime_suspend(dev);
131562306a36Sopenharmony_ci		/*
131662306a36Sopenharmony_ci		 * -EBUSY and -EAGAIN is used to request the runtime PM core
131762306a36Sopenharmony_ci		 * to schedule a new suspend, so log the event only with debug
131862306a36Sopenharmony_ci		 * log level.
131962306a36Sopenharmony_ci		 */
132062306a36Sopenharmony_ci		if (error == -EBUSY || error == -EAGAIN) {
132162306a36Sopenharmony_ci			pci_dbg(pci_dev, "can't suspend now (%ps returned %d)\n",
132262306a36Sopenharmony_ci				pm->runtime_suspend, error);
132362306a36Sopenharmony_ci			return error;
132462306a36Sopenharmony_ci		} else if (error) {
132562306a36Sopenharmony_ci			pci_err(pci_dev, "can't suspend (%ps returned %d)\n",
132662306a36Sopenharmony_ci				pm->runtime_suspend, error);
132762306a36Sopenharmony_ci			return error;
132862306a36Sopenharmony_ci		}
132962306a36Sopenharmony_ci	}
133062306a36Sopenharmony_ci
133162306a36Sopenharmony_ci	pci_fixup_device(pci_fixup_suspend, pci_dev);
133262306a36Sopenharmony_ci
133362306a36Sopenharmony_ci	if (pm && pm->runtime_suspend
133462306a36Sopenharmony_ci	    && !pci_dev->state_saved && pci_dev->current_state != PCI_D0
133562306a36Sopenharmony_ci	    && pci_dev->current_state != PCI_UNKNOWN) {
133662306a36Sopenharmony_ci		pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev,
133762306a36Sopenharmony_ci			      "PCI PM: State of device not saved by %pS\n",
133862306a36Sopenharmony_ci			      pm->runtime_suspend);
133962306a36Sopenharmony_ci		return 0;
134062306a36Sopenharmony_ci	}
134162306a36Sopenharmony_ci
134262306a36Sopenharmony_ci	if (!pci_dev->state_saved) {
134362306a36Sopenharmony_ci		pci_save_state(pci_dev);
134462306a36Sopenharmony_ci		pci_finish_runtime_suspend(pci_dev);
134562306a36Sopenharmony_ci	}
134662306a36Sopenharmony_ci
134762306a36Sopenharmony_ci	return 0;
134862306a36Sopenharmony_ci}
134962306a36Sopenharmony_ci
135062306a36Sopenharmony_cistatic int pci_pm_runtime_resume(struct device *dev)
135162306a36Sopenharmony_ci{
135262306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
135362306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
135462306a36Sopenharmony_ci	pci_power_t prev_state = pci_dev->current_state;
135562306a36Sopenharmony_ci	int error = 0;
135662306a36Sopenharmony_ci
135762306a36Sopenharmony_ci	/*
135862306a36Sopenharmony_ci	 * Restoring config space is necessary even if the device is not bound
135962306a36Sopenharmony_ci	 * to a driver because although we left it in D0, it may have gone to
136062306a36Sopenharmony_ci	 * D3cold when the bridge above it runtime suspended.
136162306a36Sopenharmony_ci	 */
136262306a36Sopenharmony_ci	pci_pm_default_resume_early(pci_dev);
136362306a36Sopenharmony_ci	pci_resume_ptm(pci_dev);
136462306a36Sopenharmony_ci
136562306a36Sopenharmony_ci	if (!pci_dev->driver)
136662306a36Sopenharmony_ci		return 0;
136762306a36Sopenharmony_ci
136862306a36Sopenharmony_ci	pci_fixup_device(pci_fixup_resume_early, pci_dev);
136962306a36Sopenharmony_ci	pci_pm_default_resume(pci_dev);
137062306a36Sopenharmony_ci
137162306a36Sopenharmony_ci	if (prev_state == PCI_D3cold)
137262306a36Sopenharmony_ci		pci_pm_bridge_power_up_actions(pci_dev);
137362306a36Sopenharmony_ci
137462306a36Sopenharmony_ci	if (pm && pm->runtime_resume)
137562306a36Sopenharmony_ci		error = pm->runtime_resume(dev);
137662306a36Sopenharmony_ci
137762306a36Sopenharmony_ci	return error;
137862306a36Sopenharmony_ci}
137962306a36Sopenharmony_ci
138062306a36Sopenharmony_cistatic int pci_pm_runtime_idle(struct device *dev)
138162306a36Sopenharmony_ci{
138262306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
138362306a36Sopenharmony_ci	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
138462306a36Sopenharmony_ci
138562306a36Sopenharmony_ci	/*
138662306a36Sopenharmony_ci	 * If pci_dev->driver is not set (unbound), the device should
138762306a36Sopenharmony_ci	 * always remain in D0 regardless of the runtime PM status
138862306a36Sopenharmony_ci	 */
138962306a36Sopenharmony_ci	if (!pci_dev->driver)
139062306a36Sopenharmony_ci		return 0;
139162306a36Sopenharmony_ci
139262306a36Sopenharmony_ci	if (!pm)
139362306a36Sopenharmony_ci		return -ENOSYS;
139462306a36Sopenharmony_ci
139562306a36Sopenharmony_ci	if (pm->runtime_idle)
139662306a36Sopenharmony_ci		return pm->runtime_idle(dev);
139762306a36Sopenharmony_ci
139862306a36Sopenharmony_ci	return 0;
139962306a36Sopenharmony_ci}
140062306a36Sopenharmony_ci
140162306a36Sopenharmony_cistatic const struct dev_pm_ops pci_dev_pm_ops = {
140262306a36Sopenharmony_ci	.prepare = pci_pm_prepare,
140362306a36Sopenharmony_ci	.complete = pci_pm_complete,
140462306a36Sopenharmony_ci	.suspend = pci_pm_suspend,
140562306a36Sopenharmony_ci	.suspend_late = pci_pm_suspend_late,
140662306a36Sopenharmony_ci	.resume = pci_pm_resume,
140762306a36Sopenharmony_ci	.resume_early = pci_pm_resume_early,
140862306a36Sopenharmony_ci	.freeze = pci_pm_freeze,
140962306a36Sopenharmony_ci	.thaw = pci_pm_thaw,
141062306a36Sopenharmony_ci	.poweroff = pci_pm_poweroff,
141162306a36Sopenharmony_ci	.poweroff_late = pci_pm_poweroff_late,
141262306a36Sopenharmony_ci	.restore = pci_pm_restore,
141362306a36Sopenharmony_ci	.suspend_noirq = pci_pm_suspend_noirq,
141462306a36Sopenharmony_ci	.resume_noirq = pci_pm_resume_noirq,
141562306a36Sopenharmony_ci	.freeze_noirq = pci_pm_freeze_noirq,
141662306a36Sopenharmony_ci	.thaw_noirq = pci_pm_thaw_noirq,
141762306a36Sopenharmony_ci	.poweroff_noirq = pci_pm_poweroff_noirq,
141862306a36Sopenharmony_ci	.restore_noirq = pci_pm_restore_noirq,
141962306a36Sopenharmony_ci	.runtime_suspend = pci_pm_runtime_suspend,
142062306a36Sopenharmony_ci	.runtime_resume = pci_pm_runtime_resume,
142162306a36Sopenharmony_ci	.runtime_idle = pci_pm_runtime_idle,
142262306a36Sopenharmony_ci};
142362306a36Sopenharmony_ci
142462306a36Sopenharmony_ci#define PCI_PM_OPS_PTR	(&pci_dev_pm_ops)
142562306a36Sopenharmony_ci
142662306a36Sopenharmony_ci#else /* !CONFIG_PM */
142762306a36Sopenharmony_ci
142862306a36Sopenharmony_ci#define pci_pm_runtime_suspend	NULL
142962306a36Sopenharmony_ci#define pci_pm_runtime_resume	NULL
143062306a36Sopenharmony_ci#define pci_pm_runtime_idle	NULL
143162306a36Sopenharmony_ci
143262306a36Sopenharmony_ci#define PCI_PM_OPS_PTR	NULL
143362306a36Sopenharmony_ci
143462306a36Sopenharmony_ci#endif /* !CONFIG_PM */
143562306a36Sopenharmony_ci
143662306a36Sopenharmony_ci/**
143762306a36Sopenharmony_ci * __pci_register_driver - register a new pci driver
143862306a36Sopenharmony_ci * @drv: the driver structure to register
143962306a36Sopenharmony_ci * @owner: owner module of drv
144062306a36Sopenharmony_ci * @mod_name: module name string
144162306a36Sopenharmony_ci *
144262306a36Sopenharmony_ci * Adds the driver structure to the list of registered drivers.
144362306a36Sopenharmony_ci * Returns a negative value on error, otherwise 0.
144462306a36Sopenharmony_ci * If no error occurred, the driver remains registered even if
144562306a36Sopenharmony_ci * no device was claimed during registration.
144662306a36Sopenharmony_ci */
144762306a36Sopenharmony_ciint __pci_register_driver(struct pci_driver *drv, struct module *owner,
144862306a36Sopenharmony_ci			  const char *mod_name)
144962306a36Sopenharmony_ci{
145062306a36Sopenharmony_ci	/* initialize common driver fields */
145162306a36Sopenharmony_ci	drv->driver.name = drv->name;
145262306a36Sopenharmony_ci	drv->driver.bus = &pci_bus_type;
145362306a36Sopenharmony_ci	drv->driver.owner = owner;
145462306a36Sopenharmony_ci	drv->driver.mod_name = mod_name;
145562306a36Sopenharmony_ci	drv->driver.groups = drv->groups;
145662306a36Sopenharmony_ci	drv->driver.dev_groups = drv->dev_groups;
145762306a36Sopenharmony_ci
145862306a36Sopenharmony_ci	spin_lock_init(&drv->dynids.lock);
145962306a36Sopenharmony_ci	INIT_LIST_HEAD(&drv->dynids.list);
146062306a36Sopenharmony_ci
146162306a36Sopenharmony_ci	/* register with core */
146262306a36Sopenharmony_ci	return driver_register(&drv->driver);
146362306a36Sopenharmony_ci}
146462306a36Sopenharmony_ciEXPORT_SYMBOL(__pci_register_driver);
146562306a36Sopenharmony_ci
146662306a36Sopenharmony_ci/**
146762306a36Sopenharmony_ci * pci_unregister_driver - unregister a pci driver
146862306a36Sopenharmony_ci * @drv: the driver structure to unregister
146962306a36Sopenharmony_ci *
147062306a36Sopenharmony_ci * Deletes the driver structure from the list of registered PCI drivers,
147162306a36Sopenharmony_ci * gives it a chance to clean up by calling its remove() function for
147262306a36Sopenharmony_ci * each device it was responsible for, and marks those devices as
147362306a36Sopenharmony_ci * driverless.
147462306a36Sopenharmony_ci */
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_civoid pci_unregister_driver(struct pci_driver *drv)
147762306a36Sopenharmony_ci{
147862306a36Sopenharmony_ci	driver_unregister(&drv->driver);
147962306a36Sopenharmony_ci	pci_free_dynids(drv);
148062306a36Sopenharmony_ci}
148162306a36Sopenharmony_ciEXPORT_SYMBOL(pci_unregister_driver);
148262306a36Sopenharmony_ci
148362306a36Sopenharmony_cistatic struct pci_driver pci_compat_driver = {
148462306a36Sopenharmony_ci	.name = "compat"
148562306a36Sopenharmony_ci};
148662306a36Sopenharmony_ci
148762306a36Sopenharmony_ci/**
148862306a36Sopenharmony_ci * pci_dev_driver - get the pci_driver of a device
148962306a36Sopenharmony_ci * @dev: the device to query
149062306a36Sopenharmony_ci *
149162306a36Sopenharmony_ci * Returns the appropriate pci_driver structure or %NULL if there is no
149262306a36Sopenharmony_ci * registered driver for the device.
149362306a36Sopenharmony_ci */
149462306a36Sopenharmony_cistruct pci_driver *pci_dev_driver(const struct pci_dev *dev)
149562306a36Sopenharmony_ci{
149662306a36Sopenharmony_ci	int i;
149762306a36Sopenharmony_ci
149862306a36Sopenharmony_ci	if (dev->driver)
149962306a36Sopenharmony_ci		return dev->driver;
150062306a36Sopenharmony_ci
150162306a36Sopenharmony_ci	for (i = 0; i <= PCI_ROM_RESOURCE; i++)
150262306a36Sopenharmony_ci		if (dev->resource[i].flags & IORESOURCE_BUSY)
150362306a36Sopenharmony_ci			return &pci_compat_driver;
150462306a36Sopenharmony_ci
150562306a36Sopenharmony_ci	return NULL;
150662306a36Sopenharmony_ci}
150762306a36Sopenharmony_ciEXPORT_SYMBOL(pci_dev_driver);
150862306a36Sopenharmony_ci
150962306a36Sopenharmony_ci/**
151062306a36Sopenharmony_ci * pci_bus_match - Tell if a PCI device structure has a matching PCI device id structure
151162306a36Sopenharmony_ci * @dev: the PCI device structure to match against
151262306a36Sopenharmony_ci * @drv: the device driver to search for matching PCI device id structures
151362306a36Sopenharmony_ci *
151462306a36Sopenharmony_ci * Used by a driver to check whether a PCI device present in the
151562306a36Sopenharmony_ci * system is in its list of supported devices. Returns the matching
151662306a36Sopenharmony_ci * pci_device_id structure or %NULL if there is no match.
151762306a36Sopenharmony_ci */
151862306a36Sopenharmony_cistatic int pci_bus_match(struct device *dev, struct device_driver *drv)
151962306a36Sopenharmony_ci{
152062306a36Sopenharmony_ci	struct pci_dev *pci_dev = to_pci_dev(dev);
152162306a36Sopenharmony_ci	struct pci_driver *pci_drv;
152262306a36Sopenharmony_ci	const struct pci_device_id *found_id;
152362306a36Sopenharmony_ci
152462306a36Sopenharmony_ci	if (!pci_dev->match_driver)
152562306a36Sopenharmony_ci		return 0;
152662306a36Sopenharmony_ci
152762306a36Sopenharmony_ci	pci_drv = to_pci_driver(drv);
152862306a36Sopenharmony_ci	found_id = pci_match_device(pci_drv, pci_dev);
152962306a36Sopenharmony_ci	if (found_id)
153062306a36Sopenharmony_ci		return 1;
153162306a36Sopenharmony_ci
153262306a36Sopenharmony_ci	return 0;
153362306a36Sopenharmony_ci}
153462306a36Sopenharmony_ci
153562306a36Sopenharmony_ci/**
153662306a36Sopenharmony_ci * pci_dev_get - increments the reference count of the pci device structure
153762306a36Sopenharmony_ci * @dev: the device being referenced
153862306a36Sopenharmony_ci *
153962306a36Sopenharmony_ci * Each live reference to a device should be refcounted.
154062306a36Sopenharmony_ci *
154162306a36Sopenharmony_ci * Drivers for PCI devices should normally record such references in
154262306a36Sopenharmony_ci * their probe() methods, when they bind to a device, and release
154362306a36Sopenharmony_ci * them by calling pci_dev_put(), in their disconnect() methods.
154462306a36Sopenharmony_ci *
154562306a36Sopenharmony_ci * A pointer to the device with the incremented reference counter is returned.
154662306a36Sopenharmony_ci */
154762306a36Sopenharmony_cistruct pci_dev *pci_dev_get(struct pci_dev *dev)
154862306a36Sopenharmony_ci{
154962306a36Sopenharmony_ci	if (dev)
155062306a36Sopenharmony_ci		get_device(&dev->dev);
155162306a36Sopenharmony_ci	return dev;
155262306a36Sopenharmony_ci}
155362306a36Sopenharmony_ciEXPORT_SYMBOL(pci_dev_get);
155462306a36Sopenharmony_ci
155562306a36Sopenharmony_ci/**
155662306a36Sopenharmony_ci * pci_dev_put - release a use of the pci device structure
155762306a36Sopenharmony_ci * @dev: device that's been disconnected
155862306a36Sopenharmony_ci *
155962306a36Sopenharmony_ci * Must be called when a user of a device is finished with it.  When the last
156062306a36Sopenharmony_ci * user of the device calls this function, the memory of the device is freed.
156162306a36Sopenharmony_ci */
156262306a36Sopenharmony_civoid pci_dev_put(struct pci_dev *dev)
156362306a36Sopenharmony_ci{
156462306a36Sopenharmony_ci	if (dev)
156562306a36Sopenharmony_ci		put_device(&dev->dev);
156662306a36Sopenharmony_ci}
156762306a36Sopenharmony_ciEXPORT_SYMBOL(pci_dev_put);
156862306a36Sopenharmony_ci
156962306a36Sopenharmony_cistatic int pci_uevent(const struct device *dev, struct kobj_uevent_env *env)
157062306a36Sopenharmony_ci{
157162306a36Sopenharmony_ci	const struct pci_dev *pdev;
157262306a36Sopenharmony_ci
157362306a36Sopenharmony_ci	if (!dev)
157462306a36Sopenharmony_ci		return -ENODEV;
157562306a36Sopenharmony_ci
157662306a36Sopenharmony_ci	pdev = to_pci_dev(dev);
157762306a36Sopenharmony_ci
157862306a36Sopenharmony_ci	if (add_uevent_var(env, "PCI_CLASS=%04X", pdev->class))
157962306a36Sopenharmony_ci		return -ENOMEM;
158062306a36Sopenharmony_ci
158162306a36Sopenharmony_ci	if (add_uevent_var(env, "PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
158262306a36Sopenharmony_ci		return -ENOMEM;
158362306a36Sopenharmony_ci
158462306a36Sopenharmony_ci	if (add_uevent_var(env, "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
158562306a36Sopenharmony_ci			   pdev->subsystem_device))
158662306a36Sopenharmony_ci		return -ENOMEM;
158762306a36Sopenharmony_ci
158862306a36Sopenharmony_ci	if (add_uevent_var(env, "PCI_SLOT_NAME=%s", pci_name(pdev)))
158962306a36Sopenharmony_ci		return -ENOMEM;
159062306a36Sopenharmony_ci
159162306a36Sopenharmony_ci	if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02X",
159262306a36Sopenharmony_ci			   pdev->vendor, pdev->device,
159362306a36Sopenharmony_ci			   pdev->subsystem_vendor, pdev->subsystem_device,
159462306a36Sopenharmony_ci			   (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
159562306a36Sopenharmony_ci			   (u8)(pdev->class)))
159662306a36Sopenharmony_ci		return -ENOMEM;
159762306a36Sopenharmony_ci
159862306a36Sopenharmony_ci	return 0;
159962306a36Sopenharmony_ci}
160062306a36Sopenharmony_ci
160162306a36Sopenharmony_ci#if defined(CONFIG_PCIEAER) || defined(CONFIG_EEH)
160262306a36Sopenharmony_ci/**
160362306a36Sopenharmony_ci * pci_uevent_ers - emit a uevent during recovery path of PCI device
160462306a36Sopenharmony_ci * @pdev: PCI device undergoing error recovery
160562306a36Sopenharmony_ci * @err_type: type of error event
160662306a36Sopenharmony_ci */
160762306a36Sopenharmony_civoid pci_uevent_ers(struct pci_dev *pdev, enum pci_ers_result err_type)
160862306a36Sopenharmony_ci{
160962306a36Sopenharmony_ci	int idx = 0;
161062306a36Sopenharmony_ci	char *envp[3];
161162306a36Sopenharmony_ci
161262306a36Sopenharmony_ci	switch (err_type) {
161362306a36Sopenharmony_ci	case PCI_ERS_RESULT_NONE:
161462306a36Sopenharmony_ci	case PCI_ERS_RESULT_CAN_RECOVER:
161562306a36Sopenharmony_ci		envp[idx++] = "ERROR_EVENT=BEGIN_RECOVERY";
161662306a36Sopenharmony_ci		envp[idx++] = "DEVICE_ONLINE=0";
161762306a36Sopenharmony_ci		break;
161862306a36Sopenharmony_ci	case PCI_ERS_RESULT_RECOVERED:
161962306a36Sopenharmony_ci		envp[idx++] = "ERROR_EVENT=SUCCESSFUL_RECOVERY";
162062306a36Sopenharmony_ci		envp[idx++] = "DEVICE_ONLINE=1";
162162306a36Sopenharmony_ci		break;
162262306a36Sopenharmony_ci	case PCI_ERS_RESULT_DISCONNECT:
162362306a36Sopenharmony_ci		envp[idx++] = "ERROR_EVENT=FAILED_RECOVERY";
162462306a36Sopenharmony_ci		envp[idx++] = "DEVICE_ONLINE=0";
162562306a36Sopenharmony_ci		break;
162662306a36Sopenharmony_ci	default:
162762306a36Sopenharmony_ci		break;
162862306a36Sopenharmony_ci	}
162962306a36Sopenharmony_ci
163062306a36Sopenharmony_ci	if (idx > 0) {
163162306a36Sopenharmony_ci		envp[idx++] = NULL;
163262306a36Sopenharmony_ci		kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, envp);
163362306a36Sopenharmony_ci	}
163462306a36Sopenharmony_ci}
163562306a36Sopenharmony_ci#endif
163662306a36Sopenharmony_ci
163762306a36Sopenharmony_cistatic int pci_bus_num_vf(struct device *dev)
163862306a36Sopenharmony_ci{
163962306a36Sopenharmony_ci	return pci_num_vf(to_pci_dev(dev));
164062306a36Sopenharmony_ci}
164162306a36Sopenharmony_ci
164262306a36Sopenharmony_ci/**
164362306a36Sopenharmony_ci * pci_dma_configure - Setup DMA configuration
164462306a36Sopenharmony_ci * @dev: ptr to dev structure
164562306a36Sopenharmony_ci *
164662306a36Sopenharmony_ci * Function to update PCI devices's DMA configuration using the same
164762306a36Sopenharmony_ci * info from the OF node or ACPI node of host bridge's parent (if any).
164862306a36Sopenharmony_ci */
164962306a36Sopenharmony_cistatic int pci_dma_configure(struct device *dev)
165062306a36Sopenharmony_ci{
165162306a36Sopenharmony_ci	struct pci_driver *driver = to_pci_driver(dev->driver);
165262306a36Sopenharmony_ci	struct device *bridge;
165362306a36Sopenharmony_ci	int ret = 0;
165462306a36Sopenharmony_ci
165562306a36Sopenharmony_ci	bridge = pci_get_host_bridge_device(to_pci_dev(dev));
165662306a36Sopenharmony_ci
165762306a36Sopenharmony_ci	if (IS_ENABLED(CONFIG_OF) && bridge->parent &&
165862306a36Sopenharmony_ci	    bridge->parent->of_node) {
165962306a36Sopenharmony_ci		ret = of_dma_configure(dev, bridge->parent->of_node, true);
166062306a36Sopenharmony_ci	} else if (has_acpi_companion(bridge)) {
166162306a36Sopenharmony_ci		struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
166262306a36Sopenharmony_ci
166362306a36Sopenharmony_ci		ret = acpi_dma_configure(dev, acpi_get_dma_attr(adev));
166462306a36Sopenharmony_ci	}
166562306a36Sopenharmony_ci
166662306a36Sopenharmony_ci	pci_put_host_bridge_device(bridge);
166762306a36Sopenharmony_ci
166862306a36Sopenharmony_ci	if (!ret && !driver->driver_managed_dma) {
166962306a36Sopenharmony_ci		ret = iommu_device_use_default_domain(dev);
167062306a36Sopenharmony_ci		if (ret)
167162306a36Sopenharmony_ci			arch_teardown_dma_ops(dev);
167262306a36Sopenharmony_ci	}
167362306a36Sopenharmony_ci
167462306a36Sopenharmony_ci	return ret;
167562306a36Sopenharmony_ci}
167662306a36Sopenharmony_ci
167762306a36Sopenharmony_cistatic void pci_dma_cleanup(struct device *dev)
167862306a36Sopenharmony_ci{
167962306a36Sopenharmony_ci	struct pci_driver *driver = to_pci_driver(dev->driver);
168062306a36Sopenharmony_ci
168162306a36Sopenharmony_ci	if (!driver->driver_managed_dma)
168262306a36Sopenharmony_ci		iommu_device_unuse_default_domain(dev);
168362306a36Sopenharmony_ci}
168462306a36Sopenharmony_ci
168562306a36Sopenharmony_cistruct bus_type pci_bus_type = {
168662306a36Sopenharmony_ci	.name		= "pci",
168762306a36Sopenharmony_ci	.match		= pci_bus_match,
168862306a36Sopenharmony_ci	.uevent		= pci_uevent,
168962306a36Sopenharmony_ci	.probe		= pci_device_probe,
169062306a36Sopenharmony_ci	.remove		= pci_device_remove,
169162306a36Sopenharmony_ci	.shutdown	= pci_device_shutdown,
169262306a36Sopenharmony_ci	.dev_groups	= pci_dev_groups,
169362306a36Sopenharmony_ci	.bus_groups	= pci_bus_groups,
169462306a36Sopenharmony_ci	.drv_groups	= pci_drv_groups,
169562306a36Sopenharmony_ci	.pm		= PCI_PM_OPS_PTR,
169662306a36Sopenharmony_ci	.num_vf		= pci_bus_num_vf,
169762306a36Sopenharmony_ci	.dma_configure	= pci_dma_configure,
169862306a36Sopenharmony_ci	.dma_cleanup	= pci_dma_cleanup,
169962306a36Sopenharmony_ci};
170062306a36Sopenharmony_ciEXPORT_SYMBOL(pci_bus_type);
170162306a36Sopenharmony_ci
170262306a36Sopenharmony_ci#ifdef CONFIG_PCIEPORTBUS
170362306a36Sopenharmony_cistatic int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
170462306a36Sopenharmony_ci{
170562306a36Sopenharmony_ci	struct pcie_device *pciedev;
170662306a36Sopenharmony_ci	struct pcie_port_service_driver *driver;
170762306a36Sopenharmony_ci
170862306a36Sopenharmony_ci	if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type)
170962306a36Sopenharmony_ci		return 0;
171062306a36Sopenharmony_ci
171162306a36Sopenharmony_ci	pciedev = to_pcie_device(dev);
171262306a36Sopenharmony_ci	driver = to_service_driver(drv);
171362306a36Sopenharmony_ci
171462306a36Sopenharmony_ci	if (driver->service != pciedev->service)
171562306a36Sopenharmony_ci		return 0;
171662306a36Sopenharmony_ci
171762306a36Sopenharmony_ci	if (driver->port_type != PCIE_ANY_PORT &&
171862306a36Sopenharmony_ci	    driver->port_type != pci_pcie_type(pciedev->port))
171962306a36Sopenharmony_ci		return 0;
172062306a36Sopenharmony_ci
172162306a36Sopenharmony_ci	return 1;
172262306a36Sopenharmony_ci}
172362306a36Sopenharmony_ci
172462306a36Sopenharmony_cistruct bus_type pcie_port_bus_type = {
172562306a36Sopenharmony_ci	.name		= "pci_express",
172662306a36Sopenharmony_ci	.match		= pcie_port_bus_match,
172762306a36Sopenharmony_ci};
172862306a36Sopenharmony_ci#endif
172962306a36Sopenharmony_ci
173062306a36Sopenharmony_cistatic int __init pci_driver_init(void)
173162306a36Sopenharmony_ci{
173262306a36Sopenharmony_ci	int ret;
173362306a36Sopenharmony_ci
173462306a36Sopenharmony_ci	ret = bus_register(&pci_bus_type);
173562306a36Sopenharmony_ci	if (ret)
173662306a36Sopenharmony_ci		return ret;
173762306a36Sopenharmony_ci
173862306a36Sopenharmony_ci#ifdef CONFIG_PCIEPORTBUS
173962306a36Sopenharmony_ci	ret = bus_register(&pcie_port_bus_type);
174062306a36Sopenharmony_ci	if (ret)
174162306a36Sopenharmony_ci		return ret;
174262306a36Sopenharmony_ci#endif
174362306a36Sopenharmony_ci	dma_debug_add_bus(&pci_bus_type);
174462306a36Sopenharmony_ci	return 0;
174562306a36Sopenharmony_ci}
174662306a36Sopenharmony_cipostcore_initcall(pci_driver_init);
1747