162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * PCI Bus Services, see include/linux/pci.h for further explanation.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter,
662306a36Sopenharmony_ci * David Mosberger-Tang
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Copyright 1997 -- 2000 Martin Mares <mj@ucw.cz>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/acpi.h>
1262306a36Sopenharmony_ci#include <linux/kernel.h>
1362306a36Sopenharmony_ci#include <linux/delay.h>
1462306a36Sopenharmony_ci#include <linux/dmi.h>
1562306a36Sopenharmony_ci#include <linux/init.h>
1662306a36Sopenharmony_ci#include <linux/msi.h>
1762306a36Sopenharmony_ci#include <linux/of.h>
1862306a36Sopenharmony_ci#include <linux/pci.h>
1962306a36Sopenharmony_ci#include <linux/pm.h>
2062306a36Sopenharmony_ci#include <linux/slab.h>
2162306a36Sopenharmony_ci#include <linux/module.h>
2262306a36Sopenharmony_ci#include <linux/spinlock.h>
2362306a36Sopenharmony_ci#include <linux/string.h>
2462306a36Sopenharmony_ci#include <linux/log2.h>
2562306a36Sopenharmony_ci#include <linux/logic_pio.h>
2662306a36Sopenharmony_ci#include <linux/pm_wakeup.h>
2762306a36Sopenharmony_ci#include <linux/interrupt.h>
2862306a36Sopenharmony_ci#include <linux/device.h>
2962306a36Sopenharmony_ci#include <linux/pm_runtime.h>
3062306a36Sopenharmony_ci#include <linux/pci_hotplug.h>
3162306a36Sopenharmony_ci#include <linux/vmalloc.h>
3262306a36Sopenharmony_ci#include <asm/dma.h>
3362306a36Sopenharmony_ci#include <linux/aer.h>
3462306a36Sopenharmony_ci#include <linux/bitfield.h>
3562306a36Sopenharmony_ci#include "pci.h"
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ciDEFINE_MUTEX(pci_slot_mutex);
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ciconst char *pci_power_names[] = {
4062306a36Sopenharmony_ci	"error", "D0", "D1", "D2", "D3hot", "D3cold", "unknown",
4162306a36Sopenharmony_ci};
4262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_power_names);
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci#ifdef CONFIG_X86_32
4562306a36Sopenharmony_ciint isa_dma_bridge_buggy;
4662306a36Sopenharmony_ciEXPORT_SYMBOL(isa_dma_bridge_buggy);
4762306a36Sopenharmony_ci#endif
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ciint pci_pci_problems;
5062306a36Sopenharmony_ciEXPORT_SYMBOL(pci_pci_problems);
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ciunsigned int pci_pm_d3hot_delay;
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_cistatic void pci_pme_list_scan(struct work_struct *work);
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_cistatic LIST_HEAD(pci_pme_list);
5762306a36Sopenharmony_cistatic DEFINE_MUTEX(pci_pme_list_mutex);
5862306a36Sopenharmony_cistatic DECLARE_DELAYED_WORK(pci_pme_work, pci_pme_list_scan);
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_cistruct pci_pme_device {
6162306a36Sopenharmony_ci	struct list_head list;
6262306a36Sopenharmony_ci	struct pci_dev *dev;
6362306a36Sopenharmony_ci};
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci#define PME_TIMEOUT 1000 /* How long between PME checks */
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci/*
6862306a36Sopenharmony_ci * Following exit from Conventional Reset, devices must be ready within 1 sec
6962306a36Sopenharmony_ci * (PCIe r6.0 sec 6.6.1).  A D3cold to D0 transition implies a Conventional
7062306a36Sopenharmony_ci * Reset (PCIe r6.0 sec 5.8).
7162306a36Sopenharmony_ci */
7262306a36Sopenharmony_ci#define PCI_RESET_WAIT 1000 /* msec */
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci/*
7562306a36Sopenharmony_ci * Devices may extend the 1 sec period through Request Retry Status
7662306a36Sopenharmony_ci * completions (PCIe r6.0 sec 2.3.1).  The spec does not provide an upper
7762306a36Sopenharmony_ci * limit, but 60 sec ought to be enough for any device to become
7862306a36Sopenharmony_ci * responsive.
7962306a36Sopenharmony_ci */
8062306a36Sopenharmony_ci#define PCIE_RESET_READY_POLL_MS 60000 /* msec */
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistatic void pci_dev_d3_sleep(struct pci_dev *dev)
8362306a36Sopenharmony_ci{
8462306a36Sopenharmony_ci	unsigned int delay_ms = max(dev->d3hot_delay, pci_pm_d3hot_delay);
8562306a36Sopenharmony_ci	unsigned int upper;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	if (delay_ms) {
8862306a36Sopenharmony_ci		/* Use a 20% upper bound, 1ms minimum */
8962306a36Sopenharmony_ci		upper = max(DIV_ROUND_CLOSEST(delay_ms, 5), 1U);
9062306a36Sopenharmony_ci		usleep_range(delay_ms * USEC_PER_MSEC,
9162306a36Sopenharmony_ci			     (delay_ms + upper) * USEC_PER_MSEC);
9262306a36Sopenharmony_ci	}
9362306a36Sopenharmony_ci}
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_cibool pci_reset_supported(struct pci_dev *dev)
9662306a36Sopenharmony_ci{
9762306a36Sopenharmony_ci	return dev->reset_methods[0] != 0;
9862306a36Sopenharmony_ci}
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci#ifdef CONFIG_PCI_DOMAINS
10162306a36Sopenharmony_ciint pci_domains_supported = 1;
10262306a36Sopenharmony_ci#endif
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci#define DEFAULT_CARDBUS_IO_SIZE		(256)
10562306a36Sopenharmony_ci#define DEFAULT_CARDBUS_MEM_SIZE	(64*1024*1024)
10662306a36Sopenharmony_ci/* pci=cbmemsize=nnM,cbiosize=nn can override this */
10762306a36Sopenharmony_ciunsigned long pci_cardbus_io_size = DEFAULT_CARDBUS_IO_SIZE;
10862306a36Sopenharmony_ciunsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE;
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci#define DEFAULT_HOTPLUG_IO_SIZE		(256)
11162306a36Sopenharmony_ci#define DEFAULT_HOTPLUG_MMIO_SIZE	(2*1024*1024)
11262306a36Sopenharmony_ci#define DEFAULT_HOTPLUG_MMIO_PREF_SIZE	(2*1024*1024)
11362306a36Sopenharmony_ci/* hpiosize=nn can override this */
11462306a36Sopenharmony_ciunsigned long pci_hotplug_io_size  = DEFAULT_HOTPLUG_IO_SIZE;
11562306a36Sopenharmony_ci/*
11662306a36Sopenharmony_ci * pci=hpmmiosize=nnM overrides non-prefetchable MMIO size,
11762306a36Sopenharmony_ci * pci=hpmmioprefsize=nnM overrides prefetchable MMIO size;
11862306a36Sopenharmony_ci * pci=hpmemsize=nnM overrides both
11962306a36Sopenharmony_ci */
12062306a36Sopenharmony_ciunsigned long pci_hotplug_mmio_size = DEFAULT_HOTPLUG_MMIO_SIZE;
12162306a36Sopenharmony_ciunsigned long pci_hotplug_mmio_pref_size = DEFAULT_HOTPLUG_MMIO_PREF_SIZE;
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci#define DEFAULT_HOTPLUG_BUS_SIZE	1
12462306a36Sopenharmony_ciunsigned long pci_hotplug_bus_size = DEFAULT_HOTPLUG_BUS_SIZE;
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci/* PCIe MPS/MRRS strategy; can be overridden by kernel command-line param */
12862306a36Sopenharmony_ci#ifdef CONFIG_PCIE_BUS_TUNE_OFF
12962306a36Sopenharmony_cienum pcie_bus_config_types pcie_bus_config = PCIE_BUS_TUNE_OFF;
13062306a36Sopenharmony_ci#elif defined CONFIG_PCIE_BUS_SAFE
13162306a36Sopenharmony_cienum pcie_bus_config_types pcie_bus_config = PCIE_BUS_SAFE;
13262306a36Sopenharmony_ci#elif defined CONFIG_PCIE_BUS_PERFORMANCE
13362306a36Sopenharmony_cienum pcie_bus_config_types pcie_bus_config = PCIE_BUS_PERFORMANCE;
13462306a36Sopenharmony_ci#elif defined CONFIG_PCIE_BUS_PEER2PEER
13562306a36Sopenharmony_cienum pcie_bus_config_types pcie_bus_config = PCIE_BUS_PEER2PEER;
13662306a36Sopenharmony_ci#else
13762306a36Sopenharmony_cienum pcie_bus_config_types pcie_bus_config = PCIE_BUS_DEFAULT;
13862306a36Sopenharmony_ci#endif
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci/*
14162306a36Sopenharmony_ci * The default CLS is used if arch didn't set CLS explicitly and not
14262306a36Sopenharmony_ci * all pci devices agree on the same value.  Arch can override either
14362306a36Sopenharmony_ci * the dfl or actual value as it sees fit.  Don't forget this is
14462306a36Sopenharmony_ci * measured in 32-bit words, not bytes.
14562306a36Sopenharmony_ci */
14662306a36Sopenharmony_ciu8 pci_dfl_cache_line_size = L1_CACHE_BYTES >> 2;
14762306a36Sopenharmony_ciu8 pci_cache_line_size;
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci/*
15062306a36Sopenharmony_ci * If we set up a device for bus mastering, we need to check the latency
15162306a36Sopenharmony_ci * timer as certain BIOSes forget to set it properly.
15262306a36Sopenharmony_ci */
15362306a36Sopenharmony_ciunsigned int pcibios_max_latency = 255;
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci/* If set, the PCIe ARI capability will not be used. */
15662306a36Sopenharmony_cistatic bool pcie_ari_disabled;
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci/* If set, the PCIe ATS capability will not be used. */
15962306a36Sopenharmony_cistatic bool pcie_ats_disabled;
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci/* If set, the PCI config space of each device is printed during boot. */
16262306a36Sopenharmony_cibool pci_early_dump;
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_cibool pci_ats_disabled(void)
16562306a36Sopenharmony_ci{
16662306a36Sopenharmony_ci	return pcie_ats_disabled;
16762306a36Sopenharmony_ci}
16862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_ats_disabled);
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci/* Disable bridge_d3 for all PCIe ports */
17162306a36Sopenharmony_cistatic bool pci_bridge_d3_disable;
17262306a36Sopenharmony_ci/* Force bridge_d3 for all PCIe ports */
17362306a36Sopenharmony_cistatic bool pci_bridge_d3_force;
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_cistatic int __init pcie_port_pm_setup(char *str)
17662306a36Sopenharmony_ci{
17762306a36Sopenharmony_ci	if (!strcmp(str, "off"))
17862306a36Sopenharmony_ci		pci_bridge_d3_disable = true;
17962306a36Sopenharmony_ci	else if (!strcmp(str, "force"))
18062306a36Sopenharmony_ci		pci_bridge_d3_force = true;
18162306a36Sopenharmony_ci	return 1;
18262306a36Sopenharmony_ci}
18362306a36Sopenharmony_ci__setup("pcie_port_pm=", pcie_port_pm_setup);
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci/**
18662306a36Sopenharmony_ci * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
18762306a36Sopenharmony_ci * @bus: pointer to PCI bus structure to search
18862306a36Sopenharmony_ci *
18962306a36Sopenharmony_ci * Given a PCI bus, returns the highest PCI bus number present in the set
19062306a36Sopenharmony_ci * including the given PCI bus and its list of child PCI buses.
19162306a36Sopenharmony_ci */
19262306a36Sopenharmony_ciunsigned char pci_bus_max_busnr(struct pci_bus *bus)
19362306a36Sopenharmony_ci{
19462306a36Sopenharmony_ci	struct pci_bus *tmp;
19562306a36Sopenharmony_ci	unsigned char max, n;
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	max = bus->busn_res.end;
19862306a36Sopenharmony_ci	list_for_each_entry(tmp, &bus->children, node) {
19962306a36Sopenharmony_ci		n = pci_bus_max_busnr(tmp);
20062306a36Sopenharmony_ci		if (n > max)
20162306a36Sopenharmony_ci			max = n;
20262306a36Sopenharmony_ci	}
20362306a36Sopenharmony_ci	return max;
20462306a36Sopenharmony_ci}
20562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_bus_max_busnr);
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci/**
20862306a36Sopenharmony_ci * pci_status_get_and_clear_errors - return and clear error bits in PCI_STATUS
20962306a36Sopenharmony_ci * @pdev: the PCI device
21062306a36Sopenharmony_ci *
21162306a36Sopenharmony_ci * Returns error bits set in PCI_STATUS and clears them.
21262306a36Sopenharmony_ci */
21362306a36Sopenharmony_ciint pci_status_get_and_clear_errors(struct pci_dev *pdev)
21462306a36Sopenharmony_ci{
21562306a36Sopenharmony_ci	u16 status;
21662306a36Sopenharmony_ci	int ret;
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	ret = pci_read_config_word(pdev, PCI_STATUS, &status);
21962306a36Sopenharmony_ci	if (ret != PCIBIOS_SUCCESSFUL)
22062306a36Sopenharmony_ci		return -EIO;
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	status &= PCI_STATUS_ERROR_BITS;
22362306a36Sopenharmony_ci	if (status)
22462306a36Sopenharmony_ci		pci_write_config_word(pdev, PCI_STATUS, status);
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	return status;
22762306a36Sopenharmony_ci}
22862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_status_get_and_clear_errors);
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci#ifdef CONFIG_HAS_IOMEM
23162306a36Sopenharmony_cistatic void __iomem *__pci_ioremap_resource(struct pci_dev *pdev, int bar,
23262306a36Sopenharmony_ci					    bool write_combine)
23362306a36Sopenharmony_ci{
23462306a36Sopenharmony_ci	struct resource *res = &pdev->resource[bar];
23562306a36Sopenharmony_ci	resource_size_t start = res->start;
23662306a36Sopenharmony_ci	resource_size_t size = resource_size(res);
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci	/*
23962306a36Sopenharmony_ci	 * Make sure the BAR is actually a memory resource, not an IO resource
24062306a36Sopenharmony_ci	 */
24162306a36Sopenharmony_ci	if (res->flags & IORESOURCE_UNSET || !(res->flags & IORESOURCE_MEM)) {
24262306a36Sopenharmony_ci		pci_err(pdev, "can't ioremap BAR %d: %pR\n", bar, res);
24362306a36Sopenharmony_ci		return NULL;
24462306a36Sopenharmony_ci	}
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci	if (write_combine)
24762306a36Sopenharmony_ci		return ioremap_wc(start, size);
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci	return ioremap(start, size);
25062306a36Sopenharmony_ci}
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_civoid __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar)
25362306a36Sopenharmony_ci{
25462306a36Sopenharmony_ci	return __pci_ioremap_resource(pdev, bar, false);
25562306a36Sopenharmony_ci}
25662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_ioremap_bar);
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_civoid __iomem *pci_ioremap_wc_bar(struct pci_dev *pdev, int bar)
25962306a36Sopenharmony_ci{
26062306a36Sopenharmony_ci	return __pci_ioremap_resource(pdev, bar, true);
26162306a36Sopenharmony_ci}
26262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_ioremap_wc_bar);
26362306a36Sopenharmony_ci#endif
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci/**
26662306a36Sopenharmony_ci * pci_dev_str_match_path - test if a path string matches a device
26762306a36Sopenharmony_ci * @dev: the PCI device to test
26862306a36Sopenharmony_ci * @path: string to match the device against
26962306a36Sopenharmony_ci * @endptr: pointer to the string after the match
27062306a36Sopenharmony_ci *
27162306a36Sopenharmony_ci * Test if a string (typically from a kernel parameter) formatted as a
27262306a36Sopenharmony_ci * path of device/function addresses matches a PCI device. The string must
27362306a36Sopenharmony_ci * be of the form:
27462306a36Sopenharmony_ci *
27562306a36Sopenharmony_ci *   [<domain>:]<bus>:<device>.<func>[/<device>.<func>]*
27662306a36Sopenharmony_ci *
27762306a36Sopenharmony_ci * A path for a device can be obtained using 'lspci -t'.  Using a path
27862306a36Sopenharmony_ci * is more robust against bus renumbering than using only a single bus,
27962306a36Sopenharmony_ci * device and function address.
28062306a36Sopenharmony_ci *
28162306a36Sopenharmony_ci * Returns 1 if the string matches the device, 0 if it does not and
28262306a36Sopenharmony_ci * a negative error code if it fails to parse the string.
28362306a36Sopenharmony_ci */
28462306a36Sopenharmony_cistatic int pci_dev_str_match_path(struct pci_dev *dev, const char *path,
28562306a36Sopenharmony_ci				  const char **endptr)
28662306a36Sopenharmony_ci{
28762306a36Sopenharmony_ci	int ret;
28862306a36Sopenharmony_ci	unsigned int seg, bus, slot, func;
28962306a36Sopenharmony_ci	char *wpath, *p;
29062306a36Sopenharmony_ci	char end;
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci	*endptr = strchrnul(path, ';');
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci	wpath = kmemdup_nul(path, *endptr - path, GFP_ATOMIC);
29562306a36Sopenharmony_ci	if (!wpath)
29662306a36Sopenharmony_ci		return -ENOMEM;
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ci	while (1) {
29962306a36Sopenharmony_ci		p = strrchr(wpath, '/');
30062306a36Sopenharmony_ci		if (!p)
30162306a36Sopenharmony_ci			break;
30262306a36Sopenharmony_ci		ret = sscanf(p, "/%x.%x%c", &slot, &func, &end);
30362306a36Sopenharmony_ci		if (ret != 2) {
30462306a36Sopenharmony_ci			ret = -EINVAL;
30562306a36Sopenharmony_ci			goto free_and_exit;
30662306a36Sopenharmony_ci		}
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci		if (dev->devfn != PCI_DEVFN(slot, func)) {
30962306a36Sopenharmony_ci			ret = 0;
31062306a36Sopenharmony_ci			goto free_and_exit;
31162306a36Sopenharmony_ci		}
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci		/*
31462306a36Sopenharmony_ci		 * Note: we don't need to get a reference to the upstream
31562306a36Sopenharmony_ci		 * bridge because we hold a reference to the top level
31662306a36Sopenharmony_ci		 * device which should hold a reference to the bridge,
31762306a36Sopenharmony_ci		 * and so on.
31862306a36Sopenharmony_ci		 */
31962306a36Sopenharmony_ci		dev = pci_upstream_bridge(dev);
32062306a36Sopenharmony_ci		if (!dev) {
32162306a36Sopenharmony_ci			ret = 0;
32262306a36Sopenharmony_ci			goto free_and_exit;
32362306a36Sopenharmony_ci		}
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci		*p = 0;
32662306a36Sopenharmony_ci	}
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	ret = sscanf(wpath, "%x:%x:%x.%x%c", &seg, &bus, &slot,
32962306a36Sopenharmony_ci		     &func, &end);
33062306a36Sopenharmony_ci	if (ret != 4) {
33162306a36Sopenharmony_ci		seg = 0;
33262306a36Sopenharmony_ci		ret = sscanf(wpath, "%x:%x.%x%c", &bus, &slot, &func, &end);
33362306a36Sopenharmony_ci		if (ret != 3) {
33462306a36Sopenharmony_ci			ret = -EINVAL;
33562306a36Sopenharmony_ci			goto free_and_exit;
33662306a36Sopenharmony_ci		}
33762306a36Sopenharmony_ci	}
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	ret = (seg == pci_domain_nr(dev->bus) &&
34062306a36Sopenharmony_ci	       bus == dev->bus->number &&
34162306a36Sopenharmony_ci	       dev->devfn == PCI_DEVFN(slot, func));
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_cifree_and_exit:
34462306a36Sopenharmony_ci	kfree(wpath);
34562306a36Sopenharmony_ci	return ret;
34662306a36Sopenharmony_ci}
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci/**
34962306a36Sopenharmony_ci * pci_dev_str_match - test if a string matches a device
35062306a36Sopenharmony_ci * @dev: the PCI device to test
35162306a36Sopenharmony_ci * @p: string to match the device against
35262306a36Sopenharmony_ci * @endptr: pointer to the string after the match
35362306a36Sopenharmony_ci *
35462306a36Sopenharmony_ci * Test if a string (typically from a kernel parameter) matches a specified
35562306a36Sopenharmony_ci * PCI device. The string may be of one of the following formats:
35662306a36Sopenharmony_ci *
35762306a36Sopenharmony_ci *   [<domain>:]<bus>:<device>.<func>[/<device>.<func>]*
35862306a36Sopenharmony_ci *   pci:<vendor>:<device>[:<subvendor>:<subdevice>]
35962306a36Sopenharmony_ci *
36062306a36Sopenharmony_ci * The first format specifies a PCI bus/device/function address which
36162306a36Sopenharmony_ci * may change if new hardware is inserted, if motherboard firmware changes,
36262306a36Sopenharmony_ci * or due to changes caused in kernel parameters. If the domain is
36362306a36Sopenharmony_ci * left unspecified, it is taken to be 0.  In order to be robust against
36462306a36Sopenharmony_ci * bus renumbering issues, a path of PCI device/function numbers may be used
36562306a36Sopenharmony_ci * to address the specific device.  The path for a device can be determined
36662306a36Sopenharmony_ci * through the use of 'lspci -t'.
36762306a36Sopenharmony_ci *
36862306a36Sopenharmony_ci * The second format matches devices using IDs in the configuration
36962306a36Sopenharmony_ci * space which may match multiple devices in the system. A value of 0
37062306a36Sopenharmony_ci * for any field will match all devices. (Note: this differs from
37162306a36Sopenharmony_ci * in-kernel code that uses PCI_ANY_ID which is ~0; this is for
37262306a36Sopenharmony_ci * legacy reasons and convenience so users don't have to specify
37362306a36Sopenharmony_ci * FFFFFFFFs on the command line.)
37462306a36Sopenharmony_ci *
37562306a36Sopenharmony_ci * Returns 1 if the string matches the device, 0 if it does not and
37662306a36Sopenharmony_ci * a negative error code if the string cannot be parsed.
37762306a36Sopenharmony_ci */
37862306a36Sopenharmony_cistatic int pci_dev_str_match(struct pci_dev *dev, const char *p,
37962306a36Sopenharmony_ci			     const char **endptr)
38062306a36Sopenharmony_ci{
38162306a36Sopenharmony_ci	int ret;
38262306a36Sopenharmony_ci	int count;
38362306a36Sopenharmony_ci	unsigned short vendor, device, subsystem_vendor, subsystem_device;
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	if (strncmp(p, "pci:", 4) == 0) {
38662306a36Sopenharmony_ci		/* PCI vendor/device (subvendor/subdevice) IDs are specified */
38762306a36Sopenharmony_ci		p += 4;
38862306a36Sopenharmony_ci		ret = sscanf(p, "%hx:%hx:%hx:%hx%n", &vendor, &device,
38962306a36Sopenharmony_ci			     &subsystem_vendor, &subsystem_device, &count);
39062306a36Sopenharmony_ci		if (ret != 4) {
39162306a36Sopenharmony_ci			ret = sscanf(p, "%hx:%hx%n", &vendor, &device, &count);
39262306a36Sopenharmony_ci			if (ret != 2)
39362306a36Sopenharmony_ci				return -EINVAL;
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci			subsystem_vendor = 0;
39662306a36Sopenharmony_ci			subsystem_device = 0;
39762306a36Sopenharmony_ci		}
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci		p += count;
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci		if ((!vendor || vendor == dev->vendor) &&
40262306a36Sopenharmony_ci		    (!device || device == dev->device) &&
40362306a36Sopenharmony_ci		    (!subsystem_vendor ||
40462306a36Sopenharmony_ci			    subsystem_vendor == dev->subsystem_vendor) &&
40562306a36Sopenharmony_ci		    (!subsystem_device ||
40662306a36Sopenharmony_ci			    subsystem_device == dev->subsystem_device))
40762306a36Sopenharmony_ci			goto found;
40862306a36Sopenharmony_ci	} else {
40962306a36Sopenharmony_ci		/*
41062306a36Sopenharmony_ci		 * PCI Bus, Device, Function IDs are specified
41162306a36Sopenharmony_ci		 * (optionally, may include a path of devfns following it)
41262306a36Sopenharmony_ci		 */
41362306a36Sopenharmony_ci		ret = pci_dev_str_match_path(dev, p, &p);
41462306a36Sopenharmony_ci		if (ret < 0)
41562306a36Sopenharmony_ci			return ret;
41662306a36Sopenharmony_ci		else if (ret)
41762306a36Sopenharmony_ci			goto found;
41862306a36Sopenharmony_ci	}
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci	*endptr = p;
42162306a36Sopenharmony_ci	return 0;
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_cifound:
42462306a36Sopenharmony_ci	*endptr = p;
42562306a36Sopenharmony_ci	return 1;
42662306a36Sopenharmony_ci}
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_cistatic u8 __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
42962306a36Sopenharmony_ci				  u8 pos, int cap, int *ttl)
43062306a36Sopenharmony_ci{
43162306a36Sopenharmony_ci	u8 id;
43262306a36Sopenharmony_ci	u16 ent;
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci	pci_bus_read_config_byte(bus, devfn, pos, &pos);
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ci	while ((*ttl)--) {
43762306a36Sopenharmony_ci		if (pos < 0x40)
43862306a36Sopenharmony_ci			break;
43962306a36Sopenharmony_ci		pos &= ~3;
44062306a36Sopenharmony_ci		pci_bus_read_config_word(bus, devfn, pos, &ent);
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci		id = ent & 0xff;
44362306a36Sopenharmony_ci		if (id == 0xff)
44462306a36Sopenharmony_ci			break;
44562306a36Sopenharmony_ci		if (id == cap)
44662306a36Sopenharmony_ci			return pos;
44762306a36Sopenharmony_ci		pos = (ent >> 8);
44862306a36Sopenharmony_ci	}
44962306a36Sopenharmony_ci	return 0;
45062306a36Sopenharmony_ci}
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_cistatic u8 __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn,
45362306a36Sopenharmony_ci			      u8 pos, int cap)
45462306a36Sopenharmony_ci{
45562306a36Sopenharmony_ci	int ttl = PCI_FIND_CAP_TTL;
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci	return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl);
45862306a36Sopenharmony_ci}
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_ciu8 pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap)
46162306a36Sopenharmony_ci{
46262306a36Sopenharmony_ci	return __pci_find_next_cap(dev->bus, dev->devfn,
46362306a36Sopenharmony_ci				   pos + PCI_CAP_LIST_NEXT, cap);
46462306a36Sopenharmony_ci}
46562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_find_next_capability);
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_cistatic u8 __pci_bus_find_cap_start(struct pci_bus *bus,
46862306a36Sopenharmony_ci				    unsigned int devfn, u8 hdr_type)
46962306a36Sopenharmony_ci{
47062306a36Sopenharmony_ci	u16 status;
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
47362306a36Sopenharmony_ci	if (!(status & PCI_STATUS_CAP_LIST))
47462306a36Sopenharmony_ci		return 0;
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci	switch (hdr_type) {
47762306a36Sopenharmony_ci	case PCI_HEADER_TYPE_NORMAL:
47862306a36Sopenharmony_ci	case PCI_HEADER_TYPE_BRIDGE:
47962306a36Sopenharmony_ci		return PCI_CAPABILITY_LIST;
48062306a36Sopenharmony_ci	case PCI_HEADER_TYPE_CARDBUS:
48162306a36Sopenharmony_ci		return PCI_CB_CAPABILITY_LIST;
48262306a36Sopenharmony_ci	}
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_ci	return 0;
48562306a36Sopenharmony_ci}
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci/**
48862306a36Sopenharmony_ci * pci_find_capability - query for devices' capabilities
48962306a36Sopenharmony_ci * @dev: PCI device to query
49062306a36Sopenharmony_ci * @cap: capability code
49162306a36Sopenharmony_ci *
49262306a36Sopenharmony_ci * Tell if a device supports a given PCI capability.
49362306a36Sopenharmony_ci * Returns the address of the requested capability structure within the
49462306a36Sopenharmony_ci * device's PCI configuration space or 0 in case the device does not
49562306a36Sopenharmony_ci * support it.  Possible values for @cap include:
49662306a36Sopenharmony_ci *
49762306a36Sopenharmony_ci *  %PCI_CAP_ID_PM           Power Management
49862306a36Sopenharmony_ci *  %PCI_CAP_ID_AGP          Accelerated Graphics Port
49962306a36Sopenharmony_ci *  %PCI_CAP_ID_VPD          Vital Product Data
50062306a36Sopenharmony_ci *  %PCI_CAP_ID_SLOTID       Slot Identification
50162306a36Sopenharmony_ci *  %PCI_CAP_ID_MSI          Message Signalled Interrupts
50262306a36Sopenharmony_ci *  %PCI_CAP_ID_CHSWP        CompactPCI HotSwap
50362306a36Sopenharmony_ci *  %PCI_CAP_ID_PCIX         PCI-X
50462306a36Sopenharmony_ci *  %PCI_CAP_ID_EXP          PCI Express
50562306a36Sopenharmony_ci */
50662306a36Sopenharmony_ciu8 pci_find_capability(struct pci_dev *dev, int cap)
50762306a36Sopenharmony_ci{
50862306a36Sopenharmony_ci	u8 pos;
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_ci	pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
51162306a36Sopenharmony_ci	if (pos)
51262306a36Sopenharmony_ci		pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap);
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci	return pos;
51562306a36Sopenharmony_ci}
51662306a36Sopenharmony_ciEXPORT_SYMBOL(pci_find_capability);
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci/**
51962306a36Sopenharmony_ci * pci_bus_find_capability - query for devices' capabilities
52062306a36Sopenharmony_ci * @bus: the PCI bus to query
52162306a36Sopenharmony_ci * @devfn: PCI device to query
52262306a36Sopenharmony_ci * @cap: capability code
52362306a36Sopenharmony_ci *
52462306a36Sopenharmony_ci * Like pci_find_capability() but works for PCI devices that do not have a
52562306a36Sopenharmony_ci * pci_dev structure set up yet.
52662306a36Sopenharmony_ci *
52762306a36Sopenharmony_ci * Returns the address of the requested capability structure within the
52862306a36Sopenharmony_ci * device's PCI configuration space or 0 in case the device does not
52962306a36Sopenharmony_ci * support it.
53062306a36Sopenharmony_ci */
53162306a36Sopenharmony_ciu8 pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
53262306a36Sopenharmony_ci{
53362306a36Sopenharmony_ci	u8 hdr_type, pos;
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci	pos = __pci_bus_find_cap_start(bus, devfn, hdr_type & 0x7f);
53862306a36Sopenharmony_ci	if (pos)
53962306a36Sopenharmony_ci		pos = __pci_find_next_cap(bus, devfn, pos, cap);
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_ci	return pos;
54262306a36Sopenharmony_ci}
54362306a36Sopenharmony_ciEXPORT_SYMBOL(pci_bus_find_capability);
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci/**
54662306a36Sopenharmony_ci * pci_find_next_ext_capability - Find an extended capability
54762306a36Sopenharmony_ci * @dev: PCI device to query
54862306a36Sopenharmony_ci * @start: address at which to start looking (0 to start at beginning of list)
54962306a36Sopenharmony_ci * @cap: capability code
55062306a36Sopenharmony_ci *
55162306a36Sopenharmony_ci * Returns the address of the next matching extended capability structure
55262306a36Sopenharmony_ci * within the device's PCI configuration space or 0 if the device does
55362306a36Sopenharmony_ci * not support it.  Some capabilities can occur several times, e.g., the
55462306a36Sopenharmony_ci * vendor-specific capability, and this provides a way to find them all.
55562306a36Sopenharmony_ci */
55662306a36Sopenharmony_ciu16 pci_find_next_ext_capability(struct pci_dev *dev, u16 start, int cap)
55762306a36Sopenharmony_ci{
55862306a36Sopenharmony_ci	u32 header;
55962306a36Sopenharmony_ci	int ttl;
56062306a36Sopenharmony_ci	u16 pos = PCI_CFG_SPACE_SIZE;
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci	/* minimum 8 bytes per capability */
56362306a36Sopenharmony_ci	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci	if (dev->cfg_size <= PCI_CFG_SPACE_SIZE)
56662306a36Sopenharmony_ci		return 0;
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ci	if (start)
56962306a36Sopenharmony_ci		pos = start;
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_ci	if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
57262306a36Sopenharmony_ci		return 0;
57362306a36Sopenharmony_ci
57462306a36Sopenharmony_ci	/*
57562306a36Sopenharmony_ci	 * If we have no capabilities, this is indicated by cap ID,
57662306a36Sopenharmony_ci	 * cap version and next pointer all being 0.
57762306a36Sopenharmony_ci	 */
57862306a36Sopenharmony_ci	if (header == 0)
57962306a36Sopenharmony_ci		return 0;
58062306a36Sopenharmony_ci
58162306a36Sopenharmony_ci	while (ttl-- > 0) {
58262306a36Sopenharmony_ci		if (PCI_EXT_CAP_ID(header) == cap && pos != start)
58362306a36Sopenharmony_ci			return pos;
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci		pos = PCI_EXT_CAP_NEXT(header);
58662306a36Sopenharmony_ci		if (pos < PCI_CFG_SPACE_SIZE)
58762306a36Sopenharmony_ci			break;
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci		if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
59062306a36Sopenharmony_ci			break;
59162306a36Sopenharmony_ci	}
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_ci	return 0;
59462306a36Sopenharmony_ci}
59562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_find_next_ext_capability);
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_ci/**
59862306a36Sopenharmony_ci * pci_find_ext_capability - Find an extended capability
59962306a36Sopenharmony_ci * @dev: PCI device to query
60062306a36Sopenharmony_ci * @cap: capability code
60162306a36Sopenharmony_ci *
60262306a36Sopenharmony_ci * Returns the address of the requested extended capability structure
60362306a36Sopenharmony_ci * within the device's PCI configuration space or 0 if the device does
60462306a36Sopenharmony_ci * not support it.  Possible values for @cap include:
60562306a36Sopenharmony_ci *
60662306a36Sopenharmony_ci *  %PCI_EXT_CAP_ID_ERR		Advanced Error Reporting
60762306a36Sopenharmony_ci *  %PCI_EXT_CAP_ID_VC		Virtual Channel
60862306a36Sopenharmony_ci *  %PCI_EXT_CAP_ID_DSN		Device Serial Number
60962306a36Sopenharmony_ci *  %PCI_EXT_CAP_ID_PWR		Power Budgeting
61062306a36Sopenharmony_ci */
61162306a36Sopenharmony_ciu16 pci_find_ext_capability(struct pci_dev *dev, int cap)
61262306a36Sopenharmony_ci{
61362306a36Sopenharmony_ci	return pci_find_next_ext_capability(dev, 0, cap);
61462306a36Sopenharmony_ci}
61562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_find_ext_capability);
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci/**
61862306a36Sopenharmony_ci * pci_get_dsn - Read and return the 8-byte Device Serial Number
61962306a36Sopenharmony_ci * @dev: PCI device to query
62062306a36Sopenharmony_ci *
62162306a36Sopenharmony_ci * Looks up the PCI_EXT_CAP_ID_DSN and reads the 8 bytes of the Device Serial
62262306a36Sopenharmony_ci * Number.
62362306a36Sopenharmony_ci *
62462306a36Sopenharmony_ci * Returns the DSN, or zero if the capability does not exist.
62562306a36Sopenharmony_ci */
62662306a36Sopenharmony_ciu64 pci_get_dsn(struct pci_dev *dev)
62762306a36Sopenharmony_ci{
62862306a36Sopenharmony_ci	u32 dword;
62962306a36Sopenharmony_ci	u64 dsn;
63062306a36Sopenharmony_ci	int pos;
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_ci	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DSN);
63362306a36Sopenharmony_ci	if (!pos)
63462306a36Sopenharmony_ci		return 0;
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_ci	/*
63762306a36Sopenharmony_ci	 * The Device Serial Number is two dwords offset 4 bytes from the
63862306a36Sopenharmony_ci	 * capability position. The specification says that the first dword is
63962306a36Sopenharmony_ci	 * the lower half, and the second dword is the upper half.
64062306a36Sopenharmony_ci	 */
64162306a36Sopenharmony_ci	pos += 4;
64262306a36Sopenharmony_ci	pci_read_config_dword(dev, pos, &dword);
64362306a36Sopenharmony_ci	dsn = (u64)dword;
64462306a36Sopenharmony_ci	pci_read_config_dword(dev, pos + 4, &dword);
64562306a36Sopenharmony_ci	dsn |= ((u64)dword) << 32;
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_ci	return dsn;
64862306a36Sopenharmony_ci}
64962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_get_dsn);
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_cistatic u8 __pci_find_next_ht_cap(struct pci_dev *dev, u8 pos, int ht_cap)
65262306a36Sopenharmony_ci{
65362306a36Sopenharmony_ci	int rc, ttl = PCI_FIND_CAP_TTL;
65462306a36Sopenharmony_ci	u8 cap, mask;
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_ci	if (ht_cap == HT_CAPTYPE_SLAVE || ht_cap == HT_CAPTYPE_HOST)
65762306a36Sopenharmony_ci		mask = HT_3BIT_CAP_MASK;
65862306a36Sopenharmony_ci	else
65962306a36Sopenharmony_ci		mask = HT_5BIT_CAP_MASK;
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ci	pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos,
66262306a36Sopenharmony_ci				      PCI_CAP_ID_HT, &ttl);
66362306a36Sopenharmony_ci	while (pos) {
66462306a36Sopenharmony_ci		rc = pci_read_config_byte(dev, pos + 3, &cap);
66562306a36Sopenharmony_ci		if (rc != PCIBIOS_SUCCESSFUL)
66662306a36Sopenharmony_ci			return 0;
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_ci		if ((cap & mask) == ht_cap)
66962306a36Sopenharmony_ci			return pos;
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci		pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn,
67262306a36Sopenharmony_ci					      pos + PCI_CAP_LIST_NEXT,
67362306a36Sopenharmony_ci					      PCI_CAP_ID_HT, &ttl);
67462306a36Sopenharmony_ci	}
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci	return 0;
67762306a36Sopenharmony_ci}
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci/**
68062306a36Sopenharmony_ci * pci_find_next_ht_capability - query a device's HyperTransport capabilities
68162306a36Sopenharmony_ci * @dev: PCI device to query
68262306a36Sopenharmony_ci * @pos: Position from which to continue searching
68362306a36Sopenharmony_ci * @ht_cap: HyperTransport capability code
68462306a36Sopenharmony_ci *
68562306a36Sopenharmony_ci * To be used in conjunction with pci_find_ht_capability() to search for
68662306a36Sopenharmony_ci * all capabilities matching @ht_cap. @pos should always be a value returned
68762306a36Sopenharmony_ci * from pci_find_ht_capability().
68862306a36Sopenharmony_ci *
68962306a36Sopenharmony_ci * NB. To be 100% safe against broken PCI devices, the caller should take
69062306a36Sopenharmony_ci * steps to avoid an infinite loop.
69162306a36Sopenharmony_ci */
69262306a36Sopenharmony_ciu8 pci_find_next_ht_capability(struct pci_dev *dev, u8 pos, int ht_cap)
69362306a36Sopenharmony_ci{
69462306a36Sopenharmony_ci	return __pci_find_next_ht_cap(dev, pos + PCI_CAP_LIST_NEXT, ht_cap);
69562306a36Sopenharmony_ci}
69662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_find_next_ht_capability);
69762306a36Sopenharmony_ci
69862306a36Sopenharmony_ci/**
69962306a36Sopenharmony_ci * pci_find_ht_capability - query a device's HyperTransport capabilities
70062306a36Sopenharmony_ci * @dev: PCI device to query
70162306a36Sopenharmony_ci * @ht_cap: HyperTransport capability code
70262306a36Sopenharmony_ci *
70362306a36Sopenharmony_ci * Tell if a device supports a given HyperTransport capability.
70462306a36Sopenharmony_ci * Returns an address within the device's PCI configuration space
70562306a36Sopenharmony_ci * or 0 in case the device does not support the request capability.
70662306a36Sopenharmony_ci * The address points to the PCI capability, of type PCI_CAP_ID_HT,
70762306a36Sopenharmony_ci * which has a HyperTransport capability matching @ht_cap.
70862306a36Sopenharmony_ci */
70962306a36Sopenharmony_ciu8 pci_find_ht_capability(struct pci_dev *dev, int ht_cap)
71062306a36Sopenharmony_ci{
71162306a36Sopenharmony_ci	u8 pos;
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci	pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
71462306a36Sopenharmony_ci	if (pos)
71562306a36Sopenharmony_ci		pos = __pci_find_next_ht_cap(dev, pos, ht_cap);
71662306a36Sopenharmony_ci
71762306a36Sopenharmony_ci	return pos;
71862306a36Sopenharmony_ci}
71962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_find_ht_capability);
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_ci/**
72262306a36Sopenharmony_ci * pci_find_vsec_capability - Find a vendor-specific extended capability
72362306a36Sopenharmony_ci * @dev: PCI device to query
72462306a36Sopenharmony_ci * @vendor: Vendor ID for which capability is defined
72562306a36Sopenharmony_ci * @cap: Vendor-specific capability ID
72662306a36Sopenharmony_ci *
72762306a36Sopenharmony_ci * If @dev has Vendor ID @vendor, search for a VSEC capability with
72862306a36Sopenharmony_ci * VSEC ID @cap. If found, return the capability offset in
72962306a36Sopenharmony_ci * config space; otherwise return 0.
73062306a36Sopenharmony_ci */
73162306a36Sopenharmony_ciu16 pci_find_vsec_capability(struct pci_dev *dev, u16 vendor, int cap)
73262306a36Sopenharmony_ci{
73362306a36Sopenharmony_ci	u16 vsec = 0;
73462306a36Sopenharmony_ci	u32 header;
73562306a36Sopenharmony_ci	int ret;
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci	if (vendor != dev->vendor)
73862306a36Sopenharmony_ci		return 0;
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci	while ((vsec = pci_find_next_ext_capability(dev, vsec,
74162306a36Sopenharmony_ci						     PCI_EXT_CAP_ID_VNDR))) {
74262306a36Sopenharmony_ci		ret = pci_read_config_dword(dev, vsec + PCI_VNDR_HEADER, &header);
74362306a36Sopenharmony_ci		if (ret != PCIBIOS_SUCCESSFUL)
74462306a36Sopenharmony_ci			continue;
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_ci		if (PCI_VNDR_HEADER_ID(header) == cap)
74762306a36Sopenharmony_ci			return vsec;
74862306a36Sopenharmony_ci	}
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_ci	return 0;
75162306a36Sopenharmony_ci}
75262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_find_vsec_capability);
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_ci/**
75562306a36Sopenharmony_ci * pci_find_dvsec_capability - Find DVSEC for vendor
75662306a36Sopenharmony_ci * @dev: PCI device to query
75762306a36Sopenharmony_ci * @vendor: Vendor ID to match for the DVSEC
75862306a36Sopenharmony_ci * @dvsec: Designated Vendor-specific capability ID
75962306a36Sopenharmony_ci *
76062306a36Sopenharmony_ci * If DVSEC has Vendor ID @vendor and DVSEC ID @dvsec return the capability
76162306a36Sopenharmony_ci * offset in config space; otherwise return 0.
76262306a36Sopenharmony_ci */
76362306a36Sopenharmony_ciu16 pci_find_dvsec_capability(struct pci_dev *dev, u16 vendor, u16 dvsec)
76462306a36Sopenharmony_ci{
76562306a36Sopenharmony_ci	int pos;
76662306a36Sopenharmony_ci
76762306a36Sopenharmony_ci	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DVSEC);
76862306a36Sopenharmony_ci	if (!pos)
76962306a36Sopenharmony_ci		return 0;
77062306a36Sopenharmony_ci
77162306a36Sopenharmony_ci	while (pos) {
77262306a36Sopenharmony_ci		u16 v, id;
77362306a36Sopenharmony_ci
77462306a36Sopenharmony_ci		pci_read_config_word(dev, pos + PCI_DVSEC_HEADER1, &v);
77562306a36Sopenharmony_ci		pci_read_config_word(dev, pos + PCI_DVSEC_HEADER2, &id);
77662306a36Sopenharmony_ci		if (vendor == v && dvsec == id)
77762306a36Sopenharmony_ci			return pos;
77862306a36Sopenharmony_ci
77962306a36Sopenharmony_ci		pos = pci_find_next_ext_capability(dev, pos, PCI_EXT_CAP_ID_DVSEC);
78062306a36Sopenharmony_ci	}
78162306a36Sopenharmony_ci
78262306a36Sopenharmony_ci	return 0;
78362306a36Sopenharmony_ci}
78462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_find_dvsec_capability);
78562306a36Sopenharmony_ci
78662306a36Sopenharmony_ci/**
78762306a36Sopenharmony_ci * pci_find_parent_resource - return resource region of parent bus of given
78862306a36Sopenharmony_ci *			      region
78962306a36Sopenharmony_ci * @dev: PCI device structure contains resources to be searched
79062306a36Sopenharmony_ci * @res: child resource record for which parent is sought
79162306a36Sopenharmony_ci *
79262306a36Sopenharmony_ci * For given resource region of given device, return the resource region of
79362306a36Sopenharmony_ci * parent bus the given region is contained in.
79462306a36Sopenharmony_ci */
79562306a36Sopenharmony_cistruct resource *pci_find_parent_resource(const struct pci_dev *dev,
79662306a36Sopenharmony_ci					  struct resource *res)
79762306a36Sopenharmony_ci{
79862306a36Sopenharmony_ci	const struct pci_bus *bus = dev->bus;
79962306a36Sopenharmony_ci	struct resource *r;
80062306a36Sopenharmony_ci
80162306a36Sopenharmony_ci	pci_bus_for_each_resource(bus, r) {
80262306a36Sopenharmony_ci		if (!r)
80362306a36Sopenharmony_ci			continue;
80462306a36Sopenharmony_ci		if (resource_contains(r, res)) {
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_ci			/*
80762306a36Sopenharmony_ci			 * If the window is prefetchable but the BAR is
80862306a36Sopenharmony_ci			 * not, the allocator made a mistake.
80962306a36Sopenharmony_ci			 */
81062306a36Sopenharmony_ci			if (r->flags & IORESOURCE_PREFETCH &&
81162306a36Sopenharmony_ci			    !(res->flags & IORESOURCE_PREFETCH))
81262306a36Sopenharmony_ci				return NULL;
81362306a36Sopenharmony_ci
81462306a36Sopenharmony_ci			/*
81562306a36Sopenharmony_ci			 * If we're below a transparent bridge, there may
81662306a36Sopenharmony_ci			 * be both a positively-decoded aperture and a
81762306a36Sopenharmony_ci			 * subtractively-decoded region that contain the BAR.
81862306a36Sopenharmony_ci			 * We want the positively-decoded one, so this depends
81962306a36Sopenharmony_ci			 * on pci_bus_for_each_resource() giving us those
82062306a36Sopenharmony_ci			 * first.
82162306a36Sopenharmony_ci			 */
82262306a36Sopenharmony_ci			return r;
82362306a36Sopenharmony_ci		}
82462306a36Sopenharmony_ci	}
82562306a36Sopenharmony_ci	return NULL;
82662306a36Sopenharmony_ci}
82762306a36Sopenharmony_ciEXPORT_SYMBOL(pci_find_parent_resource);
82862306a36Sopenharmony_ci
82962306a36Sopenharmony_ci/**
83062306a36Sopenharmony_ci * pci_find_resource - Return matching PCI device resource
83162306a36Sopenharmony_ci * @dev: PCI device to query
83262306a36Sopenharmony_ci * @res: Resource to look for
83362306a36Sopenharmony_ci *
83462306a36Sopenharmony_ci * Goes over standard PCI resources (BARs) and checks if the given resource
83562306a36Sopenharmony_ci * is partially or fully contained in any of them. In that case the
83662306a36Sopenharmony_ci * matching resource is returned, %NULL otherwise.
83762306a36Sopenharmony_ci */
83862306a36Sopenharmony_cistruct resource *pci_find_resource(struct pci_dev *dev, struct resource *res)
83962306a36Sopenharmony_ci{
84062306a36Sopenharmony_ci	int i;
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_ci	for (i = 0; i < PCI_STD_NUM_BARS; i++) {
84362306a36Sopenharmony_ci		struct resource *r = &dev->resource[i];
84462306a36Sopenharmony_ci
84562306a36Sopenharmony_ci		if (r->start && resource_contains(r, res))
84662306a36Sopenharmony_ci			return r;
84762306a36Sopenharmony_ci	}
84862306a36Sopenharmony_ci
84962306a36Sopenharmony_ci	return NULL;
85062306a36Sopenharmony_ci}
85162306a36Sopenharmony_ciEXPORT_SYMBOL(pci_find_resource);
85262306a36Sopenharmony_ci
85362306a36Sopenharmony_ci/**
85462306a36Sopenharmony_ci * pci_wait_for_pending - wait for @mask bit(s) to clear in status word @pos
85562306a36Sopenharmony_ci * @dev: the PCI device to operate on
85662306a36Sopenharmony_ci * @pos: config space offset of status word
85762306a36Sopenharmony_ci * @mask: mask of bit(s) to care about in status word
85862306a36Sopenharmony_ci *
85962306a36Sopenharmony_ci * Return 1 when mask bit(s) in status word clear, 0 otherwise.
86062306a36Sopenharmony_ci */
86162306a36Sopenharmony_ciint pci_wait_for_pending(struct pci_dev *dev, int pos, u16 mask)
86262306a36Sopenharmony_ci{
86362306a36Sopenharmony_ci	int i;
86462306a36Sopenharmony_ci
86562306a36Sopenharmony_ci	/* Wait for Transaction Pending bit clean */
86662306a36Sopenharmony_ci	for (i = 0; i < 4; i++) {
86762306a36Sopenharmony_ci		u16 status;
86862306a36Sopenharmony_ci		if (i)
86962306a36Sopenharmony_ci			msleep((1 << (i - 1)) * 100);
87062306a36Sopenharmony_ci
87162306a36Sopenharmony_ci		pci_read_config_word(dev, pos, &status);
87262306a36Sopenharmony_ci		if (!(status & mask))
87362306a36Sopenharmony_ci			return 1;
87462306a36Sopenharmony_ci	}
87562306a36Sopenharmony_ci
87662306a36Sopenharmony_ci	return 0;
87762306a36Sopenharmony_ci}
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_cistatic int pci_acs_enable;
88062306a36Sopenharmony_ci
88162306a36Sopenharmony_ci/**
88262306a36Sopenharmony_ci * pci_request_acs - ask for ACS to be enabled if supported
88362306a36Sopenharmony_ci */
88462306a36Sopenharmony_civoid pci_request_acs(void)
88562306a36Sopenharmony_ci{
88662306a36Sopenharmony_ci	pci_acs_enable = 1;
88762306a36Sopenharmony_ci}
88862306a36Sopenharmony_ci
88962306a36Sopenharmony_cistatic const char *disable_acs_redir_param;
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ci/**
89262306a36Sopenharmony_ci * pci_disable_acs_redir - disable ACS redirect capabilities
89362306a36Sopenharmony_ci * @dev: the PCI device
89462306a36Sopenharmony_ci *
89562306a36Sopenharmony_ci * For only devices specified in the disable_acs_redir parameter.
89662306a36Sopenharmony_ci */
89762306a36Sopenharmony_cistatic void pci_disable_acs_redir(struct pci_dev *dev)
89862306a36Sopenharmony_ci{
89962306a36Sopenharmony_ci	int ret = 0;
90062306a36Sopenharmony_ci	const char *p;
90162306a36Sopenharmony_ci	int pos;
90262306a36Sopenharmony_ci	u16 ctrl;
90362306a36Sopenharmony_ci
90462306a36Sopenharmony_ci	if (!disable_acs_redir_param)
90562306a36Sopenharmony_ci		return;
90662306a36Sopenharmony_ci
90762306a36Sopenharmony_ci	p = disable_acs_redir_param;
90862306a36Sopenharmony_ci	while (*p) {
90962306a36Sopenharmony_ci		ret = pci_dev_str_match(dev, p, &p);
91062306a36Sopenharmony_ci		if (ret < 0) {
91162306a36Sopenharmony_ci			pr_info_once("PCI: Can't parse disable_acs_redir parameter: %s\n",
91262306a36Sopenharmony_ci				     disable_acs_redir_param);
91362306a36Sopenharmony_ci
91462306a36Sopenharmony_ci			break;
91562306a36Sopenharmony_ci		} else if (ret == 1) {
91662306a36Sopenharmony_ci			/* Found a match */
91762306a36Sopenharmony_ci			break;
91862306a36Sopenharmony_ci		}
91962306a36Sopenharmony_ci
92062306a36Sopenharmony_ci		if (*p != ';' && *p != ',') {
92162306a36Sopenharmony_ci			/* End of param or invalid format */
92262306a36Sopenharmony_ci			break;
92362306a36Sopenharmony_ci		}
92462306a36Sopenharmony_ci		p++;
92562306a36Sopenharmony_ci	}
92662306a36Sopenharmony_ci
92762306a36Sopenharmony_ci	if (ret != 1)
92862306a36Sopenharmony_ci		return;
92962306a36Sopenharmony_ci
93062306a36Sopenharmony_ci	if (!pci_dev_specific_disable_acs_redir(dev))
93162306a36Sopenharmony_ci		return;
93262306a36Sopenharmony_ci
93362306a36Sopenharmony_ci	pos = dev->acs_cap;
93462306a36Sopenharmony_ci	if (!pos) {
93562306a36Sopenharmony_ci		pci_warn(dev, "cannot disable ACS redirect for this hardware as it does not have ACS capabilities\n");
93662306a36Sopenharmony_ci		return;
93762306a36Sopenharmony_ci	}
93862306a36Sopenharmony_ci
93962306a36Sopenharmony_ci	pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl);
94062306a36Sopenharmony_ci
94162306a36Sopenharmony_ci	/* P2P Request & Completion Redirect */
94262306a36Sopenharmony_ci	ctrl &= ~(PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC);
94362306a36Sopenharmony_ci
94462306a36Sopenharmony_ci	pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
94562306a36Sopenharmony_ci
94662306a36Sopenharmony_ci	pci_info(dev, "disabled ACS redirect\n");
94762306a36Sopenharmony_ci}
94862306a36Sopenharmony_ci
94962306a36Sopenharmony_ci/**
95062306a36Sopenharmony_ci * pci_std_enable_acs - enable ACS on devices using standard ACS capabilities
95162306a36Sopenharmony_ci * @dev: the PCI device
95262306a36Sopenharmony_ci */
95362306a36Sopenharmony_cistatic void pci_std_enable_acs(struct pci_dev *dev)
95462306a36Sopenharmony_ci{
95562306a36Sopenharmony_ci	int pos;
95662306a36Sopenharmony_ci	u16 cap;
95762306a36Sopenharmony_ci	u16 ctrl;
95862306a36Sopenharmony_ci
95962306a36Sopenharmony_ci	pos = dev->acs_cap;
96062306a36Sopenharmony_ci	if (!pos)
96162306a36Sopenharmony_ci		return;
96262306a36Sopenharmony_ci
96362306a36Sopenharmony_ci	pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap);
96462306a36Sopenharmony_ci	pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl);
96562306a36Sopenharmony_ci
96662306a36Sopenharmony_ci	/* Source Validation */
96762306a36Sopenharmony_ci	ctrl |= (cap & PCI_ACS_SV);
96862306a36Sopenharmony_ci
96962306a36Sopenharmony_ci	/* P2P Request Redirect */
97062306a36Sopenharmony_ci	ctrl |= (cap & PCI_ACS_RR);
97162306a36Sopenharmony_ci
97262306a36Sopenharmony_ci	/* P2P Completion Redirect */
97362306a36Sopenharmony_ci	ctrl |= (cap & PCI_ACS_CR);
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_ci	/* Upstream Forwarding */
97662306a36Sopenharmony_ci	ctrl |= (cap & PCI_ACS_UF);
97762306a36Sopenharmony_ci
97862306a36Sopenharmony_ci	/* Enable Translation Blocking for external devices and noats */
97962306a36Sopenharmony_ci	if (pci_ats_disabled() || dev->external_facing || dev->untrusted)
98062306a36Sopenharmony_ci		ctrl |= (cap & PCI_ACS_TB);
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ci	pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
98362306a36Sopenharmony_ci}
98462306a36Sopenharmony_ci
98562306a36Sopenharmony_ci/**
98662306a36Sopenharmony_ci * pci_enable_acs - enable ACS if hardware support it
98762306a36Sopenharmony_ci * @dev: the PCI device
98862306a36Sopenharmony_ci */
98962306a36Sopenharmony_cistatic void pci_enable_acs(struct pci_dev *dev)
99062306a36Sopenharmony_ci{
99162306a36Sopenharmony_ci	if (!pci_acs_enable)
99262306a36Sopenharmony_ci		goto disable_acs_redir;
99362306a36Sopenharmony_ci
99462306a36Sopenharmony_ci	if (!pci_dev_specific_enable_acs(dev))
99562306a36Sopenharmony_ci		goto disable_acs_redir;
99662306a36Sopenharmony_ci
99762306a36Sopenharmony_ci	pci_std_enable_acs(dev);
99862306a36Sopenharmony_ci
99962306a36Sopenharmony_cidisable_acs_redir:
100062306a36Sopenharmony_ci	/*
100162306a36Sopenharmony_ci	 * Note: pci_disable_acs_redir() must be called even if ACS was not
100262306a36Sopenharmony_ci	 * enabled by the kernel because it may have been enabled by
100362306a36Sopenharmony_ci	 * platform firmware.  So if we are told to disable it, we should
100462306a36Sopenharmony_ci	 * always disable it after setting the kernel's default
100562306a36Sopenharmony_ci	 * preferences.
100662306a36Sopenharmony_ci	 */
100762306a36Sopenharmony_ci	pci_disable_acs_redir(dev);
100862306a36Sopenharmony_ci}
100962306a36Sopenharmony_ci
101062306a36Sopenharmony_ci/**
101162306a36Sopenharmony_ci * pci_restore_bars - restore a device's BAR values (e.g. after wake-up)
101262306a36Sopenharmony_ci * @dev: PCI device to have its BARs restored
101362306a36Sopenharmony_ci *
101462306a36Sopenharmony_ci * Restore the BAR values for a given device, so as to make it
101562306a36Sopenharmony_ci * accessible by its driver.
101662306a36Sopenharmony_ci */
101762306a36Sopenharmony_cistatic void pci_restore_bars(struct pci_dev *dev)
101862306a36Sopenharmony_ci{
101962306a36Sopenharmony_ci	int i;
102062306a36Sopenharmony_ci
102162306a36Sopenharmony_ci	for (i = 0; i < PCI_BRIDGE_RESOURCES; i++)
102262306a36Sopenharmony_ci		pci_update_resource(dev, i);
102362306a36Sopenharmony_ci}
102462306a36Sopenharmony_ci
102562306a36Sopenharmony_cistatic inline bool platform_pci_power_manageable(struct pci_dev *dev)
102662306a36Sopenharmony_ci{
102762306a36Sopenharmony_ci	if (pci_use_mid_pm())
102862306a36Sopenharmony_ci		return true;
102962306a36Sopenharmony_ci
103062306a36Sopenharmony_ci	return acpi_pci_power_manageable(dev);
103162306a36Sopenharmony_ci}
103262306a36Sopenharmony_ci
103362306a36Sopenharmony_cistatic inline int platform_pci_set_power_state(struct pci_dev *dev,
103462306a36Sopenharmony_ci					       pci_power_t t)
103562306a36Sopenharmony_ci{
103662306a36Sopenharmony_ci	if (pci_use_mid_pm())
103762306a36Sopenharmony_ci		return mid_pci_set_power_state(dev, t);
103862306a36Sopenharmony_ci
103962306a36Sopenharmony_ci	return acpi_pci_set_power_state(dev, t);
104062306a36Sopenharmony_ci}
104162306a36Sopenharmony_ci
104262306a36Sopenharmony_cistatic inline pci_power_t platform_pci_get_power_state(struct pci_dev *dev)
104362306a36Sopenharmony_ci{
104462306a36Sopenharmony_ci	if (pci_use_mid_pm())
104562306a36Sopenharmony_ci		return mid_pci_get_power_state(dev);
104662306a36Sopenharmony_ci
104762306a36Sopenharmony_ci	return acpi_pci_get_power_state(dev);
104862306a36Sopenharmony_ci}
104962306a36Sopenharmony_ci
105062306a36Sopenharmony_cistatic inline void platform_pci_refresh_power_state(struct pci_dev *dev)
105162306a36Sopenharmony_ci{
105262306a36Sopenharmony_ci	if (!pci_use_mid_pm())
105362306a36Sopenharmony_ci		acpi_pci_refresh_power_state(dev);
105462306a36Sopenharmony_ci}
105562306a36Sopenharmony_ci
105662306a36Sopenharmony_cistatic inline pci_power_t platform_pci_choose_state(struct pci_dev *dev)
105762306a36Sopenharmony_ci{
105862306a36Sopenharmony_ci	if (pci_use_mid_pm())
105962306a36Sopenharmony_ci		return PCI_POWER_ERROR;
106062306a36Sopenharmony_ci
106162306a36Sopenharmony_ci	return acpi_pci_choose_state(dev);
106262306a36Sopenharmony_ci}
106362306a36Sopenharmony_ci
106462306a36Sopenharmony_cistatic inline int platform_pci_set_wakeup(struct pci_dev *dev, bool enable)
106562306a36Sopenharmony_ci{
106662306a36Sopenharmony_ci	if (pci_use_mid_pm())
106762306a36Sopenharmony_ci		return PCI_POWER_ERROR;
106862306a36Sopenharmony_ci
106962306a36Sopenharmony_ci	return acpi_pci_wakeup(dev, enable);
107062306a36Sopenharmony_ci}
107162306a36Sopenharmony_ci
107262306a36Sopenharmony_cistatic inline bool platform_pci_need_resume(struct pci_dev *dev)
107362306a36Sopenharmony_ci{
107462306a36Sopenharmony_ci	if (pci_use_mid_pm())
107562306a36Sopenharmony_ci		return false;
107662306a36Sopenharmony_ci
107762306a36Sopenharmony_ci	return acpi_pci_need_resume(dev);
107862306a36Sopenharmony_ci}
107962306a36Sopenharmony_ci
108062306a36Sopenharmony_cistatic inline bool platform_pci_bridge_d3(struct pci_dev *dev)
108162306a36Sopenharmony_ci{
108262306a36Sopenharmony_ci	if (pci_use_mid_pm())
108362306a36Sopenharmony_ci		return false;
108462306a36Sopenharmony_ci
108562306a36Sopenharmony_ci	return acpi_pci_bridge_d3(dev);
108662306a36Sopenharmony_ci}
108762306a36Sopenharmony_ci
108862306a36Sopenharmony_ci/**
108962306a36Sopenharmony_ci * pci_update_current_state - Read power state of given device and cache it
109062306a36Sopenharmony_ci * @dev: PCI device to handle.
109162306a36Sopenharmony_ci * @state: State to cache in case the device doesn't have the PM capability
109262306a36Sopenharmony_ci *
109362306a36Sopenharmony_ci * The power state is read from the PMCSR register, which however is
109462306a36Sopenharmony_ci * inaccessible in D3cold.  The platform firmware is therefore queried first
109562306a36Sopenharmony_ci * to detect accessibility of the register.  In case the platform firmware
109662306a36Sopenharmony_ci * reports an incorrect state or the device isn't power manageable by the
109762306a36Sopenharmony_ci * platform at all, we try to detect D3cold by testing accessibility of the
109862306a36Sopenharmony_ci * vendor ID in config space.
109962306a36Sopenharmony_ci */
110062306a36Sopenharmony_civoid pci_update_current_state(struct pci_dev *dev, pci_power_t state)
110162306a36Sopenharmony_ci{
110262306a36Sopenharmony_ci	if (platform_pci_get_power_state(dev) == PCI_D3cold) {
110362306a36Sopenharmony_ci		dev->current_state = PCI_D3cold;
110462306a36Sopenharmony_ci	} else if (dev->pm_cap) {
110562306a36Sopenharmony_ci		u16 pmcsr;
110662306a36Sopenharmony_ci
110762306a36Sopenharmony_ci		pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
110862306a36Sopenharmony_ci		if (PCI_POSSIBLE_ERROR(pmcsr)) {
110962306a36Sopenharmony_ci			dev->current_state = PCI_D3cold;
111062306a36Sopenharmony_ci			return;
111162306a36Sopenharmony_ci		}
111262306a36Sopenharmony_ci		dev->current_state = pmcsr & PCI_PM_CTRL_STATE_MASK;
111362306a36Sopenharmony_ci	} else {
111462306a36Sopenharmony_ci		dev->current_state = state;
111562306a36Sopenharmony_ci	}
111662306a36Sopenharmony_ci}
111762306a36Sopenharmony_ci
111862306a36Sopenharmony_ci/**
111962306a36Sopenharmony_ci * pci_refresh_power_state - Refresh the given device's power state data
112062306a36Sopenharmony_ci * @dev: Target PCI device.
112162306a36Sopenharmony_ci *
112262306a36Sopenharmony_ci * Ask the platform to refresh the devices power state information and invoke
112362306a36Sopenharmony_ci * pci_update_current_state() to update its current PCI power state.
112462306a36Sopenharmony_ci */
112562306a36Sopenharmony_civoid pci_refresh_power_state(struct pci_dev *dev)
112662306a36Sopenharmony_ci{
112762306a36Sopenharmony_ci	platform_pci_refresh_power_state(dev);
112862306a36Sopenharmony_ci	pci_update_current_state(dev, dev->current_state);
112962306a36Sopenharmony_ci}
113062306a36Sopenharmony_ci
113162306a36Sopenharmony_ci/**
113262306a36Sopenharmony_ci * pci_platform_power_transition - Use platform to change device power state
113362306a36Sopenharmony_ci * @dev: PCI device to handle.
113462306a36Sopenharmony_ci * @state: State to put the device into.
113562306a36Sopenharmony_ci */
113662306a36Sopenharmony_ciint pci_platform_power_transition(struct pci_dev *dev, pci_power_t state)
113762306a36Sopenharmony_ci{
113862306a36Sopenharmony_ci	int error;
113962306a36Sopenharmony_ci
114062306a36Sopenharmony_ci	error = platform_pci_set_power_state(dev, state);
114162306a36Sopenharmony_ci	if (!error)
114262306a36Sopenharmony_ci		pci_update_current_state(dev, state);
114362306a36Sopenharmony_ci	else if (!dev->pm_cap) /* Fall back to PCI_D0 */
114462306a36Sopenharmony_ci		dev->current_state = PCI_D0;
114562306a36Sopenharmony_ci
114662306a36Sopenharmony_ci	return error;
114762306a36Sopenharmony_ci}
114862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_platform_power_transition);
114962306a36Sopenharmony_ci
115062306a36Sopenharmony_cistatic int pci_resume_one(struct pci_dev *pci_dev, void *ign)
115162306a36Sopenharmony_ci{
115262306a36Sopenharmony_ci	pm_request_resume(&pci_dev->dev);
115362306a36Sopenharmony_ci	return 0;
115462306a36Sopenharmony_ci}
115562306a36Sopenharmony_ci
115662306a36Sopenharmony_ci/**
115762306a36Sopenharmony_ci * pci_resume_bus - Walk given bus and runtime resume devices on it
115862306a36Sopenharmony_ci * @bus: Top bus of the subtree to walk.
115962306a36Sopenharmony_ci */
116062306a36Sopenharmony_civoid pci_resume_bus(struct pci_bus *bus)
116162306a36Sopenharmony_ci{
116262306a36Sopenharmony_ci	if (bus)
116362306a36Sopenharmony_ci		pci_walk_bus(bus, pci_resume_one, NULL);
116462306a36Sopenharmony_ci}
116562306a36Sopenharmony_ci
116662306a36Sopenharmony_cistatic int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout)
116762306a36Sopenharmony_ci{
116862306a36Sopenharmony_ci	int delay = 1;
116962306a36Sopenharmony_ci	bool retrain = false;
117062306a36Sopenharmony_ci	struct pci_dev *bridge;
117162306a36Sopenharmony_ci
117262306a36Sopenharmony_ci	if (pci_is_pcie(dev)) {
117362306a36Sopenharmony_ci		bridge = pci_upstream_bridge(dev);
117462306a36Sopenharmony_ci		if (bridge)
117562306a36Sopenharmony_ci			retrain = true;
117662306a36Sopenharmony_ci	}
117762306a36Sopenharmony_ci
117862306a36Sopenharmony_ci	/*
117962306a36Sopenharmony_ci	 * After reset, the device should not silently discard config
118062306a36Sopenharmony_ci	 * requests, but it may still indicate that it needs more time by
118162306a36Sopenharmony_ci	 * responding to them with CRS completions.  The Root Port will
118262306a36Sopenharmony_ci	 * generally synthesize ~0 (PCI_ERROR_RESPONSE) data to complete
118362306a36Sopenharmony_ci	 * the read (except when CRS SV is enabled and the read was for the
118462306a36Sopenharmony_ci	 * Vendor ID; in that case it synthesizes 0x0001 data).
118562306a36Sopenharmony_ci	 *
118662306a36Sopenharmony_ci	 * Wait for the device to return a non-CRS completion.  Read the
118762306a36Sopenharmony_ci	 * Command register instead of Vendor ID so we don't have to
118862306a36Sopenharmony_ci	 * contend with the CRS SV value.
118962306a36Sopenharmony_ci	 */
119062306a36Sopenharmony_ci	for (;;) {
119162306a36Sopenharmony_ci		u32 id;
119262306a36Sopenharmony_ci
119362306a36Sopenharmony_ci		pci_read_config_dword(dev, PCI_COMMAND, &id);
119462306a36Sopenharmony_ci		if (!PCI_POSSIBLE_ERROR(id))
119562306a36Sopenharmony_ci			break;
119662306a36Sopenharmony_ci
119762306a36Sopenharmony_ci		if (delay > timeout) {
119862306a36Sopenharmony_ci			pci_warn(dev, "not ready %dms after %s; giving up\n",
119962306a36Sopenharmony_ci				 delay - 1, reset_type);
120062306a36Sopenharmony_ci			return -ENOTTY;
120162306a36Sopenharmony_ci		}
120262306a36Sopenharmony_ci
120362306a36Sopenharmony_ci		if (delay > PCI_RESET_WAIT) {
120462306a36Sopenharmony_ci			if (retrain) {
120562306a36Sopenharmony_ci				retrain = false;
120662306a36Sopenharmony_ci				if (pcie_failed_link_retrain(bridge)) {
120762306a36Sopenharmony_ci					delay = 1;
120862306a36Sopenharmony_ci					continue;
120962306a36Sopenharmony_ci				}
121062306a36Sopenharmony_ci			}
121162306a36Sopenharmony_ci			pci_info(dev, "not ready %dms after %s; waiting\n",
121262306a36Sopenharmony_ci				 delay - 1, reset_type);
121362306a36Sopenharmony_ci		}
121462306a36Sopenharmony_ci
121562306a36Sopenharmony_ci		msleep(delay);
121662306a36Sopenharmony_ci		delay *= 2;
121762306a36Sopenharmony_ci	}
121862306a36Sopenharmony_ci
121962306a36Sopenharmony_ci	if (delay > PCI_RESET_WAIT)
122062306a36Sopenharmony_ci		pci_info(dev, "ready %dms after %s\n", delay - 1,
122162306a36Sopenharmony_ci			 reset_type);
122262306a36Sopenharmony_ci
122362306a36Sopenharmony_ci	return 0;
122462306a36Sopenharmony_ci}
122562306a36Sopenharmony_ci
122662306a36Sopenharmony_ci/**
122762306a36Sopenharmony_ci * pci_power_up - Put the given device into D0
122862306a36Sopenharmony_ci * @dev: PCI device to power up
122962306a36Sopenharmony_ci *
123062306a36Sopenharmony_ci * On success, return 0 or 1, depending on whether or not it is necessary to
123162306a36Sopenharmony_ci * restore the device's BARs subsequently (1 is returned in that case).
123262306a36Sopenharmony_ci *
123362306a36Sopenharmony_ci * On failure, return a negative error code.  Always return failure if @dev
123462306a36Sopenharmony_ci * lacks a Power Management Capability, even if the platform was able to
123562306a36Sopenharmony_ci * put the device in D0 via non-PCI means.
123662306a36Sopenharmony_ci */
123762306a36Sopenharmony_ciint pci_power_up(struct pci_dev *dev)
123862306a36Sopenharmony_ci{
123962306a36Sopenharmony_ci	bool need_restore;
124062306a36Sopenharmony_ci	pci_power_t state;
124162306a36Sopenharmony_ci	u16 pmcsr;
124262306a36Sopenharmony_ci
124362306a36Sopenharmony_ci	platform_pci_set_power_state(dev, PCI_D0);
124462306a36Sopenharmony_ci
124562306a36Sopenharmony_ci	if (!dev->pm_cap) {
124662306a36Sopenharmony_ci		state = platform_pci_get_power_state(dev);
124762306a36Sopenharmony_ci		if (state == PCI_UNKNOWN)
124862306a36Sopenharmony_ci			dev->current_state = PCI_D0;
124962306a36Sopenharmony_ci		else
125062306a36Sopenharmony_ci			dev->current_state = state;
125162306a36Sopenharmony_ci
125262306a36Sopenharmony_ci		return -EIO;
125362306a36Sopenharmony_ci	}
125462306a36Sopenharmony_ci
125562306a36Sopenharmony_ci	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
125662306a36Sopenharmony_ci	if (PCI_POSSIBLE_ERROR(pmcsr)) {
125762306a36Sopenharmony_ci		pci_err(dev, "Unable to change power state from %s to D0, device inaccessible\n",
125862306a36Sopenharmony_ci			pci_power_name(dev->current_state));
125962306a36Sopenharmony_ci		dev->current_state = PCI_D3cold;
126062306a36Sopenharmony_ci		return -EIO;
126162306a36Sopenharmony_ci	}
126262306a36Sopenharmony_ci
126362306a36Sopenharmony_ci	state = pmcsr & PCI_PM_CTRL_STATE_MASK;
126462306a36Sopenharmony_ci
126562306a36Sopenharmony_ci	need_restore = (state == PCI_D3hot || dev->current_state >= PCI_D3hot) &&
126662306a36Sopenharmony_ci			!(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET);
126762306a36Sopenharmony_ci
126862306a36Sopenharmony_ci	if (state == PCI_D0)
126962306a36Sopenharmony_ci		goto end;
127062306a36Sopenharmony_ci
127162306a36Sopenharmony_ci	/*
127262306a36Sopenharmony_ci	 * Force the entire word to 0. This doesn't affect PME_Status, disables
127362306a36Sopenharmony_ci	 * PME_En, and sets PowerState to 0.
127462306a36Sopenharmony_ci	 */
127562306a36Sopenharmony_ci	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, 0);
127662306a36Sopenharmony_ci
127762306a36Sopenharmony_ci	/* Mandatory transition delays; see PCI PM 1.2. */
127862306a36Sopenharmony_ci	if (state == PCI_D3hot)
127962306a36Sopenharmony_ci		pci_dev_d3_sleep(dev);
128062306a36Sopenharmony_ci	else if (state == PCI_D2)
128162306a36Sopenharmony_ci		udelay(PCI_PM_D2_DELAY);
128262306a36Sopenharmony_ci
128362306a36Sopenharmony_ciend:
128462306a36Sopenharmony_ci	dev->current_state = PCI_D0;
128562306a36Sopenharmony_ci	if (need_restore)
128662306a36Sopenharmony_ci		return 1;
128762306a36Sopenharmony_ci
128862306a36Sopenharmony_ci	return 0;
128962306a36Sopenharmony_ci}
129062306a36Sopenharmony_ci
129162306a36Sopenharmony_ci/**
129262306a36Sopenharmony_ci * pci_set_full_power_state - Put a PCI device into D0 and update its state
129362306a36Sopenharmony_ci * @dev: PCI device to power up
129462306a36Sopenharmony_ci *
129562306a36Sopenharmony_ci * Call pci_power_up() to put @dev into D0, read from its PCI_PM_CTRL register
129662306a36Sopenharmony_ci * to confirm the state change, restore its BARs if they might be lost and
129762306a36Sopenharmony_ci * reconfigure ASPM in accordance with the new power state.
129862306a36Sopenharmony_ci *
129962306a36Sopenharmony_ci * If pci_restore_state() is going to be called right after a power state change
130062306a36Sopenharmony_ci * to D0, it is more efficient to use pci_power_up() directly instead of this
130162306a36Sopenharmony_ci * function.
130262306a36Sopenharmony_ci */
130362306a36Sopenharmony_cistatic int pci_set_full_power_state(struct pci_dev *dev)
130462306a36Sopenharmony_ci{
130562306a36Sopenharmony_ci	u16 pmcsr;
130662306a36Sopenharmony_ci	int ret;
130762306a36Sopenharmony_ci
130862306a36Sopenharmony_ci	ret = pci_power_up(dev);
130962306a36Sopenharmony_ci	if (ret < 0) {
131062306a36Sopenharmony_ci		if (dev->current_state == PCI_D0)
131162306a36Sopenharmony_ci			return 0;
131262306a36Sopenharmony_ci
131362306a36Sopenharmony_ci		return ret;
131462306a36Sopenharmony_ci	}
131562306a36Sopenharmony_ci
131662306a36Sopenharmony_ci	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
131762306a36Sopenharmony_ci	dev->current_state = pmcsr & PCI_PM_CTRL_STATE_MASK;
131862306a36Sopenharmony_ci	if (dev->current_state != PCI_D0) {
131962306a36Sopenharmony_ci		pci_info_ratelimited(dev, "Refused to change power state from %s to D0\n",
132062306a36Sopenharmony_ci				     pci_power_name(dev->current_state));
132162306a36Sopenharmony_ci	} else if (ret > 0) {
132262306a36Sopenharmony_ci		/*
132362306a36Sopenharmony_ci		 * According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
132462306a36Sopenharmony_ci		 * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning
132562306a36Sopenharmony_ci		 * from D3hot to D0 _may_ perform an internal reset, thereby
132662306a36Sopenharmony_ci		 * going to "D0 Uninitialized" rather than "D0 Initialized".
132762306a36Sopenharmony_ci		 * For example, at least some versions of the 3c905B and the
132862306a36Sopenharmony_ci		 * 3c556B exhibit this behaviour.
132962306a36Sopenharmony_ci		 *
133062306a36Sopenharmony_ci		 * At least some laptop BIOSen (e.g. the Thinkpad T21) leave
133162306a36Sopenharmony_ci		 * devices in a D3hot state at boot.  Consequently, we need to
133262306a36Sopenharmony_ci		 * restore at least the BARs so that the device will be
133362306a36Sopenharmony_ci		 * accessible to its driver.
133462306a36Sopenharmony_ci		 */
133562306a36Sopenharmony_ci		pci_restore_bars(dev);
133662306a36Sopenharmony_ci	}
133762306a36Sopenharmony_ci
133862306a36Sopenharmony_ci	if (dev->bus->self)
133962306a36Sopenharmony_ci		pcie_aspm_pm_state_change(dev->bus->self);
134062306a36Sopenharmony_ci
134162306a36Sopenharmony_ci	return 0;
134262306a36Sopenharmony_ci}
134362306a36Sopenharmony_ci
134462306a36Sopenharmony_ci/**
134562306a36Sopenharmony_ci * __pci_dev_set_current_state - Set current state of a PCI device
134662306a36Sopenharmony_ci * @dev: Device to handle
134762306a36Sopenharmony_ci * @data: pointer to state to be set
134862306a36Sopenharmony_ci */
134962306a36Sopenharmony_cistatic int __pci_dev_set_current_state(struct pci_dev *dev, void *data)
135062306a36Sopenharmony_ci{
135162306a36Sopenharmony_ci	pci_power_t state = *(pci_power_t *)data;
135262306a36Sopenharmony_ci
135362306a36Sopenharmony_ci	dev->current_state = state;
135462306a36Sopenharmony_ci	return 0;
135562306a36Sopenharmony_ci}
135662306a36Sopenharmony_ci
135762306a36Sopenharmony_ci/**
135862306a36Sopenharmony_ci * pci_bus_set_current_state - Walk given bus and set current state of devices
135962306a36Sopenharmony_ci * @bus: Top bus of the subtree to walk.
136062306a36Sopenharmony_ci * @state: state to be set
136162306a36Sopenharmony_ci */
136262306a36Sopenharmony_civoid pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state)
136362306a36Sopenharmony_ci{
136462306a36Sopenharmony_ci	if (bus)
136562306a36Sopenharmony_ci		pci_walk_bus(bus, __pci_dev_set_current_state, &state);
136662306a36Sopenharmony_ci}
136762306a36Sopenharmony_ci
136862306a36Sopenharmony_ci/**
136962306a36Sopenharmony_ci * pci_set_low_power_state - Put a PCI device into a low-power state.
137062306a36Sopenharmony_ci * @dev: PCI device to handle.
137162306a36Sopenharmony_ci * @state: PCI power state (D1, D2, D3hot) to put the device into.
137262306a36Sopenharmony_ci *
137362306a36Sopenharmony_ci * Use the device's PCI_PM_CTRL register to put it into a low-power state.
137462306a36Sopenharmony_ci *
137562306a36Sopenharmony_ci * RETURN VALUE:
137662306a36Sopenharmony_ci * -EINVAL if the requested state is invalid.
137762306a36Sopenharmony_ci * -EIO if device does not support PCI PM or its PM capabilities register has a
137862306a36Sopenharmony_ci * wrong version, or device doesn't support the requested state.
137962306a36Sopenharmony_ci * 0 if device already is in the requested state.
138062306a36Sopenharmony_ci * 0 if device's power state has been successfully changed.
138162306a36Sopenharmony_ci */
138262306a36Sopenharmony_cistatic int pci_set_low_power_state(struct pci_dev *dev, pci_power_t state)
138362306a36Sopenharmony_ci{
138462306a36Sopenharmony_ci	u16 pmcsr;
138562306a36Sopenharmony_ci
138662306a36Sopenharmony_ci	if (!dev->pm_cap)
138762306a36Sopenharmony_ci		return -EIO;
138862306a36Sopenharmony_ci
138962306a36Sopenharmony_ci	/*
139062306a36Sopenharmony_ci	 * Validate transition: We can enter D0 from any state, but if
139162306a36Sopenharmony_ci	 * we're already in a low-power state, we can only go deeper.  E.g.,
139262306a36Sopenharmony_ci	 * we can go from D1 to D3, but we can't go directly from D3 to D1;
139362306a36Sopenharmony_ci	 * we'd have to go from D3 to D0, then to D1.
139462306a36Sopenharmony_ci	 */
139562306a36Sopenharmony_ci	if (dev->current_state <= PCI_D3cold && dev->current_state > state) {
139662306a36Sopenharmony_ci		pci_dbg(dev, "Invalid power transition (from %s to %s)\n",
139762306a36Sopenharmony_ci			pci_power_name(dev->current_state),
139862306a36Sopenharmony_ci			pci_power_name(state));
139962306a36Sopenharmony_ci		return -EINVAL;
140062306a36Sopenharmony_ci	}
140162306a36Sopenharmony_ci
140262306a36Sopenharmony_ci	/* Check if this device supports the desired state */
140362306a36Sopenharmony_ci	if ((state == PCI_D1 && !dev->d1_support)
140462306a36Sopenharmony_ci	   || (state == PCI_D2 && !dev->d2_support))
140562306a36Sopenharmony_ci		return -EIO;
140662306a36Sopenharmony_ci
140762306a36Sopenharmony_ci	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
140862306a36Sopenharmony_ci	if (PCI_POSSIBLE_ERROR(pmcsr)) {
140962306a36Sopenharmony_ci		pci_err(dev, "Unable to change power state from %s to %s, device inaccessible\n",
141062306a36Sopenharmony_ci			pci_power_name(dev->current_state),
141162306a36Sopenharmony_ci			pci_power_name(state));
141262306a36Sopenharmony_ci		dev->current_state = PCI_D3cold;
141362306a36Sopenharmony_ci		return -EIO;
141462306a36Sopenharmony_ci	}
141562306a36Sopenharmony_ci
141662306a36Sopenharmony_ci	pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
141762306a36Sopenharmony_ci	pmcsr |= state;
141862306a36Sopenharmony_ci
141962306a36Sopenharmony_ci	/* Enter specified state */
142062306a36Sopenharmony_ci	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
142162306a36Sopenharmony_ci
142262306a36Sopenharmony_ci	/* Mandatory power management transition delays; see PCI PM 1.2. */
142362306a36Sopenharmony_ci	if (state == PCI_D3hot)
142462306a36Sopenharmony_ci		pci_dev_d3_sleep(dev);
142562306a36Sopenharmony_ci	else if (state == PCI_D2)
142662306a36Sopenharmony_ci		udelay(PCI_PM_D2_DELAY);
142762306a36Sopenharmony_ci
142862306a36Sopenharmony_ci	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
142962306a36Sopenharmony_ci	dev->current_state = pmcsr & PCI_PM_CTRL_STATE_MASK;
143062306a36Sopenharmony_ci	if (dev->current_state != state)
143162306a36Sopenharmony_ci		pci_info_ratelimited(dev, "Refused to change power state from %s to %s\n",
143262306a36Sopenharmony_ci				     pci_power_name(dev->current_state),
143362306a36Sopenharmony_ci				     pci_power_name(state));
143462306a36Sopenharmony_ci
143562306a36Sopenharmony_ci	if (dev->bus->self)
143662306a36Sopenharmony_ci		pcie_aspm_pm_state_change(dev->bus->self);
143762306a36Sopenharmony_ci
143862306a36Sopenharmony_ci	return 0;
143962306a36Sopenharmony_ci}
144062306a36Sopenharmony_ci
144162306a36Sopenharmony_ci/**
144262306a36Sopenharmony_ci * pci_set_power_state - Set the power state of a PCI device
144362306a36Sopenharmony_ci * @dev: PCI device to handle.
144462306a36Sopenharmony_ci * @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
144562306a36Sopenharmony_ci *
144662306a36Sopenharmony_ci * Transition a device to a new power state, using the platform firmware and/or
144762306a36Sopenharmony_ci * the device's PCI PM registers.
144862306a36Sopenharmony_ci *
144962306a36Sopenharmony_ci * RETURN VALUE:
145062306a36Sopenharmony_ci * -EINVAL if the requested state is invalid.
145162306a36Sopenharmony_ci * -EIO if device does not support PCI PM or its PM capabilities register has a
145262306a36Sopenharmony_ci * wrong version, or device doesn't support the requested state.
145362306a36Sopenharmony_ci * 0 if the transition is to D1 or D2 but D1 and D2 are not supported.
145462306a36Sopenharmony_ci * 0 if device already is in the requested state.
145562306a36Sopenharmony_ci * 0 if the transition is to D3 but D3 is not supported.
145662306a36Sopenharmony_ci * 0 if device's power state has been successfully changed.
145762306a36Sopenharmony_ci */
145862306a36Sopenharmony_ciint pci_set_power_state(struct pci_dev *dev, pci_power_t state)
145962306a36Sopenharmony_ci{
146062306a36Sopenharmony_ci	int error;
146162306a36Sopenharmony_ci
146262306a36Sopenharmony_ci	/* Bound the state we're entering */
146362306a36Sopenharmony_ci	if (state > PCI_D3cold)
146462306a36Sopenharmony_ci		state = PCI_D3cold;
146562306a36Sopenharmony_ci	else if (state < PCI_D0)
146662306a36Sopenharmony_ci		state = PCI_D0;
146762306a36Sopenharmony_ci	else if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev))
146862306a36Sopenharmony_ci
146962306a36Sopenharmony_ci		/*
147062306a36Sopenharmony_ci		 * If the device or the parent bridge do not support PCI
147162306a36Sopenharmony_ci		 * PM, ignore the request if we're doing anything other
147262306a36Sopenharmony_ci		 * than putting it into D0 (which would only happen on
147362306a36Sopenharmony_ci		 * boot).
147462306a36Sopenharmony_ci		 */
147562306a36Sopenharmony_ci		return 0;
147662306a36Sopenharmony_ci
147762306a36Sopenharmony_ci	/* Check if we're already there */
147862306a36Sopenharmony_ci	if (dev->current_state == state)
147962306a36Sopenharmony_ci		return 0;
148062306a36Sopenharmony_ci
148162306a36Sopenharmony_ci	if (state == PCI_D0)
148262306a36Sopenharmony_ci		return pci_set_full_power_state(dev);
148362306a36Sopenharmony_ci
148462306a36Sopenharmony_ci	/*
148562306a36Sopenharmony_ci	 * This device is quirked not to be put into D3, so don't put it in
148662306a36Sopenharmony_ci	 * D3
148762306a36Sopenharmony_ci	 */
148862306a36Sopenharmony_ci	if (state >= PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3))
148962306a36Sopenharmony_ci		return 0;
149062306a36Sopenharmony_ci
149162306a36Sopenharmony_ci	if (state == PCI_D3cold) {
149262306a36Sopenharmony_ci		/*
149362306a36Sopenharmony_ci		 * To put the device in D3cold, put it into D3hot in the native
149462306a36Sopenharmony_ci		 * way, then put it into D3cold using platform ops.
149562306a36Sopenharmony_ci		 */
149662306a36Sopenharmony_ci		error = pci_set_low_power_state(dev, PCI_D3hot);
149762306a36Sopenharmony_ci
149862306a36Sopenharmony_ci		if (pci_platform_power_transition(dev, PCI_D3cold))
149962306a36Sopenharmony_ci			return error;
150062306a36Sopenharmony_ci
150162306a36Sopenharmony_ci		/* Powering off a bridge may power off the whole hierarchy */
150262306a36Sopenharmony_ci		if (dev->current_state == PCI_D3cold)
150362306a36Sopenharmony_ci			pci_bus_set_current_state(dev->subordinate, PCI_D3cold);
150462306a36Sopenharmony_ci	} else {
150562306a36Sopenharmony_ci		error = pci_set_low_power_state(dev, state);
150662306a36Sopenharmony_ci
150762306a36Sopenharmony_ci		if (pci_platform_power_transition(dev, state))
150862306a36Sopenharmony_ci			return error;
150962306a36Sopenharmony_ci	}
151062306a36Sopenharmony_ci
151162306a36Sopenharmony_ci	return 0;
151262306a36Sopenharmony_ci}
151362306a36Sopenharmony_ciEXPORT_SYMBOL(pci_set_power_state);
151462306a36Sopenharmony_ci
151562306a36Sopenharmony_ci#define PCI_EXP_SAVE_REGS	7
151662306a36Sopenharmony_ci
151762306a36Sopenharmony_cistatic struct pci_cap_saved_state *_pci_find_saved_cap(struct pci_dev *pci_dev,
151862306a36Sopenharmony_ci						       u16 cap, bool extended)
151962306a36Sopenharmony_ci{
152062306a36Sopenharmony_ci	struct pci_cap_saved_state *tmp;
152162306a36Sopenharmony_ci
152262306a36Sopenharmony_ci	hlist_for_each_entry(tmp, &pci_dev->saved_cap_space, next) {
152362306a36Sopenharmony_ci		if (tmp->cap.cap_extended == extended && tmp->cap.cap_nr == cap)
152462306a36Sopenharmony_ci			return tmp;
152562306a36Sopenharmony_ci	}
152662306a36Sopenharmony_ci	return NULL;
152762306a36Sopenharmony_ci}
152862306a36Sopenharmony_ci
152962306a36Sopenharmony_cistruct pci_cap_saved_state *pci_find_saved_cap(struct pci_dev *dev, char cap)
153062306a36Sopenharmony_ci{
153162306a36Sopenharmony_ci	return _pci_find_saved_cap(dev, cap, false);
153262306a36Sopenharmony_ci}
153362306a36Sopenharmony_ci
153462306a36Sopenharmony_cistruct pci_cap_saved_state *pci_find_saved_ext_cap(struct pci_dev *dev, u16 cap)
153562306a36Sopenharmony_ci{
153662306a36Sopenharmony_ci	return _pci_find_saved_cap(dev, cap, true);
153762306a36Sopenharmony_ci}
153862306a36Sopenharmony_ci
153962306a36Sopenharmony_cistatic int pci_save_pcie_state(struct pci_dev *dev)
154062306a36Sopenharmony_ci{
154162306a36Sopenharmony_ci	int i = 0;
154262306a36Sopenharmony_ci	struct pci_cap_saved_state *save_state;
154362306a36Sopenharmony_ci	u16 *cap;
154462306a36Sopenharmony_ci
154562306a36Sopenharmony_ci	if (!pci_is_pcie(dev))
154662306a36Sopenharmony_ci		return 0;
154762306a36Sopenharmony_ci
154862306a36Sopenharmony_ci	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
154962306a36Sopenharmony_ci	if (!save_state) {
155062306a36Sopenharmony_ci		pci_err(dev, "buffer not found in %s\n", __func__);
155162306a36Sopenharmony_ci		return -ENOMEM;
155262306a36Sopenharmony_ci	}
155362306a36Sopenharmony_ci
155462306a36Sopenharmony_ci	cap = (u16 *)&save_state->cap.data[0];
155562306a36Sopenharmony_ci	pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &cap[i++]);
155662306a36Sopenharmony_ci	pcie_capability_read_word(dev, PCI_EXP_LNKCTL, &cap[i++]);
155762306a36Sopenharmony_ci	pcie_capability_read_word(dev, PCI_EXP_SLTCTL, &cap[i++]);
155862306a36Sopenharmony_ci	pcie_capability_read_word(dev, PCI_EXP_RTCTL,  &cap[i++]);
155962306a36Sopenharmony_ci	pcie_capability_read_word(dev, PCI_EXP_DEVCTL2, &cap[i++]);
156062306a36Sopenharmony_ci	pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &cap[i++]);
156162306a36Sopenharmony_ci	pcie_capability_read_word(dev, PCI_EXP_SLTCTL2, &cap[i++]);
156262306a36Sopenharmony_ci
156362306a36Sopenharmony_ci	return 0;
156462306a36Sopenharmony_ci}
156562306a36Sopenharmony_ci
156662306a36Sopenharmony_civoid pci_bridge_reconfigure_ltr(struct pci_dev *dev)
156762306a36Sopenharmony_ci{
156862306a36Sopenharmony_ci#ifdef CONFIG_PCIEASPM
156962306a36Sopenharmony_ci	struct pci_dev *bridge;
157062306a36Sopenharmony_ci	u32 ctl;
157162306a36Sopenharmony_ci
157262306a36Sopenharmony_ci	bridge = pci_upstream_bridge(dev);
157362306a36Sopenharmony_ci	if (bridge && bridge->ltr_path) {
157462306a36Sopenharmony_ci		pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2, &ctl);
157562306a36Sopenharmony_ci		if (!(ctl & PCI_EXP_DEVCTL2_LTR_EN)) {
157662306a36Sopenharmony_ci			pci_dbg(bridge, "re-enabling LTR\n");
157762306a36Sopenharmony_ci			pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2,
157862306a36Sopenharmony_ci						 PCI_EXP_DEVCTL2_LTR_EN);
157962306a36Sopenharmony_ci		}
158062306a36Sopenharmony_ci	}
158162306a36Sopenharmony_ci#endif
158262306a36Sopenharmony_ci}
158362306a36Sopenharmony_ci
158462306a36Sopenharmony_cistatic void pci_restore_pcie_state(struct pci_dev *dev)
158562306a36Sopenharmony_ci{
158662306a36Sopenharmony_ci	int i = 0;
158762306a36Sopenharmony_ci	struct pci_cap_saved_state *save_state;
158862306a36Sopenharmony_ci	u16 *cap;
158962306a36Sopenharmony_ci
159062306a36Sopenharmony_ci	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
159162306a36Sopenharmony_ci	if (!save_state)
159262306a36Sopenharmony_ci		return;
159362306a36Sopenharmony_ci
159462306a36Sopenharmony_ci	/*
159562306a36Sopenharmony_ci	 * Downstream ports reset the LTR enable bit when link goes down.
159662306a36Sopenharmony_ci	 * Check and re-configure the bit here before restoring device.
159762306a36Sopenharmony_ci	 * PCIe r5.0, sec 7.5.3.16.
159862306a36Sopenharmony_ci	 */
159962306a36Sopenharmony_ci	pci_bridge_reconfigure_ltr(dev);
160062306a36Sopenharmony_ci
160162306a36Sopenharmony_ci	cap = (u16 *)&save_state->cap.data[0];
160262306a36Sopenharmony_ci	pcie_capability_write_word(dev, PCI_EXP_DEVCTL, cap[i++]);
160362306a36Sopenharmony_ci	pcie_capability_write_word(dev, PCI_EXP_LNKCTL, cap[i++]);
160462306a36Sopenharmony_ci	pcie_capability_write_word(dev, PCI_EXP_SLTCTL, cap[i++]);
160562306a36Sopenharmony_ci	pcie_capability_write_word(dev, PCI_EXP_RTCTL, cap[i++]);
160662306a36Sopenharmony_ci	pcie_capability_write_word(dev, PCI_EXP_DEVCTL2, cap[i++]);
160762306a36Sopenharmony_ci	pcie_capability_write_word(dev, PCI_EXP_LNKCTL2, cap[i++]);
160862306a36Sopenharmony_ci	pcie_capability_write_word(dev, PCI_EXP_SLTCTL2, cap[i++]);
160962306a36Sopenharmony_ci}
161062306a36Sopenharmony_ci
161162306a36Sopenharmony_cistatic int pci_save_pcix_state(struct pci_dev *dev)
161262306a36Sopenharmony_ci{
161362306a36Sopenharmony_ci	int pos;
161462306a36Sopenharmony_ci	struct pci_cap_saved_state *save_state;
161562306a36Sopenharmony_ci
161662306a36Sopenharmony_ci	pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
161762306a36Sopenharmony_ci	if (!pos)
161862306a36Sopenharmony_ci		return 0;
161962306a36Sopenharmony_ci
162062306a36Sopenharmony_ci	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX);
162162306a36Sopenharmony_ci	if (!save_state) {
162262306a36Sopenharmony_ci		pci_err(dev, "buffer not found in %s\n", __func__);
162362306a36Sopenharmony_ci		return -ENOMEM;
162462306a36Sopenharmony_ci	}
162562306a36Sopenharmony_ci
162662306a36Sopenharmony_ci	pci_read_config_word(dev, pos + PCI_X_CMD,
162762306a36Sopenharmony_ci			     (u16 *)save_state->cap.data);
162862306a36Sopenharmony_ci
162962306a36Sopenharmony_ci	return 0;
163062306a36Sopenharmony_ci}
163162306a36Sopenharmony_ci
163262306a36Sopenharmony_cistatic void pci_restore_pcix_state(struct pci_dev *dev)
163362306a36Sopenharmony_ci{
163462306a36Sopenharmony_ci	int i = 0, pos;
163562306a36Sopenharmony_ci	struct pci_cap_saved_state *save_state;
163662306a36Sopenharmony_ci	u16 *cap;
163762306a36Sopenharmony_ci
163862306a36Sopenharmony_ci	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX);
163962306a36Sopenharmony_ci	pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
164062306a36Sopenharmony_ci	if (!save_state || !pos)
164162306a36Sopenharmony_ci		return;
164262306a36Sopenharmony_ci	cap = (u16 *)&save_state->cap.data[0];
164362306a36Sopenharmony_ci
164462306a36Sopenharmony_ci	pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]);
164562306a36Sopenharmony_ci}
164662306a36Sopenharmony_ci
164762306a36Sopenharmony_cistatic void pci_save_ltr_state(struct pci_dev *dev)
164862306a36Sopenharmony_ci{
164962306a36Sopenharmony_ci	int ltr;
165062306a36Sopenharmony_ci	struct pci_cap_saved_state *save_state;
165162306a36Sopenharmony_ci	u32 *cap;
165262306a36Sopenharmony_ci
165362306a36Sopenharmony_ci	if (!pci_is_pcie(dev))
165462306a36Sopenharmony_ci		return;
165562306a36Sopenharmony_ci
165662306a36Sopenharmony_ci	ltr = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_LTR);
165762306a36Sopenharmony_ci	if (!ltr)
165862306a36Sopenharmony_ci		return;
165962306a36Sopenharmony_ci
166062306a36Sopenharmony_ci	save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_LTR);
166162306a36Sopenharmony_ci	if (!save_state) {
166262306a36Sopenharmony_ci		pci_err(dev, "no suspend buffer for LTR; ASPM issues possible after resume\n");
166362306a36Sopenharmony_ci		return;
166462306a36Sopenharmony_ci	}
166562306a36Sopenharmony_ci
166662306a36Sopenharmony_ci	/* Some broken devices only support dword access to LTR */
166762306a36Sopenharmony_ci	cap = &save_state->cap.data[0];
166862306a36Sopenharmony_ci	pci_read_config_dword(dev, ltr + PCI_LTR_MAX_SNOOP_LAT, cap);
166962306a36Sopenharmony_ci}
167062306a36Sopenharmony_ci
167162306a36Sopenharmony_cistatic void pci_restore_ltr_state(struct pci_dev *dev)
167262306a36Sopenharmony_ci{
167362306a36Sopenharmony_ci	struct pci_cap_saved_state *save_state;
167462306a36Sopenharmony_ci	int ltr;
167562306a36Sopenharmony_ci	u32 *cap;
167662306a36Sopenharmony_ci
167762306a36Sopenharmony_ci	save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_LTR);
167862306a36Sopenharmony_ci	ltr = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_LTR);
167962306a36Sopenharmony_ci	if (!save_state || !ltr)
168062306a36Sopenharmony_ci		return;
168162306a36Sopenharmony_ci
168262306a36Sopenharmony_ci	/* Some broken devices only support dword access to LTR */
168362306a36Sopenharmony_ci	cap = &save_state->cap.data[0];
168462306a36Sopenharmony_ci	pci_write_config_dword(dev, ltr + PCI_LTR_MAX_SNOOP_LAT, *cap);
168562306a36Sopenharmony_ci}
168662306a36Sopenharmony_ci
168762306a36Sopenharmony_ci/**
168862306a36Sopenharmony_ci * pci_save_state - save the PCI configuration space of a device before
168962306a36Sopenharmony_ci *		    suspending
169062306a36Sopenharmony_ci * @dev: PCI device that we're dealing with
169162306a36Sopenharmony_ci */
169262306a36Sopenharmony_ciint pci_save_state(struct pci_dev *dev)
169362306a36Sopenharmony_ci{
169462306a36Sopenharmony_ci	int i;
169562306a36Sopenharmony_ci	/* XXX: 100% dword access ok here? */
169662306a36Sopenharmony_ci	for (i = 0; i < 16; i++) {
169762306a36Sopenharmony_ci		pci_read_config_dword(dev, i * 4, &dev->saved_config_space[i]);
169862306a36Sopenharmony_ci		pci_dbg(dev, "save config %#04x: %#010x\n",
169962306a36Sopenharmony_ci			i * 4, dev->saved_config_space[i]);
170062306a36Sopenharmony_ci	}
170162306a36Sopenharmony_ci	dev->state_saved = true;
170262306a36Sopenharmony_ci
170362306a36Sopenharmony_ci	i = pci_save_pcie_state(dev);
170462306a36Sopenharmony_ci	if (i != 0)
170562306a36Sopenharmony_ci		return i;
170662306a36Sopenharmony_ci
170762306a36Sopenharmony_ci	i = pci_save_pcix_state(dev);
170862306a36Sopenharmony_ci	if (i != 0)
170962306a36Sopenharmony_ci		return i;
171062306a36Sopenharmony_ci
171162306a36Sopenharmony_ci	pci_save_ltr_state(dev);
171262306a36Sopenharmony_ci	pci_save_dpc_state(dev);
171362306a36Sopenharmony_ci	pci_save_aer_state(dev);
171462306a36Sopenharmony_ci	pci_save_ptm_state(dev);
171562306a36Sopenharmony_ci	return pci_save_vc_state(dev);
171662306a36Sopenharmony_ci}
171762306a36Sopenharmony_ciEXPORT_SYMBOL(pci_save_state);
171862306a36Sopenharmony_ci
171962306a36Sopenharmony_cistatic void pci_restore_config_dword(struct pci_dev *pdev, int offset,
172062306a36Sopenharmony_ci				     u32 saved_val, int retry, bool force)
172162306a36Sopenharmony_ci{
172262306a36Sopenharmony_ci	u32 val;
172362306a36Sopenharmony_ci
172462306a36Sopenharmony_ci	pci_read_config_dword(pdev, offset, &val);
172562306a36Sopenharmony_ci	if (!force && val == saved_val)
172662306a36Sopenharmony_ci		return;
172762306a36Sopenharmony_ci
172862306a36Sopenharmony_ci	for (;;) {
172962306a36Sopenharmony_ci		pci_dbg(pdev, "restore config %#04x: %#010x -> %#010x\n",
173062306a36Sopenharmony_ci			offset, val, saved_val);
173162306a36Sopenharmony_ci		pci_write_config_dword(pdev, offset, saved_val);
173262306a36Sopenharmony_ci		if (retry-- <= 0)
173362306a36Sopenharmony_ci			return;
173462306a36Sopenharmony_ci
173562306a36Sopenharmony_ci		pci_read_config_dword(pdev, offset, &val);
173662306a36Sopenharmony_ci		if (val == saved_val)
173762306a36Sopenharmony_ci			return;
173862306a36Sopenharmony_ci
173962306a36Sopenharmony_ci		mdelay(1);
174062306a36Sopenharmony_ci	}
174162306a36Sopenharmony_ci}
174262306a36Sopenharmony_ci
174362306a36Sopenharmony_cistatic void pci_restore_config_space_range(struct pci_dev *pdev,
174462306a36Sopenharmony_ci					   int start, int end, int retry,
174562306a36Sopenharmony_ci					   bool force)
174662306a36Sopenharmony_ci{
174762306a36Sopenharmony_ci	int index;
174862306a36Sopenharmony_ci
174962306a36Sopenharmony_ci	for (index = end; index >= start; index--)
175062306a36Sopenharmony_ci		pci_restore_config_dword(pdev, 4 * index,
175162306a36Sopenharmony_ci					 pdev->saved_config_space[index],
175262306a36Sopenharmony_ci					 retry, force);
175362306a36Sopenharmony_ci}
175462306a36Sopenharmony_ci
175562306a36Sopenharmony_cistatic void pci_restore_config_space(struct pci_dev *pdev)
175662306a36Sopenharmony_ci{
175762306a36Sopenharmony_ci	if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL) {
175862306a36Sopenharmony_ci		pci_restore_config_space_range(pdev, 10, 15, 0, false);
175962306a36Sopenharmony_ci		/* Restore BARs before the command register. */
176062306a36Sopenharmony_ci		pci_restore_config_space_range(pdev, 4, 9, 10, false);
176162306a36Sopenharmony_ci		pci_restore_config_space_range(pdev, 0, 3, 0, false);
176262306a36Sopenharmony_ci	} else if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
176362306a36Sopenharmony_ci		pci_restore_config_space_range(pdev, 12, 15, 0, false);
176462306a36Sopenharmony_ci
176562306a36Sopenharmony_ci		/*
176662306a36Sopenharmony_ci		 * Force rewriting of prefetch registers to avoid S3 resume
176762306a36Sopenharmony_ci		 * issues on Intel PCI bridges that occur when these
176862306a36Sopenharmony_ci		 * registers are not explicitly written.
176962306a36Sopenharmony_ci		 */
177062306a36Sopenharmony_ci		pci_restore_config_space_range(pdev, 9, 11, 0, true);
177162306a36Sopenharmony_ci		pci_restore_config_space_range(pdev, 0, 8, 0, false);
177262306a36Sopenharmony_ci	} else {
177362306a36Sopenharmony_ci		pci_restore_config_space_range(pdev, 0, 15, 0, false);
177462306a36Sopenharmony_ci	}
177562306a36Sopenharmony_ci}
177662306a36Sopenharmony_ci
177762306a36Sopenharmony_cistatic void pci_restore_rebar_state(struct pci_dev *pdev)
177862306a36Sopenharmony_ci{
177962306a36Sopenharmony_ci	unsigned int pos, nbars, i;
178062306a36Sopenharmony_ci	u32 ctrl;
178162306a36Sopenharmony_ci
178262306a36Sopenharmony_ci	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
178362306a36Sopenharmony_ci	if (!pos)
178462306a36Sopenharmony_ci		return;
178562306a36Sopenharmony_ci
178662306a36Sopenharmony_ci	pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
178762306a36Sopenharmony_ci	nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >>
178862306a36Sopenharmony_ci		    PCI_REBAR_CTRL_NBAR_SHIFT;
178962306a36Sopenharmony_ci
179062306a36Sopenharmony_ci	for (i = 0; i < nbars; i++, pos += 8) {
179162306a36Sopenharmony_ci		struct resource *res;
179262306a36Sopenharmony_ci		int bar_idx, size;
179362306a36Sopenharmony_ci
179462306a36Sopenharmony_ci		pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
179562306a36Sopenharmony_ci		bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
179662306a36Sopenharmony_ci		res = pdev->resource + bar_idx;
179762306a36Sopenharmony_ci		size = pci_rebar_bytes_to_size(resource_size(res));
179862306a36Sopenharmony_ci		ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE;
179962306a36Sopenharmony_ci		ctrl |= size << PCI_REBAR_CTRL_BAR_SHIFT;
180062306a36Sopenharmony_ci		pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl);
180162306a36Sopenharmony_ci	}
180262306a36Sopenharmony_ci}
180362306a36Sopenharmony_ci
180462306a36Sopenharmony_ci/**
180562306a36Sopenharmony_ci * pci_restore_state - Restore the saved state of a PCI device
180662306a36Sopenharmony_ci * @dev: PCI device that we're dealing with
180762306a36Sopenharmony_ci */
180862306a36Sopenharmony_civoid pci_restore_state(struct pci_dev *dev)
180962306a36Sopenharmony_ci{
181062306a36Sopenharmony_ci	if (!dev->state_saved)
181162306a36Sopenharmony_ci		return;
181262306a36Sopenharmony_ci
181362306a36Sopenharmony_ci	/*
181462306a36Sopenharmony_ci	 * Restore max latencies (in the LTR capability) before enabling
181562306a36Sopenharmony_ci	 * LTR itself (in the PCIe capability).
181662306a36Sopenharmony_ci	 */
181762306a36Sopenharmony_ci	pci_restore_ltr_state(dev);
181862306a36Sopenharmony_ci
181962306a36Sopenharmony_ci	pci_restore_pcie_state(dev);
182062306a36Sopenharmony_ci	pci_restore_pasid_state(dev);
182162306a36Sopenharmony_ci	pci_restore_pri_state(dev);
182262306a36Sopenharmony_ci	pci_restore_ats_state(dev);
182362306a36Sopenharmony_ci	pci_restore_vc_state(dev);
182462306a36Sopenharmony_ci	pci_restore_rebar_state(dev);
182562306a36Sopenharmony_ci	pci_restore_dpc_state(dev);
182662306a36Sopenharmony_ci	pci_restore_ptm_state(dev);
182762306a36Sopenharmony_ci
182862306a36Sopenharmony_ci	pci_aer_clear_status(dev);
182962306a36Sopenharmony_ci	pci_restore_aer_state(dev);
183062306a36Sopenharmony_ci
183162306a36Sopenharmony_ci	pci_restore_config_space(dev);
183262306a36Sopenharmony_ci
183362306a36Sopenharmony_ci	pci_restore_pcix_state(dev);
183462306a36Sopenharmony_ci	pci_restore_msi_state(dev);
183562306a36Sopenharmony_ci
183662306a36Sopenharmony_ci	/* Restore ACS and IOV configuration state */
183762306a36Sopenharmony_ci	pci_enable_acs(dev);
183862306a36Sopenharmony_ci	pci_restore_iov_state(dev);
183962306a36Sopenharmony_ci
184062306a36Sopenharmony_ci	dev->state_saved = false;
184162306a36Sopenharmony_ci}
184262306a36Sopenharmony_ciEXPORT_SYMBOL(pci_restore_state);
184362306a36Sopenharmony_ci
184462306a36Sopenharmony_cistruct pci_saved_state {
184562306a36Sopenharmony_ci	u32 config_space[16];
184662306a36Sopenharmony_ci	struct pci_cap_saved_data cap[];
184762306a36Sopenharmony_ci};
184862306a36Sopenharmony_ci
184962306a36Sopenharmony_ci/**
185062306a36Sopenharmony_ci * pci_store_saved_state - Allocate and return an opaque struct containing
185162306a36Sopenharmony_ci *			   the device saved state.
185262306a36Sopenharmony_ci * @dev: PCI device that we're dealing with
185362306a36Sopenharmony_ci *
185462306a36Sopenharmony_ci * Return NULL if no state or error.
185562306a36Sopenharmony_ci */
185662306a36Sopenharmony_cistruct pci_saved_state *pci_store_saved_state(struct pci_dev *dev)
185762306a36Sopenharmony_ci{
185862306a36Sopenharmony_ci	struct pci_saved_state *state;
185962306a36Sopenharmony_ci	struct pci_cap_saved_state *tmp;
186062306a36Sopenharmony_ci	struct pci_cap_saved_data *cap;
186162306a36Sopenharmony_ci	size_t size;
186262306a36Sopenharmony_ci
186362306a36Sopenharmony_ci	if (!dev->state_saved)
186462306a36Sopenharmony_ci		return NULL;
186562306a36Sopenharmony_ci
186662306a36Sopenharmony_ci	size = sizeof(*state) + sizeof(struct pci_cap_saved_data);
186762306a36Sopenharmony_ci
186862306a36Sopenharmony_ci	hlist_for_each_entry(tmp, &dev->saved_cap_space, next)
186962306a36Sopenharmony_ci		size += sizeof(struct pci_cap_saved_data) + tmp->cap.size;
187062306a36Sopenharmony_ci
187162306a36Sopenharmony_ci	state = kzalloc(size, GFP_KERNEL);
187262306a36Sopenharmony_ci	if (!state)
187362306a36Sopenharmony_ci		return NULL;
187462306a36Sopenharmony_ci
187562306a36Sopenharmony_ci	memcpy(state->config_space, dev->saved_config_space,
187662306a36Sopenharmony_ci	       sizeof(state->config_space));
187762306a36Sopenharmony_ci
187862306a36Sopenharmony_ci	cap = state->cap;
187962306a36Sopenharmony_ci	hlist_for_each_entry(tmp, &dev->saved_cap_space, next) {
188062306a36Sopenharmony_ci		size_t len = sizeof(struct pci_cap_saved_data) + tmp->cap.size;
188162306a36Sopenharmony_ci		memcpy(cap, &tmp->cap, len);
188262306a36Sopenharmony_ci		cap = (struct pci_cap_saved_data *)((u8 *)cap + len);
188362306a36Sopenharmony_ci	}
188462306a36Sopenharmony_ci	/* Empty cap_save terminates list */
188562306a36Sopenharmony_ci
188662306a36Sopenharmony_ci	return state;
188762306a36Sopenharmony_ci}
188862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_store_saved_state);
188962306a36Sopenharmony_ci
189062306a36Sopenharmony_ci/**
189162306a36Sopenharmony_ci * pci_load_saved_state - Reload the provided save state into struct pci_dev.
189262306a36Sopenharmony_ci * @dev: PCI device that we're dealing with
189362306a36Sopenharmony_ci * @state: Saved state returned from pci_store_saved_state()
189462306a36Sopenharmony_ci */
189562306a36Sopenharmony_ciint pci_load_saved_state(struct pci_dev *dev,
189662306a36Sopenharmony_ci			 struct pci_saved_state *state)
189762306a36Sopenharmony_ci{
189862306a36Sopenharmony_ci	struct pci_cap_saved_data *cap;
189962306a36Sopenharmony_ci
190062306a36Sopenharmony_ci	dev->state_saved = false;
190162306a36Sopenharmony_ci
190262306a36Sopenharmony_ci	if (!state)
190362306a36Sopenharmony_ci		return 0;
190462306a36Sopenharmony_ci
190562306a36Sopenharmony_ci	memcpy(dev->saved_config_space, state->config_space,
190662306a36Sopenharmony_ci	       sizeof(state->config_space));
190762306a36Sopenharmony_ci
190862306a36Sopenharmony_ci	cap = state->cap;
190962306a36Sopenharmony_ci	while (cap->size) {
191062306a36Sopenharmony_ci		struct pci_cap_saved_state *tmp;
191162306a36Sopenharmony_ci
191262306a36Sopenharmony_ci		tmp = _pci_find_saved_cap(dev, cap->cap_nr, cap->cap_extended);
191362306a36Sopenharmony_ci		if (!tmp || tmp->cap.size != cap->size)
191462306a36Sopenharmony_ci			return -EINVAL;
191562306a36Sopenharmony_ci
191662306a36Sopenharmony_ci		memcpy(tmp->cap.data, cap->data, tmp->cap.size);
191762306a36Sopenharmony_ci		cap = (struct pci_cap_saved_data *)((u8 *)cap +
191862306a36Sopenharmony_ci		       sizeof(struct pci_cap_saved_data) + cap->size);
191962306a36Sopenharmony_ci	}
192062306a36Sopenharmony_ci
192162306a36Sopenharmony_ci	dev->state_saved = true;
192262306a36Sopenharmony_ci	return 0;
192362306a36Sopenharmony_ci}
192462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_load_saved_state);
192562306a36Sopenharmony_ci
192662306a36Sopenharmony_ci/**
192762306a36Sopenharmony_ci * pci_load_and_free_saved_state - Reload the save state pointed to by state,
192862306a36Sopenharmony_ci *				   and free the memory allocated for it.
192962306a36Sopenharmony_ci * @dev: PCI device that we're dealing with
193062306a36Sopenharmony_ci * @state: Pointer to saved state returned from pci_store_saved_state()
193162306a36Sopenharmony_ci */
193262306a36Sopenharmony_ciint pci_load_and_free_saved_state(struct pci_dev *dev,
193362306a36Sopenharmony_ci				  struct pci_saved_state **state)
193462306a36Sopenharmony_ci{
193562306a36Sopenharmony_ci	int ret = pci_load_saved_state(dev, *state);
193662306a36Sopenharmony_ci	kfree(*state);
193762306a36Sopenharmony_ci	*state = NULL;
193862306a36Sopenharmony_ci	return ret;
193962306a36Sopenharmony_ci}
194062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_load_and_free_saved_state);
194162306a36Sopenharmony_ci
194262306a36Sopenharmony_ciint __weak pcibios_enable_device(struct pci_dev *dev, int bars)
194362306a36Sopenharmony_ci{
194462306a36Sopenharmony_ci	return pci_enable_resources(dev, bars);
194562306a36Sopenharmony_ci}
194662306a36Sopenharmony_ci
194762306a36Sopenharmony_cistatic int do_pci_enable_device(struct pci_dev *dev, int bars)
194862306a36Sopenharmony_ci{
194962306a36Sopenharmony_ci	int err;
195062306a36Sopenharmony_ci	struct pci_dev *bridge;
195162306a36Sopenharmony_ci	u16 cmd;
195262306a36Sopenharmony_ci	u8 pin;
195362306a36Sopenharmony_ci
195462306a36Sopenharmony_ci	err = pci_set_power_state(dev, PCI_D0);
195562306a36Sopenharmony_ci	if (err < 0 && err != -EIO)
195662306a36Sopenharmony_ci		return err;
195762306a36Sopenharmony_ci
195862306a36Sopenharmony_ci	bridge = pci_upstream_bridge(dev);
195962306a36Sopenharmony_ci	if (bridge)
196062306a36Sopenharmony_ci		pcie_aspm_powersave_config_link(bridge);
196162306a36Sopenharmony_ci
196262306a36Sopenharmony_ci	err = pcibios_enable_device(dev, bars);
196362306a36Sopenharmony_ci	if (err < 0)
196462306a36Sopenharmony_ci		return err;
196562306a36Sopenharmony_ci	pci_fixup_device(pci_fixup_enable, dev);
196662306a36Sopenharmony_ci
196762306a36Sopenharmony_ci	if (dev->msi_enabled || dev->msix_enabled)
196862306a36Sopenharmony_ci		return 0;
196962306a36Sopenharmony_ci
197062306a36Sopenharmony_ci	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
197162306a36Sopenharmony_ci	if (pin) {
197262306a36Sopenharmony_ci		pci_read_config_word(dev, PCI_COMMAND, &cmd);
197362306a36Sopenharmony_ci		if (cmd & PCI_COMMAND_INTX_DISABLE)
197462306a36Sopenharmony_ci			pci_write_config_word(dev, PCI_COMMAND,
197562306a36Sopenharmony_ci					      cmd & ~PCI_COMMAND_INTX_DISABLE);
197662306a36Sopenharmony_ci	}
197762306a36Sopenharmony_ci
197862306a36Sopenharmony_ci	return 0;
197962306a36Sopenharmony_ci}
198062306a36Sopenharmony_ci
198162306a36Sopenharmony_ci/**
198262306a36Sopenharmony_ci * pci_reenable_device - Resume abandoned device
198362306a36Sopenharmony_ci * @dev: PCI device to be resumed
198462306a36Sopenharmony_ci *
198562306a36Sopenharmony_ci * NOTE: This function is a backend of pci_default_resume() and is not supposed
198662306a36Sopenharmony_ci * to be called by normal code, write proper resume handler and use it instead.
198762306a36Sopenharmony_ci */
198862306a36Sopenharmony_ciint pci_reenable_device(struct pci_dev *dev)
198962306a36Sopenharmony_ci{
199062306a36Sopenharmony_ci	if (pci_is_enabled(dev))
199162306a36Sopenharmony_ci		return do_pci_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1);
199262306a36Sopenharmony_ci	return 0;
199362306a36Sopenharmony_ci}
199462306a36Sopenharmony_ciEXPORT_SYMBOL(pci_reenable_device);
199562306a36Sopenharmony_ci
199662306a36Sopenharmony_cistatic void pci_enable_bridge(struct pci_dev *dev)
199762306a36Sopenharmony_ci{
199862306a36Sopenharmony_ci	struct pci_dev *bridge;
199962306a36Sopenharmony_ci	int retval;
200062306a36Sopenharmony_ci
200162306a36Sopenharmony_ci	bridge = pci_upstream_bridge(dev);
200262306a36Sopenharmony_ci	if (bridge)
200362306a36Sopenharmony_ci		pci_enable_bridge(bridge);
200462306a36Sopenharmony_ci
200562306a36Sopenharmony_ci	if (pci_is_enabled(dev)) {
200662306a36Sopenharmony_ci		if (!dev->is_busmaster)
200762306a36Sopenharmony_ci			pci_set_master(dev);
200862306a36Sopenharmony_ci		return;
200962306a36Sopenharmony_ci	}
201062306a36Sopenharmony_ci
201162306a36Sopenharmony_ci	retval = pci_enable_device(dev);
201262306a36Sopenharmony_ci	if (retval)
201362306a36Sopenharmony_ci		pci_err(dev, "Error enabling bridge (%d), continuing\n",
201462306a36Sopenharmony_ci			retval);
201562306a36Sopenharmony_ci	pci_set_master(dev);
201662306a36Sopenharmony_ci}
201762306a36Sopenharmony_ci
201862306a36Sopenharmony_cistatic int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags)
201962306a36Sopenharmony_ci{
202062306a36Sopenharmony_ci	struct pci_dev *bridge;
202162306a36Sopenharmony_ci	int err;
202262306a36Sopenharmony_ci	int i, bars = 0;
202362306a36Sopenharmony_ci
202462306a36Sopenharmony_ci	/*
202562306a36Sopenharmony_ci	 * Power state could be unknown at this point, either due to a fresh
202662306a36Sopenharmony_ci	 * boot or a device removal call.  So get the current power state
202762306a36Sopenharmony_ci	 * so that things like MSI message writing will behave as expected
202862306a36Sopenharmony_ci	 * (e.g. if the device really is in D0 at enable time).
202962306a36Sopenharmony_ci	 */
203062306a36Sopenharmony_ci	pci_update_current_state(dev, dev->current_state);
203162306a36Sopenharmony_ci
203262306a36Sopenharmony_ci	if (atomic_inc_return(&dev->enable_cnt) > 1)
203362306a36Sopenharmony_ci		return 0;		/* already enabled */
203462306a36Sopenharmony_ci
203562306a36Sopenharmony_ci	bridge = pci_upstream_bridge(dev);
203662306a36Sopenharmony_ci	if (bridge)
203762306a36Sopenharmony_ci		pci_enable_bridge(bridge);
203862306a36Sopenharmony_ci
203962306a36Sopenharmony_ci	/* only skip sriov related */
204062306a36Sopenharmony_ci	for (i = 0; i <= PCI_ROM_RESOURCE; i++)
204162306a36Sopenharmony_ci		if (dev->resource[i].flags & flags)
204262306a36Sopenharmony_ci			bars |= (1 << i);
204362306a36Sopenharmony_ci	for (i = PCI_BRIDGE_RESOURCES; i < DEVICE_COUNT_RESOURCE; i++)
204462306a36Sopenharmony_ci		if (dev->resource[i].flags & flags)
204562306a36Sopenharmony_ci			bars |= (1 << i);
204662306a36Sopenharmony_ci
204762306a36Sopenharmony_ci	err = do_pci_enable_device(dev, bars);
204862306a36Sopenharmony_ci	if (err < 0)
204962306a36Sopenharmony_ci		atomic_dec(&dev->enable_cnt);
205062306a36Sopenharmony_ci	return err;
205162306a36Sopenharmony_ci}
205262306a36Sopenharmony_ci
205362306a36Sopenharmony_ci/**
205462306a36Sopenharmony_ci * pci_enable_device_io - Initialize a device for use with IO space
205562306a36Sopenharmony_ci * @dev: PCI device to be initialized
205662306a36Sopenharmony_ci *
205762306a36Sopenharmony_ci * Initialize device before it's used by a driver. Ask low-level code
205862306a36Sopenharmony_ci * to enable I/O resources. Wake up the device if it was suspended.
205962306a36Sopenharmony_ci * Beware, this function can fail.
206062306a36Sopenharmony_ci */
206162306a36Sopenharmony_ciint pci_enable_device_io(struct pci_dev *dev)
206262306a36Sopenharmony_ci{
206362306a36Sopenharmony_ci	return pci_enable_device_flags(dev, IORESOURCE_IO);
206462306a36Sopenharmony_ci}
206562306a36Sopenharmony_ciEXPORT_SYMBOL(pci_enable_device_io);
206662306a36Sopenharmony_ci
206762306a36Sopenharmony_ci/**
206862306a36Sopenharmony_ci * pci_enable_device_mem - Initialize a device for use with Memory space
206962306a36Sopenharmony_ci * @dev: PCI device to be initialized
207062306a36Sopenharmony_ci *
207162306a36Sopenharmony_ci * Initialize device before it's used by a driver. Ask low-level code
207262306a36Sopenharmony_ci * to enable Memory resources. Wake up the device if it was suspended.
207362306a36Sopenharmony_ci * Beware, this function can fail.
207462306a36Sopenharmony_ci */
207562306a36Sopenharmony_ciint pci_enable_device_mem(struct pci_dev *dev)
207662306a36Sopenharmony_ci{
207762306a36Sopenharmony_ci	return pci_enable_device_flags(dev, IORESOURCE_MEM);
207862306a36Sopenharmony_ci}
207962306a36Sopenharmony_ciEXPORT_SYMBOL(pci_enable_device_mem);
208062306a36Sopenharmony_ci
208162306a36Sopenharmony_ci/**
208262306a36Sopenharmony_ci * pci_enable_device - Initialize device before it's used by a driver.
208362306a36Sopenharmony_ci * @dev: PCI device to be initialized
208462306a36Sopenharmony_ci *
208562306a36Sopenharmony_ci * Initialize device before it's used by a driver. Ask low-level code
208662306a36Sopenharmony_ci * to enable I/O and memory. Wake up the device if it was suspended.
208762306a36Sopenharmony_ci * Beware, this function can fail.
208862306a36Sopenharmony_ci *
208962306a36Sopenharmony_ci * Note we don't actually enable the device many times if we call
209062306a36Sopenharmony_ci * this function repeatedly (we just increment the count).
209162306a36Sopenharmony_ci */
209262306a36Sopenharmony_ciint pci_enable_device(struct pci_dev *dev)
209362306a36Sopenharmony_ci{
209462306a36Sopenharmony_ci	return pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO);
209562306a36Sopenharmony_ci}
209662306a36Sopenharmony_ciEXPORT_SYMBOL(pci_enable_device);
209762306a36Sopenharmony_ci
209862306a36Sopenharmony_ci/*
209962306a36Sopenharmony_ci * Managed PCI resources.  This manages device on/off, INTx/MSI/MSI-X
210062306a36Sopenharmony_ci * on/off and BAR regions.  pci_dev itself records MSI/MSI-X status, so
210162306a36Sopenharmony_ci * there's no need to track it separately.  pci_devres is initialized
210262306a36Sopenharmony_ci * when a device is enabled using managed PCI device enable interface.
210362306a36Sopenharmony_ci */
210462306a36Sopenharmony_cistruct pci_devres {
210562306a36Sopenharmony_ci	unsigned int enabled:1;
210662306a36Sopenharmony_ci	unsigned int pinned:1;
210762306a36Sopenharmony_ci	unsigned int orig_intx:1;
210862306a36Sopenharmony_ci	unsigned int restore_intx:1;
210962306a36Sopenharmony_ci	unsigned int mwi:1;
211062306a36Sopenharmony_ci	u32 region_mask;
211162306a36Sopenharmony_ci};
211262306a36Sopenharmony_ci
211362306a36Sopenharmony_cistatic void pcim_release(struct device *gendev, void *res)
211462306a36Sopenharmony_ci{
211562306a36Sopenharmony_ci	struct pci_dev *dev = to_pci_dev(gendev);
211662306a36Sopenharmony_ci	struct pci_devres *this = res;
211762306a36Sopenharmony_ci	int i;
211862306a36Sopenharmony_ci
211962306a36Sopenharmony_ci	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
212062306a36Sopenharmony_ci		if (this->region_mask & (1 << i))
212162306a36Sopenharmony_ci			pci_release_region(dev, i);
212262306a36Sopenharmony_ci
212362306a36Sopenharmony_ci	if (this->mwi)
212462306a36Sopenharmony_ci		pci_clear_mwi(dev);
212562306a36Sopenharmony_ci
212662306a36Sopenharmony_ci	if (this->restore_intx)
212762306a36Sopenharmony_ci		pci_intx(dev, this->orig_intx);
212862306a36Sopenharmony_ci
212962306a36Sopenharmony_ci	if (this->enabled && !this->pinned)
213062306a36Sopenharmony_ci		pci_disable_device(dev);
213162306a36Sopenharmony_ci}
213262306a36Sopenharmony_ci
213362306a36Sopenharmony_cistatic struct pci_devres *get_pci_dr(struct pci_dev *pdev)
213462306a36Sopenharmony_ci{
213562306a36Sopenharmony_ci	struct pci_devres *dr, *new_dr;
213662306a36Sopenharmony_ci
213762306a36Sopenharmony_ci	dr = devres_find(&pdev->dev, pcim_release, NULL, NULL);
213862306a36Sopenharmony_ci	if (dr)
213962306a36Sopenharmony_ci		return dr;
214062306a36Sopenharmony_ci
214162306a36Sopenharmony_ci	new_dr = devres_alloc(pcim_release, sizeof(*new_dr), GFP_KERNEL);
214262306a36Sopenharmony_ci	if (!new_dr)
214362306a36Sopenharmony_ci		return NULL;
214462306a36Sopenharmony_ci	return devres_get(&pdev->dev, new_dr, NULL, NULL);
214562306a36Sopenharmony_ci}
214662306a36Sopenharmony_ci
214762306a36Sopenharmony_cistatic struct pci_devres *find_pci_dr(struct pci_dev *pdev)
214862306a36Sopenharmony_ci{
214962306a36Sopenharmony_ci	if (pci_is_managed(pdev))
215062306a36Sopenharmony_ci		return devres_find(&pdev->dev, pcim_release, NULL, NULL);
215162306a36Sopenharmony_ci	return NULL;
215262306a36Sopenharmony_ci}
215362306a36Sopenharmony_ci
215462306a36Sopenharmony_ci/**
215562306a36Sopenharmony_ci * pcim_enable_device - Managed pci_enable_device()
215662306a36Sopenharmony_ci * @pdev: PCI device to be initialized
215762306a36Sopenharmony_ci *
215862306a36Sopenharmony_ci * Managed pci_enable_device().
215962306a36Sopenharmony_ci */
216062306a36Sopenharmony_ciint pcim_enable_device(struct pci_dev *pdev)
216162306a36Sopenharmony_ci{
216262306a36Sopenharmony_ci	struct pci_devres *dr;
216362306a36Sopenharmony_ci	int rc;
216462306a36Sopenharmony_ci
216562306a36Sopenharmony_ci	dr = get_pci_dr(pdev);
216662306a36Sopenharmony_ci	if (unlikely(!dr))
216762306a36Sopenharmony_ci		return -ENOMEM;
216862306a36Sopenharmony_ci	if (dr->enabled)
216962306a36Sopenharmony_ci		return 0;
217062306a36Sopenharmony_ci
217162306a36Sopenharmony_ci	rc = pci_enable_device(pdev);
217262306a36Sopenharmony_ci	if (!rc) {
217362306a36Sopenharmony_ci		pdev->is_managed = 1;
217462306a36Sopenharmony_ci		dr->enabled = 1;
217562306a36Sopenharmony_ci	}
217662306a36Sopenharmony_ci	return rc;
217762306a36Sopenharmony_ci}
217862306a36Sopenharmony_ciEXPORT_SYMBOL(pcim_enable_device);
217962306a36Sopenharmony_ci
218062306a36Sopenharmony_ci/**
218162306a36Sopenharmony_ci * pcim_pin_device - Pin managed PCI device
218262306a36Sopenharmony_ci * @pdev: PCI device to pin
218362306a36Sopenharmony_ci *
218462306a36Sopenharmony_ci * Pin managed PCI device @pdev.  Pinned device won't be disabled on
218562306a36Sopenharmony_ci * driver detach.  @pdev must have been enabled with
218662306a36Sopenharmony_ci * pcim_enable_device().
218762306a36Sopenharmony_ci */
218862306a36Sopenharmony_civoid pcim_pin_device(struct pci_dev *pdev)
218962306a36Sopenharmony_ci{
219062306a36Sopenharmony_ci	struct pci_devres *dr;
219162306a36Sopenharmony_ci
219262306a36Sopenharmony_ci	dr = find_pci_dr(pdev);
219362306a36Sopenharmony_ci	WARN_ON(!dr || !dr->enabled);
219462306a36Sopenharmony_ci	if (dr)
219562306a36Sopenharmony_ci		dr->pinned = 1;
219662306a36Sopenharmony_ci}
219762306a36Sopenharmony_ciEXPORT_SYMBOL(pcim_pin_device);
219862306a36Sopenharmony_ci
219962306a36Sopenharmony_ci/*
220062306a36Sopenharmony_ci * pcibios_device_add - provide arch specific hooks when adding device dev
220162306a36Sopenharmony_ci * @dev: the PCI device being added
220262306a36Sopenharmony_ci *
220362306a36Sopenharmony_ci * Permits the platform to provide architecture specific functionality when
220462306a36Sopenharmony_ci * devices are added. This is the default implementation. Architecture
220562306a36Sopenharmony_ci * implementations can override this.
220662306a36Sopenharmony_ci */
220762306a36Sopenharmony_ciint __weak pcibios_device_add(struct pci_dev *dev)
220862306a36Sopenharmony_ci{
220962306a36Sopenharmony_ci	return 0;
221062306a36Sopenharmony_ci}
221162306a36Sopenharmony_ci
221262306a36Sopenharmony_ci/**
221362306a36Sopenharmony_ci * pcibios_release_device - provide arch specific hooks when releasing
221462306a36Sopenharmony_ci *			    device dev
221562306a36Sopenharmony_ci * @dev: the PCI device being released
221662306a36Sopenharmony_ci *
221762306a36Sopenharmony_ci * Permits the platform to provide architecture specific functionality when
221862306a36Sopenharmony_ci * devices are released. This is the default implementation. Architecture
221962306a36Sopenharmony_ci * implementations can override this.
222062306a36Sopenharmony_ci */
222162306a36Sopenharmony_civoid __weak pcibios_release_device(struct pci_dev *dev) {}
222262306a36Sopenharmony_ci
222362306a36Sopenharmony_ci/**
222462306a36Sopenharmony_ci * pcibios_disable_device - disable arch specific PCI resources for device dev
222562306a36Sopenharmony_ci * @dev: the PCI device to disable
222662306a36Sopenharmony_ci *
222762306a36Sopenharmony_ci * Disables architecture specific PCI resources for the device. This
222862306a36Sopenharmony_ci * is the default implementation. Architecture implementations can
222962306a36Sopenharmony_ci * override this.
223062306a36Sopenharmony_ci */
223162306a36Sopenharmony_civoid __weak pcibios_disable_device(struct pci_dev *dev) {}
223262306a36Sopenharmony_ci
223362306a36Sopenharmony_ci/**
223462306a36Sopenharmony_ci * pcibios_penalize_isa_irq - penalize an ISA IRQ
223562306a36Sopenharmony_ci * @irq: ISA IRQ to penalize
223662306a36Sopenharmony_ci * @active: IRQ active or not
223762306a36Sopenharmony_ci *
223862306a36Sopenharmony_ci * Permits the platform to provide architecture-specific functionality when
223962306a36Sopenharmony_ci * penalizing ISA IRQs. This is the default implementation. Architecture
224062306a36Sopenharmony_ci * implementations can override this.
224162306a36Sopenharmony_ci */
224262306a36Sopenharmony_civoid __weak pcibios_penalize_isa_irq(int irq, int active) {}
224362306a36Sopenharmony_ci
224462306a36Sopenharmony_cistatic void do_pci_disable_device(struct pci_dev *dev)
224562306a36Sopenharmony_ci{
224662306a36Sopenharmony_ci	u16 pci_command;
224762306a36Sopenharmony_ci
224862306a36Sopenharmony_ci	pci_read_config_word(dev, PCI_COMMAND, &pci_command);
224962306a36Sopenharmony_ci	if (pci_command & PCI_COMMAND_MASTER) {
225062306a36Sopenharmony_ci		pci_command &= ~PCI_COMMAND_MASTER;
225162306a36Sopenharmony_ci		pci_write_config_word(dev, PCI_COMMAND, pci_command);
225262306a36Sopenharmony_ci	}
225362306a36Sopenharmony_ci
225462306a36Sopenharmony_ci	pcibios_disable_device(dev);
225562306a36Sopenharmony_ci}
225662306a36Sopenharmony_ci
225762306a36Sopenharmony_ci/**
225862306a36Sopenharmony_ci * pci_disable_enabled_device - Disable device without updating enable_cnt
225962306a36Sopenharmony_ci * @dev: PCI device to disable
226062306a36Sopenharmony_ci *
226162306a36Sopenharmony_ci * NOTE: This function is a backend of PCI power management routines and is
226262306a36Sopenharmony_ci * not supposed to be called drivers.
226362306a36Sopenharmony_ci */
226462306a36Sopenharmony_civoid pci_disable_enabled_device(struct pci_dev *dev)
226562306a36Sopenharmony_ci{
226662306a36Sopenharmony_ci	if (pci_is_enabled(dev))
226762306a36Sopenharmony_ci		do_pci_disable_device(dev);
226862306a36Sopenharmony_ci}
226962306a36Sopenharmony_ci
227062306a36Sopenharmony_ci/**
227162306a36Sopenharmony_ci * pci_disable_device - Disable PCI device after use
227262306a36Sopenharmony_ci * @dev: PCI device to be disabled
227362306a36Sopenharmony_ci *
227462306a36Sopenharmony_ci * Signal to the system that the PCI device is not in use by the system
227562306a36Sopenharmony_ci * anymore.  This only involves disabling PCI bus-mastering, if active.
227662306a36Sopenharmony_ci *
227762306a36Sopenharmony_ci * Note we don't actually disable the device until all callers of
227862306a36Sopenharmony_ci * pci_enable_device() have called pci_disable_device().
227962306a36Sopenharmony_ci */
228062306a36Sopenharmony_civoid pci_disable_device(struct pci_dev *dev)
228162306a36Sopenharmony_ci{
228262306a36Sopenharmony_ci	struct pci_devres *dr;
228362306a36Sopenharmony_ci
228462306a36Sopenharmony_ci	dr = find_pci_dr(dev);
228562306a36Sopenharmony_ci	if (dr)
228662306a36Sopenharmony_ci		dr->enabled = 0;
228762306a36Sopenharmony_ci
228862306a36Sopenharmony_ci	dev_WARN_ONCE(&dev->dev, atomic_read(&dev->enable_cnt) <= 0,
228962306a36Sopenharmony_ci		      "disabling already-disabled device");
229062306a36Sopenharmony_ci
229162306a36Sopenharmony_ci	if (atomic_dec_return(&dev->enable_cnt) != 0)
229262306a36Sopenharmony_ci		return;
229362306a36Sopenharmony_ci
229462306a36Sopenharmony_ci	do_pci_disable_device(dev);
229562306a36Sopenharmony_ci
229662306a36Sopenharmony_ci	dev->is_busmaster = 0;
229762306a36Sopenharmony_ci}
229862306a36Sopenharmony_ciEXPORT_SYMBOL(pci_disable_device);
229962306a36Sopenharmony_ci
230062306a36Sopenharmony_ci/**
230162306a36Sopenharmony_ci * pcibios_set_pcie_reset_state - set reset state for device dev
230262306a36Sopenharmony_ci * @dev: the PCIe device reset
230362306a36Sopenharmony_ci * @state: Reset state to enter into
230462306a36Sopenharmony_ci *
230562306a36Sopenharmony_ci * Set the PCIe reset state for the device. This is the default
230662306a36Sopenharmony_ci * implementation. Architecture implementations can override this.
230762306a36Sopenharmony_ci */
230862306a36Sopenharmony_ciint __weak pcibios_set_pcie_reset_state(struct pci_dev *dev,
230962306a36Sopenharmony_ci					enum pcie_reset_state state)
231062306a36Sopenharmony_ci{
231162306a36Sopenharmony_ci	return -EINVAL;
231262306a36Sopenharmony_ci}
231362306a36Sopenharmony_ci
231462306a36Sopenharmony_ci/**
231562306a36Sopenharmony_ci * pci_set_pcie_reset_state - set reset state for device dev
231662306a36Sopenharmony_ci * @dev: the PCIe device reset
231762306a36Sopenharmony_ci * @state: Reset state to enter into
231862306a36Sopenharmony_ci *
231962306a36Sopenharmony_ci * Sets the PCI reset state for the device.
232062306a36Sopenharmony_ci */
232162306a36Sopenharmony_ciint pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state)
232262306a36Sopenharmony_ci{
232362306a36Sopenharmony_ci	return pcibios_set_pcie_reset_state(dev, state);
232462306a36Sopenharmony_ci}
232562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_set_pcie_reset_state);
232662306a36Sopenharmony_ci
232762306a36Sopenharmony_ci#ifdef CONFIG_PCIEAER
232862306a36Sopenharmony_civoid pcie_clear_device_status(struct pci_dev *dev)
232962306a36Sopenharmony_ci{
233062306a36Sopenharmony_ci	u16 sta;
233162306a36Sopenharmony_ci
233262306a36Sopenharmony_ci	pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &sta);
233362306a36Sopenharmony_ci	pcie_capability_write_word(dev, PCI_EXP_DEVSTA, sta);
233462306a36Sopenharmony_ci}
233562306a36Sopenharmony_ci#endif
233662306a36Sopenharmony_ci
233762306a36Sopenharmony_ci/**
233862306a36Sopenharmony_ci * pcie_clear_root_pme_status - Clear root port PME interrupt status.
233962306a36Sopenharmony_ci * @dev: PCIe root port or event collector.
234062306a36Sopenharmony_ci */
234162306a36Sopenharmony_civoid pcie_clear_root_pme_status(struct pci_dev *dev)
234262306a36Sopenharmony_ci{
234362306a36Sopenharmony_ci	pcie_capability_set_dword(dev, PCI_EXP_RTSTA, PCI_EXP_RTSTA_PME);
234462306a36Sopenharmony_ci}
234562306a36Sopenharmony_ci
234662306a36Sopenharmony_ci/**
234762306a36Sopenharmony_ci * pci_check_pme_status - Check if given device has generated PME.
234862306a36Sopenharmony_ci * @dev: Device to check.
234962306a36Sopenharmony_ci *
235062306a36Sopenharmony_ci * Check the PME status of the device and if set, clear it and clear PME enable
235162306a36Sopenharmony_ci * (if set).  Return 'true' if PME status and PME enable were both set or
235262306a36Sopenharmony_ci * 'false' otherwise.
235362306a36Sopenharmony_ci */
235462306a36Sopenharmony_cibool pci_check_pme_status(struct pci_dev *dev)
235562306a36Sopenharmony_ci{
235662306a36Sopenharmony_ci	int pmcsr_pos;
235762306a36Sopenharmony_ci	u16 pmcsr;
235862306a36Sopenharmony_ci	bool ret = false;
235962306a36Sopenharmony_ci
236062306a36Sopenharmony_ci	if (!dev->pm_cap)
236162306a36Sopenharmony_ci		return false;
236262306a36Sopenharmony_ci
236362306a36Sopenharmony_ci	pmcsr_pos = dev->pm_cap + PCI_PM_CTRL;
236462306a36Sopenharmony_ci	pci_read_config_word(dev, pmcsr_pos, &pmcsr);
236562306a36Sopenharmony_ci	if (!(pmcsr & PCI_PM_CTRL_PME_STATUS))
236662306a36Sopenharmony_ci		return false;
236762306a36Sopenharmony_ci
236862306a36Sopenharmony_ci	/* Clear PME status. */
236962306a36Sopenharmony_ci	pmcsr |= PCI_PM_CTRL_PME_STATUS;
237062306a36Sopenharmony_ci	if (pmcsr & PCI_PM_CTRL_PME_ENABLE) {
237162306a36Sopenharmony_ci		/* Disable PME to avoid interrupt flood. */
237262306a36Sopenharmony_ci		pmcsr &= ~PCI_PM_CTRL_PME_ENABLE;
237362306a36Sopenharmony_ci		ret = true;
237462306a36Sopenharmony_ci	}
237562306a36Sopenharmony_ci
237662306a36Sopenharmony_ci	pci_write_config_word(dev, pmcsr_pos, pmcsr);
237762306a36Sopenharmony_ci
237862306a36Sopenharmony_ci	return ret;
237962306a36Sopenharmony_ci}
238062306a36Sopenharmony_ci
238162306a36Sopenharmony_ci/**
238262306a36Sopenharmony_ci * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set.
238362306a36Sopenharmony_ci * @dev: Device to handle.
238462306a36Sopenharmony_ci * @pme_poll_reset: Whether or not to reset the device's pme_poll flag.
238562306a36Sopenharmony_ci *
238662306a36Sopenharmony_ci * Check if @dev has generated PME and queue a resume request for it in that
238762306a36Sopenharmony_ci * case.
238862306a36Sopenharmony_ci */
238962306a36Sopenharmony_cistatic int pci_pme_wakeup(struct pci_dev *dev, void *pme_poll_reset)
239062306a36Sopenharmony_ci{
239162306a36Sopenharmony_ci	if (pme_poll_reset && dev->pme_poll)
239262306a36Sopenharmony_ci		dev->pme_poll = false;
239362306a36Sopenharmony_ci
239462306a36Sopenharmony_ci	if (pci_check_pme_status(dev)) {
239562306a36Sopenharmony_ci		pci_wakeup_event(dev);
239662306a36Sopenharmony_ci		pm_request_resume(&dev->dev);
239762306a36Sopenharmony_ci	}
239862306a36Sopenharmony_ci	return 0;
239962306a36Sopenharmony_ci}
240062306a36Sopenharmony_ci
240162306a36Sopenharmony_ci/**
240262306a36Sopenharmony_ci * pci_pme_wakeup_bus - Walk given bus and wake up devices on it, if necessary.
240362306a36Sopenharmony_ci * @bus: Top bus of the subtree to walk.
240462306a36Sopenharmony_ci */
240562306a36Sopenharmony_civoid pci_pme_wakeup_bus(struct pci_bus *bus)
240662306a36Sopenharmony_ci{
240762306a36Sopenharmony_ci	if (bus)
240862306a36Sopenharmony_ci		pci_walk_bus(bus, pci_pme_wakeup, (void *)true);
240962306a36Sopenharmony_ci}
241062306a36Sopenharmony_ci
241162306a36Sopenharmony_ci
241262306a36Sopenharmony_ci/**
241362306a36Sopenharmony_ci * pci_pme_capable - check the capability of PCI device to generate PME#
241462306a36Sopenharmony_ci * @dev: PCI device to handle.
241562306a36Sopenharmony_ci * @state: PCI state from which device will issue PME#.
241662306a36Sopenharmony_ci */
241762306a36Sopenharmony_cibool pci_pme_capable(struct pci_dev *dev, pci_power_t state)
241862306a36Sopenharmony_ci{
241962306a36Sopenharmony_ci	if (!dev->pm_cap)
242062306a36Sopenharmony_ci		return false;
242162306a36Sopenharmony_ci
242262306a36Sopenharmony_ci	return !!(dev->pme_support & (1 << state));
242362306a36Sopenharmony_ci}
242462306a36Sopenharmony_ciEXPORT_SYMBOL(pci_pme_capable);
242562306a36Sopenharmony_ci
242662306a36Sopenharmony_cistatic void pci_pme_list_scan(struct work_struct *work)
242762306a36Sopenharmony_ci{
242862306a36Sopenharmony_ci	struct pci_pme_device *pme_dev, *n;
242962306a36Sopenharmony_ci
243062306a36Sopenharmony_ci	mutex_lock(&pci_pme_list_mutex);
243162306a36Sopenharmony_ci	list_for_each_entry_safe(pme_dev, n, &pci_pme_list, list) {
243262306a36Sopenharmony_ci		struct pci_dev *pdev = pme_dev->dev;
243362306a36Sopenharmony_ci
243462306a36Sopenharmony_ci		if (pdev->pme_poll) {
243562306a36Sopenharmony_ci			struct pci_dev *bridge = pdev->bus->self;
243662306a36Sopenharmony_ci			struct device *dev = &pdev->dev;
243762306a36Sopenharmony_ci			struct device *bdev = bridge ? &bridge->dev : NULL;
243862306a36Sopenharmony_ci			int bref = 0;
243962306a36Sopenharmony_ci
244062306a36Sopenharmony_ci			/*
244162306a36Sopenharmony_ci			 * If we have a bridge, it should be in an active/D0
244262306a36Sopenharmony_ci			 * state or the configuration space of subordinate
244362306a36Sopenharmony_ci			 * devices may not be accessible or stable over the
244462306a36Sopenharmony_ci			 * course of the call.
244562306a36Sopenharmony_ci			 */
244662306a36Sopenharmony_ci			if (bdev) {
244762306a36Sopenharmony_ci				bref = pm_runtime_get_if_active(bdev, true);
244862306a36Sopenharmony_ci				if (!bref)
244962306a36Sopenharmony_ci					continue;
245062306a36Sopenharmony_ci
245162306a36Sopenharmony_ci				if (bridge->current_state != PCI_D0)
245262306a36Sopenharmony_ci					goto put_bridge;
245362306a36Sopenharmony_ci			}
245462306a36Sopenharmony_ci
245562306a36Sopenharmony_ci			/*
245662306a36Sopenharmony_ci			 * The device itself should be suspended but config
245762306a36Sopenharmony_ci			 * space must be accessible, therefore it cannot be in
245862306a36Sopenharmony_ci			 * D3cold.
245962306a36Sopenharmony_ci			 */
246062306a36Sopenharmony_ci			if (pm_runtime_suspended(dev) &&
246162306a36Sopenharmony_ci			    pdev->current_state != PCI_D3cold)
246262306a36Sopenharmony_ci				pci_pme_wakeup(pdev, NULL);
246362306a36Sopenharmony_ci
246462306a36Sopenharmony_ciput_bridge:
246562306a36Sopenharmony_ci			if (bref > 0)
246662306a36Sopenharmony_ci				pm_runtime_put(bdev);
246762306a36Sopenharmony_ci		} else {
246862306a36Sopenharmony_ci			list_del(&pme_dev->list);
246962306a36Sopenharmony_ci			kfree(pme_dev);
247062306a36Sopenharmony_ci		}
247162306a36Sopenharmony_ci	}
247262306a36Sopenharmony_ci	if (!list_empty(&pci_pme_list))
247362306a36Sopenharmony_ci		queue_delayed_work(system_freezable_wq, &pci_pme_work,
247462306a36Sopenharmony_ci				   msecs_to_jiffies(PME_TIMEOUT));
247562306a36Sopenharmony_ci	mutex_unlock(&pci_pme_list_mutex);
247662306a36Sopenharmony_ci}
247762306a36Sopenharmony_ci
247862306a36Sopenharmony_cistatic void __pci_pme_active(struct pci_dev *dev, bool enable)
247962306a36Sopenharmony_ci{
248062306a36Sopenharmony_ci	u16 pmcsr;
248162306a36Sopenharmony_ci
248262306a36Sopenharmony_ci	if (!dev->pme_support)
248362306a36Sopenharmony_ci		return;
248462306a36Sopenharmony_ci
248562306a36Sopenharmony_ci	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
248662306a36Sopenharmony_ci	/* Clear PME_Status by writing 1 to it and enable PME# */
248762306a36Sopenharmony_ci	pmcsr |= PCI_PM_CTRL_PME_STATUS | PCI_PM_CTRL_PME_ENABLE;
248862306a36Sopenharmony_ci	if (!enable)
248962306a36Sopenharmony_ci		pmcsr &= ~PCI_PM_CTRL_PME_ENABLE;
249062306a36Sopenharmony_ci
249162306a36Sopenharmony_ci	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
249262306a36Sopenharmony_ci}
249362306a36Sopenharmony_ci
249462306a36Sopenharmony_ci/**
249562306a36Sopenharmony_ci * pci_pme_restore - Restore PME configuration after config space restore.
249662306a36Sopenharmony_ci * @dev: PCI device to update.
249762306a36Sopenharmony_ci */
249862306a36Sopenharmony_civoid pci_pme_restore(struct pci_dev *dev)
249962306a36Sopenharmony_ci{
250062306a36Sopenharmony_ci	u16 pmcsr;
250162306a36Sopenharmony_ci
250262306a36Sopenharmony_ci	if (!dev->pme_support)
250362306a36Sopenharmony_ci		return;
250462306a36Sopenharmony_ci
250562306a36Sopenharmony_ci	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
250662306a36Sopenharmony_ci	if (dev->wakeup_prepared) {
250762306a36Sopenharmony_ci		pmcsr |= PCI_PM_CTRL_PME_ENABLE;
250862306a36Sopenharmony_ci		pmcsr &= ~PCI_PM_CTRL_PME_STATUS;
250962306a36Sopenharmony_ci	} else {
251062306a36Sopenharmony_ci		pmcsr &= ~PCI_PM_CTRL_PME_ENABLE;
251162306a36Sopenharmony_ci		pmcsr |= PCI_PM_CTRL_PME_STATUS;
251262306a36Sopenharmony_ci	}
251362306a36Sopenharmony_ci	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
251462306a36Sopenharmony_ci}
251562306a36Sopenharmony_ci
251662306a36Sopenharmony_ci/**
251762306a36Sopenharmony_ci * pci_pme_active - enable or disable PCI device's PME# function
251862306a36Sopenharmony_ci * @dev: PCI device to handle.
251962306a36Sopenharmony_ci * @enable: 'true' to enable PME# generation; 'false' to disable it.
252062306a36Sopenharmony_ci *
252162306a36Sopenharmony_ci * The caller must verify that the device is capable of generating PME# before
252262306a36Sopenharmony_ci * calling this function with @enable equal to 'true'.
252362306a36Sopenharmony_ci */
252462306a36Sopenharmony_civoid pci_pme_active(struct pci_dev *dev, bool enable)
252562306a36Sopenharmony_ci{
252662306a36Sopenharmony_ci	__pci_pme_active(dev, enable);
252762306a36Sopenharmony_ci
252862306a36Sopenharmony_ci	/*
252962306a36Sopenharmony_ci	 * PCI (as opposed to PCIe) PME requires that the device have
253062306a36Sopenharmony_ci	 * its PME# line hooked up correctly. Not all hardware vendors
253162306a36Sopenharmony_ci	 * do this, so the PME never gets delivered and the device
253262306a36Sopenharmony_ci	 * remains asleep. The easiest way around this is to
253362306a36Sopenharmony_ci	 * periodically walk the list of suspended devices and check
253462306a36Sopenharmony_ci	 * whether any have their PME flag set. The assumption is that
253562306a36Sopenharmony_ci	 * we'll wake up often enough anyway that this won't be a huge
253662306a36Sopenharmony_ci	 * hit, and the power savings from the devices will still be a
253762306a36Sopenharmony_ci	 * win.
253862306a36Sopenharmony_ci	 *
253962306a36Sopenharmony_ci	 * Although PCIe uses in-band PME message instead of PME# line
254062306a36Sopenharmony_ci	 * to report PME, PME does not work for some PCIe devices in
254162306a36Sopenharmony_ci	 * reality.  For example, there are devices that set their PME
254262306a36Sopenharmony_ci	 * status bits, but don't really bother to send a PME message;
254362306a36Sopenharmony_ci	 * there are PCI Express Root Ports that don't bother to
254462306a36Sopenharmony_ci	 * trigger interrupts when they receive PME messages from the
254562306a36Sopenharmony_ci	 * devices below.  So PME poll is used for PCIe devices too.
254662306a36Sopenharmony_ci	 */
254762306a36Sopenharmony_ci
254862306a36Sopenharmony_ci	if (dev->pme_poll) {
254962306a36Sopenharmony_ci		struct pci_pme_device *pme_dev;
255062306a36Sopenharmony_ci		if (enable) {
255162306a36Sopenharmony_ci			pme_dev = kmalloc(sizeof(struct pci_pme_device),
255262306a36Sopenharmony_ci					  GFP_KERNEL);
255362306a36Sopenharmony_ci			if (!pme_dev) {
255462306a36Sopenharmony_ci				pci_warn(dev, "can't enable PME#\n");
255562306a36Sopenharmony_ci				return;
255662306a36Sopenharmony_ci			}
255762306a36Sopenharmony_ci			pme_dev->dev = dev;
255862306a36Sopenharmony_ci			mutex_lock(&pci_pme_list_mutex);
255962306a36Sopenharmony_ci			list_add(&pme_dev->list, &pci_pme_list);
256062306a36Sopenharmony_ci			if (list_is_singular(&pci_pme_list))
256162306a36Sopenharmony_ci				queue_delayed_work(system_freezable_wq,
256262306a36Sopenharmony_ci						   &pci_pme_work,
256362306a36Sopenharmony_ci						   msecs_to_jiffies(PME_TIMEOUT));
256462306a36Sopenharmony_ci			mutex_unlock(&pci_pme_list_mutex);
256562306a36Sopenharmony_ci		} else {
256662306a36Sopenharmony_ci			mutex_lock(&pci_pme_list_mutex);
256762306a36Sopenharmony_ci			list_for_each_entry(pme_dev, &pci_pme_list, list) {
256862306a36Sopenharmony_ci				if (pme_dev->dev == dev) {
256962306a36Sopenharmony_ci					list_del(&pme_dev->list);
257062306a36Sopenharmony_ci					kfree(pme_dev);
257162306a36Sopenharmony_ci					break;
257262306a36Sopenharmony_ci				}
257362306a36Sopenharmony_ci			}
257462306a36Sopenharmony_ci			mutex_unlock(&pci_pme_list_mutex);
257562306a36Sopenharmony_ci		}
257662306a36Sopenharmony_ci	}
257762306a36Sopenharmony_ci
257862306a36Sopenharmony_ci	pci_dbg(dev, "PME# %s\n", enable ? "enabled" : "disabled");
257962306a36Sopenharmony_ci}
258062306a36Sopenharmony_ciEXPORT_SYMBOL(pci_pme_active);
258162306a36Sopenharmony_ci
258262306a36Sopenharmony_ci/**
258362306a36Sopenharmony_ci * __pci_enable_wake - enable PCI device as wakeup event source
258462306a36Sopenharmony_ci * @dev: PCI device affected
258562306a36Sopenharmony_ci * @state: PCI state from which device will issue wakeup events
258662306a36Sopenharmony_ci * @enable: True to enable event generation; false to disable
258762306a36Sopenharmony_ci *
258862306a36Sopenharmony_ci * This enables the device as a wakeup event source, or disables it.
258962306a36Sopenharmony_ci * When such events involves platform-specific hooks, those hooks are
259062306a36Sopenharmony_ci * called automatically by this routine.
259162306a36Sopenharmony_ci *
259262306a36Sopenharmony_ci * Devices with legacy power management (no standard PCI PM capabilities)
259362306a36Sopenharmony_ci * always require such platform hooks.
259462306a36Sopenharmony_ci *
259562306a36Sopenharmony_ci * RETURN VALUE:
259662306a36Sopenharmony_ci * 0 is returned on success
259762306a36Sopenharmony_ci * -EINVAL is returned if device is not supposed to wake up the system
259862306a36Sopenharmony_ci * Error code depending on the platform is returned if both the platform and
259962306a36Sopenharmony_ci * the native mechanism fail to enable the generation of wake-up events
260062306a36Sopenharmony_ci */
260162306a36Sopenharmony_cistatic int __pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable)
260262306a36Sopenharmony_ci{
260362306a36Sopenharmony_ci	int ret = 0;
260462306a36Sopenharmony_ci
260562306a36Sopenharmony_ci	/*
260662306a36Sopenharmony_ci	 * Bridges that are not power-manageable directly only signal
260762306a36Sopenharmony_ci	 * wakeup on behalf of subordinate devices which is set up
260862306a36Sopenharmony_ci	 * elsewhere, so skip them. However, bridges that are
260962306a36Sopenharmony_ci	 * power-manageable may signal wakeup for themselves (for example,
261062306a36Sopenharmony_ci	 * on a hotplug event) and they need to be covered here.
261162306a36Sopenharmony_ci	 */
261262306a36Sopenharmony_ci	if (!pci_power_manageable(dev))
261362306a36Sopenharmony_ci		return 0;
261462306a36Sopenharmony_ci
261562306a36Sopenharmony_ci	/* Don't do the same thing twice in a row for one device. */
261662306a36Sopenharmony_ci	if (!!enable == !!dev->wakeup_prepared)
261762306a36Sopenharmony_ci		return 0;
261862306a36Sopenharmony_ci
261962306a36Sopenharmony_ci	/*
262062306a36Sopenharmony_ci	 * According to "PCI System Architecture" 4th ed. by Tom Shanley & Don
262162306a36Sopenharmony_ci	 * Anderson we should be doing PME# wake enable followed by ACPI wake
262262306a36Sopenharmony_ci	 * enable.  To disable wake-up we call the platform first, for symmetry.
262362306a36Sopenharmony_ci	 */
262462306a36Sopenharmony_ci
262562306a36Sopenharmony_ci	if (enable) {
262662306a36Sopenharmony_ci		int error;
262762306a36Sopenharmony_ci
262862306a36Sopenharmony_ci		/*
262962306a36Sopenharmony_ci		 * Enable PME signaling if the device can signal PME from
263062306a36Sopenharmony_ci		 * D3cold regardless of whether or not it can signal PME from
263162306a36Sopenharmony_ci		 * the current target state, because that will allow it to
263262306a36Sopenharmony_ci		 * signal PME when the hierarchy above it goes into D3cold and
263362306a36Sopenharmony_ci		 * the device itself ends up in D3cold as a result of that.
263462306a36Sopenharmony_ci		 */
263562306a36Sopenharmony_ci		if (pci_pme_capable(dev, state) || pci_pme_capable(dev, PCI_D3cold))
263662306a36Sopenharmony_ci			pci_pme_active(dev, true);
263762306a36Sopenharmony_ci		else
263862306a36Sopenharmony_ci			ret = 1;
263962306a36Sopenharmony_ci		error = platform_pci_set_wakeup(dev, true);
264062306a36Sopenharmony_ci		if (ret)
264162306a36Sopenharmony_ci			ret = error;
264262306a36Sopenharmony_ci		if (!ret)
264362306a36Sopenharmony_ci			dev->wakeup_prepared = true;
264462306a36Sopenharmony_ci	} else {
264562306a36Sopenharmony_ci		platform_pci_set_wakeup(dev, false);
264662306a36Sopenharmony_ci		pci_pme_active(dev, false);
264762306a36Sopenharmony_ci		dev->wakeup_prepared = false;
264862306a36Sopenharmony_ci	}
264962306a36Sopenharmony_ci
265062306a36Sopenharmony_ci	return ret;
265162306a36Sopenharmony_ci}
265262306a36Sopenharmony_ci
265362306a36Sopenharmony_ci/**
265462306a36Sopenharmony_ci * pci_enable_wake - change wakeup settings for a PCI device
265562306a36Sopenharmony_ci * @pci_dev: Target device
265662306a36Sopenharmony_ci * @state: PCI state from which device will issue wakeup events
265762306a36Sopenharmony_ci * @enable: Whether or not to enable event generation
265862306a36Sopenharmony_ci *
265962306a36Sopenharmony_ci * If @enable is set, check device_may_wakeup() for the device before calling
266062306a36Sopenharmony_ci * __pci_enable_wake() for it.
266162306a36Sopenharmony_ci */
266262306a36Sopenharmony_ciint pci_enable_wake(struct pci_dev *pci_dev, pci_power_t state, bool enable)
266362306a36Sopenharmony_ci{
266462306a36Sopenharmony_ci	if (enable && !device_may_wakeup(&pci_dev->dev))
266562306a36Sopenharmony_ci		return -EINVAL;
266662306a36Sopenharmony_ci
266762306a36Sopenharmony_ci	return __pci_enable_wake(pci_dev, state, enable);
266862306a36Sopenharmony_ci}
266962306a36Sopenharmony_ciEXPORT_SYMBOL(pci_enable_wake);
267062306a36Sopenharmony_ci
267162306a36Sopenharmony_ci/**
267262306a36Sopenharmony_ci * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold
267362306a36Sopenharmony_ci * @dev: PCI device to prepare
267462306a36Sopenharmony_ci * @enable: True to enable wake-up event generation; false to disable
267562306a36Sopenharmony_ci *
267662306a36Sopenharmony_ci * Many drivers want the device to wake up the system from D3_hot or D3_cold
267762306a36Sopenharmony_ci * and this function allows them to set that up cleanly - pci_enable_wake()
267862306a36Sopenharmony_ci * should not be called twice in a row to enable wake-up due to PCI PM vs ACPI
267962306a36Sopenharmony_ci * ordering constraints.
268062306a36Sopenharmony_ci *
268162306a36Sopenharmony_ci * This function only returns error code if the device is not allowed to wake
268262306a36Sopenharmony_ci * up the system from sleep or it is not capable of generating PME# from both
268362306a36Sopenharmony_ci * D3_hot and D3_cold and the platform is unable to enable wake-up power for it.
268462306a36Sopenharmony_ci */
268562306a36Sopenharmony_ciint pci_wake_from_d3(struct pci_dev *dev, bool enable)
268662306a36Sopenharmony_ci{
268762306a36Sopenharmony_ci	return pci_pme_capable(dev, PCI_D3cold) ?
268862306a36Sopenharmony_ci			pci_enable_wake(dev, PCI_D3cold, enable) :
268962306a36Sopenharmony_ci			pci_enable_wake(dev, PCI_D3hot, enable);
269062306a36Sopenharmony_ci}
269162306a36Sopenharmony_ciEXPORT_SYMBOL(pci_wake_from_d3);
269262306a36Sopenharmony_ci
269362306a36Sopenharmony_ci/**
269462306a36Sopenharmony_ci * pci_target_state - find an appropriate low power state for a given PCI dev
269562306a36Sopenharmony_ci * @dev: PCI device
269662306a36Sopenharmony_ci * @wakeup: Whether or not wakeup functionality will be enabled for the device.
269762306a36Sopenharmony_ci *
269862306a36Sopenharmony_ci * Use underlying platform code to find a supported low power state for @dev.
269962306a36Sopenharmony_ci * If the platform can't manage @dev, return the deepest state from which it
270062306a36Sopenharmony_ci * can generate wake events, based on any available PME info.
270162306a36Sopenharmony_ci */
270262306a36Sopenharmony_cistatic pci_power_t pci_target_state(struct pci_dev *dev, bool wakeup)
270362306a36Sopenharmony_ci{
270462306a36Sopenharmony_ci	if (platform_pci_power_manageable(dev)) {
270562306a36Sopenharmony_ci		/*
270662306a36Sopenharmony_ci		 * Call the platform to find the target state for the device.
270762306a36Sopenharmony_ci		 */
270862306a36Sopenharmony_ci		pci_power_t state = platform_pci_choose_state(dev);
270962306a36Sopenharmony_ci
271062306a36Sopenharmony_ci		switch (state) {
271162306a36Sopenharmony_ci		case PCI_POWER_ERROR:
271262306a36Sopenharmony_ci		case PCI_UNKNOWN:
271362306a36Sopenharmony_ci			return PCI_D3hot;
271462306a36Sopenharmony_ci
271562306a36Sopenharmony_ci		case PCI_D1:
271662306a36Sopenharmony_ci		case PCI_D2:
271762306a36Sopenharmony_ci			if (pci_no_d1d2(dev))
271862306a36Sopenharmony_ci				return PCI_D3hot;
271962306a36Sopenharmony_ci		}
272062306a36Sopenharmony_ci
272162306a36Sopenharmony_ci		return state;
272262306a36Sopenharmony_ci	}
272362306a36Sopenharmony_ci
272462306a36Sopenharmony_ci	/*
272562306a36Sopenharmony_ci	 * If the device is in D3cold even though it's not power-manageable by
272662306a36Sopenharmony_ci	 * the platform, it may have been powered down by non-standard means.
272762306a36Sopenharmony_ci	 * Best to let it slumber.
272862306a36Sopenharmony_ci	 */
272962306a36Sopenharmony_ci	if (dev->current_state == PCI_D3cold)
273062306a36Sopenharmony_ci		return PCI_D3cold;
273162306a36Sopenharmony_ci	else if (!dev->pm_cap)
273262306a36Sopenharmony_ci		return PCI_D0;
273362306a36Sopenharmony_ci
273462306a36Sopenharmony_ci	if (wakeup && dev->pme_support) {
273562306a36Sopenharmony_ci		pci_power_t state = PCI_D3hot;
273662306a36Sopenharmony_ci
273762306a36Sopenharmony_ci		/*
273862306a36Sopenharmony_ci		 * Find the deepest state from which the device can generate
273962306a36Sopenharmony_ci		 * PME#.
274062306a36Sopenharmony_ci		 */
274162306a36Sopenharmony_ci		while (state && !(dev->pme_support & (1 << state)))
274262306a36Sopenharmony_ci			state--;
274362306a36Sopenharmony_ci
274462306a36Sopenharmony_ci		if (state)
274562306a36Sopenharmony_ci			return state;
274662306a36Sopenharmony_ci		else if (dev->pme_support & 1)
274762306a36Sopenharmony_ci			return PCI_D0;
274862306a36Sopenharmony_ci	}
274962306a36Sopenharmony_ci
275062306a36Sopenharmony_ci	return PCI_D3hot;
275162306a36Sopenharmony_ci}
275262306a36Sopenharmony_ci
275362306a36Sopenharmony_ci/**
275462306a36Sopenharmony_ci * pci_prepare_to_sleep - prepare PCI device for system-wide transition
275562306a36Sopenharmony_ci *			  into a sleep state
275662306a36Sopenharmony_ci * @dev: Device to handle.
275762306a36Sopenharmony_ci *
275862306a36Sopenharmony_ci * Choose the power state appropriate for the device depending on whether
275962306a36Sopenharmony_ci * it can wake up the system and/or is power manageable by the platform
276062306a36Sopenharmony_ci * (PCI_D3hot is the default) and put the device into that state.
276162306a36Sopenharmony_ci */
276262306a36Sopenharmony_ciint pci_prepare_to_sleep(struct pci_dev *dev)
276362306a36Sopenharmony_ci{
276462306a36Sopenharmony_ci	bool wakeup = device_may_wakeup(&dev->dev);
276562306a36Sopenharmony_ci	pci_power_t target_state = pci_target_state(dev, wakeup);
276662306a36Sopenharmony_ci	int error;
276762306a36Sopenharmony_ci
276862306a36Sopenharmony_ci	if (target_state == PCI_POWER_ERROR)
276962306a36Sopenharmony_ci		return -EIO;
277062306a36Sopenharmony_ci
277162306a36Sopenharmony_ci	pci_enable_wake(dev, target_state, wakeup);
277262306a36Sopenharmony_ci
277362306a36Sopenharmony_ci	error = pci_set_power_state(dev, target_state);
277462306a36Sopenharmony_ci
277562306a36Sopenharmony_ci	if (error)
277662306a36Sopenharmony_ci		pci_enable_wake(dev, target_state, false);
277762306a36Sopenharmony_ci
277862306a36Sopenharmony_ci	return error;
277962306a36Sopenharmony_ci}
278062306a36Sopenharmony_ciEXPORT_SYMBOL(pci_prepare_to_sleep);
278162306a36Sopenharmony_ci
278262306a36Sopenharmony_ci/**
278362306a36Sopenharmony_ci * pci_back_from_sleep - turn PCI device on during system-wide transition
278462306a36Sopenharmony_ci *			 into working state
278562306a36Sopenharmony_ci * @dev: Device to handle.
278662306a36Sopenharmony_ci *
278762306a36Sopenharmony_ci * Disable device's system wake-up capability and put it into D0.
278862306a36Sopenharmony_ci */
278962306a36Sopenharmony_ciint pci_back_from_sleep(struct pci_dev *dev)
279062306a36Sopenharmony_ci{
279162306a36Sopenharmony_ci	int ret = pci_set_power_state(dev, PCI_D0);
279262306a36Sopenharmony_ci
279362306a36Sopenharmony_ci	if (ret)
279462306a36Sopenharmony_ci		return ret;
279562306a36Sopenharmony_ci
279662306a36Sopenharmony_ci	pci_enable_wake(dev, PCI_D0, false);
279762306a36Sopenharmony_ci	return 0;
279862306a36Sopenharmony_ci}
279962306a36Sopenharmony_ciEXPORT_SYMBOL(pci_back_from_sleep);
280062306a36Sopenharmony_ci
280162306a36Sopenharmony_ci/**
280262306a36Sopenharmony_ci * pci_finish_runtime_suspend - Carry out PCI-specific part of runtime suspend.
280362306a36Sopenharmony_ci * @dev: PCI device being suspended.
280462306a36Sopenharmony_ci *
280562306a36Sopenharmony_ci * Prepare @dev to generate wake-up events at run time and put it into a low
280662306a36Sopenharmony_ci * power state.
280762306a36Sopenharmony_ci */
280862306a36Sopenharmony_ciint pci_finish_runtime_suspend(struct pci_dev *dev)
280962306a36Sopenharmony_ci{
281062306a36Sopenharmony_ci	pci_power_t target_state;
281162306a36Sopenharmony_ci	int error;
281262306a36Sopenharmony_ci
281362306a36Sopenharmony_ci	target_state = pci_target_state(dev, device_can_wakeup(&dev->dev));
281462306a36Sopenharmony_ci	if (target_state == PCI_POWER_ERROR)
281562306a36Sopenharmony_ci		return -EIO;
281662306a36Sopenharmony_ci
281762306a36Sopenharmony_ci	__pci_enable_wake(dev, target_state, pci_dev_run_wake(dev));
281862306a36Sopenharmony_ci
281962306a36Sopenharmony_ci	error = pci_set_power_state(dev, target_state);
282062306a36Sopenharmony_ci
282162306a36Sopenharmony_ci	if (error)
282262306a36Sopenharmony_ci		pci_enable_wake(dev, target_state, false);
282362306a36Sopenharmony_ci
282462306a36Sopenharmony_ci	return error;
282562306a36Sopenharmony_ci}
282662306a36Sopenharmony_ci
282762306a36Sopenharmony_ci/**
282862306a36Sopenharmony_ci * pci_dev_run_wake - Check if device can generate run-time wake-up events.
282962306a36Sopenharmony_ci * @dev: Device to check.
283062306a36Sopenharmony_ci *
283162306a36Sopenharmony_ci * Return true if the device itself is capable of generating wake-up events
283262306a36Sopenharmony_ci * (through the platform or using the native PCIe PME) or if the device supports
283362306a36Sopenharmony_ci * PME and one of its upstream bridges can generate wake-up events.
283462306a36Sopenharmony_ci */
283562306a36Sopenharmony_cibool pci_dev_run_wake(struct pci_dev *dev)
283662306a36Sopenharmony_ci{
283762306a36Sopenharmony_ci	struct pci_bus *bus = dev->bus;
283862306a36Sopenharmony_ci
283962306a36Sopenharmony_ci	if (!dev->pme_support)
284062306a36Sopenharmony_ci		return false;
284162306a36Sopenharmony_ci
284262306a36Sopenharmony_ci	/* PME-capable in principle, but not from the target power state */
284362306a36Sopenharmony_ci	if (!pci_pme_capable(dev, pci_target_state(dev, true)))
284462306a36Sopenharmony_ci		return false;
284562306a36Sopenharmony_ci
284662306a36Sopenharmony_ci	if (device_can_wakeup(&dev->dev))
284762306a36Sopenharmony_ci		return true;
284862306a36Sopenharmony_ci
284962306a36Sopenharmony_ci	while (bus->parent) {
285062306a36Sopenharmony_ci		struct pci_dev *bridge = bus->self;
285162306a36Sopenharmony_ci
285262306a36Sopenharmony_ci		if (device_can_wakeup(&bridge->dev))
285362306a36Sopenharmony_ci			return true;
285462306a36Sopenharmony_ci
285562306a36Sopenharmony_ci		bus = bus->parent;
285662306a36Sopenharmony_ci	}
285762306a36Sopenharmony_ci
285862306a36Sopenharmony_ci	/* We have reached the root bus. */
285962306a36Sopenharmony_ci	if (bus->bridge)
286062306a36Sopenharmony_ci		return device_can_wakeup(bus->bridge);
286162306a36Sopenharmony_ci
286262306a36Sopenharmony_ci	return false;
286362306a36Sopenharmony_ci}
286462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_dev_run_wake);
286562306a36Sopenharmony_ci
286662306a36Sopenharmony_ci/**
286762306a36Sopenharmony_ci * pci_dev_need_resume - Check if it is necessary to resume the device.
286862306a36Sopenharmony_ci * @pci_dev: Device to check.
286962306a36Sopenharmony_ci *
287062306a36Sopenharmony_ci * Return 'true' if the device is not runtime-suspended or it has to be
287162306a36Sopenharmony_ci * reconfigured due to wakeup settings difference between system and runtime
287262306a36Sopenharmony_ci * suspend, or the current power state of it is not suitable for the upcoming
287362306a36Sopenharmony_ci * (system-wide) transition.
287462306a36Sopenharmony_ci */
287562306a36Sopenharmony_cibool pci_dev_need_resume(struct pci_dev *pci_dev)
287662306a36Sopenharmony_ci{
287762306a36Sopenharmony_ci	struct device *dev = &pci_dev->dev;
287862306a36Sopenharmony_ci	pci_power_t target_state;
287962306a36Sopenharmony_ci
288062306a36Sopenharmony_ci	if (!pm_runtime_suspended(dev) || platform_pci_need_resume(pci_dev))
288162306a36Sopenharmony_ci		return true;
288262306a36Sopenharmony_ci
288362306a36Sopenharmony_ci	target_state = pci_target_state(pci_dev, device_may_wakeup(dev));
288462306a36Sopenharmony_ci
288562306a36Sopenharmony_ci	/*
288662306a36Sopenharmony_ci	 * If the earlier platform check has not triggered, D3cold is just power
288762306a36Sopenharmony_ci	 * removal on top of D3hot, so no need to resume the device in that
288862306a36Sopenharmony_ci	 * case.
288962306a36Sopenharmony_ci	 */
289062306a36Sopenharmony_ci	return target_state != pci_dev->current_state &&
289162306a36Sopenharmony_ci		target_state != PCI_D3cold &&
289262306a36Sopenharmony_ci		pci_dev->current_state != PCI_D3hot;
289362306a36Sopenharmony_ci}
289462306a36Sopenharmony_ci
289562306a36Sopenharmony_ci/**
289662306a36Sopenharmony_ci * pci_dev_adjust_pme - Adjust PME setting for a suspended device.
289762306a36Sopenharmony_ci * @pci_dev: Device to check.
289862306a36Sopenharmony_ci *
289962306a36Sopenharmony_ci * If the device is suspended and it is not configured for system wakeup,
290062306a36Sopenharmony_ci * disable PME for it to prevent it from waking up the system unnecessarily.
290162306a36Sopenharmony_ci *
290262306a36Sopenharmony_ci * Note that if the device's power state is D3cold and the platform check in
290362306a36Sopenharmony_ci * pci_dev_need_resume() has not triggered, the device's configuration need not
290462306a36Sopenharmony_ci * be changed.
290562306a36Sopenharmony_ci */
290662306a36Sopenharmony_civoid pci_dev_adjust_pme(struct pci_dev *pci_dev)
290762306a36Sopenharmony_ci{
290862306a36Sopenharmony_ci	struct device *dev = &pci_dev->dev;
290962306a36Sopenharmony_ci
291062306a36Sopenharmony_ci	spin_lock_irq(&dev->power.lock);
291162306a36Sopenharmony_ci
291262306a36Sopenharmony_ci	if (pm_runtime_suspended(dev) && !device_may_wakeup(dev) &&
291362306a36Sopenharmony_ci	    pci_dev->current_state < PCI_D3cold)
291462306a36Sopenharmony_ci		__pci_pme_active(pci_dev, false);
291562306a36Sopenharmony_ci
291662306a36Sopenharmony_ci	spin_unlock_irq(&dev->power.lock);
291762306a36Sopenharmony_ci}
291862306a36Sopenharmony_ci
291962306a36Sopenharmony_ci/**
292062306a36Sopenharmony_ci * pci_dev_complete_resume - Finalize resume from system sleep for a device.
292162306a36Sopenharmony_ci * @pci_dev: Device to handle.
292262306a36Sopenharmony_ci *
292362306a36Sopenharmony_ci * If the device is runtime suspended and wakeup-capable, enable PME for it as
292462306a36Sopenharmony_ci * it might have been disabled during the prepare phase of system suspend if
292562306a36Sopenharmony_ci * the device was not configured for system wakeup.
292662306a36Sopenharmony_ci */
292762306a36Sopenharmony_civoid pci_dev_complete_resume(struct pci_dev *pci_dev)
292862306a36Sopenharmony_ci{
292962306a36Sopenharmony_ci	struct device *dev = &pci_dev->dev;
293062306a36Sopenharmony_ci
293162306a36Sopenharmony_ci	if (!pci_dev_run_wake(pci_dev))
293262306a36Sopenharmony_ci		return;
293362306a36Sopenharmony_ci
293462306a36Sopenharmony_ci	spin_lock_irq(&dev->power.lock);
293562306a36Sopenharmony_ci
293662306a36Sopenharmony_ci	if (pm_runtime_suspended(dev) && pci_dev->current_state < PCI_D3cold)
293762306a36Sopenharmony_ci		__pci_pme_active(pci_dev, true);
293862306a36Sopenharmony_ci
293962306a36Sopenharmony_ci	spin_unlock_irq(&dev->power.lock);
294062306a36Sopenharmony_ci}
294162306a36Sopenharmony_ci
294262306a36Sopenharmony_ci/**
294362306a36Sopenharmony_ci * pci_choose_state - Choose the power state of a PCI device.
294462306a36Sopenharmony_ci * @dev: Target PCI device.
294562306a36Sopenharmony_ci * @state: Target state for the whole system.
294662306a36Sopenharmony_ci *
294762306a36Sopenharmony_ci * Returns PCI power state suitable for @dev and @state.
294862306a36Sopenharmony_ci */
294962306a36Sopenharmony_cipci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
295062306a36Sopenharmony_ci{
295162306a36Sopenharmony_ci	if (state.event == PM_EVENT_ON)
295262306a36Sopenharmony_ci		return PCI_D0;
295362306a36Sopenharmony_ci
295462306a36Sopenharmony_ci	return pci_target_state(dev, false);
295562306a36Sopenharmony_ci}
295662306a36Sopenharmony_ciEXPORT_SYMBOL(pci_choose_state);
295762306a36Sopenharmony_ci
295862306a36Sopenharmony_civoid pci_config_pm_runtime_get(struct pci_dev *pdev)
295962306a36Sopenharmony_ci{
296062306a36Sopenharmony_ci	struct device *dev = &pdev->dev;
296162306a36Sopenharmony_ci	struct device *parent = dev->parent;
296262306a36Sopenharmony_ci
296362306a36Sopenharmony_ci	if (parent)
296462306a36Sopenharmony_ci		pm_runtime_get_sync(parent);
296562306a36Sopenharmony_ci	pm_runtime_get_noresume(dev);
296662306a36Sopenharmony_ci	/*
296762306a36Sopenharmony_ci	 * pdev->current_state is set to PCI_D3cold during suspending,
296862306a36Sopenharmony_ci	 * so wait until suspending completes
296962306a36Sopenharmony_ci	 */
297062306a36Sopenharmony_ci	pm_runtime_barrier(dev);
297162306a36Sopenharmony_ci	/*
297262306a36Sopenharmony_ci	 * Only need to resume devices in D3cold, because config
297362306a36Sopenharmony_ci	 * registers are still accessible for devices suspended but
297462306a36Sopenharmony_ci	 * not in D3cold.
297562306a36Sopenharmony_ci	 */
297662306a36Sopenharmony_ci	if (pdev->current_state == PCI_D3cold)
297762306a36Sopenharmony_ci		pm_runtime_resume(dev);
297862306a36Sopenharmony_ci}
297962306a36Sopenharmony_ci
298062306a36Sopenharmony_civoid pci_config_pm_runtime_put(struct pci_dev *pdev)
298162306a36Sopenharmony_ci{
298262306a36Sopenharmony_ci	struct device *dev = &pdev->dev;
298362306a36Sopenharmony_ci	struct device *parent = dev->parent;
298462306a36Sopenharmony_ci
298562306a36Sopenharmony_ci	pm_runtime_put(dev);
298662306a36Sopenharmony_ci	if (parent)
298762306a36Sopenharmony_ci		pm_runtime_put_sync(parent);
298862306a36Sopenharmony_ci}
298962306a36Sopenharmony_ci
299062306a36Sopenharmony_cistatic const struct dmi_system_id bridge_d3_blacklist[] = {
299162306a36Sopenharmony_ci#ifdef CONFIG_X86
299262306a36Sopenharmony_ci	{
299362306a36Sopenharmony_ci		/*
299462306a36Sopenharmony_ci		 * Gigabyte X299 root port is not marked as hotplug capable
299562306a36Sopenharmony_ci		 * which allows Linux to power manage it.  However, this
299662306a36Sopenharmony_ci		 * confuses the BIOS SMI handler so don't power manage root
299762306a36Sopenharmony_ci		 * ports on that system.
299862306a36Sopenharmony_ci		 */
299962306a36Sopenharmony_ci		.ident = "X299 DESIGNARE EX-CF",
300062306a36Sopenharmony_ci		.matches = {
300162306a36Sopenharmony_ci			DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
300262306a36Sopenharmony_ci			DMI_MATCH(DMI_BOARD_NAME, "X299 DESIGNARE EX-CF"),
300362306a36Sopenharmony_ci		},
300462306a36Sopenharmony_ci	},
300562306a36Sopenharmony_ci	{
300662306a36Sopenharmony_ci		/*
300762306a36Sopenharmony_ci		 * Downstream device is not accessible after putting a root port
300862306a36Sopenharmony_ci		 * into D3cold and back into D0 on Elo Continental Z2 board
300962306a36Sopenharmony_ci		 */
301062306a36Sopenharmony_ci		.ident = "Elo Continental Z2",
301162306a36Sopenharmony_ci		.matches = {
301262306a36Sopenharmony_ci			DMI_MATCH(DMI_BOARD_VENDOR, "Elo Touch Solutions"),
301362306a36Sopenharmony_ci			DMI_MATCH(DMI_BOARD_NAME, "Geminilake"),
301462306a36Sopenharmony_ci			DMI_MATCH(DMI_BOARD_VERSION, "Continental Z2"),
301562306a36Sopenharmony_ci		},
301662306a36Sopenharmony_ci	},
301762306a36Sopenharmony_ci#endif
301862306a36Sopenharmony_ci	{ }
301962306a36Sopenharmony_ci};
302062306a36Sopenharmony_ci
302162306a36Sopenharmony_ci/**
302262306a36Sopenharmony_ci * pci_bridge_d3_possible - Is it possible to put the bridge into D3
302362306a36Sopenharmony_ci * @bridge: Bridge to check
302462306a36Sopenharmony_ci *
302562306a36Sopenharmony_ci * This function checks if it is possible to move the bridge to D3.
302662306a36Sopenharmony_ci * Currently we only allow D3 for recent enough PCIe ports and Thunderbolt.
302762306a36Sopenharmony_ci */
302862306a36Sopenharmony_cibool pci_bridge_d3_possible(struct pci_dev *bridge)
302962306a36Sopenharmony_ci{
303062306a36Sopenharmony_ci	if (!pci_is_pcie(bridge))
303162306a36Sopenharmony_ci		return false;
303262306a36Sopenharmony_ci
303362306a36Sopenharmony_ci	switch (pci_pcie_type(bridge)) {
303462306a36Sopenharmony_ci	case PCI_EXP_TYPE_ROOT_PORT:
303562306a36Sopenharmony_ci	case PCI_EXP_TYPE_UPSTREAM:
303662306a36Sopenharmony_ci	case PCI_EXP_TYPE_DOWNSTREAM:
303762306a36Sopenharmony_ci		if (pci_bridge_d3_disable)
303862306a36Sopenharmony_ci			return false;
303962306a36Sopenharmony_ci
304062306a36Sopenharmony_ci		/*
304162306a36Sopenharmony_ci		 * Hotplug ports handled by firmware in System Management Mode
304262306a36Sopenharmony_ci		 * may not be put into D3 by the OS (Thunderbolt on non-Macs).
304362306a36Sopenharmony_ci		 */
304462306a36Sopenharmony_ci		if (bridge->is_hotplug_bridge && !pciehp_is_native(bridge))
304562306a36Sopenharmony_ci			return false;
304662306a36Sopenharmony_ci
304762306a36Sopenharmony_ci		if (pci_bridge_d3_force)
304862306a36Sopenharmony_ci			return true;
304962306a36Sopenharmony_ci
305062306a36Sopenharmony_ci		/* Even the oldest 2010 Thunderbolt controller supports D3. */
305162306a36Sopenharmony_ci		if (bridge->is_thunderbolt)
305262306a36Sopenharmony_ci			return true;
305362306a36Sopenharmony_ci
305462306a36Sopenharmony_ci		/* Platform might know better if the bridge supports D3 */
305562306a36Sopenharmony_ci		if (platform_pci_bridge_d3(bridge))
305662306a36Sopenharmony_ci			return true;
305762306a36Sopenharmony_ci
305862306a36Sopenharmony_ci		/*
305962306a36Sopenharmony_ci		 * Hotplug ports handled natively by the OS were not validated
306062306a36Sopenharmony_ci		 * by vendors for runtime D3 at least until 2018 because there
306162306a36Sopenharmony_ci		 * was no OS support.
306262306a36Sopenharmony_ci		 */
306362306a36Sopenharmony_ci		if (bridge->is_hotplug_bridge)
306462306a36Sopenharmony_ci			return false;
306562306a36Sopenharmony_ci
306662306a36Sopenharmony_ci		if (dmi_check_system(bridge_d3_blacklist))
306762306a36Sopenharmony_ci			return false;
306862306a36Sopenharmony_ci
306962306a36Sopenharmony_ci		/*
307062306a36Sopenharmony_ci		 * It should be safe to put PCIe ports from 2015 or newer
307162306a36Sopenharmony_ci		 * to D3.
307262306a36Sopenharmony_ci		 */
307362306a36Sopenharmony_ci		if (dmi_get_bios_year() >= 2015)
307462306a36Sopenharmony_ci			return true;
307562306a36Sopenharmony_ci		break;
307662306a36Sopenharmony_ci	}
307762306a36Sopenharmony_ci
307862306a36Sopenharmony_ci	return false;
307962306a36Sopenharmony_ci}
308062306a36Sopenharmony_ci
308162306a36Sopenharmony_cistatic int pci_dev_check_d3cold(struct pci_dev *dev, void *data)
308262306a36Sopenharmony_ci{
308362306a36Sopenharmony_ci	bool *d3cold_ok = data;
308462306a36Sopenharmony_ci
308562306a36Sopenharmony_ci	if (/* The device needs to be allowed to go D3cold ... */
308662306a36Sopenharmony_ci	    dev->no_d3cold || !dev->d3cold_allowed ||
308762306a36Sopenharmony_ci
308862306a36Sopenharmony_ci	    /* ... and if it is wakeup capable to do so from D3cold. */
308962306a36Sopenharmony_ci	    (device_may_wakeup(&dev->dev) &&
309062306a36Sopenharmony_ci	     !pci_pme_capable(dev, PCI_D3cold)) ||
309162306a36Sopenharmony_ci
309262306a36Sopenharmony_ci	    /* If it is a bridge it must be allowed to go to D3. */
309362306a36Sopenharmony_ci	    !pci_power_manageable(dev))
309462306a36Sopenharmony_ci
309562306a36Sopenharmony_ci		*d3cold_ok = false;
309662306a36Sopenharmony_ci
309762306a36Sopenharmony_ci	return !*d3cold_ok;
309862306a36Sopenharmony_ci}
309962306a36Sopenharmony_ci
310062306a36Sopenharmony_ci/*
310162306a36Sopenharmony_ci * pci_bridge_d3_update - Update bridge D3 capabilities
310262306a36Sopenharmony_ci * @dev: PCI device which is changed
310362306a36Sopenharmony_ci *
310462306a36Sopenharmony_ci * Update upstream bridge PM capabilities accordingly depending on if the
310562306a36Sopenharmony_ci * device PM configuration was changed or the device is being removed.  The
310662306a36Sopenharmony_ci * change is also propagated upstream.
310762306a36Sopenharmony_ci */
310862306a36Sopenharmony_civoid pci_bridge_d3_update(struct pci_dev *dev)
310962306a36Sopenharmony_ci{
311062306a36Sopenharmony_ci	bool remove = !device_is_registered(&dev->dev);
311162306a36Sopenharmony_ci	struct pci_dev *bridge;
311262306a36Sopenharmony_ci	bool d3cold_ok = true;
311362306a36Sopenharmony_ci
311462306a36Sopenharmony_ci	bridge = pci_upstream_bridge(dev);
311562306a36Sopenharmony_ci	if (!bridge || !pci_bridge_d3_possible(bridge))
311662306a36Sopenharmony_ci		return;
311762306a36Sopenharmony_ci
311862306a36Sopenharmony_ci	/*
311962306a36Sopenharmony_ci	 * If D3 is currently allowed for the bridge, removing one of its
312062306a36Sopenharmony_ci	 * children won't change that.
312162306a36Sopenharmony_ci	 */
312262306a36Sopenharmony_ci	if (remove && bridge->bridge_d3)
312362306a36Sopenharmony_ci		return;
312462306a36Sopenharmony_ci
312562306a36Sopenharmony_ci	/*
312662306a36Sopenharmony_ci	 * If D3 is currently allowed for the bridge and a child is added or
312762306a36Sopenharmony_ci	 * changed, disallowance of D3 can only be caused by that child, so
312862306a36Sopenharmony_ci	 * we only need to check that single device, not any of its siblings.
312962306a36Sopenharmony_ci	 *
313062306a36Sopenharmony_ci	 * If D3 is currently not allowed for the bridge, checking the device
313162306a36Sopenharmony_ci	 * first may allow us to skip checking its siblings.
313262306a36Sopenharmony_ci	 */
313362306a36Sopenharmony_ci	if (!remove)
313462306a36Sopenharmony_ci		pci_dev_check_d3cold(dev, &d3cold_ok);
313562306a36Sopenharmony_ci
313662306a36Sopenharmony_ci	/*
313762306a36Sopenharmony_ci	 * If D3 is currently not allowed for the bridge, this may be caused
313862306a36Sopenharmony_ci	 * either by the device being changed/removed or any of its siblings,
313962306a36Sopenharmony_ci	 * so we need to go through all children to find out if one of them
314062306a36Sopenharmony_ci	 * continues to block D3.
314162306a36Sopenharmony_ci	 */
314262306a36Sopenharmony_ci	if (d3cold_ok && !bridge->bridge_d3)
314362306a36Sopenharmony_ci		pci_walk_bus(bridge->subordinate, pci_dev_check_d3cold,
314462306a36Sopenharmony_ci			     &d3cold_ok);
314562306a36Sopenharmony_ci
314662306a36Sopenharmony_ci	if (bridge->bridge_d3 != d3cold_ok) {
314762306a36Sopenharmony_ci		bridge->bridge_d3 = d3cold_ok;
314862306a36Sopenharmony_ci		/* Propagate change to upstream bridges */
314962306a36Sopenharmony_ci		pci_bridge_d3_update(bridge);
315062306a36Sopenharmony_ci	}
315162306a36Sopenharmony_ci}
315262306a36Sopenharmony_ci
315362306a36Sopenharmony_ci/**
315462306a36Sopenharmony_ci * pci_d3cold_enable - Enable D3cold for device
315562306a36Sopenharmony_ci * @dev: PCI device to handle
315662306a36Sopenharmony_ci *
315762306a36Sopenharmony_ci * This function can be used in drivers to enable D3cold from the device
315862306a36Sopenharmony_ci * they handle.  It also updates upstream PCI bridge PM capabilities
315962306a36Sopenharmony_ci * accordingly.
316062306a36Sopenharmony_ci */
316162306a36Sopenharmony_civoid pci_d3cold_enable(struct pci_dev *dev)
316262306a36Sopenharmony_ci{
316362306a36Sopenharmony_ci	if (dev->no_d3cold) {
316462306a36Sopenharmony_ci		dev->no_d3cold = false;
316562306a36Sopenharmony_ci		pci_bridge_d3_update(dev);
316662306a36Sopenharmony_ci	}
316762306a36Sopenharmony_ci}
316862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_d3cold_enable);
316962306a36Sopenharmony_ci
317062306a36Sopenharmony_ci/**
317162306a36Sopenharmony_ci * pci_d3cold_disable - Disable D3cold for device
317262306a36Sopenharmony_ci * @dev: PCI device to handle
317362306a36Sopenharmony_ci *
317462306a36Sopenharmony_ci * This function can be used in drivers to disable D3cold from the device
317562306a36Sopenharmony_ci * they handle.  It also updates upstream PCI bridge PM capabilities
317662306a36Sopenharmony_ci * accordingly.
317762306a36Sopenharmony_ci */
317862306a36Sopenharmony_civoid pci_d3cold_disable(struct pci_dev *dev)
317962306a36Sopenharmony_ci{
318062306a36Sopenharmony_ci	if (!dev->no_d3cold) {
318162306a36Sopenharmony_ci		dev->no_d3cold = true;
318262306a36Sopenharmony_ci		pci_bridge_d3_update(dev);
318362306a36Sopenharmony_ci	}
318462306a36Sopenharmony_ci}
318562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_d3cold_disable);
318662306a36Sopenharmony_ci
318762306a36Sopenharmony_ci/**
318862306a36Sopenharmony_ci * pci_pm_init - Initialize PM functions of given PCI device
318962306a36Sopenharmony_ci * @dev: PCI device to handle.
319062306a36Sopenharmony_ci */
319162306a36Sopenharmony_civoid pci_pm_init(struct pci_dev *dev)
319262306a36Sopenharmony_ci{
319362306a36Sopenharmony_ci	int pm;
319462306a36Sopenharmony_ci	u16 status;
319562306a36Sopenharmony_ci	u16 pmc;
319662306a36Sopenharmony_ci
319762306a36Sopenharmony_ci	pm_runtime_forbid(&dev->dev);
319862306a36Sopenharmony_ci	pm_runtime_set_active(&dev->dev);
319962306a36Sopenharmony_ci	pm_runtime_enable(&dev->dev);
320062306a36Sopenharmony_ci	device_enable_async_suspend(&dev->dev);
320162306a36Sopenharmony_ci	dev->wakeup_prepared = false;
320262306a36Sopenharmony_ci
320362306a36Sopenharmony_ci	dev->pm_cap = 0;
320462306a36Sopenharmony_ci	dev->pme_support = 0;
320562306a36Sopenharmony_ci
320662306a36Sopenharmony_ci	/* find PCI PM capability in list */
320762306a36Sopenharmony_ci	pm = pci_find_capability(dev, PCI_CAP_ID_PM);
320862306a36Sopenharmony_ci	if (!pm)
320962306a36Sopenharmony_ci		return;
321062306a36Sopenharmony_ci	/* Check device's ability to generate PME# */
321162306a36Sopenharmony_ci	pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc);
321262306a36Sopenharmony_ci
321362306a36Sopenharmony_ci	if ((pmc & PCI_PM_CAP_VER_MASK) > 3) {
321462306a36Sopenharmony_ci		pci_err(dev, "unsupported PM cap regs version (%u)\n",
321562306a36Sopenharmony_ci			pmc & PCI_PM_CAP_VER_MASK);
321662306a36Sopenharmony_ci		return;
321762306a36Sopenharmony_ci	}
321862306a36Sopenharmony_ci
321962306a36Sopenharmony_ci	dev->pm_cap = pm;
322062306a36Sopenharmony_ci	dev->d3hot_delay = PCI_PM_D3HOT_WAIT;
322162306a36Sopenharmony_ci	dev->d3cold_delay = PCI_PM_D3COLD_WAIT;
322262306a36Sopenharmony_ci	dev->bridge_d3 = pci_bridge_d3_possible(dev);
322362306a36Sopenharmony_ci	dev->d3cold_allowed = true;
322462306a36Sopenharmony_ci
322562306a36Sopenharmony_ci	dev->d1_support = false;
322662306a36Sopenharmony_ci	dev->d2_support = false;
322762306a36Sopenharmony_ci	if (!pci_no_d1d2(dev)) {
322862306a36Sopenharmony_ci		if (pmc & PCI_PM_CAP_D1)
322962306a36Sopenharmony_ci			dev->d1_support = true;
323062306a36Sopenharmony_ci		if (pmc & PCI_PM_CAP_D2)
323162306a36Sopenharmony_ci			dev->d2_support = true;
323262306a36Sopenharmony_ci
323362306a36Sopenharmony_ci		if (dev->d1_support || dev->d2_support)
323462306a36Sopenharmony_ci			pci_info(dev, "supports%s%s\n",
323562306a36Sopenharmony_ci				   dev->d1_support ? " D1" : "",
323662306a36Sopenharmony_ci				   dev->d2_support ? " D2" : "");
323762306a36Sopenharmony_ci	}
323862306a36Sopenharmony_ci
323962306a36Sopenharmony_ci	pmc &= PCI_PM_CAP_PME_MASK;
324062306a36Sopenharmony_ci	if (pmc) {
324162306a36Sopenharmony_ci		pci_info(dev, "PME# supported from%s%s%s%s%s\n",
324262306a36Sopenharmony_ci			 (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "",
324362306a36Sopenharmony_ci			 (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "",
324462306a36Sopenharmony_ci			 (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "",
324562306a36Sopenharmony_ci			 (pmc & PCI_PM_CAP_PME_D3hot) ? " D3hot" : "",
324662306a36Sopenharmony_ci			 (pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : "");
324762306a36Sopenharmony_ci		dev->pme_support = pmc >> PCI_PM_CAP_PME_SHIFT;
324862306a36Sopenharmony_ci		dev->pme_poll = true;
324962306a36Sopenharmony_ci		/*
325062306a36Sopenharmony_ci		 * Make device's PM flags reflect the wake-up capability, but
325162306a36Sopenharmony_ci		 * let the user space enable it to wake up the system as needed.
325262306a36Sopenharmony_ci		 */
325362306a36Sopenharmony_ci		device_set_wakeup_capable(&dev->dev, true);
325462306a36Sopenharmony_ci		/* Disable the PME# generation functionality */
325562306a36Sopenharmony_ci		pci_pme_active(dev, false);
325662306a36Sopenharmony_ci	}
325762306a36Sopenharmony_ci
325862306a36Sopenharmony_ci	pci_read_config_word(dev, PCI_STATUS, &status);
325962306a36Sopenharmony_ci	if (status & PCI_STATUS_IMM_READY)
326062306a36Sopenharmony_ci		dev->imm_ready = 1;
326162306a36Sopenharmony_ci}
326262306a36Sopenharmony_ci
326362306a36Sopenharmony_cistatic unsigned long pci_ea_flags(struct pci_dev *dev, u8 prop)
326462306a36Sopenharmony_ci{
326562306a36Sopenharmony_ci	unsigned long flags = IORESOURCE_PCI_FIXED | IORESOURCE_PCI_EA_BEI;
326662306a36Sopenharmony_ci
326762306a36Sopenharmony_ci	switch (prop) {
326862306a36Sopenharmony_ci	case PCI_EA_P_MEM:
326962306a36Sopenharmony_ci	case PCI_EA_P_VF_MEM:
327062306a36Sopenharmony_ci		flags |= IORESOURCE_MEM;
327162306a36Sopenharmony_ci		break;
327262306a36Sopenharmony_ci	case PCI_EA_P_MEM_PREFETCH:
327362306a36Sopenharmony_ci	case PCI_EA_P_VF_MEM_PREFETCH:
327462306a36Sopenharmony_ci		flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
327562306a36Sopenharmony_ci		break;
327662306a36Sopenharmony_ci	case PCI_EA_P_IO:
327762306a36Sopenharmony_ci		flags |= IORESOURCE_IO;
327862306a36Sopenharmony_ci		break;
327962306a36Sopenharmony_ci	default:
328062306a36Sopenharmony_ci		return 0;
328162306a36Sopenharmony_ci	}
328262306a36Sopenharmony_ci
328362306a36Sopenharmony_ci	return flags;
328462306a36Sopenharmony_ci}
328562306a36Sopenharmony_ci
328662306a36Sopenharmony_cistatic struct resource *pci_ea_get_resource(struct pci_dev *dev, u8 bei,
328762306a36Sopenharmony_ci					    u8 prop)
328862306a36Sopenharmony_ci{
328962306a36Sopenharmony_ci	if (bei <= PCI_EA_BEI_BAR5 && prop <= PCI_EA_P_IO)
329062306a36Sopenharmony_ci		return &dev->resource[bei];
329162306a36Sopenharmony_ci#ifdef CONFIG_PCI_IOV
329262306a36Sopenharmony_ci	else if (bei >= PCI_EA_BEI_VF_BAR0 && bei <= PCI_EA_BEI_VF_BAR5 &&
329362306a36Sopenharmony_ci		 (prop == PCI_EA_P_VF_MEM || prop == PCI_EA_P_VF_MEM_PREFETCH))
329462306a36Sopenharmony_ci		return &dev->resource[PCI_IOV_RESOURCES +
329562306a36Sopenharmony_ci				      bei - PCI_EA_BEI_VF_BAR0];
329662306a36Sopenharmony_ci#endif
329762306a36Sopenharmony_ci	else if (bei == PCI_EA_BEI_ROM)
329862306a36Sopenharmony_ci		return &dev->resource[PCI_ROM_RESOURCE];
329962306a36Sopenharmony_ci	else
330062306a36Sopenharmony_ci		return NULL;
330162306a36Sopenharmony_ci}
330262306a36Sopenharmony_ci
330362306a36Sopenharmony_ci/* Read an Enhanced Allocation (EA) entry */
330462306a36Sopenharmony_cistatic int pci_ea_read(struct pci_dev *dev, int offset)
330562306a36Sopenharmony_ci{
330662306a36Sopenharmony_ci	struct resource *res;
330762306a36Sopenharmony_ci	int ent_size, ent_offset = offset;
330862306a36Sopenharmony_ci	resource_size_t start, end;
330962306a36Sopenharmony_ci	unsigned long flags;
331062306a36Sopenharmony_ci	u32 dw0, bei, base, max_offset;
331162306a36Sopenharmony_ci	u8 prop;
331262306a36Sopenharmony_ci	bool support_64 = (sizeof(resource_size_t) >= 8);
331362306a36Sopenharmony_ci
331462306a36Sopenharmony_ci	pci_read_config_dword(dev, ent_offset, &dw0);
331562306a36Sopenharmony_ci	ent_offset += 4;
331662306a36Sopenharmony_ci
331762306a36Sopenharmony_ci	/* Entry size field indicates DWORDs after 1st */
331862306a36Sopenharmony_ci	ent_size = ((dw0 & PCI_EA_ES) + 1) << 2;
331962306a36Sopenharmony_ci
332062306a36Sopenharmony_ci	if (!(dw0 & PCI_EA_ENABLE)) /* Entry not enabled */
332162306a36Sopenharmony_ci		goto out;
332262306a36Sopenharmony_ci
332362306a36Sopenharmony_ci	bei = (dw0 & PCI_EA_BEI) >> 4;
332462306a36Sopenharmony_ci	prop = (dw0 & PCI_EA_PP) >> 8;
332562306a36Sopenharmony_ci
332662306a36Sopenharmony_ci	/*
332762306a36Sopenharmony_ci	 * If the Property is in the reserved range, try the Secondary
332862306a36Sopenharmony_ci	 * Property instead.
332962306a36Sopenharmony_ci	 */
333062306a36Sopenharmony_ci	if (prop > PCI_EA_P_BRIDGE_IO && prop < PCI_EA_P_MEM_RESERVED)
333162306a36Sopenharmony_ci		prop = (dw0 & PCI_EA_SP) >> 16;
333262306a36Sopenharmony_ci	if (prop > PCI_EA_P_BRIDGE_IO)
333362306a36Sopenharmony_ci		goto out;
333462306a36Sopenharmony_ci
333562306a36Sopenharmony_ci	res = pci_ea_get_resource(dev, bei, prop);
333662306a36Sopenharmony_ci	if (!res) {
333762306a36Sopenharmony_ci		pci_err(dev, "Unsupported EA entry BEI: %u\n", bei);
333862306a36Sopenharmony_ci		goto out;
333962306a36Sopenharmony_ci	}
334062306a36Sopenharmony_ci
334162306a36Sopenharmony_ci	flags = pci_ea_flags(dev, prop);
334262306a36Sopenharmony_ci	if (!flags) {
334362306a36Sopenharmony_ci		pci_err(dev, "Unsupported EA properties: %#x\n", prop);
334462306a36Sopenharmony_ci		goto out;
334562306a36Sopenharmony_ci	}
334662306a36Sopenharmony_ci
334762306a36Sopenharmony_ci	/* Read Base */
334862306a36Sopenharmony_ci	pci_read_config_dword(dev, ent_offset, &base);
334962306a36Sopenharmony_ci	start = (base & PCI_EA_FIELD_MASK);
335062306a36Sopenharmony_ci	ent_offset += 4;
335162306a36Sopenharmony_ci
335262306a36Sopenharmony_ci	/* Read MaxOffset */
335362306a36Sopenharmony_ci	pci_read_config_dword(dev, ent_offset, &max_offset);
335462306a36Sopenharmony_ci	ent_offset += 4;
335562306a36Sopenharmony_ci
335662306a36Sopenharmony_ci	/* Read Base MSBs (if 64-bit entry) */
335762306a36Sopenharmony_ci	if (base & PCI_EA_IS_64) {
335862306a36Sopenharmony_ci		u32 base_upper;
335962306a36Sopenharmony_ci
336062306a36Sopenharmony_ci		pci_read_config_dword(dev, ent_offset, &base_upper);
336162306a36Sopenharmony_ci		ent_offset += 4;
336262306a36Sopenharmony_ci
336362306a36Sopenharmony_ci		flags |= IORESOURCE_MEM_64;
336462306a36Sopenharmony_ci
336562306a36Sopenharmony_ci		/* entry starts above 32-bit boundary, can't use */
336662306a36Sopenharmony_ci		if (!support_64 && base_upper)
336762306a36Sopenharmony_ci			goto out;
336862306a36Sopenharmony_ci
336962306a36Sopenharmony_ci		if (support_64)
337062306a36Sopenharmony_ci			start |= ((u64)base_upper << 32);
337162306a36Sopenharmony_ci	}
337262306a36Sopenharmony_ci
337362306a36Sopenharmony_ci	end = start + (max_offset | 0x03);
337462306a36Sopenharmony_ci
337562306a36Sopenharmony_ci	/* Read MaxOffset MSBs (if 64-bit entry) */
337662306a36Sopenharmony_ci	if (max_offset & PCI_EA_IS_64) {
337762306a36Sopenharmony_ci		u32 max_offset_upper;
337862306a36Sopenharmony_ci
337962306a36Sopenharmony_ci		pci_read_config_dword(dev, ent_offset, &max_offset_upper);
338062306a36Sopenharmony_ci		ent_offset += 4;
338162306a36Sopenharmony_ci
338262306a36Sopenharmony_ci		flags |= IORESOURCE_MEM_64;
338362306a36Sopenharmony_ci
338462306a36Sopenharmony_ci		/* entry too big, can't use */
338562306a36Sopenharmony_ci		if (!support_64 && max_offset_upper)
338662306a36Sopenharmony_ci			goto out;
338762306a36Sopenharmony_ci
338862306a36Sopenharmony_ci		if (support_64)
338962306a36Sopenharmony_ci			end += ((u64)max_offset_upper << 32);
339062306a36Sopenharmony_ci	}
339162306a36Sopenharmony_ci
339262306a36Sopenharmony_ci	if (end < start) {
339362306a36Sopenharmony_ci		pci_err(dev, "EA Entry crosses address boundary\n");
339462306a36Sopenharmony_ci		goto out;
339562306a36Sopenharmony_ci	}
339662306a36Sopenharmony_ci
339762306a36Sopenharmony_ci	if (ent_size != ent_offset - offset) {
339862306a36Sopenharmony_ci		pci_err(dev, "EA Entry Size (%d) does not match length read (%d)\n",
339962306a36Sopenharmony_ci			ent_size, ent_offset - offset);
340062306a36Sopenharmony_ci		goto out;
340162306a36Sopenharmony_ci	}
340262306a36Sopenharmony_ci
340362306a36Sopenharmony_ci	res->name = pci_name(dev);
340462306a36Sopenharmony_ci	res->start = start;
340562306a36Sopenharmony_ci	res->end = end;
340662306a36Sopenharmony_ci	res->flags = flags;
340762306a36Sopenharmony_ci
340862306a36Sopenharmony_ci	if (bei <= PCI_EA_BEI_BAR5)
340962306a36Sopenharmony_ci		pci_info(dev, "BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n",
341062306a36Sopenharmony_ci			   bei, res, prop);
341162306a36Sopenharmony_ci	else if (bei == PCI_EA_BEI_ROM)
341262306a36Sopenharmony_ci		pci_info(dev, "ROM: %pR (from Enhanced Allocation, properties %#02x)\n",
341362306a36Sopenharmony_ci			   res, prop);
341462306a36Sopenharmony_ci	else if (bei >= PCI_EA_BEI_VF_BAR0 && bei <= PCI_EA_BEI_VF_BAR5)
341562306a36Sopenharmony_ci		pci_info(dev, "VF BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n",
341662306a36Sopenharmony_ci			   bei - PCI_EA_BEI_VF_BAR0, res, prop);
341762306a36Sopenharmony_ci	else
341862306a36Sopenharmony_ci		pci_info(dev, "BEI %d res: %pR (from Enhanced Allocation, properties %#02x)\n",
341962306a36Sopenharmony_ci			   bei, res, prop);
342062306a36Sopenharmony_ci
342162306a36Sopenharmony_ciout:
342262306a36Sopenharmony_ci	return offset + ent_size;
342362306a36Sopenharmony_ci}
342462306a36Sopenharmony_ci
342562306a36Sopenharmony_ci/* Enhanced Allocation Initialization */
342662306a36Sopenharmony_civoid pci_ea_init(struct pci_dev *dev)
342762306a36Sopenharmony_ci{
342862306a36Sopenharmony_ci	int ea;
342962306a36Sopenharmony_ci	u8 num_ent;
343062306a36Sopenharmony_ci	int offset;
343162306a36Sopenharmony_ci	int i;
343262306a36Sopenharmony_ci
343362306a36Sopenharmony_ci	/* find PCI EA capability in list */
343462306a36Sopenharmony_ci	ea = pci_find_capability(dev, PCI_CAP_ID_EA);
343562306a36Sopenharmony_ci	if (!ea)
343662306a36Sopenharmony_ci		return;
343762306a36Sopenharmony_ci
343862306a36Sopenharmony_ci	/* determine the number of entries */
343962306a36Sopenharmony_ci	pci_bus_read_config_byte(dev->bus, dev->devfn, ea + PCI_EA_NUM_ENT,
344062306a36Sopenharmony_ci					&num_ent);
344162306a36Sopenharmony_ci	num_ent &= PCI_EA_NUM_ENT_MASK;
344262306a36Sopenharmony_ci
344362306a36Sopenharmony_ci	offset = ea + PCI_EA_FIRST_ENT;
344462306a36Sopenharmony_ci
344562306a36Sopenharmony_ci	/* Skip DWORD 2 for type 1 functions */
344662306a36Sopenharmony_ci	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
344762306a36Sopenharmony_ci		offset += 4;
344862306a36Sopenharmony_ci
344962306a36Sopenharmony_ci	/* parse each EA entry */
345062306a36Sopenharmony_ci	for (i = 0; i < num_ent; ++i)
345162306a36Sopenharmony_ci		offset = pci_ea_read(dev, offset);
345262306a36Sopenharmony_ci}
345362306a36Sopenharmony_ci
345462306a36Sopenharmony_cistatic void pci_add_saved_cap(struct pci_dev *pci_dev,
345562306a36Sopenharmony_ci	struct pci_cap_saved_state *new_cap)
345662306a36Sopenharmony_ci{
345762306a36Sopenharmony_ci	hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space);
345862306a36Sopenharmony_ci}
345962306a36Sopenharmony_ci
346062306a36Sopenharmony_ci/**
346162306a36Sopenharmony_ci * _pci_add_cap_save_buffer - allocate buffer for saving given
346262306a36Sopenharmony_ci *			      capability registers
346362306a36Sopenharmony_ci * @dev: the PCI device
346462306a36Sopenharmony_ci * @cap: the capability to allocate the buffer for
346562306a36Sopenharmony_ci * @extended: Standard or Extended capability ID
346662306a36Sopenharmony_ci * @size: requested size of the buffer
346762306a36Sopenharmony_ci */
346862306a36Sopenharmony_cistatic int _pci_add_cap_save_buffer(struct pci_dev *dev, u16 cap,
346962306a36Sopenharmony_ci				    bool extended, unsigned int size)
347062306a36Sopenharmony_ci{
347162306a36Sopenharmony_ci	int pos;
347262306a36Sopenharmony_ci	struct pci_cap_saved_state *save_state;
347362306a36Sopenharmony_ci
347462306a36Sopenharmony_ci	if (extended)
347562306a36Sopenharmony_ci		pos = pci_find_ext_capability(dev, cap);
347662306a36Sopenharmony_ci	else
347762306a36Sopenharmony_ci		pos = pci_find_capability(dev, cap);
347862306a36Sopenharmony_ci
347962306a36Sopenharmony_ci	if (!pos)
348062306a36Sopenharmony_ci		return 0;
348162306a36Sopenharmony_ci
348262306a36Sopenharmony_ci	save_state = kzalloc(sizeof(*save_state) + size, GFP_KERNEL);
348362306a36Sopenharmony_ci	if (!save_state)
348462306a36Sopenharmony_ci		return -ENOMEM;
348562306a36Sopenharmony_ci
348662306a36Sopenharmony_ci	save_state->cap.cap_nr = cap;
348762306a36Sopenharmony_ci	save_state->cap.cap_extended = extended;
348862306a36Sopenharmony_ci	save_state->cap.size = size;
348962306a36Sopenharmony_ci	pci_add_saved_cap(dev, save_state);
349062306a36Sopenharmony_ci
349162306a36Sopenharmony_ci	return 0;
349262306a36Sopenharmony_ci}
349362306a36Sopenharmony_ci
349462306a36Sopenharmony_ciint pci_add_cap_save_buffer(struct pci_dev *dev, char cap, unsigned int size)
349562306a36Sopenharmony_ci{
349662306a36Sopenharmony_ci	return _pci_add_cap_save_buffer(dev, cap, false, size);
349762306a36Sopenharmony_ci}
349862306a36Sopenharmony_ci
349962306a36Sopenharmony_ciint pci_add_ext_cap_save_buffer(struct pci_dev *dev, u16 cap, unsigned int size)
350062306a36Sopenharmony_ci{
350162306a36Sopenharmony_ci	return _pci_add_cap_save_buffer(dev, cap, true, size);
350262306a36Sopenharmony_ci}
350362306a36Sopenharmony_ci
350462306a36Sopenharmony_ci/**
350562306a36Sopenharmony_ci * pci_allocate_cap_save_buffers - allocate buffers for saving capabilities
350662306a36Sopenharmony_ci * @dev: the PCI device
350762306a36Sopenharmony_ci */
350862306a36Sopenharmony_civoid pci_allocate_cap_save_buffers(struct pci_dev *dev)
350962306a36Sopenharmony_ci{
351062306a36Sopenharmony_ci	int error;
351162306a36Sopenharmony_ci
351262306a36Sopenharmony_ci	error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_EXP,
351362306a36Sopenharmony_ci					PCI_EXP_SAVE_REGS * sizeof(u16));
351462306a36Sopenharmony_ci	if (error)
351562306a36Sopenharmony_ci		pci_err(dev, "unable to preallocate PCI Express save buffer\n");
351662306a36Sopenharmony_ci
351762306a36Sopenharmony_ci	error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_PCIX, sizeof(u16));
351862306a36Sopenharmony_ci	if (error)
351962306a36Sopenharmony_ci		pci_err(dev, "unable to preallocate PCI-X save buffer\n");
352062306a36Sopenharmony_ci
352162306a36Sopenharmony_ci	error = pci_add_ext_cap_save_buffer(dev, PCI_EXT_CAP_ID_LTR,
352262306a36Sopenharmony_ci					    2 * sizeof(u16));
352362306a36Sopenharmony_ci	if (error)
352462306a36Sopenharmony_ci		pci_err(dev, "unable to allocate suspend buffer for LTR\n");
352562306a36Sopenharmony_ci
352662306a36Sopenharmony_ci	pci_allocate_vc_save_buffers(dev);
352762306a36Sopenharmony_ci}
352862306a36Sopenharmony_ci
352962306a36Sopenharmony_civoid pci_free_cap_save_buffers(struct pci_dev *dev)
353062306a36Sopenharmony_ci{
353162306a36Sopenharmony_ci	struct pci_cap_saved_state *tmp;
353262306a36Sopenharmony_ci	struct hlist_node *n;
353362306a36Sopenharmony_ci
353462306a36Sopenharmony_ci	hlist_for_each_entry_safe(tmp, n, &dev->saved_cap_space, next)
353562306a36Sopenharmony_ci		kfree(tmp);
353662306a36Sopenharmony_ci}
353762306a36Sopenharmony_ci
353862306a36Sopenharmony_ci/**
353962306a36Sopenharmony_ci * pci_configure_ari - enable or disable ARI forwarding
354062306a36Sopenharmony_ci * @dev: the PCI device
354162306a36Sopenharmony_ci *
354262306a36Sopenharmony_ci * If @dev and its upstream bridge both support ARI, enable ARI in the
354362306a36Sopenharmony_ci * bridge.  Otherwise, disable ARI in the bridge.
354462306a36Sopenharmony_ci */
354562306a36Sopenharmony_civoid pci_configure_ari(struct pci_dev *dev)
354662306a36Sopenharmony_ci{
354762306a36Sopenharmony_ci	u32 cap;
354862306a36Sopenharmony_ci	struct pci_dev *bridge;
354962306a36Sopenharmony_ci
355062306a36Sopenharmony_ci	if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn)
355162306a36Sopenharmony_ci		return;
355262306a36Sopenharmony_ci
355362306a36Sopenharmony_ci	bridge = dev->bus->self;
355462306a36Sopenharmony_ci	if (!bridge)
355562306a36Sopenharmony_ci		return;
355662306a36Sopenharmony_ci
355762306a36Sopenharmony_ci	pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, &cap);
355862306a36Sopenharmony_ci	if (!(cap & PCI_EXP_DEVCAP2_ARI))
355962306a36Sopenharmony_ci		return;
356062306a36Sopenharmony_ci
356162306a36Sopenharmony_ci	if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) {
356262306a36Sopenharmony_ci		pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2,
356362306a36Sopenharmony_ci					 PCI_EXP_DEVCTL2_ARI);
356462306a36Sopenharmony_ci		bridge->ari_enabled = 1;
356562306a36Sopenharmony_ci	} else {
356662306a36Sopenharmony_ci		pcie_capability_clear_word(bridge, PCI_EXP_DEVCTL2,
356762306a36Sopenharmony_ci					   PCI_EXP_DEVCTL2_ARI);
356862306a36Sopenharmony_ci		bridge->ari_enabled = 0;
356962306a36Sopenharmony_ci	}
357062306a36Sopenharmony_ci}
357162306a36Sopenharmony_ci
357262306a36Sopenharmony_cistatic bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags)
357362306a36Sopenharmony_ci{
357462306a36Sopenharmony_ci	int pos;
357562306a36Sopenharmony_ci	u16 cap, ctrl;
357662306a36Sopenharmony_ci
357762306a36Sopenharmony_ci	pos = pdev->acs_cap;
357862306a36Sopenharmony_ci	if (!pos)
357962306a36Sopenharmony_ci		return false;
358062306a36Sopenharmony_ci
358162306a36Sopenharmony_ci	/*
358262306a36Sopenharmony_ci	 * Except for egress control, capabilities are either required
358362306a36Sopenharmony_ci	 * or only required if controllable.  Features missing from the
358462306a36Sopenharmony_ci	 * capability field can therefore be assumed as hard-wired enabled.
358562306a36Sopenharmony_ci	 */
358662306a36Sopenharmony_ci	pci_read_config_word(pdev, pos + PCI_ACS_CAP, &cap);
358762306a36Sopenharmony_ci	acs_flags &= (cap | PCI_ACS_EC);
358862306a36Sopenharmony_ci
358962306a36Sopenharmony_ci	pci_read_config_word(pdev, pos + PCI_ACS_CTRL, &ctrl);
359062306a36Sopenharmony_ci	return (ctrl & acs_flags) == acs_flags;
359162306a36Sopenharmony_ci}
359262306a36Sopenharmony_ci
359362306a36Sopenharmony_ci/**
359462306a36Sopenharmony_ci * pci_acs_enabled - test ACS against required flags for a given device
359562306a36Sopenharmony_ci * @pdev: device to test
359662306a36Sopenharmony_ci * @acs_flags: required PCI ACS flags
359762306a36Sopenharmony_ci *
359862306a36Sopenharmony_ci * Return true if the device supports the provided flags.  Automatically
359962306a36Sopenharmony_ci * filters out flags that are not implemented on multifunction devices.
360062306a36Sopenharmony_ci *
360162306a36Sopenharmony_ci * Note that this interface checks the effective ACS capabilities of the
360262306a36Sopenharmony_ci * device rather than the actual capabilities.  For instance, most single
360362306a36Sopenharmony_ci * function endpoints are not required to support ACS because they have no
360462306a36Sopenharmony_ci * opportunity for peer-to-peer access.  We therefore return 'true'
360562306a36Sopenharmony_ci * regardless of whether the device exposes an ACS capability.  This makes
360662306a36Sopenharmony_ci * it much easier for callers of this function to ignore the actual type
360762306a36Sopenharmony_ci * or topology of the device when testing ACS support.
360862306a36Sopenharmony_ci */
360962306a36Sopenharmony_cibool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags)
361062306a36Sopenharmony_ci{
361162306a36Sopenharmony_ci	int ret;
361262306a36Sopenharmony_ci
361362306a36Sopenharmony_ci	ret = pci_dev_specific_acs_enabled(pdev, acs_flags);
361462306a36Sopenharmony_ci	if (ret >= 0)
361562306a36Sopenharmony_ci		return ret > 0;
361662306a36Sopenharmony_ci
361762306a36Sopenharmony_ci	/*
361862306a36Sopenharmony_ci	 * Conventional PCI and PCI-X devices never support ACS, either
361962306a36Sopenharmony_ci	 * effectively or actually.  The shared bus topology implies that
362062306a36Sopenharmony_ci	 * any device on the bus can receive or snoop DMA.
362162306a36Sopenharmony_ci	 */
362262306a36Sopenharmony_ci	if (!pci_is_pcie(pdev))
362362306a36Sopenharmony_ci		return false;
362462306a36Sopenharmony_ci
362562306a36Sopenharmony_ci	switch (pci_pcie_type(pdev)) {
362662306a36Sopenharmony_ci	/*
362762306a36Sopenharmony_ci	 * PCI/X-to-PCIe bridges are not specifically mentioned by the spec,
362862306a36Sopenharmony_ci	 * but since their primary interface is PCI/X, we conservatively
362962306a36Sopenharmony_ci	 * handle them as we would a non-PCIe device.
363062306a36Sopenharmony_ci	 */
363162306a36Sopenharmony_ci	case PCI_EXP_TYPE_PCIE_BRIDGE:
363262306a36Sopenharmony_ci	/*
363362306a36Sopenharmony_ci	 * PCIe 3.0, 6.12.1 excludes ACS on these devices.  "ACS is never
363462306a36Sopenharmony_ci	 * applicable... must never implement an ACS Extended Capability...".
363562306a36Sopenharmony_ci	 * This seems arbitrary, but we take a conservative interpretation
363662306a36Sopenharmony_ci	 * of this statement.
363762306a36Sopenharmony_ci	 */
363862306a36Sopenharmony_ci	case PCI_EXP_TYPE_PCI_BRIDGE:
363962306a36Sopenharmony_ci	case PCI_EXP_TYPE_RC_EC:
364062306a36Sopenharmony_ci		return false;
364162306a36Sopenharmony_ci	/*
364262306a36Sopenharmony_ci	 * PCIe 3.0, 6.12.1.1 specifies that downstream and root ports should
364362306a36Sopenharmony_ci	 * implement ACS in order to indicate their peer-to-peer capabilities,
364462306a36Sopenharmony_ci	 * regardless of whether they are single- or multi-function devices.
364562306a36Sopenharmony_ci	 */
364662306a36Sopenharmony_ci	case PCI_EXP_TYPE_DOWNSTREAM:
364762306a36Sopenharmony_ci	case PCI_EXP_TYPE_ROOT_PORT:
364862306a36Sopenharmony_ci		return pci_acs_flags_enabled(pdev, acs_flags);
364962306a36Sopenharmony_ci	/*
365062306a36Sopenharmony_ci	 * PCIe 3.0, 6.12.1.2 specifies ACS capabilities that should be
365162306a36Sopenharmony_ci	 * implemented by the remaining PCIe types to indicate peer-to-peer
365262306a36Sopenharmony_ci	 * capabilities, but only when they are part of a multifunction
365362306a36Sopenharmony_ci	 * device.  The footnote for section 6.12 indicates the specific
365462306a36Sopenharmony_ci	 * PCIe types included here.
365562306a36Sopenharmony_ci	 */
365662306a36Sopenharmony_ci	case PCI_EXP_TYPE_ENDPOINT:
365762306a36Sopenharmony_ci	case PCI_EXP_TYPE_UPSTREAM:
365862306a36Sopenharmony_ci	case PCI_EXP_TYPE_LEG_END:
365962306a36Sopenharmony_ci	case PCI_EXP_TYPE_RC_END:
366062306a36Sopenharmony_ci		if (!pdev->multifunction)
366162306a36Sopenharmony_ci			break;
366262306a36Sopenharmony_ci
366362306a36Sopenharmony_ci		return pci_acs_flags_enabled(pdev, acs_flags);
366462306a36Sopenharmony_ci	}
366562306a36Sopenharmony_ci
366662306a36Sopenharmony_ci	/*
366762306a36Sopenharmony_ci	 * PCIe 3.0, 6.12.1.3 specifies no ACS capabilities are applicable
366862306a36Sopenharmony_ci	 * to single function devices with the exception of downstream ports.
366962306a36Sopenharmony_ci	 */
367062306a36Sopenharmony_ci	return true;
367162306a36Sopenharmony_ci}
367262306a36Sopenharmony_ci
367362306a36Sopenharmony_ci/**
367462306a36Sopenharmony_ci * pci_acs_path_enabled - test ACS flags from start to end in a hierarchy
367562306a36Sopenharmony_ci * @start: starting downstream device
367662306a36Sopenharmony_ci * @end: ending upstream device or NULL to search to the root bus
367762306a36Sopenharmony_ci * @acs_flags: required flags
367862306a36Sopenharmony_ci *
367962306a36Sopenharmony_ci * Walk up a device tree from start to end testing PCI ACS support.  If
368062306a36Sopenharmony_ci * any step along the way does not support the required flags, return false.
368162306a36Sopenharmony_ci */
368262306a36Sopenharmony_cibool pci_acs_path_enabled(struct pci_dev *start,
368362306a36Sopenharmony_ci			  struct pci_dev *end, u16 acs_flags)
368462306a36Sopenharmony_ci{
368562306a36Sopenharmony_ci	struct pci_dev *pdev, *parent = start;
368662306a36Sopenharmony_ci
368762306a36Sopenharmony_ci	do {
368862306a36Sopenharmony_ci		pdev = parent;
368962306a36Sopenharmony_ci
369062306a36Sopenharmony_ci		if (!pci_acs_enabled(pdev, acs_flags))
369162306a36Sopenharmony_ci			return false;
369262306a36Sopenharmony_ci
369362306a36Sopenharmony_ci		if (pci_is_root_bus(pdev->bus))
369462306a36Sopenharmony_ci			return (end == NULL);
369562306a36Sopenharmony_ci
369662306a36Sopenharmony_ci		parent = pdev->bus->self;
369762306a36Sopenharmony_ci	} while (pdev != end);
369862306a36Sopenharmony_ci
369962306a36Sopenharmony_ci	return true;
370062306a36Sopenharmony_ci}
370162306a36Sopenharmony_ci
370262306a36Sopenharmony_ci/**
370362306a36Sopenharmony_ci * pci_acs_init - Initialize ACS if hardware supports it
370462306a36Sopenharmony_ci * @dev: the PCI device
370562306a36Sopenharmony_ci */
370662306a36Sopenharmony_civoid pci_acs_init(struct pci_dev *dev)
370762306a36Sopenharmony_ci{
370862306a36Sopenharmony_ci	dev->acs_cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
370962306a36Sopenharmony_ci
371062306a36Sopenharmony_ci	/*
371162306a36Sopenharmony_ci	 * Attempt to enable ACS regardless of capability because some Root
371262306a36Sopenharmony_ci	 * Ports (e.g. those quirked with *_intel_pch_acs_*) do not have
371362306a36Sopenharmony_ci	 * the standard ACS capability but still support ACS via those
371462306a36Sopenharmony_ci	 * quirks.
371562306a36Sopenharmony_ci	 */
371662306a36Sopenharmony_ci	pci_enable_acs(dev);
371762306a36Sopenharmony_ci}
371862306a36Sopenharmony_ci
371962306a36Sopenharmony_ci/**
372062306a36Sopenharmony_ci * pci_rebar_find_pos - find position of resize ctrl reg for BAR
372162306a36Sopenharmony_ci * @pdev: PCI device
372262306a36Sopenharmony_ci * @bar: BAR to find
372362306a36Sopenharmony_ci *
372462306a36Sopenharmony_ci * Helper to find the position of the ctrl register for a BAR.
372562306a36Sopenharmony_ci * Returns -ENOTSUPP if resizable BARs are not supported at all.
372662306a36Sopenharmony_ci * Returns -ENOENT if no ctrl register for the BAR could be found.
372762306a36Sopenharmony_ci */
372862306a36Sopenharmony_cistatic int pci_rebar_find_pos(struct pci_dev *pdev, int bar)
372962306a36Sopenharmony_ci{
373062306a36Sopenharmony_ci	unsigned int pos, nbars, i;
373162306a36Sopenharmony_ci	u32 ctrl;
373262306a36Sopenharmony_ci
373362306a36Sopenharmony_ci	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
373462306a36Sopenharmony_ci	if (!pos)
373562306a36Sopenharmony_ci		return -ENOTSUPP;
373662306a36Sopenharmony_ci
373762306a36Sopenharmony_ci	pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
373862306a36Sopenharmony_ci	nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >>
373962306a36Sopenharmony_ci		    PCI_REBAR_CTRL_NBAR_SHIFT;
374062306a36Sopenharmony_ci
374162306a36Sopenharmony_ci	for (i = 0; i < nbars; i++, pos += 8) {
374262306a36Sopenharmony_ci		int bar_idx;
374362306a36Sopenharmony_ci
374462306a36Sopenharmony_ci		pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
374562306a36Sopenharmony_ci		bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
374662306a36Sopenharmony_ci		if (bar_idx == bar)
374762306a36Sopenharmony_ci			return pos;
374862306a36Sopenharmony_ci	}
374962306a36Sopenharmony_ci
375062306a36Sopenharmony_ci	return -ENOENT;
375162306a36Sopenharmony_ci}
375262306a36Sopenharmony_ci
375362306a36Sopenharmony_ci/**
375462306a36Sopenharmony_ci * pci_rebar_get_possible_sizes - get possible sizes for BAR
375562306a36Sopenharmony_ci * @pdev: PCI device
375662306a36Sopenharmony_ci * @bar: BAR to query
375762306a36Sopenharmony_ci *
375862306a36Sopenharmony_ci * Get the possible sizes of a resizable BAR as bitmask defined in the spec
375962306a36Sopenharmony_ci * (bit 0=1MB, bit 19=512GB). Returns 0 if BAR isn't resizable.
376062306a36Sopenharmony_ci */
376162306a36Sopenharmony_ciu32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar)
376262306a36Sopenharmony_ci{
376362306a36Sopenharmony_ci	int pos;
376462306a36Sopenharmony_ci	u32 cap;
376562306a36Sopenharmony_ci
376662306a36Sopenharmony_ci	pos = pci_rebar_find_pos(pdev, bar);
376762306a36Sopenharmony_ci	if (pos < 0)
376862306a36Sopenharmony_ci		return 0;
376962306a36Sopenharmony_ci
377062306a36Sopenharmony_ci	pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap);
377162306a36Sopenharmony_ci	cap = FIELD_GET(PCI_REBAR_CAP_SIZES, cap);
377262306a36Sopenharmony_ci
377362306a36Sopenharmony_ci	/* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */
377462306a36Sopenharmony_ci	if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f &&
377562306a36Sopenharmony_ci	    bar == 0 && cap == 0x700)
377662306a36Sopenharmony_ci		return 0x3f00;
377762306a36Sopenharmony_ci
377862306a36Sopenharmony_ci	return cap;
377962306a36Sopenharmony_ci}
378062306a36Sopenharmony_ciEXPORT_SYMBOL(pci_rebar_get_possible_sizes);
378162306a36Sopenharmony_ci
378262306a36Sopenharmony_ci/**
378362306a36Sopenharmony_ci * pci_rebar_get_current_size - get the current size of a BAR
378462306a36Sopenharmony_ci * @pdev: PCI device
378562306a36Sopenharmony_ci * @bar: BAR to set size to
378662306a36Sopenharmony_ci *
378762306a36Sopenharmony_ci * Read the size of a BAR from the resizable BAR config.
378862306a36Sopenharmony_ci * Returns size if found or negative error code.
378962306a36Sopenharmony_ci */
379062306a36Sopenharmony_ciint pci_rebar_get_current_size(struct pci_dev *pdev, int bar)
379162306a36Sopenharmony_ci{
379262306a36Sopenharmony_ci	int pos;
379362306a36Sopenharmony_ci	u32 ctrl;
379462306a36Sopenharmony_ci
379562306a36Sopenharmony_ci	pos = pci_rebar_find_pos(pdev, bar);
379662306a36Sopenharmony_ci	if (pos < 0)
379762306a36Sopenharmony_ci		return pos;
379862306a36Sopenharmony_ci
379962306a36Sopenharmony_ci	pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
380062306a36Sopenharmony_ci	return (ctrl & PCI_REBAR_CTRL_BAR_SIZE) >> PCI_REBAR_CTRL_BAR_SHIFT;
380162306a36Sopenharmony_ci}
380262306a36Sopenharmony_ci
380362306a36Sopenharmony_ci/**
380462306a36Sopenharmony_ci * pci_rebar_set_size - set a new size for a BAR
380562306a36Sopenharmony_ci * @pdev: PCI device
380662306a36Sopenharmony_ci * @bar: BAR to set size to
380762306a36Sopenharmony_ci * @size: new size as defined in the spec (0=1MB, 19=512GB)
380862306a36Sopenharmony_ci *
380962306a36Sopenharmony_ci * Set the new size of a BAR as defined in the spec.
381062306a36Sopenharmony_ci * Returns zero if resizing was successful, error code otherwise.
381162306a36Sopenharmony_ci */
381262306a36Sopenharmony_ciint pci_rebar_set_size(struct pci_dev *pdev, int bar, int size)
381362306a36Sopenharmony_ci{
381462306a36Sopenharmony_ci	int pos;
381562306a36Sopenharmony_ci	u32 ctrl;
381662306a36Sopenharmony_ci
381762306a36Sopenharmony_ci	pos = pci_rebar_find_pos(pdev, bar);
381862306a36Sopenharmony_ci	if (pos < 0)
381962306a36Sopenharmony_ci		return pos;
382062306a36Sopenharmony_ci
382162306a36Sopenharmony_ci	pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
382262306a36Sopenharmony_ci	ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE;
382362306a36Sopenharmony_ci	ctrl |= size << PCI_REBAR_CTRL_BAR_SHIFT;
382462306a36Sopenharmony_ci	pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl);
382562306a36Sopenharmony_ci	return 0;
382662306a36Sopenharmony_ci}
382762306a36Sopenharmony_ci
382862306a36Sopenharmony_ci/**
382962306a36Sopenharmony_ci * pci_enable_atomic_ops_to_root - enable AtomicOp requests to root port
383062306a36Sopenharmony_ci * @dev: the PCI device
383162306a36Sopenharmony_ci * @cap_mask: mask of desired AtomicOp sizes, including one or more of:
383262306a36Sopenharmony_ci *	PCI_EXP_DEVCAP2_ATOMIC_COMP32
383362306a36Sopenharmony_ci *	PCI_EXP_DEVCAP2_ATOMIC_COMP64
383462306a36Sopenharmony_ci *	PCI_EXP_DEVCAP2_ATOMIC_COMP128
383562306a36Sopenharmony_ci *
383662306a36Sopenharmony_ci * Return 0 if all upstream bridges support AtomicOp routing, egress
383762306a36Sopenharmony_ci * blocking is disabled on all upstream ports, and the root port supports
383862306a36Sopenharmony_ci * the requested completion capabilities (32-bit, 64-bit and/or 128-bit
383962306a36Sopenharmony_ci * AtomicOp completion), or negative otherwise.
384062306a36Sopenharmony_ci */
384162306a36Sopenharmony_ciint pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask)
384262306a36Sopenharmony_ci{
384362306a36Sopenharmony_ci	struct pci_bus *bus = dev->bus;
384462306a36Sopenharmony_ci	struct pci_dev *bridge;
384562306a36Sopenharmony_ci	u32 cap, ctl2;
384662306a36Sopenharmony_ci
384762306a36Sopenharmony_ci	/*
384862306a36Sopenharmony_ci	 * Per PCIe r5.0, sec 9.3.5.10, the AtomicOp Requester Enable bit
384962306a36Sopenharmony_ci	 * in Device Control 2 is reserved in VFs and the PF value applies
385062306a36Sopenharmony_ci	 * to all associated VFs.
385162306a36Sopenharmony_ci	 */
385262306a36Sopenharmony_ci	if (dev->is_virtfn)
385362306a36Sopenharmony_ci		return -EINVAL;
385462306a36Sopenharmony_ci
385562306a36Sopenharmony_ci	if (!pci_is_pcie(dev))
385662306a36Sopenharmony_ci		return -EINVAL;
385762306a36Sopenharmony_ci
385862306a36Sopenharmony_ci	/*
385962306a36Sopenharmony_ci	 * Per PCIe r4.0, sec 6.15, endpoints and root ports may be
386062306a36Sopenharmony_ci	 * AtomicOp requesters.  For now, we only support endpoints as
386162306a36Sopenharmony_ci	 * requesters and root ports as completers.  No endpoints as
386262306a36Sopenharmony_ci	 * completers, and no peer-to-peer.
386362306a36Sopenharmony_ci	 */
386462306a36Sopenharmony_ci
386562306a36Sopenharmony_ci	switch (pci_pcie_type(dev)) {
386662306a36Sopenharmony_ci	case PCI_EXP_TYPE_ENDPOINT:
386762306a36Sopenharmony_ci	case PCI_EXP_TYPE_LEG_END:
386862306a36Sopenharmony_ci	case PCI_EXP_TYPE_RC_END:
386962306a36Sopenharmony_ci		break;
387062306a36Sopenharmony_ci	default:
387162306a36Sopenharmony_ci		return -EINVAL;
387262306a36Sopenharmony_ci	}
387362306a36Sopenharmony_ci
387462306a36Sopenharmony_ci	while (bus->parent) {
387562306a36Sopenharmony_ci		bridge = bus->self;
387662306a36Sopenharmony_ci
387762306a36Sopenharmony_ci		pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, &cap);
387862306a36Sopenharmony_ci
387962306a36Sopenharmony_ci		switch (pci_pcie_type(bridge)) {
388062306a36Sopenharmony_ci		/* Ensure switch ports support AtomicOp routing */
388162306a36Sopenharmony_ci		case PCI_EXP_TYPE_UPSTREAM:
388262306a36Sopenharmony_ci		case PCI_EXP_TYPE_DOWNSTREAM:
388362306a36Sopenharmony_ci			if (!(cap & PCI_EXP_DEVCAP2_ATOMIC_ROUTE))
388462306a36Sopenharmony_ci				return -EINVAL;
388562306a36Sopenharmony_ci			break;
388662306a36Sopenharmony_ci
388762306a36Sopenharmony_ci		/* Ensure root port supports all the sizes we care about */
388862306a36Sopenharmony_ci		case PCI_EXP_TYPE_ROOT_PORT:
388962306a36Sopenharmony_ci			if ((cap & cap_mask) != cap_mask)
389062306a36Sopenharmony_ci				return -EINVAL;
389162306a36Sopenharmony_ci			break;
389262306a36Sopenharmony_ci		}
389362306a36Sopenharmony_ci
389462306a36Sopenharmony_ci		/* Ensure upstream ports don't block AtomicOps on egress */
389562306a36Sopenharmony_ci		if (pci_pcie_type(bridge) == PCI_EXP_TYPE_UPSTREAM) {
389662306a36Sopenharmony_ci			pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2,
389762306a36Sopenharmony_ci						   &ctl2);
389862306a36Sopenharmony_ci			if (ctl2 & PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK)
389962306a36Sopenharmony_ci				return -EINVAL;
390062306a36Sopenharmony_ci		}
390162306a36Sopenharmony_ci
390262306a36Sopenharmony_ci		bus = bus->parent;
390362306a36Sopenharmony_ci	}
390462306a36Sopenharmony_ci
390562306a36Sopenharmony_ci	pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
390662306a36Sopenharmony_ci				 PCI_EXP_DEVCTL2_ATOMIC_REQ);
390762306a36Sopenharmony_ci	return 0;
390862306a36Sopenharmony_ci}
390962306a36Sopenharmony_ciEXPORT_SYMBOL(pci_enable_atomic_ops_to_root);
391062306a36Sopenharmony_ci
391162306a36Sopenharmony_ci/**
391262306a36Sopenharmony_ci * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
391362306a36Sopenharmony_ci * @dev: the PCI device
391462306a36Sopenharmony_ci * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTC, 4=INTD)
391562306a36Sopenharmony_ci *
391662306a36Sopenharmony_ci * Perform INTx swizzling for a device behind one level of bridge.  This is
391762306a36Sopenharmony_ci * required by section 9.1 of the PCI-to-PCI bridge specification for devices
391862306a36Sopenharmony_ci * behind bridges on add-in cards.  For devices with ARI enabled, the slot
391962306a36Sopenharmony_ci * number is always 0 (see the Implementation Note in section 2.2.8.1 of
392062306a36Sopenharmony_ci * the PCI Express Base Specification, Revision 2.1)
392162306a36Sopenharmony_ci */
392262306a36Sopenharmony_ciu8 pci_swizzle_interrupt_pin(const struct pci_dev *dev, u8 pin)
392362306a36Sopenharmony_ci{
392462306a36Sopenharmony_ci	int slot;
392562306a36Sopenharmony_ci
392662306a36Sopenharmony_ci	if (pci_ari_enabled(dev->bus))
392762306a36Sopenharmony_ci		slot = 0;
392862306a36Sopenharmony_ci	else
392962306a36Sopenharmony_ci		slot = PCI_SLOT(dev->devfn);
393062306a36Sopenharmony_ci
393162306a36Sopenharmony_ci	return (((pin - 1) + slot) % 4) + 1;
393262306a36Sopenharmony_ci}
393362306a36Sopenharmony_ci
393462306a36Sopenharmony_ciint pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
393562306a36Sopenharmony_ci{
393662306a36Sopenharmony_ci	u8 pin;
393762306a36Sopenharmony_ci
393862306a36Sopenharmony_ci	pin = dev->pin;
393962306a36Sopenharmony_ci	if (!pin)
394062306a36Sopenharmony_ci		return -1;
394162306a36Sopenharmony_ci
394262306a36Sopenharmony_ci	while (!pci_is_root_bus(dev->bus)) {
394362306a36Sopenharmony_ci		pin = pci_swizzle_interrupt_pin(dev, pin);
394462306a36Sopenharmony_ci		dev = dev->bus->self;
394562306a36Sopenharmony_ci	}
394662306a36Sopenharmony_ci	*bridge = dev;
394762306a36Sopenharmony_ci	return pin;
394862306a36Sopenharmony_ci}
394962306a36Sopenharmony_ci
395062306a36Sopenharmony_ci/**
395162306a36Sopenharmony_ci * pci_common_swizzle - swizzle INTx all the way to root bridge
395262306a36Sopenharmony_ci * @dev: the PCI device
395362306a36Sopenharmony_ci * @pinp: pointer to the INTx pin value (1=INTA, 2=INTB, 3=INTD, 4=INTD)
395462306a36Sopenharmony_ci *
395562306a36Sopenharmony_ci * Perform INTx swizzling for a device.  This traverses through all PCI-to-PCI
395662306a36Sopenharmony_ci * bridges all the way up to a PCI root bus.
395762306a36Sopenharmony_ci */
395862306a36Sopenharmony_ciu8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp)
395962306a36Sopenharmony_ci{
396062306a36Sopenharmony_ci	u8 pin = *pinp;
396162306a36Sopenharmony_ci
396262306a36Sopenharmony_ci	while (!pci_is_root_bus(dev->bus)) {
396362306a36Sopenharmony_ci		pin = pci_swizzle_interrupt_pin(dev, pin);
396462306a36Sopenharmony_ci		dev = dev->bus->self;
396562306a36Sopenharmony_ci	}
396662306a36Sopenharmony_ci	*pinp = pin;
396762306a36Sopenharmony_ci	return PCI_SLOT(dev->devfn);
396862306a36Sopenharmony_ci}
396962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_common_swizzle);
397062306a36Sopenharmony_ci
397162306a36Sopenharmony_ci/**
397262306a36Sopenharmony_ci * pci_release_region - Release a PCI bar
397362306a36Sopenharmony_ci * @pdev: PCI device whose resources were previously reserved by
397462306a36Sopenharmony_ci *	  pci_request_region()
397562306a36Sopenharmony_ci * @bar: BAR to release
397662306a36Sopenharmony_ci *
397762306a36Sopenharmony_ci * Releases the PCI I/O and memory resources previously reserved by a
397862306a36Sopenharmony_ci * successful call to pci_request_region().  Call this function only
397962306a36Sopenharmony_ci * after all use of the PCI regions has ceased.
398062306a36Sopenharmony_ci */
398162306a36Sopenharmony_civoid pci_release_region(struct pci_dev *pdev, int bar)
398262306a36Sopenharmony_ci{
398362306a36Sopenharmony_ci	struct pci_devres *dr;
398462306a36Sopenharmony_ci
398562306a36Sopenharmony_ci	if (pci_resource_len(pdev, bar) == 0)
398662306a36Sopenharmony_ci		return;
398762306a36Sopenharmony_ci	if (pci_resource_flags(pdev, bar) & IORESOURCE_IO)
398862306a36Sopenharmony_ci		release_region(pci_resource_start(pdev, bar),
398962306a36Sopenharmony_ci				pci_resource_len(pdev, bar));
399062306a36Sopenharmony_ci	else if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM)
399162306a36Sopenharmony_ci		release_mem_region(pci_resource_start(pdev, bar),
399262306a36Sopenharmony_ci				pci_resource_len(pdev, bar));
399362306a36Sopenharmony_ci
399462306a36Sopenharmony_ci	dr = find_pci_dr(pdev);
399562306a36Sopenharmony_ci	if (dr)
399662306a36Sopenharmony_ci		dr->region_mask &= ~(1 << bar);
399762306a36Sopenharmony_ci}
399862306a36Sopenharmony_ciEXPORT_SYMBOL(pci_release_region);
399962306a36Sopenharmony_ci
400062306a36Sopenharmony_ci/**
400162306a36Sopenharmony_ci * __pci_request_region - Reserved PCI I/O and memory resource
400262306a36Sopenharmony_ci * @pdev: PCI device whose resources are to be reserved
400362306a36Sopenharmony_ci * @bar: BAR to be reserved
400462306a36Sopenharmony_ci * @res_name: Name to be associated with resource.
400562306a36Sopenharmony_ci * @exclusive: whether the region access is exclusive or not
400662306a36Sopenharmony_ci *
400762306a36Sopenharmony_ci * Mark the PCI region associated with PCI device @pdev BAR @bar as
400862306a36Sopenharmony_ci * being reserved by owner @res_name.  Do not access any
400962306a36Sopenharmony_ci * address inside the PCI regions unless this call returns
401062306a36Sopenharmony_ci * successfully.
401162306a36Sopenharmony_ci *
401262306a36Sopenharmony_ci * If @exclusive is set, then the region is marked so that userspace
401362306a36Sopenharmony_ci * is explicitly not allowed to map the resource via /dev/mem or
401462306a36Sopenharmony_ci * sysfs MMIO access.
401562306a36Sopenharmony_ci *
401662306a36Sopenharmony_ci * Returns 0 on success, or %EBUSY on error.  A warning
401762306a36Sopenharmony_ci * message is also printed on failure.
401862306a36Sopenharmony_ci */
401962306a36Sopenharmony_cistatic int __pci_request_region(struct pci_dev *pdev, int bar,
402062306a36Sopenharmony_ci				const char *res_name, int exclusive)
402162306a36Sopenharmony_ci{
402262306a36Sopenharmony_ci	struct pci_devres *dr;
402362306a36Sopenharmony_ci
402462306a36Sopenharmony_ci	if (pci_resource_len(pdev, bar) == 0)
402562306a36Sopenharmony_ci		return 0;
402662306a36Sopenharmony_ci
402762306a36Sopenharmony_ci	if (pci_resource_flags(pdev, bar) & IORESOURCE_IO) {
402862306a36Sopenharmony_ci		if (!request_region(pci_resource_start(pdev, bar),
402962306a36Sopenharmony_ci			    pci_resource_len(pdev, bar), res_name))
403062306a36Sopenharmony_ci			goto err_out;
403162306a36Sopenharmony_ci	} else if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
403262306a36Sopenharmony_ci		if (!__request_mem_region(pci_resource_start(pdev, bar),
403362306a36Sopenharmony_ci					pci_resource_len(pdev, bar), res_name,
403462306a36Sopenharmony_ci					exclusive))
403562306a36Sopenharmony_ci			goto err_out;
403662306a36Sopenharmony_ci	}
403762306a36Sopenharmony_ci
403862306a36Sopenharmony_ci	dr = find_pci_dr(pdev);
403962306a36Sopenharmony_ci	if (dr)
404062306a36Sopenharmony_ci		dr->region_mask |= 1 << bar;
404162306a36Sopenharmony_ci
404262306a36Sopenharmony_ci	return 0;
404362306a36Sopenharmony_ci
404462306a36Sopenharmony_cierr_out:
404562306a36Sopenharmony_ci	pci_warn(pdev, "BAR %d: can't reserve %pR\n", bar,
404662306a36Sopenharmony_ci		 &pdev->resource[bar]);
404762306a36Sopenharmony_ci	return -EBUSY;
404862306a36Sopenharmony_ci}
404962306a36Sopenharmony_ci
405062306a36Sopenharmony_ci/**
405162306a36Sopenharmony_ci * pci_request_region - Reserve PCI I/O and memory resource
405262306a36Sopenharmony_ci * @pdev: PCI device whose resources are to be reserved
405362306a36Sopenharmony_ci * @bar: BAR to be reserved
405462306a36Sopenharmony_ci * @res_name: Name to be associated with resource
405562306a36Sopenharmony_ci *
405662306a36Sopenharmony_ci * Mark the PCI region associated with PCI device @pdev BAR @bar as
405762306a36Sopenharmony_ci * being reserved by owner @res_name.  Do not access any
405862306a36Sopenharmony_ci * address inside the PCI regions unless this call returns
405962306a36Sopenharmony_ci * successfully.
406062306a36Sopenharmony_ci *
406162306a36Sopenharmony_ci * Returns 0 on success, or %EBUSY on error.  A warning
406262306a36Sopenharmony_ci * message is also printed on failure.
406362306a36Sopenharmony_ci */
406462306a36Sopenharmony_ciint pci_request_region(struct pci_dev *pdev, int bar, const char *res_name)
406562306a36Sopenharmony_ci{
406662306a36Sopenharmony_ci	return __pci_request_region(pdev, bar, res_name, 0);
406762306a36Sopenharmony_ci}
406862306a36Sopenharmony_ciEXPORT_SYMBOL(pci_request_region);
406962306a36Sopenharmony_ci
407062306a36Sopenharmony_ci/**
407162306a36Sopenharmony_ci * pci_release_selected_regions - Release selected PCI I/O and memory resources
407262306a36Sopenharmony_ci * @pdev: PCI device whose resources were previously reserved
407362306a36Sopenharmony_ci * @bars: Bitmask of BARs to be released
407462306a36Sopenharmony_ci *
407562306a36Sopenharmony_ci * Release selected PCI I/O and memory resources previously reserved.
407662306a36Sopenharmony_ci * Call this function only after all use of the PCI regions has ceased.
407762306a36Sopenharmony_ci */
407862306a36Sopenharmony_civoid pci_release_selected_regions(struct pci_dev *pdev, int bars)
407962306a36Sopenharmony_ci{
408062306a36Sopenharmony_ci	int i;
408162306a36Sopenharmony_ci
408262306a36Sopenharmony_ci	for (i = 0; i < PCI_STD_NUM_BARS; i++)
408362306a36Sopenharmony_ci		if (bars & (1 << i))
408462306a36Sopenharmony_ci			pci_release_region(pdev, i);
408562306a36Sopenharmony_ci}
408662306a36Sopenharmony_ciEXPORT_SYMBOL(pci_release_selected_regions);
408762306a36Sopenharmony_ci
408862306a36Sopenharmony_cistatic int __pci_request_selected_regions(struct pci_dev *pdev, int bars,
408962306a36Sopenharmony_ci					  const char *res_name, int excl)
409062306a36Sopenharmony_ci{
409162306a36Sopenharmony_ci	int i;
409262306a36Sopenharmony_ci
409362306a36Sopenharmony_ci	for (i = 0; i < PCI_STD_NUM_BARS; i++)
409462306a36Sopenharmony_ci		if (bars & (1 << i))
409562306a36Sopenharmony_ci			if (__pci_request_region(pdev, i, res_name, excl))
409662306a36Sopenharmony_ci				goto err_out;
409762306a36Sopenharmony_ci	return 0;
409862306a36Sopenharmony_ci
409962306a36Sopenharmony_cierr_out:
410062306a36Sopenharmony_ci	while (--i >= 0)
410162306a36Sopenharmony_ci		if (bars & (1 << i))
410262306a36Sopenharmony_ci			pci_release_region(pdev, i);
410362306a36Sopenharmony_ci
410462306a36Sopenharmony_ci	return -EBUSY;
410562306a36Sopenharmony_ci}
410662306a36Sopenharmony_ci
410762306a36Sopenharmony_ci
410862306a36Sopenharmony_ci/**
410962306a36Sopenharmony_ci * pci_request_selected_regions - Reserve selected PCI I/O and memory resources
411062306a36Sopenharmony_ci * @pdev: PCI device whose resources are to be reserved
411162306a36Sopenharmony_ci * @bars: Bitmask of BARs to be requested
411262306a36Sopenharmony_ci * @res_name: Name to be associated with resource
411362306a36Sopenharmony_ci */
411462306a36Sopenharmony_ciint pci_request_selected_regions(struct pci_dev *pdev, int bars,
411562306a36Sopenharmony_ci				 const char *res_name)
411662306a36Sopenharmony_ci{
411762306a36Sopenharmony_ci	return __pci_request_selected_regions(pdev, bars, res_name, 0);
411862306a36Sopenharmony_ci}
411962306a36Sopenharmony_ciEXPORT_SYMBOL(pci_request_selected_regions);
412062306a36Sopenharmony_ci
412162306a36Sopenharmony_ciint pci_request_selected_regions_exclusive(struct pci_dev *pdev, int bars,
412262306a36Sopenharmony_ci					   const char *res_name)
412362306a36Sopenharmony_ci{
412462306a36Sopenharmony_ci	return __pci_request_selected_regions(pdev, bars, res_name,
412562306a36Sopenharmony_ci			IORESOURCE_EXCLUSIVE);
412662306a36Sopenharmony_ci}
412762306a36Sopenharmony_ciEXPORT_SYMBOL(pci_request_selected_regions_exclusive);
412862306a36Sopenharmony_ci
412962306a36Sopenharmony_ci/**
413062306a36Sopenharmony_ci * pci_release_regions - Release reserved PCI I/O and memory resources
413162306a36Sopenharmony_ci * @pdev: PCI device whose resources were previously reserved by
413262306a36Sopenharmony_ci *	  pci_request_regions()
413362306a36Sopenharmony_ci *
413462306a36Sopenharmony_ci * Releases all PCI I/O and memory resources previously reserved by a
413562306a36Sopenharmony_ci * successful call to pci_request_regions().  Call this function only
413662306a36Sopenharmony_ci * after all use of the PCI regions has ceased.
413762306a36Sopenharmony_ci */
413862306a36Sopenharmony_ci
413962306a36Sopenharmony_civoid pci_release_regions(struct pci_dev *pdev)
414062306a36Sopenharmony_ci{
414162306a36Sopenharmony_ci	pci_release_selected_regions(pdev, (1 << PCI_STD_NUM_BARS) - 1);
414262306a36Sopenharmony_ci}
414362306a36Sopenharmony_ciEXPORT_SYMBOL(pci_release_regions);
414462306a36Sopenharmony_ci
414562306a36Sopenharmony_ci/**
414662306a36Sopenharmony_ci * pci_request_regions - Reserve PCI I/O and memory resources
414762306a36Sopenharmony_ci * @pdev: PCI device whose resources are to be reserved
414862306a36Sopenharmony_ci * @res_name: Name to be associated with resource.
414962306a36Sopenharmony_ci *
415062306a36Sopenharmony_ci * Mark all PCI regions associated with PCI device @pdev as
415162306a36Sopenharmony_ci * being reserved by owner @res_name.  Do not access any
415262306a36Sopenharmony_ci * address inside the PCI regions unless this call returns
415362306a36Sopenharmony_ci * successfully.
415462306a36Sopenharmony_ci *
415562306a36Sopenharmony_ci * Returns 0 on success, or %EBUSY on error.  A warning
415662306a36Sopenharmony_ci * message is also printed on failure.
415762306a36Sopenharmony_ci */
415862306a36Sopenharmony_ciint pci_request_regions(struct pci_dev *pdev, const char *res_name)
415962306a36Sopenharmony_ci{
416062306a36Sopenharmony_ci	return pci_request_selected_regions(pdev,
416162306a36Sopenharmony_ci			((1 << PCI_STD_NUM_BARS) - 1), res_name);
416262306a36Sopenharmony_ci}
416362306a36Sopenharmony_ciEXPORT_SYMBOL(pci_request_regions);
416462306a36Sopenharmony_ci
416562306a36Sopenharmony_ci/**
416662306a36Sopenharmony_ci * pci_request_regions_exclusive - Reserve PCI I/O and memory resources
416762306a36Sopenharmony_ci * @pdev: PCI device whose resources are to be reserved
416862306a36Sopenharmony_ci * @res_name: Name to be associated with resource.
416962306a36Sopenharmony_ci *
417062306a36Sopenharmony_ci * Mark all PCI regions associated with PCI device @pdev as being reserved
417162306a36Sopenharmony_ci * by owner @res_name.  Do not access any address inside the PCI regions
417262306a36Sopenharmony_ci * unless this call returns successfully.
417362306a36Sopenharmony_ci *
417462306a36Sopenharmony_ci * pci_request_regions_exclusive() will mark the region so that /dev/mem
417562306a36Sopenharmony_ci * and the sysfs MMIO access will not be allowed.
417662306a36Sopenharmony_ci *
417762306a36Sopenharmony_ci * Returns 0 on success, or %EBUSY on error.  A warning message is also
417862306a36Sopenharmony_ci * printed on failure.
417962306a36Sopenharmony_ci */
418062306a36Sopenharmony_ciint pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name)
418162306a36Sopenharmony_ci{
418262306a36Sopenharmony_ci	return pci_request_selected_regions_exclusive(pdev,
418362306a36Sopenharmony_ci				((1 << PCI_STD_NUM_BARS) - 1), res_name);
418462306a36Sopenharmony_ci}
418562306a36Sopenharmony_ciEXPORT_SYMBOL(pci_request_regions_exclusive);
418662306a36Sopenharmony_ci
418762306a36Sopenharmony_ci/*
418862306a36Sopenharmony_ci * Record the PCI IO range (expressed as CPU physical address + size).
418962306a36Sopenharmony_ci * Return a negative value if an error has occurred, zero otherwise
419062306a36Sopenharmony_ci */
419162306a36Sopenharmony_ciint pci_register_io_range(struct fwnode_handle *fwnode, phys_addr_t addr,
419262306a36Sopenharmony_ci			resource_size_t	size)
419362306a36Sopenharmony_ci{
419462306a36Sopenharmony_ci	int ret = 0;
419562306a36Sopenharmony_ci#ifdef PCI_IOBASE
419662306a36Sopenharmony_ci	struct logic_pio_hwaddr *range;
419762306a36Sopenharmony_ci
419862306a36Sopenharmony_ci	if (!size || addr + size < addr)
419962306a36Sopenharmony_ci		return -EINVAL;
420062306a36Sopenharmony_ci
420162306a36Sopenharmony_ci	range = kzalloc(sizeof(*range), GFP_ATOMIC);
420262306a36Sopenharmony_ci	if (!range)
420362306a36Sopenharmony_ci		return -ENOMEM;
420462306a36Sopenharmony_ci
420562306a36Sopenharmony_ci	range->fwnode = fwnode;
420662306a36Sopenharmony_ci	range->size = size;
420762306a36Sopenharmony_ci	range->hw_start = addr;
420862306a36Sopenharmony_ci	range->flags = LOGIC_PIO_CPU_MMIO;
420962306a36Sopenharmony_ci
421062306a36Sopenharmony_ci	ret = logic_pio_register_range(range);
421162306a36Sopenharmony_ci	if (ret)
421262306a36Sopenharmony_ci		kfree(range);
421362306a36Sopenharmony_ci
421462306a36Sopenharmony_ci	/* Ignore duplicates due to deferred probing */
421562306a36Sopenharmony_ci	if (ret == -EEXIST)
421662306a36Sopenharmony_ci		ret = 0;
421762306a36Sopenharmony_ci#endif
421862306a36Sopenharmony_ci
421962306a36Sopenharmony_ci	return ret;
422062306a36Sopenharmony_ci}
422162306a36Sopenharmony_ci
422262306a36Sopenharmony_ciphys_addr_t pci_pio_to_address(unsigned long pio)
422362306a36Sopenharmony_ci{
422462306a36Sopenharmony_ci#ifdef PCI_IOBASE
422562306a36Sopenharmony_ci	if (pio < MMIO_UPPER_LIMIT)
422662306a36Sopenharmony_ci		return logic_pio_to_hwaddr(pio);
422762306a36Sopenharmony_ci#endif
422862306a36Sopenharmony_ci
422962306a36Sopenharmony_ci	return (phys_addr_t) OF_BAD_ADDR;
423062306a36Sopenharmony_ci}
423162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_pio_to_address);
423262306a36Sopenharmony_ci
423362306a36Sopenharmony_ciunsigned long __weak pci_address_to_pio(phys_addr_t address)
423462306a36Sopenharmony_ci{
423562306a36Sopenharmony_ci#ifdef PCI_IOBASE
423662306a36Sopenharmony_ci	return logic_pio_trans_cpuaddr(address);
423762306a36Sopenharmony_ci#else
423862306a36Sopenharmony_ci	if (address > IO_SPACE_LIMIT)
423962306a36Sopenharmony_ci		return (unsigned long)-1;
424062306a36Sopenharmony_ci
424162306a36Sopenharmony_ci	return (unsigned long) address;
424262306a36Sopenharmony_ci#endif
424362306a36Sopenharmony_ci}
424462306a36Sopenharmony_ci
424562306a36Sopenharmony_ci/**
424662306a36Sopenharmony_ci * pci_remap_iospace - Remap the memory mapped I/O space
424762306a36Sopenharmony_ci * @res: Resource describing the I/O space
424862306a36Sopenharmony_ci * @phys_addr: physical address of range to be mapped
424962306a36Sopenharmony_ci *
425062306a36Sopenharmony_ci * Remap the memory mapped I/O space described by the @res and the CPU
425162306a36Sopenharmony_ci * physical address @phys_addr into virtual address space.  Only
425262306a36Sopenharmony_ci * architectures that have memory mapped IO functions defined (and the
425362306a36Sopenharmony_ci * PCI_IOBASE value defined) should call this function.
425462306a36Sopenharmony_ci */
425562306a36Sopenharmony_ci#ifndef pci_remap_iospace
425662306a36Sopenharmony_ciint pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr)
425762306a36Sopenharmony_ci{
425862306a36Sopenharmony_ci#if defined(PCI_IOBASE) && defined(CONFIG_MMU)
425962306a36Sopenharmony_ci	unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start;
426062306a36Sopenharmony_ci
426162306a36Sopenharmony_ci	if (!(res->flags & IORESOURCE_IO))
426262306a36Sopenharmony_ci		return -EINVAL;
426362306a36Sopenharmony_ci
426462306a36Sopenharmony_ci	if (res->end > IO_SPACE_LIMIT)
426562306a36Sopenharmony_ci		return -EINVAL;
426662306a36Sopenharmony_ci
426762306a36Sopenharmony_ci	return ioremap_page_range(vaddr, vaddr + resource_size(res), phys_addr,
426862306a36Sopenharmony_ci				  pgprot_device(PAGE_KERNEL));
426962306a36Sopenharmony_ci#else
427062306a36Sopenharmony_ci	/*
427162306a36Sopenharmony_ci	 * This architecture does not have memory mapped I/O space,
427262306a36Sopenharmony_ci	 * so this function should never be called
427362306a36Sopenharmony_ci	 */
427462306a36Sopenharmony_ci	WARN_ONCE(1, "This architecture does not support memory mapped I/O\n");
427562306a36Sopenharmony_ci	return -ENODEV;
427662306a36Sopenharmony_ci#endif
427762306a36Sopenharmony_ci}
427862306a36Sopenharmony_ciEXPORT_SYMBOL(pci_remap_iospace);
427962306a36Sopenharmony_ci#endif
428062306a36Sopenharmony_ci
428162306a36Sopenharmony_ci/**
428262306a36Sopenharmony_ci * pci_unmap_iospace - Unmap the memory mapped I/O space
428362306a36Sopenharmony_ci * @res: resource to be unmapped
428462306a36Sopenharmony_ci *
428562306a36Sopenharmony_ci * Unmap the CPU virtual address @res from virtual address space.  Only
428662306a36Sopenharmony_ci * architectures that have memory mapped IO functions defined (and the
428762306a36Sopenharmony_ci * PCI_IOBASE value defined) should call this function.
428862306a36Sopenharmony_ci */
428962306a36Sopenharmony_civoid pci_unmap_iospace(struct resource *res)
429062306a36Sopenharmony_ci{
429162306a36Sopenharmony_ci#if defined(PCI_IOBASE) && defined(CONFIG_MMU)
429262306a36Sopenharmony_ci	unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start;
429362306a36Sopenharmony_ci
429462306a36Sopenharmony_ci	vunmap_range(vaddr, vaddr + resource_size(res));
429562306a36Sopenharmony_ci#endif
429662306a36Sopenharmony_ci}
429762306a36Sopenharmony_ciEXPORT_SYMBOL(pci_unmap_iospace);
429862306a36Sopenharmony_ci
429962306a36Sopenharmony_cistatic void devm_pci_unmap_iospace(struct device *dev, void *ptr)
430062306a36Sopenharmony_ci{
430162306a36Sopenharmony_ci	struct resource **res = ptr;
430262306a36Sopenharmony_ci
430362306a36Sopenharmony_ci	pci_unmap_iospace(*res);
430462306a36Sopenharmony_ci}
430562306a36Sopenharmony_ci
430662306a36Sopenharmony_ci/**
430762306a36Sopenharmony_ci * devm_pci_remap_iospace - Managed pci_remap_iospace()
430862306a36Sopenharmony_ci * @dev: Generic device to remap IO address for
430962306a36Sopenharmony_ci * @res: Resource describing the I/O space
431062306a36Sopenharmony_ci * @phys_addr: physical address of range to be mapped
431162306a36Sopenharmony_ci *
431262306a36Sopenharmony_ci * Managed pci_remap_iospace().  Map is automatically unmapped on driver
431362306a36Sopenharmony_ci * detach.
431462306a36Sopenharmony_ci */
431562306a36Sopenharmony_ciint devm_pci_remap_iospace(struct device *dev, const struct resource *res,
431662306a36Sopenharmony_ci			   phys_addr_t phys_addr)
431762306a36Sopenharmony_ci{
431862306a36Sopenharmony_ci	const struct resource **ptr;
431962306a36Sopenharmony_ci	int error;
432062306a36Sopenharmony_ci
432162306a36Sopenharmony_ci	ptr = devres_alloc(devm_pci_unmap_iospace, sizeof(*ptr), GFP_KERNEL);
432262306a36Sopenharmony_ci	if (!ptr)
432362306a36Sopenharmony_ci		return -ENOMEM;
432462306a36Sopenharmony_ci
432562306a36Sopenharmony_ci	error = pci_remap_iospace(res, phys_addr);
432662306a36Sopenharmony_ci	if (error) {
432762306a36Sopenharmony_ci		devres_free(ptr);
432862306a36Sopenharmony_ci	} else	{
432962306a36Sopenharmony_ci		*ptr = res;
433062306a36Sopenharmony_ci		devres_add(dev, ptr);
433162306a36Sopenharmony_ci	}
433262306a36Sopenharmony_ci
433362306a36Sopenharmony_ci	return error;
433462306a36Sopenharmony_ci}
433562306a36Sopenharmony_ciEXPORT_SYMBOL(devm_pci_remap_iospace);
433662306a36Sopenharmony_ci
433762306a36Sopenharmony_ci/**
433862306a36Sopenharmony_ci * devm_pci_remap_cfgspace - Managed pci_remap_cfgspace()
433962306a36Sopenharmony_ci * @dev: Generic device to remap IO address for
434062306a36Sopenharmony_ci * @offset: Resource address to map
434162306a36Sopenharmony_ci * @size: Size of map
434262306a36Sopenharmony_ci *
434362306a36Sopenharmony_ci * Managed pci_remap_cfgspace().  Map is automatically unmapped on driver
434462306a36Sopenharmony_ci * detach.
434562306a36Sopenharmony_ci */
434662306a36Sopenharmony_civoid __iomem *devm_pci_remap_cfgspace(struct device *dev,
434762306a36Sopenharmony_ci				      resource_size_t offset,
434862306a36Sopenharmony_ci				      resource_size_t size)
434962306a36Sopenharmony_ci{
435062306a36Sopenharmony_ci	void __iomem **ptr, *addr;
435162306a36Sopenharmony_ci
435262306a36Sopenharmony_ci	ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
435362306a36Sopenharmony_ci	if (!ptr)
435462306a36Sopenharmony_ci		return NULL;
435562306a36Sopenharmony_ci
435662306a36Sopenharmony_ci	addr = pci_remap_cfgspace(offset, size);
435762306a36Sopenharmony_ci	if (addr) {
435862306a36Sopenharmony_ci		*ptr = addr;
435962306a36Sopenharmony_ci		devres_add(dev, ptr);
436062306a36Sopenharmony_ci	} else
436162306a36Sopenharmony_ci		devres_free(ptr);
436262306a36Sopenharmony_ci
436362306a36Sopenharmony_ci	return addr;
436462306a36Sopenharmony_ci}
436562306a36Sopenharmony_ciEXPORT_SYMBOL(devm_pci_remap_cfgspace);
436662306a36Sopenharmony_ci
436762306a36Sopenharmony_ci/**
436862306a36Sopenharmony_ci * devm_pci_remap_cfg_resource - check, request region and ioremap cfg resource
436962306a36Sopenharmony_ci * @dev: generic device to handle the resource for
437062306a36Sopenharmony_ci * @res: configuration space resource to be handled
437162306a36Sopenharmony_ci *
437262306a36Sopenharmony_ci * Checks that a resource is a valid memory region, requests the memory
437362306a36Sopenharmony_ci * region and ioremaps with pci_remap_cfgspace() API that ensures the
437462306a36Sopenharmony_ci * proper PCI configuration space memory attributes are guaranteed.
437562306a36Sopenharmony_ci *
437662306a36Sopenharmony_ci * All operations are managed and will be undone on driver detach.
437762306a36Sopenharmony_ci *
437862306a36Sopenharmony_ci * Returns a pointer to the remapped memory or an ERR_PTR() encoded error code
437962306a36Sopenharmony_ci * on failure. Usage example::
438062306a36Sopenharmony_ci *
438162306a36Sopenharmony_ci *	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
438262306a36Sopenharmony_ci *	base = devm_pci_remap_cfg_resource(&pdev->dev, res);
438362306a36Sopenharmony_ci *	if (IS_ERR(base))
438462306a36Sopenharmony_ci *		return PTR_ERR(base);
438562306a36Sopenharmony_ci */
438662306a36Sopenharmony_civoid __iomem *devm_pci_remap_cfg_resource(struct device *dev,
438762306a36Sopenharmony_ci					  struct resource *res)
438862306a36Sopenharmony_ci{
438962306a36Sopenharmony_ci	resource_size_t size;
439062306a36Sopenharmony_ci	const char *name;
439162306a36Sopenharmony_ci	void __iomem *dest_ptr;
439262306a36Sopenharmony_ci
439362306a36Sopenharmony_ci	BUG_ON(!dev);
439462306a36Sopenharmony_ci
439562306a36Sopenharmony_ci	if (!res || resource_type(res) != IORESOURCE_MEM) {
439662306a36Sopenharmony_ci		dev_err(dev, "invalid resource\n");
439762306a36Sopenharmony_ci		return IOMEM_ERR_PTR(-EINVAL);
439862306a36Sopenharmony_ci	}
439962306a36Sopenharmony_ci
440062306a36Sopenharmony_ci	size = resource_size(res);
440162306a36Sopenharmony_ci
440262306a36Sopenharmony_ci	if (res->name)
440362306a36Sopenharmony_ci		name = devm_kasprintf(dev, GFP_KERNEL, "%s %s", dev_name(dev),
440462306a36Sopenharmony_ci				      res->name);
440562306a36Sopenharmony_ci	else
440662306a36Sopenharmony_ci		name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
440762306a36Sopenharmony_ci	if (!name)
440862306a36Sopenharmony_ci		return IOMEM_ERR_PTR(-ENOMEM);
440962306a36Sopenharmony_ci
441062306a36Sopenharmony_ci	if (!devm_request_mem_region(dev, res->start, size, name)) {
441162306a36Sopenharmony_ci		dev_err(dev, "can't request region for resource %pR\n", res);
441262306a36Sopenharmony_ci		return IOMEM_ERR_PTR(-EBUSY);
441362306a36Sopenharmony_ci	}
441462306a36Sopenharmony_ci
441562306a36Sopenharmony_ci	dest_ptr = devm_pci_remap_cfgspace(dev, res->start, size);
441662306a36Sopenharmony_ci	if (!dest_ptr) {
441762306a36Sopenharmony_ci		dev_err(dev, "ioremap failed for resource %pR\n", res);
441862306a36Sopenharmony_ci		devm_release_mem_region(dev, res->start, size);
441962306a36Sopenharmony_ci		dest_ptr = IOMEM_ERR_PTR(-ENOMEM);
442062306a36Sopenharmony_ci	}
442162306a36Sopenharmony_ci
442262306a36Sopenharmony_ci	return dest_ptr;
442362306a36Sopenharmony_ci}
442462306a36Sopenharmony_ciEXPORT_SYMBOL(devm_pci_remap_cfg_resource);
442562306a36Sopenharmony_ci
442662306a36Sopenharmony_cistatic void __pci_set_master(struct pci_dev *dev, bool enable)
442762306a36Sopenharmony_ci{
442862306a36Sopenharmony_ci	u16 old_cmd, cmd;
442962306a36Sopenharmony_ci
443062306a36Sopenharmony_ci	pci_read_config_word(dev, PCI_COMMAND, &old_cmd);
443162306a36Sopenharmony_ci	if (enable)
443262306a36Sopenharmony_ci		cmd = old_cmd | PCI_COMMAND_MASTER;
443362306a36Sopenharmony_ci	else
443462306a36Sopenharmony_ci		cmd = old_cmd & ~PCI_COMMAND_MASTER;
443562306a36Sopenharmony_ci	if (cmd != old_cmd) {
443662306a36Sopenharmony_ci		pci_dbg(dev, "%s bus mastering\n",
443762306a36Sopenharmony_ci			enable ? "enabling" : "disabling");
443862306a36Sopenharmony_ci		pci_write_config_word(dev, PCI_COMMAND, cmd);
443962306a36Sopenharmony_ci	}
444062306a36Sopenharmony_ci	dev->is_busmaster = enable;
444162306a36Sopenharmony_ci}
444262306a36Sopenharmony_ci
444362306a36Sopenharmony_ci/**
444462306a36Sopenharmony_ci * pcibios_setup - process "pci=" kernel boot arguments
444562306a36Sopenharmony_ci * @str: string used to pass in "pci=" kernel boot arguments
444662306a36Sopenharmony_ci *
444762306a36Sopenharmony_ci * Process kernel boot arguments.  This is the default implementation.
444862306a36Sopenharmony_ci * Architecture specific implementations can override this as necessary.
444962306a36Sopenharmony_ci */
445062306a36Sopenharmony_cichar * __weak __init pcibios_setup(char *str)
445162306a36Sopenharmony_ci{
445262306a36Sopenharmony_ci	return str;
445362306a36Sopenharmony_ci}
445462306a36Sopenharmony_ci
445562306a36Sopenharmony_ci/**
445662306a36Sopenharmony_ci * pcibios_set_master - enable PCI bus-mastering for device dev
445762306a36Sopenharmony_ci * @dev: the PCI device to enable
445862306a36Sopenharmony_ci *
445962306a36Sopenharmony_ci * Enables PCI bus-mastering for the device.  This is the default
446062306a36Sopenharmony_ci * implementation.  Architecture specific implementations can override
446162306a36Sopenharmony_ci * this if necessary.
446262306a36Sopenharmony_ci */
446362306a36Sopenharmony_civoid __weak pcibios_set_master(struct pci_dev *dev)
446462306a36Sopenharmony_ci{
446562306a36Sopenharmony_ci	u8 lat;
446662306a36Sopenharmony_ci
446762306a36Sopenharmony_ci	/* The latency timer doesn't apply to PCIe (either Type 0 or Type 1) */
446862306a36Sopenharmony_ci	if (pci_is_pcie(dev))
446962306a36Sopenharmony_ci		return;
447062306a36Sopenharmony_ci
447162306a36Sopenharmony_ci	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
447262306a36Sopenharmony_ci	if (lat < 16)
447362306a36Sopenharmony_ci		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
447462306a36Sopenharmony_ci	else if (lat > pcibios_max_latency)
447562306a36Sopenharmony_ci		lat = pcibios_max_latency;
447662306a36Sopenharmony_ci	else
447762306a36Sopenharmony_ci		return;
447862306a36Sopenharmony_ci
447962306a36Sopenharmony_ci	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
448062306a36Sopenharmony_ci}
448162306a36Sopenharmony_ci
448262306a36Sopenharmony_ci/**
448362306a36Sopenharmony_ci * pci_set_master - enables bus-mastering for device dev
448462306a36Sopenharmony_ci * @dev: the PCI device to enable
448562306a36Sopenharmony_ci *
448662306a36Sopenharmony_ci * Enables bus-mastering on the device and calls pcibios_set_master()
448762306a36Sopenharmony_ci * to do the needed arch specific settings.
448862306a36Sopenharmony_ci */
448962306a36Sopenharmony_civoid pci_set_master(struct pci_dev *dev)
449062306a36Sopenharmony_ci{
449162306a36Sopenharmony_ci	__pci_set_master(dev, true);
449262306a36Sopenharmony_ci	pcibios_set_master(dev);
449362306a36Sopenharmony_ci}
449462306a36Sopenharmony_ciEXPORT_SYMBOL(pci_set_master);
449562306a36Sopenharmony_ci
449662306a36Sopenharmony_ci/**
449762306a36Sopenharmony_ci * pci_clear_master - disables bus-mastering for device dev
449862306a36Sopenharmony_ci * @dev: the PCI device to disable
449962306a36Sopenharmony_ci */
450062306a36Sopenharmony_civoid pci_clear_master(struct pci_dev *dev)
450162306a36Sopenharmony_ci{
450262306a36Sopenharmony_ci	__pci_set_master(dev, false);
450362306a36Sopenharmony_ci}
450462306a36Sopenharmony_ciEXPORT_SYMBOL(pci_clear_master);
450562306a36Sopenharmony_ci
450662306a36Sopenharmony_ci/**
450762306a36Sopenharmony_ci * pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed
450862306a36Sopenharmony_ci * @dev: the PCI device for which MWI is to be enabled
450962306a36Sopenharmony_ci *
451062306a36Sopenharmony_ci * Helper function for pci_set_mwi.
451162306a36Sopenharmony_ci * Originally copied from drivers/net/acenic.c.
451262306a36Sopenharmony_ci * Copyright 1998-2001 by Jes Sorensen, <jes@trained-monkey.org>.
451362306a36Sopenharmony_ci *
451462306a36Sopenharmony_ci * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
451562306a36Sopenharmony_ci */
451662306a36Sopenharmony_ciint pci_set_cacheline_size(struct pci_dev *dev)
451762306a36Sopenharmony_ci{
451862306a36Sopenharmony_ci	u8 cacheline_size;
451962306a36Sopenharmony_ci
452062306a36Sopenharmony_ci	if (!pci_cache_line_size)
452162306a36Sopenharmony_ci		return -EINVAL;
452262306a36Sopenharmony_ci
452362306a36Sopenharmony_ci	/* Validate current setting: the PCI_CACHE_LINE_SIZE must be
452462306a36Sopenharmony_ci	   equal to or multiple of the right value. */
452562306a36Sopenharmony_ci	pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cacheline_size);
452662306a36Sopenharmony_ci	if (cacheline_size >= pci_cache_line_size &&
452762306a36Sopenharmony_ci	    (cacheline_size % pci_cache_line_size) == 0)
452862306a36Sopenharmony_ci		return 0;
452962306a36Sopenharmony_ci
453062306a36Sopenharmony_ci	/* Write the correct value. */
453162306a36Sopenharmony_ci	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cache_line_size);
453262306a36Sopenharmony_ci	/* Read it back. */
453362306a36Sopenharmony_ci	pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cacheline_size);
453462306a36Sopenharmony_ci	if (cacheline_size == pci_cache_line_size)
453562306a36Sopenharmony_ci		return 0;
453662306a36Sopenharmony_ci
453762306a36Sopenharmony_ci	pci_dbg(dev, "cache line size of %d is not supported\n",
453862306a36Sopenharmony_ci		   pci_cache_line_size << 2);
453962306a36Sopenharmony_ci
454062306a36Sopenharmony_ci	return -EINVAL;
454162306a36Sopenharmony_ci}
454262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_set_cacheline_size);
454362306a36Sopenharmony_ci
454462306a36Sopenharmony_ci/**
454562306a36Sopenharmony_ci * pci_set_mwi - enables memory-write-invalidate PCI transaction
454662306a36Sopenharmony_ci * @dev: the PCI device for which MWI is enabled
454762306a36Sopenharmony_ci *
454862306a36Sopenharmony_ci * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND.
454962306a36Sopenharmony_ci *
455062306a36Sopenharmony_ci * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
455162306a36Sopenharmony_ci */
455262306a36Sopenharmony_ciint pci_set_mwi(struct pci_dev *dev)
455362306a36Sopenharmony_ci{
455462306a36Sopenharmony_ci#ifdef PCI_DISABLE_MWI
455562306a36Sopenharmony_ci	return 0;
455662306a36Sopenharmony_ci#else
455762306a36Sopenharmony_ci	int rc;
455862306a36Sopenharmony_ci	u16 cmd;
455962306a36Sopenharmony_ci
456062306a36Sopenharmony_ci	rc = pci_set_cacheline_size(dev);
456162306a36Sopenharmony_ci	if (rc)
456262306a36Sopenharmony_ci		return rc;
456362306a36Sopenharmony_ci
456462306a36Sopenharmony_ci	pci_read_config_word(dev, PCI_COMMAND, &cmd);
456562306a36Sopenharmony_ci	if (!(cmd & PCI_COMMAND_INVALIDATE)) {
456662306a36Sopenharmony_ci		pci_dbg(dev, "enabling Mem-Wr-Inval\n");
456762306a36Sopenharmony_ci		cmd |= PCI_COMMAND_INVALIDATE;
456862306a36Sopenharmony_ci		pci_write_config_word(dev, PCI_COMMAND, cmd);
456962306a36Sopenharmony_ci	}
457062306a36Sopenharmony_ci	return 0;
457162306a36Sopenharmony_ci#endif
457262306a36Sopenharmony_ci}
457362306a36Sopenharmony_ciEXPORT_SYMBOL(pci_set_mwi);
457462306a36Sopenharmony_ci
457562306a36Sopenharmony_ci/**
457662306a36Sopenharmony_ci * pcim_set_mwi - a device-managed pci_set_mwi()
457762306a36Sopenharmony_ci * @dev: the PCI device for which MWI is enabled
457862306a36Sopenharmony_ci *
457962306a36Sopenharmony_ci * Managed pci_set_mwi().
458062306a36Sopenharmony_ci *
458162306a36Sopenharmony_ci * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
458262306a36Sopenharmony_ci */
458362306a36Sopenharmony_ciint pcim_set_mwi(struct pci_dev *dev)
458462306a36Sopenharmony_ci{
458562306a36Sopenharmony_ci	struct pci_devres *dr;
458662306a36Sopenharmony_ci
458762306a36Sopenharmony_ci	dr = find_pci_dr(dev);
458862306a36Sopenharmony_ci	if (!dr)
458962306a36Sopenharmony_ci		return -ENOMEM;
459062306a36Sopenharmony_ci
459162306a36Sopenharmony_ci	dr->mwi = 1;
459262306a36Sopenharmony_ci	return pci_set_mwi(dev);
459362306a36Sopenharmony_ci}
459462306a36Sopenharmony_ciEXPORT_SYMBOL(pcim_set_mwi);
459562306a36Sopenharmony_ci
459662306a36Sopenharmony_ci/**
459762306a36Sopenharmony_ci * pci_try_set_mwi - enables memory-write-invalidate PCI transaction
459862306a36Sopenharmony_ci * @dev: the PCI device for which MWI is enabled
459962306a36Sopenharmony_ci *
460062306a36Sopenharmony_ci * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND.
460162306a36Sopenharmony_ci * Callers are not required to check the return value.
460262306a36Sopenharmony_ci *
460362306a36Sopenharmony_ci * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
460462306a36Sopenharmony_ci */
460562306a36Sopenharmony_ciint pci_try_set_mwi(struct pci_dev *dev)
460662306a36Sopenharmony_ci{
460762306a36Sopenharmony_ci#ifdef PCI_DISABLE_MWI
460862306a36Sopenharmony_ci	return 0;
460962306a36Sopenharmony_ci#else
461062306a36Sopenharmony_ci	return pci_set_mwi(dev);
461162306a36Sopenharmony_ci#endif
461262306a36Sopenharmony_ci}
461362306a36Sopenharmony_ciEXPORT_SYMBOL(pci_try_set_mwi);
461462306a36Sopenharmony_ci
461562306a36Sopenharmony_ci/**
461662306a36Sopenharmony_ci * pci_clear_mwi - disables Memory-Write-Invalidate for device dev
461762306a36Sopenharmony_ci * @dev: the PCI device to disable
461862306a36Sopenharmony_ci *
461962306a36Sopenharmony_ci * Disables PCI Memory-Write-Invalidate transaction on the device
462062306a36Sopenharmony_ci */
462162306a36Sopenharmony_civoid pci_clear_mwi(struct pci_dev *dev)
462262306a36Sopenharmony_ci{
462362306a36Sopenharmony_ci#ifndef PCI_DISABLE_MWI
462462306a36Sopenharmony_ci	u16 cmd;
462562306a36Sopenharmony_ci
462662306a36Sopenharmony_ci	pci_read_config_word(dev, PCI_COMMAND, &cmd);
462762306a36Sopenharmony_ci	if (cmd & PCI_COMMAND_INVALIDATE) {
462862306a36Sopenharmony_ci		cmd &= ~PCI_COMMAND_INVALIDATE;
462962306a36Sopenharmony_ci		pci_write_config_word(dev, PCI_COMMAND, cmd);
463062306a36Sopenharmony_ci	}
463162306a36Sopenharmony_ci#endif
463262306a36Sopenharmony_ci}
463362306a36Sopenharmony_ciEXPORT_SYMBOL(pci_clear_mwi);
463462306a36Sopenharmony_ci
463562306a36Sopenharmony_ci/**
463662306a36Sopenharmony_ci * pci_disable_parity - disable parity checking for device
463762306a36Sopenharmony_ci * @dev: the PCI device to operate on
463862306a36Sopenharmony_ci *
463962306a36Sopenharmony_ci * Disable parity checking for device @dev
464062306a36Sopenharmony_ci */
464162306a36Sopenharmony_civoid pci_disable_parity(struct pci_dev *dev)
464262306a36Sopenharmony_ci{
464362306a36Sopenharmony_ci	u16 cmd;
464462306a36Sopenharmony_ci
464562306a36Sopenharmony_ci	pci_read_config_word(dev, PCI_COMMAND, &cmd);
464662306a36Sopenharmony_ci	if (cmd & PCI_COMMAND_PARITY) {
464762306a36Sopenharmony_ci		cmd &= ~PCI_COMMAND_PARITY;
464862306a36Sopenharmony_ci		pci_write_config_word(dev, PCI_COMMAND, cmd);
464962306a36Sopenharmony_ci	}
465062306a36Sopenharmony_ci}
465162306a36Sopenharmony_ci
465262306a36Sopenharmony_ci/**
465362306a36Sopenharmony_ci * pci_intx - enables/disables PCI INTx for device dev
465462306a36Sopenharmony_ci * @pdev: the PCI device to operate on
465562306a36Sopenharmony_ci * @enable: boolean: whether to enable or disable PCI INTx
465662306a36Sopenharmony_ci *
465762306a36Sopenharmony_ci * Enables/disables PCI INTx for device @pdev
465862306a36Sopenharmony_ci */
465962306a36Sopenharmony_civoid pci_intx(struct pci_dev *pdev, int enable)
466062306a36Sopenharmony_ci{
466162306a36Sopenharmony_ci	u16 pci_command, new;
466262306a36Sopenharmony_ci
466362306a36Sopenharmony_ci	pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
466462306a36Sopenharmony_ci
466562306a36Sopenharmony_ci	if (enable)
466662306a36Sopenharmony_ci		new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
466762306a36Sopenharmony_ci	else
466862306a36Sopenharmony_ci		new = pci_command | PCI_COMMAND_INTX_DISABLE;
466962306a36Sopenharmony_ci
467062306a36Sopenharmony_ci	if (new != pci_command) {
467162306a36Sopenharmony_ci		struct pci_devres *dr;
467262306a36Sopenharmony_ci
467362306a36Sopenharmony_ci		pci_write_config_word(pdev, PCI_COMMAND, new);
467462306a36Sopenharmony_ci
467562306a36Sopenharmony_ci		dr = find_pci_dr(pdev);
467662306a36Sopenharmony_ci		if (dr && !dr->restore_intx) {
467762306a36Sopenharmony_ci			dr->restore_intx = 1;
467862306a36Sopenharmony_ci			dr->orig_intx = !enable;
467962306a36Sopenharmony_ci		}
468062306a36Sopenharmony_ci	}
468162306a36Sopenharmony_ci}
468262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_intx);
468362306a36Sopenharmony_ci
468462306a36Sopenharmony_cistatic bool pci_check_and_set_intx_mask(struct pci_dev *dev, bool mask)
468562306a36Sopenharmony_ci{
468662306a36Sopenharmony_ci	struct pci_bus *bus = dev->bus;
468762306a36Sopenharmony_ci	bool mask_updated = true;
468862306a36Sopenharmony_ci	u32 cmd_status_dword;
468962306a36Sopenharmony_ci	u16 origcmd, newcmd;
469062306a36Sopenharmony_ci	unsigned long flags;
469162306a36Sopenharmony_ci	bool irq_pending;
469262306a36Sopenharmony_ci
469362306a36Sopenharmony_ci	/*
469462306a36Sopenharmony_ci	 * We do a single dword read to retrieve both command and status.
469562306a36Sopenharmony_ci	 * Document assumptions that make this possible.
469662306a36Sopenharmony_ci	 */
469762306a36Sopenharmony_ci	BUILD_BUG_ON(PCI_COMMAND % 4);
469862306a36Sopenharmony_ci	BUILD_BUG_ON(PCI_COMMAND + 2 != PCI_STATUS);
469962306a36Sopenharmony_ci
470062306a36Sopenharmony_ci	raw_spin_lock_irqsave(&pci_lock, flags);
470162306a36Sopenharmony_ci
470262306a36Sopenharmony_ci	bus->ops->read(bus, dev->devfn, PCI_COMMAND, 4, &cmd_status_dword);
470362306a36Sopenharmony_ci
470462306a36Sopenharmony_ci	irq_pending = (cmd_status_dword >> 16) & PCI_STATUS_INTERRUPT;
470562306a36Sopenharmony_ci
470662306a36Sopenharmony_ci	/*
470762306a36Sopenharmony_ci	 * Check interrupt status register to see whether our device
470862306a36Sopenharmony_ci	 * triggered the interrupt (when masking) or the next IRQ is
470962306a36Sopenharmony_ci	 * already pending (when unmasking).
471062306a36Sopenharmony_ci	 */
471162306a36Sopenharmony_ci	if (mask != irq_pending) {
471262306a36Sopenharmony_ci		mask_updated = false;
471362306a36Sopenharmony_ci		goto done;
471462306a36Sopenharmony_ci	}
471562306a36Sopenharmony_ci
471662306a36Sopenharmony_ci	origcmd = cmd_status_dword;
471762306a36Sopenharmony_ci	newcmd = origcmd & ~PCI_COMMAND_INTX_DISABLE;
471862306a36Sopenharmony_ci	if (mask)
471962306a36Sopenharmony_ci		newcmd |= PCI_COMMAND_INTX_DISABLE;
472062306a36Sopenharmony_ci	if (newcmd != origcmd)
472162306a36Sopenharmony_ci		bus->ops->write(bus, dev->devfn, PCI_COMMAND, 2, newcmd);
472262306a36Sopenharmony_ci
472362306a36Sopenharmony_cidone:
472462306a36Sopenharmony_ci	raw_spin_unlock_irqrestore(&pci_lock, flags);
472562306a36Sopenharmony_ci
472662306a36Sopenharmony_ci	return mask_updated;
472762306a36Sopenharmony_ci}
472862306a36Sopenharmony_ci
472962306a36Sopenharmony_ci/**
473062306a36Sopenharmony_ci * pci_check_and_mask_intx - mask INTx on pending interrupt
473162306a36Sopenharmony_ci * @dev: the PCI device to operate on
473262306a36Sopenharmony_ci *
473362306a36Sopenharmony_ci * Check if the device dev has its INTx line asserted, mask it and return
473462306a36Sopenharmony_ci * true in that case. False is returned if no interrupt was pending.
473562306a36Sopenharmony_ci */
473662306a36Sopenharmony_cibool pci_check_and_mask_intx(struct pci_dev *dev)
473762306a36Sopenharmony_ci{
473862306a36Sopenharmony_ci	return pci_check_and_set_intx_mask(dev, true);
473962306a36Sopenharmony_ci}
474062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_check_and_mask_intx);
474162306a36Sopenharmony_ci
474262306a36Sopenharmony_ci/**
474362306a36Sopenharmony_ci * pci_check_and_unmask_intx - unmask INTx if no interrupt is pending
474462306a36Sopenharmony_ci * @dev: the PCI device to operate on
474562306a36Sopenharmony_ci *
474662306a36Sopenharmony_ci * Check if the device dev has its INTx line asserted, unmask it if not and
474762306a36Sopenharmony_ci * return true. False is returned and the mask remains active if there was
474862306a36Sopenharmony_ci * still an interrupt pending.
474962306a36Sopenharmony_ci */
475062306a36Sopenharmony_cibool pci_check_and_unmask_intx(struct pci_dev *dev)
475162306a36Sopenharmony_ci{
475262306a36Sopenharmony_ci	return pci_check_and_set_intx_mask(dev, false);
475362306a36Sopenharmony_ci}
475462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_check_and_unmask_intx);
475562306a36Sopenharmony_ci
475662306a36Sopenharmony_ci/**
475762306a36Sopenharmony_ci * pci_wait_for_pending_transaction - wait for pending transaction
475862306a36Sopenharmony_ci * @dev: the PCI device to operate on
475962306a36Sopenharmony_ci *
476062306a36Sopenharmony_ci * Return 0 if transaction is pending 1 otherwise.
476162306a36Sopenharmony_ci */
476262306a36Sopenharmony_ciint pci_wait_for_pending_transaction(struct pci_dev *dev)
476362306a36Sopenharmony_ci{
476462306a36Sopenharmony_ci	if (!pci_is_pcie(dev))
476562306a36Sopenharmony_ci		return 1;
476662306a36Sopenharmony_ci
476762306a36Sopenharmony_ci	return pci_wait_for_pending(dev, pci_pcie_cap(dev) + PCI_EXP_DEVSTA,
476862306a36Sopenharmony_ci				    PCI_EXP_DEVSTA_TRPND);
476962306a36Sopenharmony_ci}
477062306a36Sopenharmony_ciEXPORT_SYMBOL(pci_wait_for_pending_transaction);
477162306a36Sopenharmony_ci
477262306a36Sopenharmony_ci/**
477362306a36Sopenharmony_ci * pcie_flr - initiate a PCIe function level reset
477462306a36Sopenharmony_ci * @dev: device to reset
477562306a36Sopenharmony_ci *
477662306a36Sopenharmony_ci * Initiate a function level reset unconditionally on @dev without
477762306a36Sopenharmony_ci * checking any flags and DEVCAP
477862306a36Sopenharmony_ci */
477962306a36Sopenharmony_ciint pcie_flr(struct pci_dev *dev)
478062306a36Sopenharmony_ci{
478162306a36Sopenharmony_ci	if (!pci_wait_for_pending_transaction(dev))
478262306a36Sopenharmony_ci		pci_err(dev, "timed out waiting for pending transaction; performing function level reset anyway\n");
478362306a36Sopenharmony_ci
478462306a36Sopenharmony_ci	pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
478562306a36Sopenharmony_ci
478662306a36Sopenharmony_ci	if (dev->imm_ready)
478762306a36Sopenharmony_ci		return 0;
478862306a36Sopenharmony_ci
478962306a36Sopenharmony_ci	/*
479062306a36Sopenharmony_ci	 * Per PCIe r4.0, sec 6.6.2, a device must complete an FLR within
479162306a36Sopenharmony_ci	 * 100ms, but may silently discard requests while the FLR is in
479262306a36Sopenharmony_ci	 * progress.  Wait 100ms before trying to access the device.
479362306a36Sopenharmony_ci	 */
479462306a36Sopenharmony_ci	msleep(100);
479562306a36Sopenharmony_ci
479662306a36Sopenharmony_ci	return pci_dev_wait(dev, "FLR", PCIE_RESET_READY_POLL_MS);
479762306a36Sopenharmony_ci}
479862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pcie_flr);
479962306a36Sopenharmony_ci
480062306a36Sopenharmony_ci/**
480162306a36Sopenharmony_ci * pcie_reset_flr - initiate a PCIe function level reset
480262306a36Sopenharmony_ci * @dev: device to reset
480362306a36Sopenharmony_ci * @probe: if true, return 0 if device can be reset this way
480462306a36Sopenharmony_ci *
480562306a36Sopenharmony_ci * Initiate a function level reset on @dev.
480662306a36Sopenharmony_ci */
480762306a36Sopenharmony_ciint pcie_reset_flr(struct pci_dev *dev, bool probe)
480862306a36Sopenharmony_ci{
480962306a36Sopenharmony_ci	if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET)
481062306a36Sopenharmony_ci		return -ENOTTY;
481162306a36Sopenharmony_ci
481262306a36Sopenharmony_ci	if (!(dev->devcap & PCI_EXP_DEVCAP_FLR))
481362306a36Sopenharmony_ci		return -ENOTTY;
481462306a36Sopenharmony_ci
481562306a36Sopenharmony_ci	if (probe)
481662306a36Sopenharmony_ci		return 0;
481762306a36Sopenharmony_ci
481862306a36Sopenharmony_ci	return pcie_flr(dev);
481962306a36Sopenharmony_ci}
482062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pcie_reset_flr);
482162306a36Sopenharmony_ci
482262306a36Sopenharmony_cistatic int pci_af_flr(struct pci_dev *dev, bool probe)
482362306a36Sopenharmony_ci{
482462306a36Sopenharmony_ci	int pos;
482562306a36Sopenharmony_ci	u8 cap;
482662306a36Sopenharmony_ci
482762306a36Sopenharmony_ci	pos = pci_find_capability(dev, PCI_CAP_ID_AF);
482862306a36Sopenharmony_ci	if (!pos)
482962306a36Sopenharmony_ci		return -ENOTTY;
483062306a36Sopenharmony_ci
483162306a36Sopenharmony_ci	if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET)
483262306a36Sopenharmony_ci		return -ENOTTY;
483362306a36Sopenharmony_ci
483462306a36Sopenharmony_ci	pci_read_config_byte(dev, pos + PCI_AF_CAP, &cap);
483562306a36Sopenharmony_ci	if (!(cap & PCI_AF_CAP_TP) || !(cap & PCI_AF_CAP_FLR))
483662306a36Sopenharmony_ci		return -ENOTTY;
483762306a36Sopenharmony_ci
483862306a36Sopenharmony_ci	if (probe)
483962306a36Sopenharmony_ci		return 0;
484062306a36Sopenharmony_ci
484162306a36Sopenharmony_ci	/*
484262306a36Sopenharmony_ci	 * Wait for Transaction Pending bit to clear.  A word-aligned test
484362306a36Sopenharmony_ci	 * is used, so we use the control offset rather than status and shift
484462306a36Sopenharmony_ci	 * the test bit to match.
484562306a36Sopenharmony_ci	 */
484662306a36Sopenharmony_ci	if (!pci_wait_for_pending(dev, pos + PCI_AF_CTRL,
484762306a36Sopenharmony_ci				 PCI_AF_STATUS_TP << 8))
484862306a36Sopenharmony_ci		pci_err(dev, "timed out waiting for pending transaction; performing AF function level reset anyway\n");
484962306a36Sopenharmony_ci
485062306a36Sopenharmony_ci	pci_write_config_byte(dev, pos + PCI_AF_CTRL, PCI_AF_CTRL_FLR);
485162306a36Sopenharmony_ci
485262306a36Sopenharmony_ci	if (dev->imm_ready)
485362306a36Sopenharmony_ci		return 0;
485462306a36Sopenharmony_ci
485562306a36Sopenharmony_ci	/*
485662306a36Sopenharmony_ci	 * Per Advanced Capabilities for Conventional PCI ECN, 13 April 2006,
485762306a36Sopenharmony_ci	 * updated 27 July 2006; a device must complete an FLR within
485862306a36Sopenharmony_ci	 * 100ms, but may silently discard requests while the FLR is in
485962306a36Sopenharmony_ci	 * progress.  Wait 100ms before trying to access the device.
486062306a36Sopenharmony_ci	 */
486162306a36Sopenharmony_ci	msleep(100);
486262306a36Sopenharmony_ci
486362306a36Sopenharmony_ci	return pci_dev_wait(dev, "AF_FLR", PCIE_RESET_READY_POLL_MS);
486462306a36Sopenharmony_ci}
486562306a36Sopenharmony_ci
486662306a36Sopenharmony_ci/**
486762306a36Sopenharmony_ci * pci_pm_reset - Put device into PCI_D3 and back into PCI_D0.
486862306a36Sopenharmony_ci * @dev: Device to reset.
486962306a36Sopenharmony_ci * @probe: if true, return 0 if the device can be reset this way.
487062306a36Sopenharmony_ci *
487162306a36Sopenharmony_ci * If @dev supports native PCI PM and its PCI_PM_CTRL_NO_SOFT_RESET flag is
487262306a36Sopenharmony_ci * unset, it will be reinitialized internally when going from PCI_D3hot to
487362306a36Sopenharmony_ci * PCI_D0.  If that's the case and the device is not in a low-power state
487462306a36Sopenharmony_ci * already, force it into PCI_D3hot and back to PCI_D0, causing it to be reset.
487562306a36Sopenharmony_ci *
487662306a36Sopenharmony_ci * NOTE: This causes the caller to sleep for twice the device power transition
487762306a36Sopenharmony_ci * cooldown period, which for the D0->D3hot and D3hot->D0 transitions is 10 ms
487862306a36Sopenharmony_ci * by default (i.e. unless the @dev's d3hot_delay field has a different value).
487962306a36Sopenharmony_ci * Moreover, only devices in D0 can be reset by this function.
488062306a36Sopenharmony_ci */
488162306a36Sopenharmony_cistatic int pci_pm_reset(struct pci_dev *dev, bool probe)
488262306a36Sopenharmony_ci{
488362306a36Sopenharmony_ci	u16 csr;
488462306a36Sopenharmony_ci
488562306a36Sopenharmony_ci	if (!dev->pm_cap || dev->dev_flags & PCI_DEV_FLAGS_NO_PM_RESET)
488662306a36Sopenharmony_ci		return -ENOTTY;
488762306a36Sopenharmony_ci
488862306a36Sopenharmony_ci	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &csr);
488962306a36Sopenharmony_ci	if (csr & PCI_PM_CTRL_NO_SOFT_RESET)
489062306a36Sopenharmony_ci		return -ENOTTY;
489162306a36Sopenharmony_ci
489262306a36Sopenharmony_ci	if (probe)
489362306a36Sopenharmony_ci		return 0;
489462306a36Sopenharmony_ci
489562306a36Sopenharmony_ci	if (dev->current_state != PCI_D0)
489662306a36Sopenharmony_ci		return -EINVAL;
489762306a36Sopenharmony_ci
489862306a36Sopenharmony_ci	csr &= ~PCI_PM_CTRL_STATE_MASK;
489962306a36Sopenharmony_ci	csr |= PCI_D3hot;
490062306a36Sopenharmony_ci	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr);
490162306a36Sopenharmony_ci	pci_dev_d3_sleep(dev);
490262306a36Sopenharmony_ci
490362306a36Sopenharmony_ci	csr &= ~PCI_PM_CTRL_STATE_MASK;
490462306a36Sopenharmony_ci	csr |= PCI_D0;
490562306a36Sopenharmony_ci	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr);
490662306a36Sopenharmony_ci	pci_dev_d3_sleep(dev);
490762306a36Sopenharmony_ci
490862306a36Sopenharmony_ci	return pci_dev_wait(dev, "PM D3hot->D0", PCIE_RESET_READY_POLL_MS);
490962306a36Sopenharmony_ci}
491062306a36Sopenharmony_ci
491162306a36Sopenharmony_ci/**
491262306a36Sopenharmony_ci * pcie_wait_for_link_status - Wait for link status change
491362306a36Sopenharmony_ci * @pdev: Device whose link to wait for.
491462306a36Sopenharmony_ci * @use_lt: Use the LT bit if TRUE, or the DLLLA bit if FALSE.
491562306a36Sopenharmony_ci * @active: Waiting for active or inactive?
491662306a36Sopenharmony_ci *
491762306a36Sopenharmony_ci * Return 0 if successful, or -ETIMEDOUT if status has not changed within
491862306a36Sopenharmony_ci * PCIE_LINK_RETRAIN_TIMEOUT_MS milliseconds.
491962306a36Sopenharmony_ci */
492062306a36Sopenharmony_cistatic int pcie_wait_for_link_status(struct pci_dev *pdev,
492162306a36Sopenharmony_ci				     bool use_lt, bool active)
492262306a36Sopenharmony_ci{
492362306a36Sopenharmony_ci	u16 lnksta_mask, lnksta_match;
492462306a36Sopenharmony_ci	unsigned long end_jiffies;
492562306a36Sopenharmony_ci	u16 lnksta;
492662306a36Sopenharmony_ci
492762306a36Sopenharmony_ci	lnksta_mask = use_lt ? PCI_EXP_LNKSTA_LT : PCI_EXP_LNKSTA_DLLLA;
492862306a36Sopenharmony_ci	lnksta_match = active ? lnksta_mask : 0;
492962306a36Sopenharmony_ci
493062306a36Sopenharmony_ci	end_jiffies = jiffies + msecs_to_jiffies(PCIE_LINK_RETRAIN_TIMEOUT_MS);
493162306a36Sopenharmony_ci	do {
493262306a36Sopenharmony_ci		pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnksta);
493362306a36Sopenharmony_ci		if ((lnksta & lnksta_mask) == lnksta_match)
493462306a36Sopenharmony_ci			return 0;
493562306a36Sopenharmony_ci		msleep(1);
493662306a36Sopenharmony_ci	} while (time_before(jiffies, end_jiffies));
493762306a36Sopenharmony_ci
493862306a36Sopenharmony_ci	return -ETIMEDOUT;
493962306a36Sopenharmony_ci}
494062306a36Sopenharmony_ci
494162306a36Sopenharmony_ci/**
494262306a36Sopenharmony_ci * pcie_retrain_link - Request a link retrain and wait for it to complete
494362306a36Sopenharmony_ci * @pdev: Device whose link to retrain.
494462306a36Sopenharmony_ci * @use_lt: Use the LT bit if TRUE, or the DLLLA bit if FALSE, for status.
494562306a36Sopenharmony_ci *
494662306a36Sopenharmony_ci * Retrain completion status is retrieved from the Link Status Register
494762306a36Sopenharmony_ci * according to @use_lt.  It is not verified whether the use of the DLLLA
494862306a36Sopenharmony_ci * bit is valid.
494962306a36Sopenharmony_ci *
495062306a36Sopenharmony_ci * Return 0 if successful, or -ETIMEDOUT if training has not completed
495162306a36Sopenharmony_ci * within PCIE_LINK_RETRAIN_TIMEOUT_MS milliseconds.
495262306a36Sopenharmony_ci */
495362306a36Sopenharmony_ciint pcie_retrain_link(struct pci_dev *pdev, bool use_lt)
495462306a36Sopenharmony_ci{
495562306a36Sopenharmony_ci	int rc;
495662306a36Sopenharmony_ci
495762306a36Sopenharmony_ci	/*
495862306a36Sopenharmony_ci	 * Ensure the updated LNKCTL parameters are used during link
495962306a36Sopenharmony_ci	 * training by checking that there is no ongoing link training to
496062306a36Sopenharmony_ci	 * avoid LTSSM race as recommended in Implementation Note at the
496162306a36Sopenharmony_ci	 * end of PCIe r6.0.1 sec 7.5.3.7.
496262306a36Sopenharmony_ci	 */
496362306a36Sopenharmony_ci	rc = pcie_wait_for_link_status(pdev, use_lt, !use_lt);
496462306a36Sopenharmony_ci	if (rc)
496562306a36Sopenharmony_ci		return rc;
496662306a36Sopenharmony_ci
496762306a36Sopenharmony_ci	pcie_capability_set_word(pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_RL);
496862306a36Sopenharmony_ci	if (pdev->clear_retrain_link) {
496962306a36Sopenharmony_ci		/*
497062306a36Sopenharmony_ci		 * Due to an erratum in some devices the Retrain Link bit
497162306a36Sopenharmony_ci		 * needs to be cleared again manually to allow the link
497262306a36Sopenharmony_ci		 * training to succeed.
497362306a36Sopenharmony_ci		 */
497462306a36Sopenharmony_ci		pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_RL);
497562306a36Sopenharmony_ci	}
497662306a36Sopenharmony_ci
497762306a36Sopenharmony_ci	return pcie_wait_for_link_status(pdev, use_lt, !use_lt);
497862306a36Sopenharmony_ci}
497962306a36Sopenharmony_ci
498062306a36Sopenharmony_ci/**
498162306a36Sopenharmony_ci * pcie_wait_for_link_delay - Wait until link is active or inactive
498262306a36Sopenharmony_ci * @pdev: Bridge device
498362306a36Sopenharmony_ci * @active: waiting for active or inactive?
498462306a36Sopenharmony_ci * @delay: Delay to wait after link has become active (in ms)
498562306a36Sopenharmony_ci *
498662306a36Sopenharmony_ci * Use this to wait till link becomes active or inactive.
498762306a36Sopenharmony_ci */
498862306a36Sopenharmony_cistatic bool pcie_wait_for_link_delay(struct pci_dev *pdev, bool active,
498962306a36Sopenharmony_ci				     int delay)
499062306a36Sopenharmony_ci{
499162306a36Sopenharmony_ci	int rc;
499262306a36Sopenharmony_ci
499362306a36Sopenharmony_ci	/*
499462306a36Sopenharmony_ci	 * Some controllers might not implement link active reporting. In this
499562306a36Sopenharmony_ci	 * case, we wait for 1000 ms + any delay requested by the caller.
499662306a36Sopenharmony_ci	 */
499762306a36Sopenharmony_ci	if (!pdev->link_active_reporting) {
499862306a36Sopenharmony_ci		msleep(PCIE_LINK_RETRAIN_TIMEOUT_MS + delay);
499962306a36Sopenharmony_ci		return true;
500062306a36Sopenharmony_ci	}
500162306a36Sopenharmony_ci
500262306a36Sopenharmony_ci	/*
500362306a36Sopenharmony_ci	 * PCIe r4.0 sec 6.6.1, a component must enter LTSSM Detect within 20ms,
500462306a36Sopenharmony_ci	 * after which we should expect an link active if the reset was
500562306a36Sopenharmony_ci	 * successful. If so, software must wait a minimum 100ms before sending
500662306a36Sopenharmony_ci	 * configuration requests to devices downstream this port.
500762306a36Sopenharmony_ci	 *
500862306a36Sopenharmony_ci	 * If the link fails to activate, either the device was physically
500962306a36Sopenharmony_ci	 * removed or the link is permanently failed.
501062306a36Sopenharmony_ci	 */
501162306a36Sopenharmony_ci	if (active)
501262306a36Sopenharmony_ci		msleep(20);
501362306a36Sopenharmony_ci	rc = pcie_wait_for_link_status(pdev, false, active);
501462306a36Sopenharmony_ci	if (active) {
501562306a36Sopenharmony_ci		if (rc)
501662306a36Sopenharmony_ci			rc = pcie_failed_link_retrain(pdev);
501762306a36Sopenharmony_ci		if (rc)
501862306a36Sopenharmony_ci			return false;
501962306a36Sopenharmony_ci
502062306a36Sopenharmony_ci		msleep(delay);
502162306a36Sopenharmony_ci		return true;
502262306a36Sopenharmony_ci	}
502362306a36Sopenharmony_ci
502462306a36Sopenharmony_ci	if (rc)
502562306a36Sopenharmony_ci		return false;
502662306a36Sopenharmony_ci
502762306a36Sopenharmony_ci	return true;
502862306a36Sopenharmony_ci}
502962306a36Sopenharmony_ci
503062306a36Sopenharmony_ci/**
503162306a36Sopenharmony_ci * pcie_wait_for_link - Wait until link is active or inactive
503262306a36Sopenharmony_ci * @pdev: Bridge device
503362306a36Sopenharmony_ci * @active: waiting for active or inactive?
503462306a36Sopenharmony_ci *
503562306a36Sopenharmony_ci * Use this to wait till link becomes active or inactive.
503662306a36Sopenharmony_ci */
503762306a36Sopenharmony_cibool pcie_wait_for_link(struct pci_dev *pdev, bool active)
503862306a36Sopenharmony_ci{
503962306a36Sopenharmony_ci	return pcie_wait_for_link_delay(pdev, active, 100);
504062306a36Sopenharmony_ci}
504162306a36Sopenharmony_ci
504262306a36Sopenharmony_ci/*
504362306a36Sopenharmony_ci * Find maximum D3cold delay required by all the devices on the bus.  The
504462306a36Sopenharmony_ci * spec says 100 ms, but firmware can lower it and we allow drivers to
504562306a36Sopenharmony_ci * increase it as well.
504662306a36Sopenharmony_ci *
504762306a36Sopenharmony_ci * Called with @pci_bus_sem locked for reading.
504862306a36Sopenharmony_ci */
504962306a36Sopenharmony_cistatic int pci_bus_max_d3cold_delay(const struct pci_bus *bus)
505062306a36Sopenharmony_ci{
505162306a36Sopenharmony_ci	const struct pci_dev *pdev;
505262306a36Sopenharmony_ci	int min_delay = 100;
505362306a36Sopenharmony_ci	int max_delay = 0;
505462306a36Sopenharmony_ci
505562306a36Sopenharmony_ci	list_for_each_entry(pdev, &bus->devices, bus_list) {
505662306a36Sopenharmony_ci		if (pdev->d3cold_delay < min_delay)
505762306a36Sopenharmony_ci			min_delay = pdev->d3cold_delay;
505862306a36Sopenharmony_ci		if (pdev->d3cold_delay > max_delay)
505962306a36Sopenharmony_ci			max_delay = pdev->d3cold_delay;
506062306a36Sopenharmony_ci	}
506162306a36Sopenharmony_ci
506262306a36Sopenharmony_ci	return max(min_delay, max_delay);
506362306a36Sopenharmony_ci}
506462306a36Sopenharmony_ci
506562306a36Sopenharmony_ci/**
506662306a36Sopenharmony_ci * pci_bridge_wait_for_secondary_bus - Wait for secondary bus to be accessible
506762306a36Sopenharmony_ci * @dev: PCI bridge
506862306a36Sopenharmony_ci * @reset_type: reset type in human-readable form
506962306a36Sopenharmony_ci *
507062306a36Sopenharmony_ci * Handle necessary delays before access to the devices on the secondary
507162306a36Sopenharmony_ci * side of the bridge are permitted after D3cold to D0 transition
507262306a36Sopenharmony_ci * or Conventional Reset.
507362306a36Sopenharmony_ci *
507462306a36Sopenharmony_ci * For PCIe this means the delays in PCIe 5.0 section 6.6.1. For
507562306a36Sopenharmony_ci * conventional PCI it means Tpvrh + Trhfa specified in PCI 3.0 section
507662306a36Sopenharmony_ci * 4.3.2.
507762306a36Sopenharmony_ci *
507862306a36Sopenharmony_ci * Return 0 on success or -ENOTTY if the first device on the secondary bus
507962306a36Sopenharmony_ci * failed to become accessible.
508062306a36Sopenharmony_ci */
508162306a36Sopenharmony_ciint pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type)
508262306a36Sopenharmony_ci{
508362306a36Sopenharmony_ci	struct pci_dev *child;
508462306a36Sopenharmony_ci	int delay;
508562306a36Sopenharmony_ci
508662306a36Sopenharmony_ci	if (pci_dev_is_disconnected(dev))
508762306a36Sopenharmony_ci		return 0;
508862306a36Sopenharmony_ci
508962306a36Sopenharmony_ci	if (!pci_is_bridge(dev))
509062306a36Sopenharmony_ci		return 0;
509162306a36Sopenharmony_ci
509262306a36Sopenharmony_ci	down_read(&pci_bus_sem);
509362306a36Sopenharmony_ci
509462306a36Sopenharmony_ci	/*
509562306a36Sopenharmony_ci	 * We only deal with devices that are present currently on the bus.
509662306a36Sopenharmony_ci	 * For any hot-added devices the access delay is handled in pciehp
509762306a36Sopenharmony_ci	 * board_added(). In case of ACPI hotplug the firmware is expected
509862306a36Sopenharmony_ci	 * to configure the devices before OS is notified.
509962306a36Sopenharmony_ci	 */
510062306a36Sopenharmony_ci	if (!dev->subordinate || list_empty(&dev->subordinate->devices)) {
510162306a36Sopenharmony_ci		up_read(&pci_bus_sem);
510262306a36Sopenharmony_ci		return 0;
510362306a36Sopenharmony_ci	}
510462306a36Sopenharmony_ci
510562306a36Sopenharmony_ci	/* Take d3cold_delay requirements into account */
510662306a36Sopenharmony_ci	delay = pci_bus_max_d3cold_delay(dev->subordinate);
510762306a36Sopenharmony_ci	if (!delay) {
510862306a36Sopenharmony_ci		up_read(&pci_bus_sem);
510962306a36Sopenharmony_ci		return 0;
511062306a36Sopenharmony_ci	}
511162306a36Sopenharmony_ci
511262306a36Sopenharmony_ci	child = list_first_entry(&dev->subordinate->devices, struct pci_dev,
511362306a36Sopenharmony_ci				 bus_list);
511462306a36Sopenharmony_ci	up_read(&pci_bus_sem);
511562306a36Sopenharmony_ci
511662306a36Sopenharmony_ci	/*
511762306a36Sopenharmony_ci	 * Conventional PCI and PCI-X we need to wait Tpvrh + Trhfa before
511862306a36Sopenharmony_ci	 * accessing the device after reset (that is 1000 ms + 100 ms).
511962306a36Sopenharmony_ci	 */
512062306a36Sopenharmony_ci	if (!pci_is_pcie(dev)) {
512162306a36Sopenharmony_ci		pci_dbg(dev, "waiting %d ms for secondary bus\n", 1000 + delay);
512262306a36Sopenharmony_ci		msleep(1000 + delay);
512362306a36Sopenharmony_ci		return 0;
512462306a36Sopenharmony_ci	}
512562306a36Sopenharmony_ci
512662306a36Sopenharmony_ci	/*
512762306a36Sopenharmony_ci	 * For PCIe downstream and root ports that do not support speeds
512862306a36Sopenharmony_ci	 * greater than 5 GT/s need to wait minimum 100 ms. For higher
512962306a36Sopenharmony_ci	 * speeds (gen3) we need to wait first for the data link layer to
513062306a36Sopenharmony_ci	 * become active.
513162306a36Sopenharmony_ci	 *
513262306a36Sopenharmony_ci	 * However, 100 ms is the minimum and the PCIe spec says the
513362306a36Sopenharmony_ci	 * software must allow at least 1s before it can determine that the
513462306a36Sopenharmony_ci	 * device that did not respond is a broken device. Also device can
513562306a36Sopenharmony_ci	 * take longer than that to respond if it indicates so through Request
513662306a36Sopenharmony_ci	 * Retry Status completions.
513762306a36Sopenharmony_ci	 *
513862306a36Sopenharmony_ci	 * Therefore we wait for 100 ms and check for the device presence
513962306a36Sopenharmony_ci	 * until the timeout expires.
514062306a36Sopenharmony_ci	 */
514162306a36Sopenharmony_ci	if (!pcie_downstream_port(dev))
514262306a36Sopenharmony_ci		return 0;
514362306a36Sopenharmony_ci
514462306a36Sopenharmony_ci	if (pcie_get_speed_cap(dev) <= PCIE_SPEED_5_0GT) {
514562306a36Sopenharmony_ci		u16 status;
514662306a36Sopenharmony_ci
514762306a36Sopenharmony_ci		pci_dbg(dev, "waiting %d ms for downstream link\n", delay);
514862306a36Sopenharmony_ci		msleep(delay);
514962306a36Sopenharmony_ci
515062306a36Sopenharmony_ci		if (!pci_dev_wait(child, reset_type, PCI_RESET_WAIT - delay))
515162306a36Sopenharmony_ci			return 0;
515262306a36Sopenharmony_ci
515362306a36Sopenharmony_ci		/*
515462306a36Sopenharmony_ci		 * If the port supports active link reporting we now check
515562306a36Sopenharmony_ci		 * whether the link is active and if not bail out early with
515662306a36Sopenharmony_ci		 * the assumption that the device is not present anymore.
515762306a36Sopenharmony_ci		 */
515862306a36Sopenharmony_ci		if (!dev->link_active_reporting)
515962306a36Sopenharmony_ci			return -ENOTTY;
516062306a36Sopenharmony_ci
516162306a36Sopenharmony_ci		pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &status);
516262306a36Sopenharmony_ci		if (!(status & PCI_EXP_LNKSTA_DLLLA))
516362306a36Sopenharmony_ci			return -ENOTTY;
516462306a36Sopenharmony_ci
516562306a36Sopenharmony_ci		return pci_dev_wait(child, reset_type,
516662306a36Sopenharmony_ci				    PCIE_RESET_READY_POLL_MS - PCI_RESET_WAIT);
516762306a36Sopenharmony_ci	}
516862306a36Sopenharmony_ci
516962306a36Sopenharmony_ci	pci_dbg(dev, "waiting %d ms for downstream link, after activation\n",
517062306a36Sopenharmony_ci		delay);
517162306a36Sopenharmony_ci	if (!pcie_wait_for_link_delay(dev, true, delay)) {
517262306a36Sopenharmony_ci		/* Did not train, no need to wait any further */
517362306a36Sopenharmony_ci		pci_info(dev, "Data Link Layer Link Active not set in 1000 msec\n");
517462306a36Sopenharmony_ci		return -ENOTTY;
517562306a36Sopenharmony_ci	}
517662306a36Sopenharmony_ci
517762306a36Sopenharmony_ci	return pci_dev_wait(child, reset_type,
517862306a36Sopenharmony_ci			    PCIE_RESET_READY_POLL_MS - delay);
517962306a36Sopenharmony_ci}
518062306a36Sopenharmony_ci
518162306a36Sopenharmony_civoid pci_reset_secondary_bus(struct pci_dev *dev)
518262306a36Sopenharmony_ci{
518362306a36Sopenharmony_ci	u16 ctrl;
518462306a36Sopenharmony_ci
518562306a36Sopenharmony_ci	pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &ctrl);
518662306a36Sopenharmony_ci	ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
518762306a36Sopenharmony_ci	pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl);
518862306a36Sopenharmony_ci
518962306a36Sopenharmony_ci	/*
519062306a36Sopenharmony_ci	 * PCI spec v3.0 7.6.4.2 requires minimum Trst of 1ms.  Double
519162306a36Sopenharmony_ci	 * this to 2ms to ensure that we meet the minimum requirement.
519262306a36Sopenharmony_ci	 */
519362306a36Sopenharmony_ci	msleep(2);
519462306a36Sopenharmony_ci
519562306a36Sopenharmony_ci	ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
519662306a36Sopenharmony_ci	pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl);
519762306a36Sopenharmony_ci}
519862306a36Sopenharmony_ci
519962306a36Sopenharmony_civoid __weak pcibios_reset_secondary_bus(struct pci_dev *dev)
520062306a36Sopenharmony_ci{
520162306a36Sopenharmony_ci	pci_reset_secondary_bus(dev);
520262306a36Sopenharmony_ci}
520362306a36Sopenharmony_ci
520462306a36Sopenharmony_ci/**
520562306a36Sopenharmony_ci * pci_bridge_secondary_bus_reset - Reset the secondary bus on a PCI bridge.
520662306a36Sopenharmony_ci * @dev: Bridge device
520762306a36Sopenharmony_ci *
520862306a36Sopenharmony_ci * Use the bridge control register to assert reset on the secondary bus.
520962306a36Sopenharmony_ci * Devices on the secondary bus are left in power-on state.
521062306a36Sopenharmony_ci */
521162306a36Sopenharmony_ciint pci_bridge_secondary_bus_reset(struct pci_dev *dev)
521262306a36Sopenharmony_ci{
521362306a36Sopenharmony_ci	pcibios_reset_secondary_bus(dev);
521462306a36Sopenharmony_ci
521562306a36Sopenharmony_ci	return pci_bridge_wait_for_secondary_bus(dev, "bus reset");
521662306a36Sopenharmony_ci}
521762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_bridge_secondary_bus_reset);
521862306a36Sopenharmony_ci
521962306a36Sopenharmony_cistatic int pci_parent_bus_reset(struct pci_dev *dev, bool probe)
522062306a36Sopenharmony_ci{
522162306a36Sopenharmony_ci	struct pci_dev *pdev;
522262306a36Sopenharmony_ci
522362306a36Sopenharmony_ci	if (pci_is_root_bus(dev->bus) || dev->subordinate ||
522462306a36Sopenharmony_ci	    !dev->bus->self || dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET)
522562306a36Sopenharmony_ci		return -ENOTTY;
522662306a36Sopenharmony_ci
522762306a36Sopenharmony_ci	list_for_each_entry(pdev, &dev->bus->devices, bus_list)
522862306a36Sopenharmony_ci		if (pdev != dev)
522962306a36Sopenharmony_ci			return -ENOTTY;
523062306a36Sopenharmony_ci
523162306a36Sopenharmony_ci	if (probe)
523262306a36Sopenharmony_ci		return 0;
523362306a36Sopenharmony_ci
523462306a36Sopenharmony_ci	return pci_bridge_secondary_bus_reset(dev->bus->self);
523562306a36Sopenharmony_ci}
523662306a36Sopenharmony_ci
523762306a36Sopenharmony_cistatic int pci_reset_hotplug_slot(struct hotplug_slot *hotplug, bool probe)
523862306a36Sopenharmony_ci{
523962306a36Sopenharmony_ci	int rc = -ENOTTY;
524062306a36Sopenharmony_ci
524162306a36Sopenharmony_ci	if (!hotplug || !try_module_get(hotplug->owner))
524262306a36Sopenharmony_ci		return rc;
524362306a36Sopenharmony_ci
524462306a36Sopenharmony_ci	if (hotplug->ops->reset_slot)
524562306a36Sopenharmony_ci		rc = hotplug->ops->reset_slot(hotplug, probe);
524662306a36Sopenharmony_ci
524762306a36Sopenharmony_ci	module_put(hotplug->owner);
524862306a36Sopenharmony_ci
524962306a36Sopenharmony_ci	return rc;
525062306a36Sopenharmony_ci}
525162306a36Sopenharmony_ci
525262306a36Sopenharmony_cistatic int pci_dev_reset_slot_function(struct pci_dev *dev, bool probe)
525362306a36Sopenharmony_ci{
525462306a36Sopenharmony_ci	if (dev->multifunction || dev->subordinate || !dev->slot ||
525562306a36Sopenharmony_ci	    dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET)
525662306a36Sopenharmony_ci		return -ENOTTY;
525762306a36Sopenharmony_ci
525862306a36Sopenharmony_ci	return pci_reset_hotplug_slot(dev->slot->hotplug, probe);
525962306a36Sopenharmony_ci}
526062306a36Sopenharmony_ci
526162306a36Sopenharmony_cistatic int pci_reset_bus_function(struct pci_dev *dev, bool probe)
526262306a36Sopenharmony_ci{
526362306a36Sopenharmony_ci	int rc;
526462306a36Sopenharmony_ci
526562306a36Sopenharmony_ci	rc = pci_dev_reset_slot_function(dev, probe);
526662306a36Sopenharmony_ci	if (rc != -ENOTTY)
526762306a36Sopenharmony_ci		return rc;
526862306a36Sopenharmony_ci	return pci_parent_bus_reset(dev, probe);
526962306a36Sopenharmony_ci}
527062306a36Sopenharmony_ci
527162306a36Sopenharmony_civoid pci_dev_lock(struct pci_dev *dev)
527262306a36Sopenharmony_ci{
527362306a36Sopenharmony_ci	/* block PM suspend, driver probe, etc. */
527462306a36Sopenharmony_ci	device_lock(&dev->dev);
527562306a36Sopenharmony_ci	pci_cfg_access_lock(dev);
527662306a36Sopenharmony_ci}
527762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_dev_lock);
527862306a36Sopenharmony_ci
527962306a36Sopenharmony_ci/* Return 1 on successful lock, 0 on contention */
528062306a36Sopenharmony_ciint pci_dev_trylock(struct pci_dev *dev)
528162306a36Sopenharmony_ci{
528262306a36Sopenharmony_ci	if (device_trylock(&dev->dev)) {
528362306a36Sopenharmony_ci		if (pci_cfg_access_trylock(dev))
528462306a36Sopenharmony_ci			return 1;
528562306a36Sopenharmony_ci		device_unlock(&dev->dev);
528662306a36Sopenharmony_ci	}
528762306a36Sopenharmony_ci
528862306a36Sopenharmony_ci	return 0;
528962306a36Sopenharmony_ci}
529062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_dev_trylock);
529162306a36Sopenharmony_ci
529262306a36Sopenharmony_civoid pci_dev_unlock(struct pci_dev *dev)
529362306a36Sopenharmony_ci{
529462306a36Sopenharmony_ci	pci_cfg_access_unlock(dev);
529562306a36Sopenharmony_ci	device_unlock(&dev->dev);
529662306a36Sopenharmony_ci}
529762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_dev_unlock);
529862306a36Sopenharmony_ci
529962306a36Sopenharmony_cistatic void pci_dev_save_and_disable(struct pci_dev *dev)
530062306a36Sopenharmony_ci{
530162306a36Sopenharmony_ci	const struct pci_error_handlers *err_handler =
530262306a36Sopenharmony_ci			dev->driver ? dev->driver->err_handler : NULL;
530362306a36Sopenharmony_ci
530462306a36Sopenharmony_ci	/*
530562306a36Sopenharmony_ci	 * dev->driver->err_handler->reset_prepare() is protected against
530662306a36Sopenharmony_ci	 * races with ->remove() by the device lock, which must be held by
530762306a36Sopenharmony_ci	 * the caller.
530862306a36Sopenharmony_ci	 */
530962306a36Sopenharmony_ci	if (err_handler && err_handler->reset_prepare)
531062306a36Sopenharmony_ci		err_handler->reset_prepare(dev);
531162306a36Sopenharmony_ci
531262306a36Sopenharmony_ci	/*
531362306a36Sopenharmony_ci	 * Wake-up device prior to save.  PM registers default to D0 after
531462306a36Sopenharmony_ci	 * reset and a simple register restore doesn't reliably return
531562306a36Sopenharmony_ci	 * to a non-D0 state anyway.
531662306a36Sopenharmony_ci	 */
531762306a36Sopenharmony_ci	pci_set_power_state(dev, PCI_D0);
531862306a36Sopenharmony_ci
531962306a36Sopenharmony_ci	pci_save_state(dev);
532062306a36Sopenharmony_ci	/*
532162306a36Sopenharmony_ci	 * Disable the device by clearing the Command register, except for
532262306a36Sopenharmony_ci	 * INTx-disable which is set.  This not only disables MMIO and I/O port
532362306a36Sopenharmony_ci	 * BARs, but also prevents the device from being Bus Master, preventing
532462306a36Sopenharmony_ci	 * DMA from the device including MSI/MSI-X interrupts.  For PCI 2.3
532562306a36Sopenharmony_ci	 * compliant devices, INTx-disable prevents legacy interrupts.
532662306a36Sopenharmony_ci	 */
532762306a36Sopenharmony_ci	pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
532862306a36Sopenharmony_ci}
532962306a36Sopenharmony_ci
533062306a36Sopenharmony_cistatic void pci_dev_restore(struct pci_dev *dev)
533162306a36Sopenharmony_ci{
533262306a36Sopenharmony_ci	const struct pci_error_handlers *err_handler =
533362306a36Sopenharmony_ci			dev->driver ? dev->driver->err_handler : NULL;
533462306a36Sopenharmony_ci
533562306a36Sopenharmony_ci	pci_restore_state(dev);
533662306a36Sopenharmony_ci
533762306a36Sopenharmony_ci	/*
533862306a36Sopenharmony_ci	 * dev->driver->err_handler->reset_done() is protected against
533962306a36Sopenharmony_ci	 * races with ->remove() by the device lock, which must be held by
534062306a36Sopenharmony_ci	 * the caller.
534162306a36Sopenharmony_ci	 */
534262306a36Sopenharmony_ci	if (err_handler && err_handler->reset_done)
534362306a36Sopenharmony_ci		err_handler->reset_done(dev);
534462306a36Sopenharmony_ci}
534562306a36Sopenharmony_ci
534662306a36Sopenharmony_ci/* dev->reset_methods[] is a 0-terminated list of indices into this array */
534762306a36Sopenharmony_cistatic const struct pci_reset_fn_method pci_reset_fn_methods[] = {
534862306a36Sopenharmony_ci	{ },
534962306a36Sopenharmony_ci	{ pci_dev_specific_reset, .name = "device_specific" },
535062306a36Sopenharmony_ci	{ pci_dev_acpi_reset, .name = "acpi" },
535162306a36Sopenharmony_ci	{ pcie_reset_flr, .name = "flr" },
535262306a36Sopenharmony_ci	{ pci_af_flr, .name = "af_flr" },
535362306a36Sopenharmony_ci	{ pci_pm_reset, .name = "pm" },
535462306a36Sopenharmony_ci	{ pci_reset_bus_function, .name = "bus" },
535562306a36Sopenharmony_ci};
535662306a36Sopenharmony_ci
535762306a36Sopenharmony_cistatic ssize_t reset_method_show(struct device *dev,
535862306a36Sopenharmony_ci				 struct device_attribute *attr, char *buf)
535962306a36Sopenharmony_ci{
536062306a36Sopenharmony_ci	struct pci_dev *pdev = to_pci_dev(dev);
536162306a36Sopenharmony_ci	ssize_t len = 0;
536262306a36Sopenharmony_ci	int i, m;
536362306a36Sopenharmony_ci
536462306a36Sopenharmony_ci	for (i = 0; i < PCI_NUM_RESET_METHODS; i++) {
536562306a36Sopenharmony_ci		m = pdev->reset_methods[i];
536662306a36Sopenharmony_ci		if (!m)
536762306a36Sopenharmony_ci			break;
536862306a36Sopenharmony_ci
536962306a36Sopenharmony_ci		len += sysfs_emit_at(buf, len, "%s%s", len ? " " : "",
537062306a36Sopenharmony_ci				     pci_reset_fn_methods[m].name);
537162306a36Sopenharmony_ci	}
537262306a36Sopenharmony_ci
537362306a36Sopenharmony_ci	if (len)
537462306a36Sopenharmony_ci		len += sysfs_emit_at(buf, len, "\n");
537562306a36Sopenharmony_ci
537662306a36Sopenharmony_ci	return len;
537762306a36Sopenharmony_ci}
537862306a36Sopenharmony_ci
537962306a36Sopenharmony_cistatic int reset_method_lookup(const char *name)
538062306a36Sopenharmony_ci{
538162306a36Sopenharmony_ci	int m;
538262306a36Sopenharmony_ci
538362306a36Sopenharmony_ci	for (m = 1; m < PCI_NUM_RESET_METHODS; m++) {
538462306a36Sopenharmony_ci		if (sysfs_streq(name, pci_reset_fn_methods[m].name))
538562306a36Sopenharmony_ci			return m;
538662306a36Sopenharmony_ci	}
538762306a36Sopenharmony_ci
538862306a36Sopenharmony_ci	return 0;	/* not found */
538962306a36Sopenharmony_ci}
539062306a36Sopenharmony_ci
539162306a36Sopenharmony_cistatic ssize_t reset_method_store(struct device *dev,
539262306a36Sopenharmony_ci				  struct device_attribute *attr,
539362306a36Sopenharmony_ci				  const char *buf, size_t count)
539462306a36Sopenharmony_ci{
539562306a36Sopenharmony_ci	struct pci_dev *pdev = to_pci_dev(dev);
539662306a36Sopenharmony_ci	char *options, *name;
539762306a36Sopenharmony_ci	int m, n;
539862306a36Sopenharmony_ci	u8 reset_methods[PCI_NUM_RESET_METHODS] = { 0 };
539962306a36Sopenharmony_ci
540062306a36Sopenharmony_ci	if (sysfs_streq(buf, "")) {
540162306a36Sopenharmony_ci		pdev->reset_methods[0] = 0;
540262306a36Sopenharmony_ci		pci_warn(pdev, "All device reset methods disabled by user");
540362306a36Sopenharmony_ci		return count;
540462306a36Sopenharmony_ci	}
540562306a36Sopenharmony_ci
540662306a36Sopenharmony_ci	if (sysfs_streq(buf, "default")) {
540762306a36Sopenharmony_ci		pci_init_reset_methods(pdev);
540862306a36Sopenharmony_ci		return count;
540962306a36Sopenharmony_ci	}
541062306a36Sopenharmony_ci
541162306a36Sopenharmony_ci	options = kstrndup(buf, count, GFP_KERNEL);
541262306a36Sopenharmony_ci	if (!options)
541362306a36Sopenharmony_ci		return -ENOMEM;
541462306a36Sopenharmony_ci
541562306a36Sopenharmony_ci	n = 0;
541662306a36Sopenharmony_ci	while ((name = strsep(&options, " ")) != NULL) {
541762306a36Sopenharmony_ci		if (sysfs_streq(name, ""))
541862306a36Sopenharmony_ci			continue;
541962306a36Sopenharmony_ci
542062306a36Sopenharmony_ci		name = strim(name);
542162306a36Sopenharmony_ci
542262306a36Sopenharmony_ci		m = reset_method_lookup(name);
542362306a36Sopenharmony_ci		if (!m) {
542462306a36Sopenharmony_ci			pci_err(pdev, "Invalid reset method '%s'", name);
542562306a36Sopenharmony_ci			goto error;
542662306a36Sopenharmony_ci		}
542762306a36Sopenharmony_ci
542862306a36Sopenharmony_ci		if (pci_reset_fn_methods[m].reset_fn(pdev, PCI_RESET_PROBE)) {
542962306a36Sopenharmony_ci			pci_err(pdev, "Unsupported reset method '%s'", name);
543062306a36Sopenharmony_ci			goto error;
543162306a36Sopenharmony_ci		}
543262306a36Sopenharmony_ci
543362306a36Sopenharmony_ci		if (n == PCI_NUM_RESET_METHODS - 1) {
543462306a36Sopenharmony_ci			pci_err(pdev, "Too many reset methods\n");
543562306a36Sopenharmony_ci			goto error;
543662306a36Sopenharmony_ci		}
543762306a36Sopenharmony_ci
543862306a36Sopenharmony_ci		reset_methods[n++] = m;
543962306a36Sopenharmony_ci	}
544062306a36Sopenharmony_ci
544162306a36Sopenharmony_ci	reset_methods[n] = 0;
544262306a36Sopenharmony_ci
544362306a36Sopenharmony_ci	/* Warn if dev-specific supported but not highest priority */
544462306a36Sopenharmony_ci	if (pci_reset_fn_methods[1].reset_fn(pdev, PCI_RESET_PROBE) == 0 &&
544562306a36Sopenharmony_ci	    reset_methods[0] != 1)
544662306a36Sopenharmony_ci		pci_warn(pdev, "Device-specific reset disabled/de-prioritized by user");
544762306a36Sopenharmony_ci	memcpy(pdev->reset_methods, reset_methods, sizeof(pdev->reset_methods));
544862306a36Sopenharmony_ci	kfree(options);
544962306a36Sopenharmony_ci	return count;
545062306a36Sopenharmony_ci
545162306a36Sopenharmony_cierror:
545262306a36Sopenharmony_ci	/* Leave previous methods unchanged */
545362306a36Sopenharmony_ci	kfree(options);
545462306a36Sopenharmony_ci	return -EINVAL;
545562306a36Sopenharmony_ci}
545662306a36Sopenharmony_cistatic DEVICE_ATTR_RW(reset_method);
545762306a36Sopenharmony_ci
545862306a36Sopenharmony_cistatic struct attribute *pci_dev_reset_method_attrs[] = {
545962306a36Sopenharmony_ci	&dev_attr_reset_method.attr,
546062306a36Sopenharmony_ci	NULL,
546162306a36Sopenharmony_ci};
546262306a36Sopenharmony_ci
546362306a36Sopenharmony_cistatic umode_t pci_dev_reset_method_attr_is_visible(struct kobject *kobj,
546462306a36Sopenharmony_ci						    struct attribute *a, int n)
546562306a36Sopenharmony_ci{
546662306a36Sopenharmony_ci	struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
546762306a36Sopenharmony_ci
546862306a36Sopenharmony_ci	if (!pci_reset_supported(pdev))
546962306a36Sopenharmony_ci		return 0;
547062306a36Sopenharmony_ci
547162306a36Sopenharmony_ci	return a->mode;
547262306a36Sopenharmony_ci}
547362306a36Sopenharmony_ci
547462306a36Sopenharmony_ciconst struct attribute_group pci_dev_reset_method_attr_group = {
547562306a36Sopenharmony_ci	.attrs = pci_dev_reset_method_attrs,
547662306a36Sopenharmony_ci	.is_visible = pci_dev_reset_method_attr_is_visible,
547762306a36Sopenharmony_ci};
547862306a36Sopenharmony_ci
547962306a36Sopenharmony_ci/**
548062306a36Sopenharmony_ci * __pci_reset_function_locked - reset a PCI device function while holding
548162306a36Sopenharmony_ci * the @dev mutex lock.
548262306a36Sopenharmony_ci * @dev: PCI device to reset
548362306a36Sopenharmony_ci *
548462306a36Sopenharmony_ci * Some devices allow an individual function to be reset without affecting
548562306a36Sopenharmony_ci * other functions in the same device.  The PCI device must be responsive
548662306a36Sopenharmony_ci * to PCI config space in order to use this function.
548762306a36Sopenharmony_ci *
548862306a36Sopenharmony_ci * The device function is presumed to be unused and the caller is holding
548962306a36Sopenharmony_ci * the device mutex lock when this function is called.
549062306a36Sopenharmony_ci *
549162306a36Sopenharmony_ci * Resetting the device will make the contents of PCI configuration space
549262306a36Sopenharmony_ci * random, so any caller of this must be prepared to reinitialise the
549362306a36Sopenharmony_ci * device including MSI, bus mastering, BARs, decoding IO and memory spaces,
549462306a36Sopenharmony_ci * etc.
549562306a36Sopenharmony_ci *
549662306a36Sopenharmony_ci * Returns 0 if the device function was successfully reset or negative if the
549762306a36Sopenharmony_ci * device doesn't support resetting a single function.
549862306a36Sopenharmony_ci */
549962306a36Sopenharmony_ciint __pci_reset_function_locked(struct pci_dev *dev)
550062306a36Sopenharmony_ci{
550162306a36Sopenharmony_ci	int i, m, rc;
550262306a36Sopenharmony_ci
550362306a36Sopenharmony_ci	might_sleep();
550462306a36Sopenharmony_ci
550562306a36Sopenharmony_ci	/*
550662306a36Sopenharmony_ci	 * A reset method returns -ENOTTY if it doesn't support this device and
550762306a36Sopenharmony_ci	 * we should try the next method.
550862306a36Sopenharmony_ci	 *
550962306a36Sopenharmony_ci	 * If it returns 0 (success), we're finished.  If it returns any other
551062306a36Sopenharmony_ci	 * error, we're also finished: this indicates that further reset
551162306a36Sopenharmony_ci	 * mechanisms might be broken on the device.
551262306a36Sopenharmony_ci	 */
551362306a36Sopenharmony_ci	for (i = 0; i < PCI_NUM_RESET_METHODS; i++) {
551462306a36Sopenharmony_ci		m = dev->reset_methods[i];
551562306a36Sopenharmony_ci		if (!m)
551662306a36Sopenharmony_ci			return -ENOTTY;
551762306a36Sopenharmony_ci
551862306a36Sopenharmony_ci		rc = pci_reset_fn_methods[m].reset_fn(dev, PCI_RESET_DO_RESET);
551962306a36Sopenharmony_ci		if (!rc)
552062306a36Sopenharmony_ci			return 0;
552162306a36Sopenharmony_ci		if (rc != -ENOTTY)
552262306a36Sopenharmony_ci			return rc;
552362306a36Sopenharmony_ci	}
552462306a36Sopenharmony_ci
552562306a36Sopenharmony_ci	return -ENOTTY;
552662306a36Sopenharmony_ci}
552762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(__pci_reset_function_locked);
552862306a36Sopenharmony_ci
552962306a36Sopenharmony_ci/**
553062306a36Sopenharmony_ci * pci_init_reset_methods - check whether device can be safely reset
553162306a36Sopenharmony_ci * and store supported reset mechanisms.
553262306a36Sopenharmony_ci * @dev: PCI device to check for reset mechanisms
553362306a36Sopenharmony_ci *
553462306a36Sopenharmony_ci * Some devices allow an individual function to be reset without affecting
553562306a36Sopenharmony_ci * other functions in the same device.  The PCI device must be in D0-D3hot
553662306a36Sopenharmony_ci * state.
553762306a36Sopenharmony_ci *
553862306a36Sopenharmony_ci * Stores reset mechanisms supported by device in reset_methods byte array
553962306a36Sopenharmony_ci * which is a member of struct pci_dev.
554062306a36Sopenharmony_ci */
554162306a36Sopenharmony_civoid pci_init_reset_methods(struct pci_dev *dev)
554262306a36Sopenharmony_ci{
554362306a36Sopenharmony_ci	int m, i, rc;
554462306a36Sopenharmony_ci
554562306a36Sopenharmony_ci	BUILD_BUG_ON(ARRAY_SIZE(pci_reset_fn_methods) != PCI_NUM_RESET_METHODS);
554662306a36Sopenharmony_ci
554762306a36Sopenharmony_ci	might_sleep();
554862306a36Sopenharmony_ci
554962306a36Sopenharmony_ci	i = 0;
555062306a36Sopenharmony_ci	for (m = 1; m < PCI_NUM_RESET_METHODS; m++) {
555162306a36Sopenharmony_ci		rc = pci_reset_fn_methods[m].reset_fn(dev, PCI_RESET_PROBE);
555262306a36Sopenharmony_ci		if (!rc)
555362306a36Sopenharmony_ci			dev->reset_methods[i++] = m;
555462306a36Sopenharmony_ci		else if (rc != -ENOTTY)
555562306a36Sopenharmony_ci			break;
555662306a36Sopenharmony_ci	}
555762306a36Sopenharmony_ci
555862306a36Sopenharmony_ci	dev->reset_methods[i] = 0;
555962306a36Sopenharmony_ci}
556062306a36Sopenharmony_ci
556162306a36Sopenharmony_ci/**
556262306a36Sopenharmony_ci * pci_reset_function - quiesce and reset a PCI device function
556362306a36Sopenharmony_ci * @dev: PCI device to reset
556462306a36Sopenharmony_ci *
556562306a36Sopenharmony_ci * Some devices allow an individual function to be reset without affecting
556662306a36Sopenharmony_ci * other functions in the same device.  The PCI device must be responsive
556762306a36Sopenharmony_ci * to PCI config space in order to use this function.
556862306a36Sopenharmony_ci *
556962306a36Sopenharmony_ci * This function does not just reset the PCI portion of a device, but
557062306a36Sopenharmony_ci * clears all the state associated with the device.  This function differs
557162306a36Sopenharmony_ci * from __pci_reset_function_locked() in that it saves and restores device state
557262306a36Sopenharmony_ci * over the reset and takes the PCI device lock.
557362306a36Sopenharmony_ci *
557462306a36Sopenharmony_ci * Returns 0 if the device function was successfully reset or negative if the
557562306a36Sopenharmony_ci * device doesn't support resetting a single function.
557662306a36Sopenharmony_ci */
557762306a36Sopenharmony_ciint pci_reset_function(struct pci_dev *dev)
557862306a36Sopenharmony_ci{
557962306a36Sopenharmony_ci	int rc;
558062306a36Sopenharmony_ci
558162306a36Sopenharmony_ci	if (!pci_reset_supported(dev))
558262306a36Sopenharmony_ci		return -ENOTTY;
558362306a36Sopenharmony_ci
558462306a36Sopenharmony_ci	pci_dev_lock(dev);
558562306a36Sopenharmony_ci	pci_dev_save_and_disable(dev);
558662306a36Sopenharmony_ci
558762306a36Sopenharmony_ci	rc = __pci_reset_function_locked(dev);
558862306a36Sopenharmony_ci
558962306a36Sopenharmony_ci	pci_dev_restore(dev);
559062306a36Sopenharmony_ci	pci_dev_unlock(dev);
559162306a36Sopenharmony_ci
559262306a36Sopenharmony_ci	return rc;
559362306a36Sopenharmony_ci}
559462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_reset_function);
559562306a36Sopenharmony_ci
559662306a36Sopenharmony_ci/**
559762306a36Sopenharmony_ci * pci_reset_function_locked - quiesce and reset a PCI device function
559862306a36Sopenharmony_ci * @dev: PCI device to reset
559962306a36Sopenharmony_ci *
560062306a36Sopenharmony_ci * Some devices allow an individual function to be reset without affecting
560162306a36Sopenharmony_ci * other functions in the same device.  The PCI device must be responsive
560262306a36Sopenharmony_ci * to PCI config space in order to use this function.
560362306a36Sopenharmony_ci *
560462306a36Sopenharmony_ci * This function does not just reset the PCI portion of a device, but
560562306a36Sopenharmony_ci * clears all the state associated with the device.  This function differs
560662306a36Sopenharmony_ci * from __pci_reset_function_locked() in that it saves and restores device state
560762306a36Sopenharmony_ci * over the reset.  It also differs from pci_reset_function() in that it
560862306a36Sopenharmony_ci * requires the PCI device lock to be held.
560962306a36Sopenharmony_ci *
561062306a36Sopenharmony_ci * Returns 0 if the device function was successfully reset or negative if the
561162306a36Sopenharmony_ci * device doesn't support resetting a single function.
561262306a36Sopenharmony_ci */
561362306a36Sopenharmony_ciint pci_reset_function_locked(struct pci_dev *dev)
561462306a36Sopenharmony_ci{
561562306a36Sopenharmony_ci	int rc;
561662306a36Sopenharmony_ci
561762306a36Sopenharmony_ci	if (!pci_reset_supported(dev))
561862306a36Sopenharmony_ci		return -ENOTTY;
561962306a36Sopenharmony_ci
562062306a36Sopenharmony_ci	pci_dev_save_and_disable(dev);
562162306a36Sopenharmony_ci
562262306a36Sopenharmony_ci	rc = __pci_reset_function_locked(dev);
562362306a36Sopenharmony_ci
562462306a36Sopenharmony_ci	pci_dev_restore(dev);
562562306a36Sopenharmony_ci
562662306a36Sopenharmony_ci	return rc;
562762306a36Sopenharmony_ci}
562862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_reset_function_locked);
562962306a36Sopenharmony_ci
563062306a36Sopenharmony_ci/**
563162306a36Sopenharmony_ci * pci_try_reset_function - quiesce and reset a PCI device function
563262306a36Sopenharmony_ci * @dev: PCI device to reset
563362306a36Sopenharmony_ci *
563462306a36Sopenharmony_ci * Same as above, except return -EAGAIN if unable to lock device.
563562306a36Sopenharmony_ci */
563662306a36Sopenharmony_ciint pci_try_reset_function(struct pci_dev *dev)
563762306a36Sopenharmony_ci{
563862306a36Sopenharmony_ci	int rc;
563962306a36Sopenharmony_ci
564062306a36Sopenharmony_ci	if (!pci_reset_supported(dev))
564162306a36Sopenharmony_ci		return -ENOTTY;
564262306a36Sopenharmony_ci
564362306a36Sopenharmony_ci	if (!pci_dev_trylock(dev))
564462306a36Sopenharmony_ci		return -EAGAIN;
564562306a36Sopenharmony_ci
564662306a36Sopenharmony_ci	pci_dev_save_and_disable(dev);
564762306a36Sopenharmony_ci	rc = __pci_reset_function_locked(dev);
564862306a36Sopenharmony_ci	pci_dev_restore(dev);
564962306a36Sopenharmony_ci	pci_dev_unlock(dev);
565062306a36Sopenharmony_ci
565162306a36Sopenharmony_ci	return rc;
565262306a36Sopenharmony_ci}
565362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_try_reset_function);
565462306a36Sopenharmony_ci
565562306a36Sopenharmony_ci/* Do any devices on or below this bus prevent a bus reset? */
565662306a36Sopenharmony_cistatic bool pci_bus_resettable(struct pci_bus *bus)
565762306a36Sopenharmony_ci{
565862306a36Sopenharmony_ci	struct pci_dev *dev;
565962306a36Sopenharmony_ci
566062306a36Sopenharmony_ci
566162306a36Sopenharmony_ci	if (bus->self && (bus->self->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET))
566262306a36Sopenharmony_ci		return false;
566362306a36Sopenharmony_ci
566462306a36Sopenharmony_ci	list_for_each_entry(dev, &bus->devices, bus_list) {
566562306a36Sopenharmony_ci		if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET ||
566662306a36Sopenharmony_ci		    (dev->subordinate && !pci_bus_resettable(dev->subordinate)))
566762306a36Sopenharmony_ci			return false;
566862306a36Sopenharmony_ci	}
566962306a36Sopenharmony_ci
567062306a36Sopenharmony_ci	return true;
567162306a36Sopenharmony_ci}
567262306a36Sopenharmony_ci
567362306a36Sopenharmony_ci/* Lock devices from the top of the tree down */
567462306a36Sopenharmony_cistatic void pci_bus_lock(struct pci_bus *bus)
567562306a36Sopenharmony_ci{
567662306a36Sopenharmony_ci	struct pci_dev *dev;
567762306a36Sopenharmony_ci
567862306a36Sopenharmony_ci	list_for_each_entry(dev, &bus->devices, bus_list) {
567962306a36Sopenharmony_ci		pci_dev_lock(dev);
568062306a36Sopenharmony_ci		if (dev->subordinate)
568162306a36Sopenharmony_ci			pci_bus_lock(dev->subordinate);
568262306a36Sopenharmony_ci	}
568362306a36Sopenharmony_ci}
568462306a36Sopenharmony_ci
568562306a36Sopenharmony_ci/* Unlock devices from the bottom of the tree up */
568662306a36Sopenharmony_cistatic void pci_bus_unlock(struct pci_bus *bus)
568762306a36Sopenharmony_ci{
568862306a36Sopenharmony_ci	struct pci_dev *dev;
568962306a36Sopenharmony_ci
569062306a36Sopenharmony_ci	list_for_each_entry(dev, &bus->devices, bus_list) {
569162306a36Sopenharmony_ci		if (dev->subordinate)
569262306a36Sopenharmony_ci			pci_bus_unlock(dev->subordinate);
569362306a36Sopenharmony_ci		pci_dev_unlock(dev);
569462306a36Sopenharmony_ci	}
569562306a36Sopenharmony_ci}
569662306a36Sopenharmony_ci
569762306a36Sopenharmony_ci/* Return 1 on successful lock, 0 on contention */
569862306a36Sopenharmony_cistatic int pci_bus_trylock(struct pci_bus *bus)
569962306a36Sopenharmony_ci{
570062306a36Sopenharmony_ci	struct pci_dev *dev;
570162306a36Sopenharmony_ci
570262306a36Sopenharmony_ci	list_for_each_entry(dev, &bus->devices, bus_list) {
570362306a36Sopenharmony_ci		if (!pci_dev_trylock(dev))
570462306a36Sopenharmony_ci			goto unlock;
570562306a36Sopenharmony_ci		if (dev->subordinate) {
570662306a36Sopenharmony_ci			if (!pci_bus_trylock(dev->subordinate)) {
570762306a36Sopenharmony_ci				pci_dev_unlock(dev);
570862306a36Sopenharmony_ci				goto unlock;
570962306a36Sopenharmony_ci			}
571062306a36Sopenharmony_ci		}
571162306a36Sopenharmony_ci	}
571262306a36Sopenharmony_ci	return 1;
571362306a36Sopenharmony_ci
571462306a36Sopenharmony_ciunlock:
571562306a36Sopenharmony_ci	list_for_each_entry_continue_reverse(dev, &bus->devices, bus_list) {
571662306a36Sopenharmony_ci		if (dev->subordinate)
571762306a36Sopenharmony_ci			pci_bus_unlock(dev->subordinate);
571862306a36Sopenharmony_ci		pci_dev_unlock(dev);
571962306a36Sopenharmony_ci	}
572062306a36Sopenharmony_ci	return 0;
572162306a36Sopenharmony_ci}
572262306a36Sopenharmony_ci
572362306a36Sopenharmony_ci/* Do any devices on or below this slot prevent a bus reset? */
572462306a36Sopenharmony_cistatic bool pci_slot_resettable(struct pci_slot *slot)
572562306a36Sopenharmony_ci{
572662306a36Sopenharmony_ci	struct pci_dev *dev;
572762306a36Sopenharmony_ci
572862306a36Sopenharmony_ci	if (slot->bus->self &&
572962306a36Sopenharmony_ci	    (slot->bus->self->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET))
573062306a36Sopenharmony_ci		return false;
573162306a36Sopenharmony_ci
573262306a36Sopenharmony_ci	list_for_each_entry(dev, &slot->bus->devices, bus_list) {
573362306a36Sopenharmony_ci		if (!dev->slot || dev->slot != slot)
573462306a36Sopenharmony_ci			continue;
573562306a36Sopenharmony_ci		if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET ||
573662306a36Sopenharmony_ci		    (dev->subordinate && !pci_bus_resettable(dev->subordinate)))
573762306a36Sopenharmony_ci			return false;
573862306a36Sopenharmony_ci	}
573962306a36Sopenharmony_ci
574062306a36Sopenharmony_ci	return true;
574162306a36Sopenharmony_ci}
574262306a36Sopenharmony_ci
574362306a36Sopenharmony_ci/* Lock devices from the top of the tree down */
574462306a36Sopenharmony_cistatic void pci_slot_lock(struct pci_slot *slot)
574562306a36Sopenharmony_ci{
574662306a36Sopenharmony_ci	struct pci_dev *dev;
574762306a36Sopenharmony_ci
574862306a36Sopenharmony_ci	list_for_each_entry(dev, &slot->bus->devices, bus_list) {
574962306a36Sopenharmony_ci		if (!dev->slot || dev->slot != slot)
575062306a36Sopenharmony_ci			continue;
575162306a36Sopenharmony_ci		pci_dev_lock(dev);
575262306a36Sopenharmony_ci		if (dev->subordinate)
575362306a36Sopenharmony_ci			pci_bus_lock(dev->subordinate);
575462306a36Sopenharmony_ci	}
575562306a36Sopenharmony_ci}
575662306a36Sopenharmony_ci
575762306a36Sopenharmony_ci/* Unlock devices from the bottom of the tree up */
575862306a36Sopenharmony_cistatic void pci_slot_unlock(struct pci_slot *slot)
575962306a36Sopenharmony_ci{
576062306a36Sopenharmony_ci	struct pci_dev *dev;
576162306a36Sopenharmony_ci
576262306a36Sopenharmony_ci	list_for_each_entry(dev, &slot->bus->devices, bus_list) {
576362306a36Sopenharmony_ci		if (!dev->slot || dev->slot != slot)
576462306a36Sopenharmony_ci			continue;
576562306a36Sopenharmony_ci		if (dev->subordinate)
576662306a36Sopenharmony_ci			pci_bus_unlock(dev->subordinate);
576762306a36Sopenharmony_ci		pci_dev_unlock(dev);
576862306a36Sopenharmony_ci	}
576962306a36Sopenharmony_ci}
577062306a36Sopenharmony_ci
577162306a36Sopenharmony_ci/* Return 1 on successful lock, 0 on contention */
577262306a36Sopenharmony_cistatic int pci_slot_trylock(struct pci_slot *slot)
577362306a36Sopenharmony_ci{
577462306a36Sopenharmony_ci	struct pci_dev *dev;
577562306a36Sopenharmony_ci
577662306a36Sopenharmony_ci	list_for_each_entry(dev, &slot->bus->devices, bus_list) {
577762306a36Sopenharmony_ci		if (!dev->slot || dev->slot != slot)
577862306a36Sopenharmony_ci			continue;
577962306a36Sopenharmony_ci		if (!pci_dev_trylock(dev))
578062306a36Sopenharmony_ci			goto unlock;
578162306a36Sopenharmony_ci		if (dev->subordinate) {
578262306a36Sopenharmony_ci			if (!pci_bus_trylock(dev->subordinate)) {
578362306a36Sopenharmony_ci				pci_dev_unlock(dev);
578462306a36Sopenharmony_ci				goto unlock;
578562306a36Sopenharmony_ci			}
578662306a36Sopenharmony_ci		}
578762306a36Sopenharmony_ci	}
578862306a36Sopenharmony_ci	return 1;
578962306a36Sopenharmony_ci
579062306a36Sopenharmony_ciunlock:
579162306a36Sopenharmony_ci	list_for_each_entry_continue_reverse(dev,
579262306a36Sopenharmony_ci					     &slot->bus->devices, bus_list) {
579362306a36Sopenharmony_ci		if (!dev->slot || dev->slot != slot)
579462306a36Sopenharmony_ci			continue;
579562306a36Sopenharmony_ci		if (dev->subordinate)
579662306a36Sopenharmony_ci			pci_bus_unlock(dev->subordinate);
579762306a36Sopenharmony_ci		pci_dev_unlock(dev);
579862306a36Sopenharmony_ci	}
579962306a36Sopenharmony_ci	return 0;
580062306a36Sopenharmony_ci}
580162306a36Sopenharmony_ci
580262306a36Sopenharmony_ci/*
580362306a36Sopenharmony_ci * Save and disable devices from the top of the tree down while holding
580462306a36Sopenharmony_ci * the @dev mutex lock for the entire tree.
580562306a36Sopenharmony_ci */
580662306a36Sopenharmony_cistatic void pci_bus_save_and_disable_locked(struct pci_bus *bus)
580762306a36Sopenharmony_ci{
580862306a36Sopenharmony_ci	struct pci_dev *dev;
580962306a36Sopenharmony_ci
581062306a36Sopenharmony_ci	list_for_each_entry(dev, &bus->devices, bus_list) {
581162306a36Sopenharmony_ci		pci_dev_save_and_disable(dev);
581262306a36Sopenharmony_ci		if (dev->subordinate)
581362306a36Sopenharmony_ci			pci_bus_save_and_disable_locked(dev->subordinate);
581462306a36Sopenharmony_ci	}
581562306a36Sopenharmony_ci}
581662306a36Sopenharmony_ci
581762306a36Sopenharmony_ci/*
581862306a36Sopenharmony_ci * Restore devices from top of the tree down while holding @dev mutex lock
581962306a36Sopenharmony_ci * for the entire tree.  Parent bridges need to be restored before we can
582062306a36Sopenharmony_ci * get to subordinate devices.
582162306a36Sopenharmony_ci */
582262306a36Sopenharmony_cistatic void pci_bus_restore_locked(struct pci_bus *bus)
582362306a36Sopenharmony_ci{
582462306a36Sopenharmony_ci	struct pci_dev *dev;
582562306a36Sopenharmony_ci
582662306a36Sopenharmony_ci	list_for_each_entry(dev, &bus->devices, bus_list) {
582762306a36Sopenharmony_ci		pci_dev_restore(dev);
582862306a36Sopenharmony_ci		if (dev->subordinate)
582962306a36Sopenharmony_ci			pci_bus_restore_locked(dev->subordinate);
583062306a36Sopenharmony_ci	}
583162306a36Sopenharmony_ci}
583262306a36Sopenharmony_ci
583362306a36Sopenharmony_ci/*
583462306a36Sopenharmony_ci * Save and disable devices from the top of the tree down while holding
583562306a36Sopenharmony_ci * the @dev mutex lock for the entire tree.
583662306a36Sopenharmony_ci */
583762306a36Sopenharmony_cistatic void pci_slot_save_and_disable_locked(struct pci_slot *slot)
583862306a36Sopenharmony_ci{
583962306a36Sopenharmony_ci	struct pci_dev *dev;
584062306a36Sopenharmony_ci
584162306a36Sopenharmony_ci	list_for_each_entry(dev, &slot->bus->devices, bus_list) {
584262306a36Sopenharmony_ci		if (!dev->slot || dev->slot != slot)
584362306a36Sopenharmony_ci			continue;
584462306a36Sopenharmony_ci		pci_dev_save_and_disable(dev);
584562306a36Sopenharmony_ci		if (dev->subordinate)
584662306a36Sopenharmony_ci			pci_bus_save_and_disable_locked(dev->subordinate);
584762306a36Sopenharmony_ci	}
584862306a36Sopenharmony_ci}
584962306a36Sopenharmony_ci
585062306a36Sopenharmony_ci/*
585162306a36Sopenharmony_ci * Restore devices from top of the tree down while holding @dev mutex lock
585262306a36Sopenharmony_ci * for the entire tree.  Parent bridges need to be restored before we can
585362306a36Sopenharmony_ci * get to subordinate devices.
585462306a36Sopenharmony_ci */
585562306a36Sopenharmony_cistatic void pci_slot_restore_locked(struct pci_slot *slot)
585662306a36Sopenharmony_ci{
585762306a36Sopenharmony_ci	struct pci_dev *dev;
585862306a36Sopenharmony_ci
585962306a36Sopenharmony_ci	list_for_each_entry(dev, &slot->bus->devices, bus_list) {
586062306a36Sopenharmony_ci		if (!dev->slot || dev->slot != slot)
586162306a36Sopenharmony_ci			continue;
586262306a36Sopenharmony_ci		pci_dev_restore(dev);
586362306a36Sopenharmony_ci		if (dev->subordinate)
586462306a36Sopenharmony_ci			pci_bus_restore_locked(dev->subordinate);
586562306a36Sopenharmony_ci	}
586662306a36Sopenharmony_ci}
586762306a36Sopenharmony_ci
586862306a36Sopenharmony_cistatic int pci_slot_reset(struct pci_slot *slot, bool probe)
586962306a36Sopenharmony_ci{
587062306a36Sopenharmony_ci	int rc;
587162306a36Sopenharmony_ci
587262306a36Sopenharmony_ci	if (!slot || !pci_slot_resettable(slot))
587362306a36Sopenharmony_ci		return -ENOTTY;
587462306a36Sopenharmony_ci
587562306a36Sopenharmony_ci	if (!probe)
587662306a36Sopenharmony_ci		pci_slot_lock(slot);
587762306a36Sopenharmony_ci
587862306a36Sopenharmony_ci	might_sleep();
587962306a36Sopenharmony_ci
588062306a36Sopenharmony_ci	rc = pci_reset_hotplug_slot(slot->hotplug, probe);
588162306a36Sopenharmony_ci
588262306a36Sopenharmony_ci	if (!probe)
588362306a36Sopenharmony_ci		pci_slot_unlock(slot);
588462306a36Sopenharmony_ci
588562306a36Sopenharmony_ci	return rc;
588662306a36Sopenharmony_ci}
588762306a36Sopenharmony_ci
588862306a36Sopenharmony_ci/**
588962306a36Sopenharmony_ci * pci_probe_reset_slot - probe whether a PCI slot can be reset
589062306a36Sopenharmony_ci * @slot: PCI slot to probe
589162306a36Sopenharmony_ci *
589262306a36Sopenharmony_ci * Return 0 if slot can be reset, negative if a slot reset is not supported.
589362306a36Sopenharmony_ci */
589462306a36Sopenharmony_ciint pci_probe_reset_slot(struct pci_slot *slot)
589562306a36Sopenharmony_ci{
589662306a36Sopenharmony_ci	return pci_slot_reset(slot, PCI_RESET_PROBE);
589762306a36Sopenharmony_ci}
589862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_probe_reset_slot);
589962306a36Sopenharmony_ci
590062306a36Sopenharmony_ci/**
590162306a36Sopenharmony_ci * __pci_reset_slot - Try to reset a PCI slot
590262306a36Sopenharmony_ci * @slot: PCI slot to reset
590362306a36Sopenharmony_ci *
590462306a36Sopenharmony_ci * A PCI bus may host multiple slots, each slot may support a reset mechanism
590562306a36Sopenharmony_ci * independent of other slots.  For instance, some slots may support slot power
590662306a36Sopenharmony_ci * control.  In the case of a 1:1 bus to slot architecture, this function may
590762306a36Sopenharmony_ci * wrap the bus reset to avoid spurious slot related events such as hotplug.
590862306a36Sopenharmony_ci * Generally a slot reset should be attempted before a bus reset.  All of the
590962306a36Sopenharmony_ci * function of the slot and any subordinate buses behind the slot are reset
591062306a36Sopenharmony_ci * through this function.  PCI config space of all devices in the slot and
591162306a36Sopenharmony_ci * behind the slot is saved before and restored after reset.
591262306a36Sopenharmony_ci *
591362306a36Sopenharmony_ci * Same as above except return -EAGAIN if the slot cannot be locked
591462306a36Sopenharmony_ci */
591562306a36Sopenharmony_cistatic int __pci_reset_slot(struct pci_slot *slot)
591662306a36Sopenharmony_ci{
591762306a36Sopenharmony_ci	int rc;
591862306a36Sopenharmony_ci
591962306a36Sopenharmony_ci	rc = pci_slot_reset(slot, PCI_RESET_PROBE);
592062306a36Sopenharmony_ci	if (rc)
592162306a36Sopenharmony_ci		return rc;
592262306a36Sopenharmony_ci
592362306a36Sopenharmony_ci	if (pci_slot_trylock(slot)) {
592462306a36Sopenharmony_ci		pci_slot_save_and_disable_locked(slot);
592562306a36Sopenharmony_ci		might_sleep();
592662306a36Sopenharmony_ci		rc = pci_reset_hotplug_slot(slot->hotplug, PCI_RESET_DO_RESET);
592762306a36Sopenharmony_ci		pci_slot_restore_locked(slot);
592862306a36Sopenharmony_ci		pci_slot_unlock(slot);
592962306a36Sopenharmony_ci	} else
593062306a36Sopenharmony_ci		rc = -EAGAIN;
593162306a36Sopenharmony_ci
593262306a36Sopenharmony_ci	return rc;
593362306a36Sopenharmony_ci}
593462306a36Sopenharmony_ci
593562306a36Sopenharmony_cistatic int pci_bus_reset(struct pci_bus *bus, bool probe)
593662306a36Sopenharmony_ci{
593762306a36Sopenharmony_ci	int ret;
593862306a36Sopenharmony_ci
593962306a36Sopenharmony_ci	if (!bus->self || !pci_bus_resettable(bus))
594062306a36Sopenharmony_ci		return -ENOTTY;
594162306a36Sopenharmony_ci
594262306a36Sopenharmony_ci	if (probe)
594362306a36Sopenharmony_ci		return 0;
594462306a36Sopenharmony_ci
594562306a36Sopenharmony_ci	pci_bus_lock(bus);
594662306a36Sopenharmony_ci
594762306a36Sopenharmony_ci	might_sleep();
594862306a36Sopenharmony_ci
594962306a36Sopenharmony_ci	ret = pci_bridge_secondary_bus_reset(bus->self);
595062306a36Sopenharmony_ci
595162306a36Sopenharmony_ci	pci_bus_unlock(bus);
595262306a36Sopenharmony_ci
595362306a36Sopenharmony_ci	return ret;
595462306a36Sopenharmony_ci}
595562306a36Sopenharmony_ci
595662306a36Sopenharmony_ci/**
595762306a36Sopenharmony_ci * pci_bus_error_reset - reset the bridge's subordinate bus
595862306a36Sopenharmony_ci * @bridge: The parent device that connects to the bus to reset
595962306a36Sopenharmony_ci *
596062306a36Sopenharmony_ci * This function will first try to reset the slots on this bus if the method is
596162306a36Sopenharmony_ci * available. If slot reset fails or is not available, this will fall back to a
596262306a36Sopenharmony_ci * secondary bus reset.
596362306a36Sopenharmony_ci */
596462306a36Sopenharmony_ciint pci_bus_error_reset(struct pci_dev *bridge)
596562306a36Sopenharmony_ci{
596662306a36Sopenharmony_ci	struct pci_bus *bus = bridge->subordinate;
596762306a36Sopenharmony_ci	struct pci_slot *slot;
596862306a36Sopenharmony_ci
596962306a36Sopenharmony_ci	if (!bus)
597062306a36Sopenharmony_ci		return -ENOTTY;
597162306a36Sopenharmony_ci
597262306a36Sopenharmony_ci	mutex_lock(&pci_slot_mutex);
597362306a36Sopenharmony_ci	if (list_empty(&bus->slots))
597462306a36Sopenharmony_ci		goto bus_reset;
597562306a36Sopenharmony_ci
597662306a36Sopenharmony_ci	list_for_each_entry(slot, &bus->slots, list)
597762306a36Sopenharmony_ci		if (pci_probe_reset_slot(slot))
597862306a36Sopenharmony_ci			goto bus_reset;
597962306a36Sopenharmony_ci
598062306a36Sopenharmony_ci	list_for_each_entry(slot, &bus->slots, list)
598162306a36Sopenharmony_ci		if (pci_slot_reset(slot, PCI_RESET_DO_RESET))
598262306a36Sopenharmony_ci			goto bus_reset;
598362306a36Sopenharmony_ci
598462306a36Sopenharmony_ci	mutex_unlock(&pci_slot_mutex);
598562306a36Sopenharmony_ci	return 0;
598662306a36Sopenharmony_cibus_reset:
598762306a36Sopenharmony_ci	mutex_unlock(&pci_slot_mutex);
598862306a36Sopenharmony_ci	return pci_bus_reset(bridge->subordinate, PCI_RESET_DO_RESET);
598962306a36Sopenharmony_ci}
599062306a36Sopenharmony_ci
599162306a36Sopenharmony_ci/**
599262306a36Sopenharmony_ci * pci_probe_reset_bus - probe whether a PCI bus can be reset
599362306a36Sopenharmony_ci * @bus: PCI bus to probe
599462306a36Sopenharmony_ci *
599562306a36Sopenharmony_ci * Return 0 if bus can be reset, negative if a bus reset is not supported.
599662306a36Sopenharmony_ci */
599762306a36Sopenharmony_ciint pci_probe_reset_bus(struct pci_bus *bus)
599862306a36Sopenharmony_ci{
599962306a36Sopenharmony_ci	return pci_bus_reset(bus, PCI_RESET_PROBE);
600062306a36Sopenharmony_ci}
600162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_probe_reset_bus);
600262306a36Sopenharmony_ci
600362306a36Sopenharmony_ci/**
600462306a36Sopenharmony_ci * __pci_reset_bus - Try to reset a PCI bus
600562306a36Sopenharmony_ci * @bus: top level PCI bus to reset
600662306a36Sopenharmony_ci *
600762306a36Sopenharmony_ci * Same as above except return -EAGAIN if the bus cannot be locked
600862306a36Sopenharmony_ci */
600962306a36Sopenharmony_cistatic int __pci_reset_bus(struct pci_bus *bus)
601062306a36Sopenharmony_ci{
601162306a36Sopenharmony_ci	int rc;
601262306a36Sopenharmony_ci
601362306a36Sopenharmony_ci	rc = pci_bus_reset(bus, PCI_RESET_PROBE);
601462306a36Sopenharmony_ci	if (rc)
601562306a36Sopenharmony_ci		return rc;
601662306a36Sopenharmony_ci
601762306a36Sopenharmony_ci	if (pci_bus_trylock(bus)) {
601862306a36Sopenharmony_ci		pci_bus_save_and_disable_locked(bus);
601962306a36Sopenharmony_ci		might_sleep();
602062306a36Sopenharmony_ci		rc = pci_bridge_secondary_bus_reset(bus->self);
602162306a36Sopenharmony_ci		pci_bus_restore_locked(bus);
602262306a36Sopenharmony_ci		pci_bus_unlock(bus);
602362306a36Sopenharmony_ci	} else
602462306a36Sopenharmony_ci		rc = -EAGAIN;
602562306a36Sopenharmony_ci
602662306a36Sopenharmony_ci	return rc;
602762306a36Sopenharmony_ci}
602862306a36Sopenharmony_ci
602962306a36Sopenharmony_ci/**
603062306a36Sopenharmony_ci * pci_reset_bus - Try to reset a PCI bus
603162306a36Sopenharmony_ci * @pdev: top level PCI device to reset via slot/bus
603262306a36Sopenharmony_ci *
603362306a36Sopenharmony_ci * Same as above except return -EAGAIN if the bus cannot be locked
603462306a36Sopenharmony_ci */
603562306a36Sopenharmony_ciint pci_reset_bus(struct pci_dev *pdev)
603662306a36Sopenharmony_ci{
603762306a36Sopenharmony_ci	return (!pci_probe_reset_slot(pdev->slot)) ?
603862306a36Sopenharmony_ci	    __pci_reset_slot(pdev->slot) : __pci_reset_bus(pdev->bus);
603962306a36Sopenharmony_ci}
604062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_reset_bus);
604162306a36Sopenharmony_ci
604262306a36Sopenharmony_ci/**
604362306a36Sopenharmony_ci * pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count
604462306a36Sopenharmony_ci * @dev: PCI device to query
604562306a36Sopenharmony_ci *
604662306a36Sopenharmony_ci * Returns mmrbc: maximum designed memory read count in bytes or
604762306a36Sopenharmony_ci * appropriate error value.
604862306a36Sopenharmony_ci */
604962306a36Sopenharmony_ciint pcix_get_max_mmrbc(struct pci_dev *dev)
605062306a36Sopenharmony_ci{
605162306a36Sopenharmony_ci	int cap;
605262306a36Sopenharmony_ci	u32 stat;
605362306a36Sopenharmony_ci
605462306a36Sopenharmony_ci	cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
605562306a36Sopenharmony_ci	if (!cap)
605662306a36Sopenharmony_ci		return -EINVAL;
605762306a36Sopenharmony_ci
605862306a36Sopenharmony_ci	if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat))
605962306a36Sopenharmony_ci		return -EINVAL;
606062306a36Sopenharmony_ci
606162306a36Sopenharmony_ci	return 512 << ((stat & PCI_X_STATUS_MAX_READ) >> 21);
606262306a36Sopenharmony_ci}
606362306a36Sopenharmony_ciEXPORT_SYMBOL(pcix_get_max_mmrbc);
606462306a36Sopenharmony_ci
606562306a36Sopenharmony_ci/**
606662306a36Sopenharmony_ci * pcix_get_mmrbc - get PCI-X maximum memory read byte count
606762306a36Sopenharmony_ci * @dev: PCI device to query
606862306a36Sopenharmony_ci *
606962306a36Sopenharmony_ci * Returns mmrbc: maximum memory read count in bytes or appropriate error
607062306a36Sopenharmony_ci * value.
607162306a36Sopenharmony_ci */
607262306a36Sopenharmony_ciint pcix_get_mmrbc(struct pci_dev *dev)
607362306a36Sopenharmony_ci{
607462306a36Sopenharmony_ci	int cap;
607562306a36Sopenharmony_ci	u16 cmd;
607662306a36Sopenharmony_ci
607762306a36Sopenharmony_ci	cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
607862306a36Sopenharmony_ci	if (!cap)
607962306a36Sopenharmony_ci		return -EINVAL;
608062306a36Sopenharmony_ci
608162306a36Sopenharmony_ci	if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd))
608262306a36Sopenharmony_ci		return -EINVAL;
608362306a36Sopenharmony_ci
608462306a36Sopenharmony_ci	return 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2);
608562306a36Sopenharmony_ci}
608662306a36Sopenharmony_ciEXPORT_SYMBOL(pcix_get_mmrbc);
608762306a36Sopenharmony_ci
608862306a36Sopenharmony_ci/**
608962306a36Sopenharmony_ci * pcix_set_mmrbc - set PCI-X maximum memory read byte count
609062306a36Sopenharmony_ci * @dev: PCI device to query
609162306a36Sopenharmony_ci * @mmrbc: maximum memory read count in bytes
609262306a36Sopenharmony_ci *    valid values are 512, 1024, 2048, 4096
609362306a36Sopenharmony_ci *
609462306a36Sopenharmony_ci * If possible sets maximum memory read byte count, some bridges have errata
609562306a36Sopenharmony_ci * that prevent this.
609662306a36Sopenharmony_ci */
609762306a36Sopenharmony_ciint pcix_set_mmrbc(struct pci_dev *dev, int mmrbc)
609862306a36Sopenharmony_ci{
609962306a36Sopenharmony_ci	int cap;
610062306a36Sopenharmony_ci	u32 stat, v, o;
610162306a36Sopenharmony_ci	u16 cmd;
610262306a36Sopenharmony_ci
610362306a36Sopenharmony_ci	if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc))
610462306a36Sopenharmony_ci		return -EINVAL;
610562306a36Sopenharmony_ci
610662306a36Sopenharmony_ci	v = ffs(mmrbc) - 10;
610762306a36Sopenharmony_ci
610862306a36Sopenharmony_ci	cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
610962306a36Sopenharmony_ci	if (!cap)
611062306a36Sopenharmony_ci		return -EINVAL;
611162306a36Sopenharmony_ci
611262306a36Sopenharmony_ci	if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat))
611362306a36Sopenharmony_ci		return -EINVAL;
611462306a36Sopenharmony_ci
611562306a36Sopenharmony_ci	if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21)
611662306a36Sopenharmony_ci		return -E2BIG;
611762306a36Sopenharmony_ci
611862306a36Sopenharmony_ci	if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd))
611962306a36Sopenharmony_ci		return -EINVAL;
612062306a36Sopenharmony_ci
612162306a36Sopenharmony_ci	o = (cmd & PCI_X_CMD_MAX_READ) >> 2;
612262306a36Sopenharmony_ci	if (o != v) {
612362306a36Sopenharmony_ci		if (v > o && (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MMRBC))
612462306a36Sopenharmony_ci			return -EIO;
612562306a36Sopenharmony_ci
612662306a36Sopenharmony_ci		cmd &= ~PCI_X_CMD_MAX_READ;
612762306a36Sopenharmony_ci		cmd |= v << 2;
612862306a36Sopenharmony_ci		if (pci_write_config_word(dev, cap + PCI_X_CMD, cmd))
612962306a36Sopenharmony_ci			return -EIO;
613062306a36Sopenharmony_ci	}
613162306a36Sopenharmony_ci	return 0;
613262306a36Sopenharmony_ci}
613362306a36Sopenharmony_ciEXPORT_SYMBOL(pcix_set_mmrbc);
613462306a36Sopenharmony_ci
613562306a36Sopenharmony_ci/**
613662306a36Sopenharmony_ci * pcie_get_readrq - get PCI Express read request size
613762306a36Sopenharmony_ci * @dev: PCI device to query
613862306a36Sopenharmony_ci *
613962306a36Sopenharmony_ci * Returns maximum memory read request in bytes or appropriate error value.
614062306a36Sopenharmony_ci */
614162306a36Sopenharmony_ciint pcie_get_readrq(struct pci_dev *dev)
614262306a36Sopenharmony_ci{
614362306a36Sopenharmony_ci	u16 ctl;
614462306a36Sopenharmony_ci
614562306a36Sopenharmony_ci	pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl);
614662306a36Sopenharmony_ci
614762306a36Sopenharmony_ci	return 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12);
614862306a36Sopenharmony_ci}
614962306a36Sopenharmony_ciEXPORT_SYMBOL(pcie_get_readrq);
615062306a36Sopenharmony_ci
615162306a36Sopenharmony_ci/**
615262306a36Sopenharmony_ci * pcie_set_readrq - set PCI Express maximum memory read request
615362306a36Sopenharmony_ci * @dev: PCI device to query
615462306a36Sopenharmony_ci * @rq: maximum memory read count in bytes
615562306a36Sopenharmony_ci *    valid values are 128, 256, 512, 1024, 2048, 4096
615662306a36Sopenharmony_ci *
615762306a36Sopenharmony_ci * If possible sets maximum memory read request in bytes
615862306a36Sopenharmony_ci */
615962306a36Sopenharmony_ciint pcie_set_readrq(struct pci_dev *dev, int rq)
616062306a36Sopenharmony_ci{
616162306a36Sopenharmony_ci	u16 v;
616262306a36Sopenharmony_ci	int ret;
616362306a36Sopenharmony_ci	struct pci_host_bridge *bridge = pci_find_host_bridge(dev->bus);
616462306a36Sopenharmony_ci
616562306a36Sopenharmony_ci	if (rq < 128 || rq > 4096 || !is_power_of_2(rq))
616662306a36Sopenharmony_ci		return -EINVAL;
616762306a36Sopenharmony_ci
616862306a36Sopenharmony_ci	/*
616962306a36Sopenharmony_ci	 * If using the "performance" PCIe config, we clamp the read rq
617062306a36Sopenharmony_ci	 * size to the max packet size to keep the host bridge from
617162306a36Sopenharmony_ci	 * generating requests larger than we can cope with.
617262306a36Sopenharmony_ci	 */
617362306a36Sopenharmony_ci	if (pcie_bus_config == PCIE_BUS_PERFORMANCE) {
617462306a36Sopenharmony_ci		int mps = pcie_get_mps(dev);
617562306a36Sopenharmony_ci
617662306a36Sopenharmony_ci		if (mps < rq)
617762306a36Sopenharmony_ci			rq = mps;
617862306a36Sopenharmony_ci	}
617962306a36Sopenharmony_ci
618062306a36Sopenharmony_ci	v = (ffs(rq) - 8) << 12;
618162306a36Sopenharmony_ci
618262306a36Sopenharmony_ci	if (bridge->no_inc_mrrs) {
618362306a36Sopenharmony_ci		int max_mrrs = pcie_get_readrq(dev);
618462306a36Sopenharmony_ci
618562306a36Sopenharmony_ci		if (rq > max_mrrs) {
618662306a36Sopenharmony_ci			pci_info(dev, "can't set Max_Read_Request_Size to %d; max is %d\n", rq, max_mrrs);
618762306a36Sopenharmony_ci			return -EINVAL;
618862306a36Sopenharmony_ci		}
618962306a36Sopenharmony_ci	}
619062306a36Sopenharmony_ci
619162306a36Sopenharmony_ci	ret = pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
619262306a36Sopenharmony_ci						  PCI_EXP_DEVCTL_READRQ, v);
619362306a36Sopenharmony_ci
619462306a36Sopenharmony_ci	return pcibios_err_to_errno(ret);
619562306a36Sopenharmony_ci}
619662306a36Sopenharmony_ciEXPORT_SYMBOL(pcie_set_readrq);
619762306a36Sopenharmony_ci
619862306a36Sopenharmony_ci/**
619962306a36Sopenharmony_ci * pcie_get_mps - get PCI Express maximum payload size
620062306a36Sopenharmony_ci * @dev: PCI device to query
620162306a36Sopenharmony_ci *
620262306a36Sopenharmony_ci * Returns maximum payload size in bytes
620362306a36Sopenharmony_ci */
620462306a36Sopenharmony_ciint pcie_get_mps(struct pci_dev *dev)
620562306a36Sopenharmony_ci{
620662306a36Sopenharmony_ci	u16 ctl;
620762306a36Sopenharmony_ci
620862306a36Sopenharmony_ci	pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl);
620962306a36Sopenharmony_ci
621062306a36Sopenharmony_ci	return 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
621162306a36Sopenharmony_ci}
621262306a36Sopenharmony_ciEXPORT_SYMBOL(pcie_get_mps);
621362306a36Sopenharmony_ci
621462306a36Sopenharmony_ci/**
621562306a36Sopenharmony_ci * pcie_set_mps - set PCI Express maximum payload size
621662306a36Sopenharmony_ci * @dev: PCI device to query
621762306a36Sopenharmony_ci * @mps: maximum payload size in bytes
621862306a36Sopenharmony_ci *    valid values are 128, 256, 512, 1024, 2048, 4096
621962306a36Sopenharmony_ci *
622062306a36Sopenharmony_ci * If possible sets maximum payload size
622162306a36Sopenharmony_ci */
622262306a36Sopenharmony_ciint pcie_set_mps(struct pci_dev *dev, int mps)
622362306a36Sopenharmony_ci{
622462306a36Sopenharmony_ci	u16 v;
622562306a36Sopenharmony_ci	int ret;
622662306a36Sopenharmony_ci
622762306a36Sopenharmony_ci	if (mps < 128 || mps > 4096 || !is_power_of_2(mps))
622862306a36Sopenharmony_ci		return -EINVAL;
622962306a36Sopenharmony_ci
623062306a36Sopenharmony_ci	v = ffs(mps) - 8;
623162306a36Sopenharmony_ci	if (v > dev->pcie_mpss)
623262306a36Sopenharmony_ci		return -EINVAL;
623362306a36Sopenharmony_ci	v <<= 5;
623462306a36Sopenharmony_ci
623562306a36Sopenharmony_ci	ret = pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
623662306a36Sopenharmony_ci						  PCI_EXP_DEVCTL_PAYLOAD, v);
623762306a36Sopenharmony_ci
623862306a36Sopenharmony_ci	return pcibios_err_to_errno(ret);
623962306a36Sopenharmony_ci}
624062306a36Sopenharmony_ciEXPORT_SYMBOL(pcie_set_mps);
624162306a36Sopenharmony_ci
624262306a36Sopenharmony_ci/**
624362306a36Sopenharmony_ci * pcie_bandwidth_available - determine minimum link settings of a PCIe
624462306a36Sopenharmony_ci *			      device and its bandwidth limitation
624562306a36Sopenharmony_ci * @dev: PCI device to query
624662306a36Sopenharmony_ci * @limiting_dev: storage for device causing the bandwidth limitation
624762306a36Sopenharmony_ci * @speed: storage for speed of limiting device
624862306a36Sopenharmony_ci * @width: storage for width of limiting device
624962306a36Sopenharmony_ci *
625062306a36Sopenharmony_ci * Walk up the PCI device chain and find the point where the minimum
625162306a36Sopenharmony_ci * bandwidth is available.  Return the bandwidth available there and (if
625262306a36Sopenharmony_ci * limiting_dev, speed, and width pointers are supplied) information about
625362306a36Sopenharmony_ci * that point.  The bandwidth returned is in Mb/s, i.e., megabits/second of
625462306a36Sopenharmony_ci * raw bandwidth.
625562306a36Sopenharmony_ci */
625662306a36Sopenharmony_ciu32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev,
625762306a36Sopenharmony_ci			     enum pci_bus_speed *speed,
625862306a36Sopenharmony_ci			     enum pcie_link_width *width)
625962306a36Sopenharmony_ci{
626062306a36Sopenharmony_ci	u16 lnksta;
626162306a36Sopenharmony_ci	enum pci_bus_speed next_speed;
626262306a36Sopenharmony_ci	enum pcie_link_width next_width;
626362306a36Sopenharmony_ci	u32 bw, next_bw;
626462306a36Sopenharmony_ci
626562306a36Sopenharmony_ci	if (speed)
626662306a36Sopenharmony_ci		*speed = PCI_SPEED_UNKNOWN;
626762306a36Sopenharmony_ci	if (width)
626862306a36Sopenharmony_ci		*width = PCIE_LNK_WIDTH_UNKNOWN;
626962306a36Sopenharmony_ci
627062306a36Sopenharmony_ci	bw = 0;
627162306a36Sopenharmony_ci
627262306a36Sopenharmony_ci	while (dev) {
627362306a36Sopenharmony_ci		pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
627462306a36Sopenharmony_ci
627562306a36Sopenharmony_ci		next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS];
627662306a36Sopenharmony_ci		next_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, lnksta);
627762306a36Sopenharmony_ci
627862306a36Sopenharmony_ci		next_bw = next_width * PCIE_SPEED2MBS_ENC(next_speed);
627962306a36Sopenharmony_ci
628062306a36Sopenharmony_ci		/* Check if current device limits the total bandwidth */
628162306a36Sopenharmony_ci		if (!bw || next_bw <= bw) {
628262306a36Sopenharmony_ci			bw = next_bw;
628362306a36Sopenharmony_ci
628462306a36Sopenharmony_ci			if (limiting_dev)
628562306a36Sopenharmony_ci				*limiting_dev = dev;
628662306a36Sopenharmony_ci			if (speed)
628762306a36Sopenharmony_ci				*speed = next_speed;
628862306a36Sopenharmony_ci			if (width)
628962306a36Sopenharmony_ci				*width = next_width;
629062306a36Sopenharmony_ci		}
629162306a36Sopenharmony_ci
629262306a36Sopenharmony_ci		dev = pci_upstream_bridge(dev);
629362306a36Sopenharmony_ci	}
629462306a36Sopenharmony_ci
629562306a36Sopenharmony_ci	return bw;
629662306a36Sopenharmony_ci}
629762306a36Sopenharmony_ciEXPORT_SYMBOL(pcie_bandwidth_available);
629862306a36Sopenharmony_ci
629962306a36Sopenharmony_ci/**
630062306a36Sopenharmony_ci * pcie_get_speed_cap - query for the PCI device's link speed capability
630162306a36Sopenharmony_ci * @dev: PCI device to query
630262306a36Sopenharmony_ci *
630362306a36Sopenharmony_ci * Query the PCI device speed capability.  Return the maximum link speed
630462306a36Sopenharmony_ci * supported by the device.
630562306a36Sopenharmony_ci */
630662306a36Sopenharmony_cienum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev)
630762306a36Sopenharmony_ci{
630862306a36Sopenharmony_ci	u32 lnkcap2, lnkcap;
630962306a36Sopenharmony_ci
631062306a36Sopenharmony_ci	/*
631162306a36Sopenharmony_ci	 * Link Capabilities 2 was added in PCIe r3.0, sec 7.8.18.  The
631262306a36Sopenharmony_ci	 * implementation note there recommends using the Supported Link
631362306a36Sopenharmony_ci	 * Speeds Vector in Link Capabilities 2 when supported.
631462306a36Sopenharmony_ci	 *
631562306a36Sopenharmony_ci	 * Without Link Capabilities 2, i.e., prior to PCIe r3.0, software
631662306a36Sopenharmony_ci	 * should use the Supported Link Speeds field in Link Capabilities,
631762306a36Sopenharmony_ci	 * where only 2.5 GT/s and 5.0 GT/s speeds were defined.
631862306a36Sopenharmony_ci	 */
631962306a36Sopenharmony_ci	pcie_capability_read_dword(dev, PCI_EXP_LNKCAP2, &lnkcap2);
632062306a36Sopenharmony_ci
632162306a36Sopenharmony_ci	/* PCIe r3.0-compliant */
632262306a36Sopenharmony_ci	if (lnkcap2)
632362306a36Sopenharmony_ci		return PCIE_LNKCAP2_SLS2SPEED(lnkcap2);
632462306a36Sopenharmony_ci
632562306a36Sopenharmony_ci	pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap);
632662306a36Sopenharmony_ci	if ((lnkcap & PCI_EXP_LNKCAP_SLS) == PCI_EXP_LNKCAP_SLS_5_0GB)
632762306a36Sopenharmony_ci		return PCIE_SPEED_5_0GT;
632862306a36Sopenharmony_ci	else if ((lnkcap & PCI_EXP_LNKCAP_SLS) == PCI_EXP_LNKCAP_SLS_2_5GB)
632962306a36Sopenharmony_ci		return PCIE_SPEED_2_5GT;
633062306a36Sopenharmony_ci
633162306a36Sopenharmony_ci	return PCI_SPEED_UNKNOWN;
633262306a36Sopenharmony_ci}
633362306a36Sopenharmony_ciEXPORT_SYMBOL(pcie_get_speed_cap);
633462306a36Sopenharmony_ci
633562306a36Sopenharmony_ci/**
633662306a36Sopenharmony_ci * pcie_get_width_cap - query for the PCI device's link width capability
633762306a36Sopenharmony_ci * @dev: PCI device to query
633862306a36Sopenharmony_ci *
633962306a36Sopenharmony_ci * Query the PCI device width capability.  Return the maximum link width
634062306a36Sopenharmony_ci * supported by the device.
634162306a36Sopenharmony_ci */
634262306a36Sopenharmony_cienum pcie_link_width pcie_get_width_cap(struct pci_dev *dev)
634362306a36Sopenharmony_ci{
634462306a36Sopenharmony_ci	u32 lnkcap;
634562306a36Sopenharmony_ci
634662306a36Sopenharmony_ci	pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap);
634762306a36Sopenharmony_ci	if (lnkcap)
634862306a36Sopenharmony_ci		return FIELD_GET(PCI_EXP_LNKCAP_MLW, lnkcap);
634962306a36Sopenharmony_ci
635062306a36Sopenharmony_ci	return PCIE_LNK_WIDTH_UNKNOWN;
635162306a36Sopenharmony_ci}
635262306a36Sopenharmony_ciEXPORT_SYMBOL(pcie_get_width_cap);
635362306a36Sopenharmony_ci
635462306a36Sopenharmony_ci/**
635562306a36Sopenharmony_ci * pcie_bandwidth_capable - calculate a PCI device's link bandwidth capability
635662306a36Sopenharmony_ci * @dev: PCI device
635762306a36Sopenharmony_ci * @speed: storage for link speed
635862306a36Sopenharmony_ci * @width: storage for link width
635962306a36Sopenharmony_ci *
636062306a36Sopenharmony_ci * Calculate a PCI device's link bandwidth by querying for its link speed
636162306a36Sopenharmony_ci * and width, multiplying them, and applying encoding overhead.  The result
636262306a36Sopenharmony_ci * is in Mb/s, i.e., megabits/second of raw bandwidth.
636362306a36Sopenharmony_ci */
636462306a36Sopenharmony_ciu32 pcie_bandwidth_capable(struct pci_dev *dev, enum pci_bus_speed *speed,
636562306a36Sopenharmony_ci			   enum pcie_link_width *width)
636662306a36Sopenharmony_ci{
636762306a36Sopenharmony_ci	*speed = pcie_get_speed_cap(dev);
636862306a36Sopenharmony_ci	*width = pcie_get_width_cap(dev);
636962306a36Sopenharmony_ci
637062306a36Sopenharmony_ci	if (*speed == PCI_SPEED_UNKNOWN || *width == PCIE_LNK_WIDTH_UNKNOWN)
637162306a36Sopenharmony_ci		return 0;
637262306a36Sopenharmony_ci
637362306a36Sopenharmony_ci	return *width * PCIE_SPEED2MBS_ENC(*speed);
637462306a36Sopenharmony_ci}
637562306a36Sopenharmony_ci
637662306a36Sopenharmony_ci/**
637762306a36Sopenharmony_ci * __pcie_print_link_status - Report the PCI device's link speed and width
637862306a36Sopenharmony_ci * @dev: PCI device to query
637962306a36Sopenharmony_ci * @verbose: Print info even when enough bandwidth is available
638062306a36Sopenharmony_ci *
638162306a36Sopenharmony_ci * If the available bandwidth at the device is less than the device is
638262306a36Sopenharmony_ci * capable of, report the device's maximum possible bandwidth and the
638362306a36Sopenharmony_ci * upstream link that limits its performance.  If @verbose, always print
638462306a36Sopenharmony_ci * the available bandwidth, even if the device isn't constrained.
638562306a36Sopenharmony_ci */
638662306a36Sopenharmony_civoid __pcie_print_link_status(struct pci_dev *dev, bool verbose)
638762306a36Sopenharmony_ci{
638862306a36Sopenharmony_ci	enum pcie_link_width width, width_cap;
638962306a36Sopenharmony_ci	enum pci_bus_speed speed, speed_cap;
639062306a36Sopenharmony_ci	struct pci_dev *limiting_dev = NULL;
639162306a36Sopenharmony_ci	u32 bw_avail, bw_cap;
639262306a36Sopenharmony_ci
639362306a36Sopenharmony_ci	bw_cap = pcie_bandwidth_capable(dev, &speed_cap, &width_cap);
639462306a36Sopenharmony_ci	bw_avail = pcie_bandwidth_available(dev, &limiting_dev, &speed, &width);
639562306a36Sopenharmony_ci
639662306a36Sopenharmony_ci	if (bw_avail >= bw_cap && verbose)
639762306a36Sopenharmony_ci		pci_info(dev, "%u.%03u Gb/s available PCIe bandwidth (%s x%d link)\n",
639862306a36Sopenharmony_ci			 bw_cap / 1000, bw_cap % 1000,
639962306a36Sopenharmony_ci			 pci_speed_string(speed_cap), width_cap);
640062306a36Sopenharmony_ci	else if (bw_avail < bw_cap)
640162306a36Sopenharmony_ci		pci_info(dev, "%u.%03u Gb/s available PCIe bandwidth, limited by %s x%d link at %s (capable of %u.%03u Gb/s with %s x%d link)\n",
640262306a36Sopenharmony_ci			 bw_avail / 1000, bw_avail % 1000,
640362306a36Sopenharmony_ci			 pci_speed_string(speed), width,
640462306a36Sopenharmony_ci			 limiting_dev ? pci_name(limiting_dev) : "<unknown>",
640562306a36Sopenharmony_ci			 bw_cap / 1000, bw_cap % 1000,
640662306a36Sopenharmony_ci			 pci_speed_string(speed_cap), width_cap);
640762306a36Sopenharmony_ci}
640862306a36Sopenharmony_ci
640962306a36Sopenharmony_ci/**
641062306a36Sopenharmony_ci * pcie_print_link_status - Report the PCI device's link speed and width
641162306a36Sopenharmony_ci * @dev: PCI device to query
641262306a36Sopenharmony_ci *
641362306a36Sopenharmony_ci * Report the available bandwidth at the device.
641462306a36Sopenharmony_ci */
641562306a36Sopenharmony_civoid pcie_print_link_status(struct pci_dev *dev)
641662306a36Sopenharmony_ci{
641762306a36Sopenharmony_ci	__pcie_print_link_status(dev, true);
641862306a36Sopenharmony_ci}
641962306a36Sopenharmony_ciEXPORT_SYMBOL(pcie_print_link_status);
642062306a36Sopenharmony_ci
642162306a36Sopenharmony_ci/**
642262306a36Sopenharmony_ci * pci_select_bars - Make BAR mask from the type of resource
642362306a36Sopenharmony_ci * @dev: the PCI device for which BAR mask is made
642462306a36Sopenharmony_ci * @flags: resource type mask to be selected
642562306a36Sopenharmony_ci *
642662306a36Sopenharmony_ci * This helper routine makes bar mask from the type of resource.
642762306a36Sopenharmony_ci */
642862306a36Sopenharmony_ciint pci_select_bars(struct pci_dev *dev, unsigned long flags)
642962306a36Sopenharmony_ci{
643062306a36Sopenharmony_ci	int i, bars = 0;
643162306a36Sopenharmony_ci	for (i = 0; i < PCI_NUM_RESOURCES; i++)
643262306a36Sopenharmony_ci		if (pci_resource_flags(dev, i) & flags)
643362306a36Sopenharmony_ci			bars |= (1 << i);
643462306a36Sopenharmony_ci	return bars;
643562306a36Sopenharmony_ci}
643662306a36Sopenharmony_ciEXPORT_SYMBOL(pci_select_bars);
643762306a36Sopenharmony_ci
643862306a36Sopenharmony_ci/* Some architectures require additional programming to enable VGA */
643962306a36Sopenharmony_cistatic arch_set_vga_state_t arch_set_vga_state;
644062306a36Sopenharmony_ci
644162306a36Sopenharmony_civoid __init pci_register_set_vga_state(arch_set_vga_state_t func)
644262306a36Sopenharmony_ci{
644362306a36Sopenharmony_ci	arch_set_vga_state = func;	/* NULL disables */
644462306a36Sopenharmony_ci}
644562306a36Sopenharmony_ci
644662306a36Sopenharmony_cistatic int pci_set_vga_state_arch(struct pci_dev *dev, bool decode,
644762306a36Sopenharmony_ci				  unsigned int command_bits, u32 flags)
644862306a36Sopenharmony_ci{
644962306a36Sopenharmony_ci	if (arch_set_vga_state)
645062306a36Sopenharmony_ci		return arch_set_vga_state(dev, decode, command_bits,
645162306a36Sopenharmony_ci						flags);
645262306a36Sopenharmony_ci	return 0;
645362306a36Sopenharmony_ci}
645462306a36Sopenharmony_ci
645562306a36Sopenharmony_ci/**
645662306a36Sopenharmony_ci * pci_set_vga_state - set VGA decode state on device and parents if requested
645762306a36Sopenharmony_ci * @dev: the PCI device
645862306a36Sopenharmony_ci * @decode: true = enable decoding, false = disable decoding
645962306a36Sopenharmony_ci * @command_bits: PCI_COMMAND_IO and/or PCI_COMMAND_MEMORY
646062306a36Sopenharmony_ci * @flags: traverse ancestors and change bridges
646162306a36Sopenharmony_ci * CHANGE_BRIDGE_ONLY / CHANGE_BRIDGE
646262306a36Sopenharmony_ci */
646362306a36Sopenharmony_ciint pci_set_vga_state(struct pci_dev *dev, bool decode,
646462306a36Sopenharmony_ci		      unsigned int command_bits, u32 flags)
646562306a36Sopenharmony_ci{
646662306a36Sopenharmony_ci	struct pci_bus *bus;
646762306a36Sopenharmony_ci	struct pci_dev *bridge;
646862306a36Sopenharmony_ci	u16 cmd;
646962306a36Sopenharmony_ci	int rc;
647062306a36Sopenharmony_ci
647162306a36Sopenharmony_ci	WARN_ON((flags & PCI_VGA_STATE_CHANGE_DECODES) && (command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY)));
647262306a36Sopenharmony_ci
647362306a36Sopenharmony_ci	/* ARCH specific VGA enables */
647462306a36Sopenharmony_ci	rc = pci_set_vga_state_arch(dev, decode, command_bits, flags);
647562306a36Sopenharmony_ci	if (rc)
647662306a36Sopenharmony_ci		return rc;
647762306a36Sopenharmony_ci
647862306a36Sopenharmony_ci	if (flags & PCI_VGA_STATE_CHANGE_DECODES) {
647962306a36Sopenharmony_ci		pci_read_config_word(dev, PCI_COMMAND, &cmd);
648062306a36Sopenharmony_ci		if (decode)
648162306a36Sopenharmony_ci			cmd |= command_bits;
648262306a36Sopenharmony_ci		else
648362306a36Sopenharmony_ci			cmd &= ~command_bits;
648462306a36Sopenharmony_ci		pci_write_config_word(dev, PCI_COMMAND, cmd);
648562306a36Sopenharmony_ci	}
648662306a36Sopenharmony_ci
648762306a36Sopenharmony_ci	if (!(flags & PCI_VGA_STATE_CHANGE_BRIDGE))
648862306a36Sopenharmony_ci		return 0;
648962306a36Sopenharmony_ci
649062306a36Sopenharmony_ci	bus = dev->bus;
649162306a36Sopenharmony_ci	while (bus) {
649262306a36Sopenharmony_ci		bridge = bus->self;
649362306a36Sopenharmony_ci		if (bridge) {
649462306a36Sopenharmony_ci			pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
649562306a36Sopenharmony_ci					     &cmd);
649662306a36Sopenharmony_ci			if (decode)
649762306a36Sopenharmony_ci				cmd |= PCI_BRIDGE_CTL_VGA;
649862306a36Sopenharmony_ci			else
649962306a36Sopenharmony_ci				cmd &= ~PCI_BRIDGE_CTL_VGA;
650062306a36Sopenharmony_ci			pci_write_config_word(bridge, PCI_BRIDGE_CONTROL,
650162306a36Sopenharmony_ci					      cmd);
650262306a36Sopenharmony_ci		}
650362306a36Sopenharmony_ci		bus = bus->parent;
650462306a36Sopenharmony_ci	}
650562306a36Sopenharmony_ci	return 0;
650662306a36Sopenharmony_ci}
650762306a36Sopenharmony_ci
650862306a36Sopenharmony_ci#ifdef CONFIG_ACPI
650962306a36Sopenharmony_cibool pci_pr3_present(struct pci_dev *pdev)
651062306a36Sopenharmony_ci{
651162306a36Sopenharmony_ci	struct acpi_device *adev;
651262306a36Sopenharmony_ci
651362306a36Sopenharmony_ci	if (acpi_disabled)
651462306a36Sopenharmony_ci		return false;
651562306a36Sopenharmony_ci
651662306a36Sopenharmony_ci	adev = ACPI_COMPANION(&pdev->dev);
651762306a36Sopenharmony_ci	if (!adev)
651862306a36Sopenharmony_ci		return false;
651962306a36Sopenharmony_ci
652062306a36Sopenharmony_ci	return adev->power.flags.power_resources &&
652162306a36Sopenharmony_ci		acpi_has_method(adev->handle, "_PR3");
652262306a36Sopenharmony_ci}
652362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_pr3_present);
652462306a36Sopenharmony_ci#endif
652562306a36Sopenharmony_ci
652662306a36Sopenharmony_ci/**
652762306a36Sopenharmony_ci * pci_add_dma_alias - Add a DMA devfn alias for a device
652862306a36Sopenharmony_ci * @dev: the PCI device for which alias is added
652962306a36Sopenharmony_ci * @devfn_from: alias slot and function
653062306a36Sopenharmony_ci * @nr_devfns: number of subsequent devfns to alias
653162306a36Sopenharmony_ci *
653262306a36Sopenharmony_ci * This helper encodes an 8-bit devfn as a bit number in dma_alias_mask
653362306a36Sopenharmony_ci * which is used to program permissible bus-devfn source addresses for DMA
653462306a36Sopenharmony_ci * requests in an IOMMU.  These aliases factor into IOMMU group creation
653562306a36Sopenharmony_ci * and are useful for devices generating DMA requests beyond or different
653662306a36Sopenharmony_ci * from their logical bus-devfn.  Examples include device quirks where the
653762306a36Sopenharmony_ci * device simply uses the wrong devfn, as well as non-transparent bridges
653862306a36Sopenharmony_ci * where the alias may be a proxy for devices in another domain.
653962306a36Sopenharmony_ci *
654062306a36Sopenharmony_ci * IOMMU group creation is performed during device discovery or addition,
654162306a36Sopenharmony_ci * prior to any potential DMA mapping and therefore prior to driver probing
654262306a36Sopenharmony_ci * (especially for userspace assigned devices where IOMMU group definition
654362306a36Sopenharmony_ci * cannot be left as a userspace activity).  DMA aliases should therefore
654462306a36Sopenharmony_ci * be configured via quirks, such as the PCI fixup header quirk.
654562306a36Sopenharmony_ci */
654662306a36Sopenharmony_civoid pci_add_dma_alias(struct pci_dev *dev, u8 devfn_from,
654762306a36Sopenharmony_ci		       unsigned int nr_devfns)
654862306a36Sopenharmony_ci{
654962306a36Sopenharmony_ci	int devfn_to;
655062306a36Sopenharmony_ci
655162306a36Sopenharmony_ci	nr_devfns = min(nr_devfns, (unsigned int)MAX_NR_DEVFNS - devfn_from);
655262306a36Sopenharmony_ci	devfn_to = devfn_from + nr_devfns - 1;
655362306a36Sopenharmony_ci
655462306a36Sopenharmony_ci	if (!dev->dma_alias_mask)
655562306a36Sopenharmony_ci		dev->dma_alias_mask = bitmap_zalloc(MAX_NR_DEVFNS, GFP_KERNEL);
655662306a36Sopenharmony_ci	if (!dev->dma_alias_mask) {
655762306a36Sopenharmony_ci		pci_warn(dev, "Unable to allocate DMA alias mask\n");
655862306a36Sopenharmony_ci		return;
655962306a36Sopenharmony_ci	}
656062306a36Sopenharmony_ci
656162306a36Sopenharmony_ci	bitmap_set(dev->dma_alias_mask, devfn_from, nr_devfns);
656262306a36Sopenharmony_ci
656362306a36Sopenharmony_ci	if (nr_devfns == 1)
656462306a36Sopenharmony_ci		pci_info(dev, "Enabling fixed DMA alias to %02x.%d\n",
656562306a36Sopenharmony_ci				PCI_SLOT(devfn_from), PCI_FUNC(devfn_from));
656662306a36Sopenharmony_ci	else if (nr_devfns > 1)
656762306a36Sopenharmony_ci		pci_info(dev, "Enabling fixed DMA alias for devfn range from %02x.%d to %02x.%d\n",
656862306a36Sopenharmony_ci				PCI_SLOT(devfn_from), PCI_FUNC(devfn_from),
656962306a36Sopenharmony_ci				PCI_SLOT(devfn_to), PCI_FUNC(devfn_to));
657062306a36Sopenharmony_ci}
657162306a36Sopenharmony_ci
657262306a36Sopenharmony_cibool pci_devs_are_dma_aliases(struct pci_dev *dev1, struct pci_dev *dev2)
657362306a36Sopenharmony_ci{
657462306a36Sopenharmony_ci	return (dev1->dma_alias_mask &&
657562306a36Sopenharmony_ci		test_bit(dev2->devfn, dev1->dma_alias_mask)) ||
657662306a36Sopenharmony_ci	       (dev2->dma_alias_mask &&
657762306a36Sopenharmony_ci		test_bit(dev1->devfn, dev2->dma_alias_mask)) ||
657862306a36Sopenharmony_ci	       pci_real_dma_dev(dev1) == dev2 ||
657962306a36Sopenharmony_ci	       pci_real_dma_dev(dev2) == dev1;
658062306a36Sopenharmony_ci}
658162306a36Sopenharmony_ci
658262306a36Sopenharmony_cibool pci_device_is_present(struct pci_dev *pdev)
658362306a36Sopenharmony_ci{
658462306a36Sopenharmony_ci	u32 v;
658562306a36Sopenharmony_ci
658662306a36Sopenharmony_ci	/* Check PF if pdev is a VF, since VF Vendor/Device IDs are 0xffff */
658762306a36Sopenharmony_ci	pdev = pci_physfn(pdev);
658862306a36Sopenharmony_ci	if (pci_dev_is_disconnected(pdev))
658962306a36Sopenharmony_ci		return false;
659062306a36Sopenharmony_ci	return pci_bus_read_dev_vendor_id(pdev->bus, pdev->devfn, &v, 0);
659162306a36Sopenharmony_ci}
659262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_device_is_present);
659362306a36Sopenharmony_ci
659462306a36Sopenharmony_civoid pci_ignore_hotplug(struct pci_dev *dev)
659562306a36Sopenharmony_ci{
659662306a36Sopenharmony_ci	struct pci_dev *bridge = dev->bus->self;
659762306a36Sopenharmony_ci
659862306a36Sopenharmony_ci	dev->ignore_hotplug = 1;
659962306a36Sopenharmony_ci	/* Propagate the "ignore hotplug" setting to the parent bridge. */
660062306a36Sopenharmony_ci	if (bridge)
660162306a36Sopenharmony_ci		bridge->ignore_hotplug = 1;
660262306a36Sopenharmony_ci}
660362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_ignore_hotplug);
660462306a36Sopenharmony_ci
660562306a36Sopenharmony_ci/**
660662306a36Sopenharmony_ci * pci_real_dma_dev - Get PCI DMA device for PCI device
660762306a36Sopenharmony_ci * @dev: the PCI device that may have a PCI DMA alias
660862306a36Sopenharmony_ci *
660962306a36Sopenharmony_ci * Permits the platform to provide architecture-specific functionality to
661062306a36Sopenharmony_ci * devices needing to alias DMA to another PCI device on another PCI bus. If
661162306a36Sopenharmony_ci * the PCI device is on the same bus, it is recommended to use
661262306a36Sopenharmony_ci * pci_add_dma_alias(). This is the default implementation. Architecture
661362306a36Sopenharmony_ci * implementations can override this.
661462306a36Sopenharmony_ci */
661562306a36Sopenharmony_cistruct pci_dev __weak *pci_real_dma_dev(struct pci_dev *dev)
661662306a36Sopenharmony_ci{
661762306a36Sopenharmony_ci	return dev;
661862306a36Sopenharmony_ci}
661962306a36Sopenharmony_ci
662062306a36Sopenharmony_ciresource_size_t __weak pcibios_default_alignment(void)
662162306a36Sopenharmony_ci{
662262306a36Sopenharmony_ci	return 0;
662362306a36Sopenharmony_ci}
662462306a36Sopenharmony_ci
662562306a36Sopenharmony_ci/*
662662306a36Sopenharmony_ci * Arches that don't want to expose struct resource to userland as-is in
662762306a36Sopenharmony_ci * sysfs and /proc can implement their own pci_resource_to_user().
662862306a36Sopenharmony_ci */
662962306a36Sopenharmony_civoid __weak pci_resource_to_user(const struct pci_dev *dev, int bar,
663062306a36Sopenharmony_ci				 const struct resource *rsrc,
663162306a36Sopenharmony_ci				 resource_size_t *start, resource_size_t *end)
663262306a36Sopenharmony_ci{
663362306a36Sopenharmony_ci	*start = rsrc->start;
663462306a36Sopenharmony_ci	*end = rsrc->end;
663562306a36Sopenharmony_ci}
663662306a36Sopenharmony_ci
663762306a36Sopenharmony_cistatic char *resource_alignment_param;
663862306a36Sopenharmony_cistatic DEFINE_SPINLOCK(resource_alignment_lock);
663962306a36Sopenharmony_ci
664062306a36Sopenharmony_ci/**
664162306a36Sopenharmony_ci * pci_specified_resource_alignment - get resource alignment specified by user.
664262306a36Sopenharmony_ci * @dev: the PCI device to get
664362306a36Sopenharmony_ci * @resize: whether or not to change resources' size when reassigning alignment
664462306a36Sopenharmony_ci *
664562306a36Sopenharmony_ci * RETURNS: Resource alignment if it is specified.
664662306a36Sopenharmony_ci *          Zero if it is not specified.
664762306a36Sopenharmony_ci */
664862306a36Sopenharmony_cistatic resource_size_t pci_specified_resource_alignment(struct pci_dev *dev,
664962306a36Sopenharmony_ci							bool *resize)
665062306a36Sopenharmony_ci{
665162306a36Sopenharmony_ci	int align_order, count;
665262306a36Sopenharmony_ci	resource_size_t align = pcibios_default_alignment();
665362306a36Sopenharmony_ci	const char *p;
665462306a36Sopenharmony_ci	int ret;
665562306a36Sopenharmony_ci
665662306a36Sopenharmony_ci	spin_lock(&resource_alignment_lock);
665762306a36Sopenharmony_ci	p = resource_alignment_param;
665862306a36Sopenharmony_ci	if (!p || !*p)
665962306a36Sopenharmony_ci		goto out;
666062306a36Sopenharmony_ci	if (pci_has_flag(PCI_PROBE_ONLY)) {
666162306a36Sopenharmony_ci		align = 0;
666262306a36Sopenharmony_ci		pr_info_once("PCI: Ignoring requested alignments (PCI_PROBE_ONLY)\n");
666362306a36Sopenharmony_ci		goto out;
666462306a36Sopenharmony_ci	}
666562306a36Sopenharmony_ci
666662306a36Sopenharmony_ci	while (*p) {
666762306a36Sopenharmony_ci		count = 0;
666862306a36Sopenharmony_ci		if (sscanf(p, "%d%n", &align_order, &count) == 1 &&
666962306a36Sopenharmony_ci		    p[count] == '@') {
667062306a36Sopenharmony_ci			p += count + 1;
667162306a36Sopenharmony_ci			if (align_order > 63) {
667262306a36Sopenharmony_ci				pr_err("PCI: Invalid requested alignment (order %d)\n",
667362306a36Sopenharmony_ci				       align_order);
667462306a36Sopenharmony_ci				align_order = PAGE_SHIFT;
667562306a36Sopenharmony_ci			}
667662306a36Sopenharmony_ci		} else {
667762306a36Sopenharmony_ci			align_order = PAGE_SHIFT;
667862306a36Sopenharmony_ci		}
667962306a36Sopenharmony_ci
668062306a36Sopenharmony_ci		ret = pci_dev_str_match(dev, p, &p);
668162306a36Sopenharmony_ci		if (ret == 1) {
668262306a36Sopenharmony_ci			*resize = true;
668362306a36Sopenharmony_ci			align = 1ULL << align_order;
668462306a36Sopenharmony_ci			break;
668562306a36Sopenharmony_ci		} else if (ret < 0) {
668662306a36Sopenharmony_ci			pr_err("PCI: Can't parse resource_alignment parameter: %s\n",
668762306a36Sopenharmony_ci			       p);
668862306a36Sopenharmony_ci			break;
668962306a36Sopenharmony_ci		}
669062306a36Sopenharmony_ci
669162306a36Sopenharmony_ci		if (*p != ';' && *p != ',') {
669262306a36Sopenharmony_ci			/* End of param or invalid format */
669362306a36Sopenharmony_ci			break;
669462306a36Sopenharmony_ci		}
669562306a36Sopenharmony_ci		p++;
669662306a36Sopenharmony_ci	}
669762306a36Sopenharmony_ciout:
669862306a36Sopenharmony_ci	spin_unlock(&resource_alignment_lock);
669962306a36Sopenharmony_ci	return align;
670062306a36Sopenharmony_ci}
670162306a36Sopenharmony_ci
670262306a36Sopenharmony_cistatic void pci_request_resource_alignment(struct pci_dev *dev, int bar,
670362306a36Sopenharmony_ci					   resource_size_t align, bool resize)
670462306a36Sopenharmony_ci{
670562306a36Sopenharmony_ci	struct resource *r = &dev->resource[bar];
670662306a36Sopenharmony_ci	resource_size_t size;
670762306a36Sopenharmony_ci
670862306a36Sopenharmony_ci	if (!(r->flags & IORESOURCE_MEM))
670962306a36Sopenharmony_ci		return;
671062306a36Sopenharmony_ci
671162306a36Sopenharmony_ci	if (r->flags & IORESOURCE_PCI_FIXED) {
671262306a36Sopenharmony_ci		pci_info(dev, "BAR%d %pR: ignoring requested alignment %#llx\n",
671362306a36Sopenharmony_ci			 bar, r, (unsigned long long)align);
671462306a36Sopenharmony_ci		return;
671562306a36Sopenharmony_ci	}
671662306a36Sopenharmony_ci
671762306a36Sopenharmony_ci	size = resource_size(r);
671862306a36Sopenharmony_ci	if (size >= align)
671962306a36Sopenharmony_ci		return;
672062306a36Sopenharmony_ci
672162306a36Sopenharmony_ci	/*
672262306a36Sopenharmony_ci	 * Increase the alignment of the resource.  There are two ways we
672362306a36Sopenharmony_ci	 * can do this:
672462306a36Sopenharmony_ci	 *
672562306a36Sopenharmony_ci	 * 1) Increase the size of the resource.  BARs are aligned on their
672662306a36Sopenharmony_ci	 *    size, so when we reallocate space for this resource, we'll
672762306a36Sopenharmony_ci	 *    allocate it with the larger alignment.  This also prevents
672862306a36Sopenharmony_ci	 *    assignment of any other BARs inside the alignment region, so
672962306a36Sopenharmony_ci	 *    if we're requesting page alignment, this means no other BARs
673062306a36Sopenharmony_ci	 *    will share the page.
673162306a36Sopenharmony_ci	 *
673262306a36Sopenharmony_ci	 *    The disadvantage is that this makes the resource larger than
673362306a36Sopenharmony_ci	 *    the hardware BAR, which may break drivers that compute things
673462306a36Sopenharmony_ci	 *    based on the resource size, e.g., to find registers at a
673562306a36Sopenharmony_ci	 *    fixed offset before the end of the BAR.
673662306a36Sopenharmony_ci	 *
673762306a36Sopenharmony_ci	 * 2) Retain the resource size, but use IORESOURCE_STARTALIGN and
673862306a36Sopenharmony_ci	 *    set r->start to the desired alignment.  By itself this
673962306a36Sopenharmony_ci	 *    doesn't prevent other BARs being put inside the alignment
674062306a36Sopenharmony_ci	 *    region, but if we realign *every* resource of every device in
674162306a36Sopenharmony_ci	 *    the system, none of them will share an alignment region.
674262306a36Sopenharmony_ci	 *
674362306a36Sopenharmony_ci	 * When the user has requested alignment for only some devices via
674462306a36Sopenharmony_ci	 * the "pci=resource_alignment" argument, "resize" is true and we
674562306a36Sopenharmony_ci	 * use the first method.  Otherwise we assume we're aligning all
674662306a36Sopenharmony_ci	 * devices and we use the second.
674762306a36Sopenharmony_ci	 */
674862306a36Sopenharmony_ci
674962306a36Sopenharmony_ci	pci_info(dev, "BAR%d %pR: requesting alignment to %#llx\n",
675062306a36Sopenharmony_ci		 bar, r, (unsigned long long)align);
675162306a36Sopenharmony_ci
675262306a36Sopenharmony_ci	if (resize) {
675362306a36Sopenharmony_ci		r->start = 0;
675462306a36Sopenharmony_ci		r->end = align - 1;
675562306a36Sopenharmony_ci	} else {
675662306a36Sopenharmony_ci		r->flags &= ~IORESOURCE_SIZEALIGN;
675762306a36Sopenharmony_ci		r->flags |= IORESOURCE_STARTALIGN;
675862306a36Sopenharmony_ci		r->start = align;
675962306a36Sopenharmony_ci		r->end = r->start + size - 1;
676062306a36Sopenharmony_ci	}
676162306a36Sopenharmony_ci	r->flags |= IORESOURCE_UNSET;
676262306a36Sopenharmony_ci}
676362306a36Sopenharmony_ci
676462306a36Sopenharmony_ci/*
676562306a36Sopenharmony_ci * This function disables memory decoding and releases memory resources
676662306a36Sopenharmony_ci * of the device specified by kernel's boot parameter 'pci=resource_alignment='.
676762306a36Sopenharmony_ci * It also rounds up size to specified alignment.
676862306a36Sopenharmony_ci * Later on, the kernel will assign page-aligned memory resource back
676962306a36Sopenharmony_ci * to the device.
677062306a36Sopenharmony_ci */
677162306a36Sopenharmony_civoid pci_reassigndev_resource_alignment(struct pci_dev *dev)
677262306a36Sopenharmony_ci{
677362306a36Sopenharmony_ci	int i;
677462306a36Sopenharmony_ci	struct resource *r;
677562306a36Sopenharmony_ci	resource_size_t align;
677662306a36Sopenharmony_ci	u16 command;
677762306a36Sopenharmony_ci	bool resize = false;
677862306a36Sopenharmony_ci
677962306a36Sopenharmony_ci	/*
678062306a36Sopenharmony_ci	 * VF BARs are read-only zero according to SR-IOV spec r1.1, sec
678162306a36Sopenharmony_ci	 * 3.4.1.11.  Their resources are allocated from the space
678262306a36Sopenharmony_ci	 * described by the VF BARx register in the PF's SR-IOV capability.
678362306a36Sopenharmony_ci	 * We can't influence their alignment here.
678462306a36Sopenharmony_ci	 */
678562306a36Sopenharmony_ci	if (dev->is_virtfn)
678662306a36Sopenharmony_ci		return;
678762306a36Sopenharmony_ci
678862306a36Sopenharmony_ci	/* check if specified PCI is target device to reassign */
678962306a36Sopenharmony_ci	align = pci_specified_resource_alignment(dev, &resize);
679062306a36Sopenharmony_ci	if (!align)
679162306a36Sopenharmony_ci		return;
679262306a36Sopenharmony_ci
679362306a36Sopenharmony_ci	if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL &&
679462306a36Sopenharmony_ci	    (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
679562306a36Sopenharmony_ci		pci_warn(dev, "Can't reassign resources to host bridge\n");
679662306a36Sopenharmony_ci		return;
679762306a36Sopenharmony_ci	}
679862306a36Sopenharmony_ci
679962306a36Sopenharmony_ci	pci_read_config_word(dev, PCI_COMMAND, &command);
680062306a36Sopenharmony_ci	command &= ~PCI_COMMAND_MEMORY;
680162306a36Sopenharmony_ci	pci_write_config_word(dev, PCI_COMMAND, command);
680262306a36Sopenharmony_ci
680362306a36Sopenharmony_ci	for (i = 0; i <= PCI_ROM_RESOURCE; i++)
680462306a36Sopenharmony_ci		pci_request_resource_alignment(dev, i, align, resize);
680562306a36Sopenharmony_ci
680662306a36Sopenharmony_ci	/*
680762306a36Sopenharmony_ci	 * Need to disable bridge's resource window,
680862306a36Sopenharmony_ci	 * to enable the kernel to reassign new resource
680962306a36Sopenharmony_ci	 * window later on.
681062306a36Sopenharmony_ci	 */
681162306a36Sopenharmony_ci	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
681262306a36Sopenharmony_ci		for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
681362306a36Sopenharmony_ci			r = &dev->resource[i];
681462306a36Sopenharmony_ci			if (!(r->flags & IORESOURCE_MEM))
681562306a36Sopenharmony_ci				continue;
681662306a36Sopenharmony_ci			r->flags |= IORESOURCE_UNSET;
681762306a36Sopenharmony_ci			r->end = resource_size(r) - 1;
681862306a36Sopenharmony_ci			r->start = 0;
681962306a36Sopenharmony_ci		}
682062306a36Sopenharmony_ci		pci_disable_bridge_window(dev);
682162306a36Sopenharmony_ci	}
682262306a36Sopenharmony_ci}
682362306a36Sopenharmony_ci
682462306a36Sopenharmony_cistatic ssize_t resource_alignment_show(const struct bus_type *bus, char *buf)
682562306a36Sopenharmony_ci{
682662306a36Sopenharmony_ci	size_t count = 0;
682762306a36Sopenharmony_ci
682862306a36Sopenharmony_ci	spin_lock(&resource_alignment_lock);
682962306a36Sopenharmony_ci	if (resource_alignment_param)
683062306a36Sopenharmony_ci		count = sysfs_emit(buf, "%s\n", resource_alignment_param);
683162306a36Sopenharmony_ci	spin_unlock(&resource_alignment_lock);
683262306a36Sopenharmony_ci
683362306a36Sopenharmony_ci	return count;
683462306a36Sopenharmony_ci}
683562306a36Sopenharmony_ci
683662306a36Sopenharmony_cistatic ssize_t resource_alignment_store(const struct bus_type *bus,
683762306a36Sopenharmony_ci					const char *buf, size_t count)
683862306a36Sopenharmony_ci{
683962306a36Sopenharmony_ci	char *param, *old, *end;
684062306a36Sopenharmony_ci
684162306a36Sopenharmony_ci	if (count >= (PAGE_SIZE - 1))
684262306a36Sopenharmony_ci		return -EINVAL;
684362306a36Sopenharmony_ci
684462306a36Sopenharmony_ci	param = kstrndup(buf, count, GFP_KERNEL);
684562306a36Sopenharmony_ci	if (!param)
684662306a36Sopenharmony_ci		return -ENOMEM;
684762306a36Sopenharmony_ci
684862306a36Sopenharmony_ci	end = strchr(param, '\n');
684962306a36Sopenharmony_ci	if (end)
685062306a36Sopenharmony_ci		*end = '\0';
685162306a36Sopenharmony_ci
685262306a36Sopenharmony_ci	spin_lock(&resource_alignment_lock);
685362306a36Sopenharmony_ci	old = resource_alignment_param;
685462306a36Sopenharmony_ci	if (strlen(param)) {
685562306a36Sopenharmony_ci		resource_alignment_param = param;
685662306a36Sopenharmony_ci	} else {
685762306a36Sopenharmony_ci		kfree(param);
685862306a36Sopenharmony_ci		resource_alignment_param = NULL;
685962306a36Sopenharmony_ci	}
686062306a36Sopenharmony_ci	spin_unlock(&resource_alignment_lock);
686162306a36Sopenharmony_ci
686262306a36Sopenharmony_ci	kfree(old);
686362306a36Sopenharmony_ci
686462306a36Sopenharmony_ci	return count;
686562306a36Sopenharmony_ci}
686662306a36Sopenharmony_ci
686762306a36Sopenharmony_cistatic BUS_ATTR_RW(resource_alignment);
686862306a36Sopenharmony_ci
686962306a36Sopenharmony_cistatic int __init pci_resource_alignment_sysfs_init(void)
687062306a36Sopenharmony_ci{
687162306a36Sopenharmony_ci	return bus_create_file(&pci_bus_type,
687262306a36Sopenharmony_ci					&bus_attr_resource_alignment);
687362306a36Sopenharmony_ci}
687462306a36Sopenharmony_cilate_initcall(pci_resource_alignment_sysfs_init);
687562306a36Sopenharmony_ci
687662306a36Sopenharmony_cistatic void pci_no_domains(void)
687762306a36Sopenharmony_ci{
687862306a36Sopenharmony_ci#ifdef CONFIG_PCI_DOMAINS
687962306a36Sopenharmony_ci	pci_domains_supported = 0;
688062306a36Sopenharmony_ci#endif
688162306a36Sopenharmony_ci}
688262306a36Sopenharmony_ci
688362306a36Sopenharmony_ci#ifdef CONFIG_PCI_DOMAINS_GENERIC
688462306a36Sopenharmony_cistatic DEFINE_IDA(pci_domain_nr_static_ida);
688562306a36Sopenharmony_cistatic DEFINE_IDA(pci_domain_nr_dynamic_ida);
688662306a36Sopenharmony_ci
688762306a36Sopenharmony_cistatic void of_pci_reserve_static_domain_nr(void)
688862306a36Sopenharmony_ci{
688962306a36Sopenharmony_ci	struct device_node *np;
689062306a36Sopenharmony_ci	int domain_nr;
689162306a36Sopenharmony_ci
689262306a36Sopenharmony_ci	for_each_node_by_type(np, "pci") {
689362306a36Sopenharmony_ci		domain_nr = of_get_pci_domain_nr(np);
689462306a36Sopenharmony_ci		if (domain_nr < 0)
689562306a36Sopenharmony_ci			continue;
689662306a36Sopenharmony_ci		/*
689762306a36Sopenharmony_ci		 * Permanently allocate domain_nr in dynamic_ida
689862306a36Sopenharmony_ci		 * to prevent it from dynamic allocation.
689962306a36Sopenharmony_ci		 */
690062306a36Sopenharmony_ci		ida_alloc_range(&pci_domain_nr_dynamic_ida,
690162306a36Sopenharmony_ci				domain_nr, domain_nr, GFP_KERNEL);
690262306a36Sopenharmony_ci	}
690362306a36Sopenharmony_ci}
690462306a36Sopenharmony_ci
690562306a36Sopenharmony_cistatic int of_pci_bus_find_domain_nr(struct device *parent)
690662306a36Sopenharmony_ci{
690762306a36Sopenharmony_ci	static bool static_domains_reserved = false;
690862306a36Sopenharmony_ci	int domain_nr;
690962306a36Sopenharmony_ci
691062306a36Sopenharmony_ci	/* On the first call scan device tree for static allocations. */
691162306a36Sopenharmony_ci	if (!static_domains_reserved) {
691262306a36Sopenharmony_ci		of_pci_reserve_static_domain_nr();
691362306a36Sopenharmony_ci		static_domains_reserved = true;
691462306a36Sopenharmony_ci	}
691562306a36Sopenharmony_ci
691662306a36Sopenharmony_ci	if (parent) {
691762306a36Sopenharmony_ci		/*
691862306a36Sopenharmony_ci		 * If domain is in DT, allocate it in static IDA.  This
691962306a36Sopenharmony_ci		 * prevents duplicate static allocations in case of errors
692062306a36Sopenharmony_ci		 * in DT.
692162306a36Sopenharmony_ci		 */
692262306a36Sopenharmony_ci		domain_nr = of_get_pci_domain_nr(parent->of_node);
692362306a36Sopenharmony_ci		if (domain_nr >= 0)
692462306a36Sopenharmony_ci			return ida_alloc_range(&pci_domain_nr_static_ida,
692562306a36Sopenharmony_ci					       domain_nr, domain_nr,
692662306a36Sopenharmony_ci					       GFP_KERNEL);
692762306a36Sopenharmony_ci	}
692862306a36Sopenharmony_ci
692962306a36Sopenharmony_ci	/*
693062306a36Sopenharmony_ci	 * If domain was not specified in DT, choose a free ID from dynamic
693162306a36Sopenharmony_ci	 * allocations. All domain numbers from DT are permanently in
693262306a36Sopenharmony_ci	 * dynamic allocations to prevent assigning them to other DT nodes
693362306a36Sopenharmony_ci	 * without static domain.
693462306a36Sopenharmony_ci	 */
693562306a36Sopenharmony_ci	return ida_alloc(&pci_domain_nr_dynamic_ida, GFP_KERNEL);
693662306a36Sopenharmony_ci}
693762306a36Sopenharmony_ci
693862306a36Sopenharmony_cistatic void of_pci_bus_release_domain_nr(struct pci_bus *bus, struct device *parent)
693962306a36Sopenharmony_ci{
694062306a36Sopenharmony_ci	if (bus->domain_nr < 0)
694162306a36Sopenharmony_ci		return;
694262306a36Sopenharmony_ci
694362306a36Sopenharmony_ci	/* Release domain from IDA where it was allocated. */
694462306a36Sopenharmony_ci	if (of_get_pci_domain_nr(parent->of_node) == bus->domain_nr)
694562306a36Sopenharmony_ci		ida_free(&pci_domain_nr_static_ida, bus->domain_nr);
694662306a36Sopenharmony_ci	else
694762306a36Sopenharmony_ci		ida_free(&pci_domain_nr_dynamic_ida, bus->domain_nr);
694862306a36Sopenharmony_ci}
694962306a36Sopenharmony_ci
695062306a36Sopenharmony_ciint pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent)
695162306a36Sopenharmony_ci{
695262306a36Sopenharmony_ci	return acpi_disabled ? of_pci_bus_find_domain_nr(parent) :
695362306a36Sopenharmony_ci			       acpi_pci_bus_find_domain_nr(bus);
695462306a36Sopenharmony_ci}
695562306a36Sopenharmony_ci
695662306a36Sopenharmony_civoid pci_bus_release_domain_nr(struct pci_bus *bus, struct device *parent)
695762306a36Sopenharmony_ci{
695862306a36Sopenharmony_ci	if (!acpi_disabled)
695962306a36Sopenharmony_ci		return;
696062306a36Sopenharmony_ci	of_pci_bus_release_domain_nr(bus, parent);
696162306a36Sopenharmony_ci}
696262306a36Sopenharmony_ci#endif
696362306a36Sopenharmony_ci
696462306a36Sopenharmony_ci/**
696562306a36Sopenharmony_ci * pci_ext_cfg_avail - can we access extended PCI config space?
696662306a36Sopenharmony_ci *
696762306a36Sopenharmony_ci * Returns 1 if we can access PCI extended config space (offsets
696862306a36Sopenharmony_ci * greater than 0xff). This is the default implementation. Architecture
696962306a36Sopenharmony_ci * implementations can override this.
697062306a36Sopenharmony_ci */
697162306a36Sopenharmony_ciint __weak pci_ext_cfg_avail(void)
697262306a36Sopenharmony_ci{
697362306a36Sopenharmony_ci	return 1;
697462306a36Sopenharmony_ci}
697562306a36Sopenharmony_ci
697662306a36Sopenharmony_civoid __weak pci_fixup_cardbus(struct pci_bus *bus)
697762306a36Sopenharmony_ci{
697862306a36Sopenharmony_ci}
697962306a36Sopenharmony_ciEXPORT_SYMBOL(pci_fixup_cardbus);
698062306a36Sopenharmony_ci
698162306a36Sopenharmony_cistatic int __init pci_setup(char *str)
698262306a36Sopenharmony_ci{
698362306a36Sopenharmony_ci	while (str) {
698462306a36Sopenharmony_ci		char *k = strchr(str, ',');
698562306a36Sopenharmony_ci		if (k)
698662306a36Sopenharmony_ci			*k++ = 0;
698762306a36Sopenharmony_ci		if (*str && (str = pcibios_setup(str)) && *str) {
698862306a36Sopenharmony_ci			if (!strcmp(str, "nomsi")) {
698962306a36Sopenharmony_ci				pci_no_msi();
699062306a36Sopenharmony_ci			} else if (!strncmp(str, "noats", 5)) {
699162306a36Sopenharmony_ci				pr_info("PCIe: ATS is disabled\n");
699262306a36Sopenharmony_ci				pcie_ats_disabled = true;
699362306a36Sopenharmony_ci			} else if (!strcmp(str, "noaer")) {
699462306a36Sopenharmony_ci				pci_no_aer();
699562306a36Sopenharmony_ci			} else if (!strcmp(str, "earlydump")) {
699662306a36Sopenharmony_ci				pci_early_dump = true;
699762306a36Sopenharmony_ci			} else if (!strncmp(str, "realloc=", 8)) {
699862306a36Sopenharmony_ci				pci_realloc_get_opt(str + 8);
699962306a36Sopenharmony_ci			} else if (!strncmp(str, "realloc", 7)) {
700062306a36Sopenharmony_ci				pci_realloc_get_opt("on");
700162306a36Sopenharmony_ci			} else if (!strcmp(str, "nodomains")) {
700262306a36Sopenharmony_ci				pci_no_domains();
700362306a36Sopenharmony_ci			} else if (!strncmp(str, "noari", 5)) {
700462306a36Sopenharmony_ci				pcie_ari_disabled = true;
700562306a36Sopenharmony_ci			} else if (!strncmp(str, "cbiosize=", 9)) {
700662306a36Sopenharmony_ci				pci_cardbus_io_size = memparse(str + 9, &str);
700762306a36Sopenharmony_ci			} else if (!strncmp(str, "cbmemsize=", 10)) {
700862306a36Sopenharmony_ci				pci_cardbus_mem_size = memparse(str + 10, &str);
700962306a36Sopenharmony_ci			} else if (!strncmp(str, "resource_alignment=", 19)) {
701062306a36Sopenharmony_ci				resource_alignment_param = str + 19;
701162306a36Sopenharmony_ci			} else if (!strncmp(str, "ecrc=", 5)) {
701262306a36Sopenharmony_ci				pcie_ecrc_get_policy(str + 5);
701362306a36Sopenharmony_ci			} else if (!strncmp(str, "hpiosize=", 9)) {
701462306a36Sopenharmony_ci				pci_hotplug_io_size = memparse(str + 9, &str);
701562306a36Sopenharmony_ci			} else if (!strncmp(str, "hpmmiosize=", 11)) {
701662306a36Sopenharmony_ci				pci_hotplug_mmio_size = memparse(str + 11, &str);
701762306a36Sopenharmony_ci			} else if (!strncmp(str, "hpmmioprefsize=", 15)) {
701862306a36Sopenharmony_ci				pci_hotplug_mmio_pref_size = memparse(str + 15, &str);
701962306a36Sopenharmony_ci			} else if (!strncmp(str, "hpmemsize=", 10)) {
702062306a36Sopenharmony_ci				pci_hotplug_mmio_size = memparse(str + 10, &str);
702162306a36Sopenharmony_ci				pci_hotplug_mmio_pref_size = pci_hotplug_mmio_size;
702262306a36Sopenharmony_ci			} else if (!strncmp(str, "hpbussize=", 10)) {
702362306a36Sopenharmony_ci				pci_hotplug_bus_size =
702462306a36Sopenharmony_ci					simple_strtoul(str + 10, &str, 0);
702562306a36Sopenharmony_ci				if (pci_hotplug_bus_size > 0xff)
702662306a36Sopenharmony_ci					pci_hotplug_bus_size = DEFAULT_HOTPLUG_BUS_SIZE;
702762306a36Sopenharmony_ci			} else if (!strncmp(str, "pcie_bus_tune_off", 17)) {
702862306a36Sopenharmony_ci				pcie_bus_config = PCIE_BUS_TUNE_OFF;
702962306a36Sopenharmony_ci			} else if (!strncmp(str, "pcie_bus_safe", 13)) {
703062306a36Sopenharmony_ci				pcie_bus_config = PCIE_BUS_SAFE;
703162306a36Sopenharmony_ci			} else if (!strncmp(str, "pcie_bus_perf", 13)) {
703262306a36Sopenharmony_ci				pcie_bus_config = PCIE_BUS_PERFORMANCE;
703362306a36Sopenharmony_ci			} else if (!strncmp(str, "pcie_bus_peer2peer", 18)) {
703462306a36Sopenharmony_ci				pcie_bus_config = PCIE_BUS_PEER2PEER;
703562306a36Sopenharmony_ci			} else if (!strncmp(str, "pcie_scan_all", 13)) {
703662306a36Sopenharmony_ci				pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS);
703762306a36Sopenharmony_ci			} else if (!strncmp(str, "disable_acs_redir=", 18)) {
703862306a36Sopenharmony_ci				disable_acs_redir_param = str + 18;
703962306a36Sopenharmony_ci			} else {
704062306a36Sopenharmony_ci				pr_err("PCI: Unknown option `%s'\n", str);
704162306a36Sopenharmony_ci			}
704262306a36Sopenharmony_ci		}
704362306a36Sopenharmony_ci		str = k;
704462306a36Sopenharmony_ci	}
704562306a36Sopenharmony_ci	return 0;
704662306a36Sopenharmony_ci}
704762306a36Sopenharmony_ciearly_param("pci", pci_setup);
704862306a36Sopenharmony_ci
704962306a36Sopenharmony_ci/*
705062306a36Sopenharmony_ci * 'resource_alignment_param' and 'disable_acs_redir_param' are initialized
705162306a36Sopenharmony_ci * in pci_setup(), above, to point to data in the __initdata section which
705262306a36Sopenharmony_ci * will be freed after the init sequence is complete. We can't allocate memory
705362306a36Sopenharmony_ci * in pci_setup() because some architectures do not have any memory allocation
705462306a36Sopenharmony_ci * service available during an early_param() call. So we allocate memory and
705562306a36Sopenharmony_ci * copy the variable here before the init section is freed.
705662306a36Sopenharmony_ci *
705762306a36Sopenharmony_ci */
705862306a36Sopenharmony_cistatic int __init pci_realloc_setup_params(void)
705962306a36Sopenharmony_ci{
706062306a36Sopenharmony_ci	resource_alignment_param = kstrdup(resource_alignment_param,
706162306a36Sopenharmony_ci					   GFP_KERNEL);
706262306a36Sopenharmony_ci	disable_acs_redir_param = kstrdup(disable_acs_redir_param, GFP_KERNEL);
706362306a36Sopenharmony_ci
706462306a36Sopenharmony_ci	return 0;
706562306a36Sopenharmony_ci}
706662306a36Sopenharmony_cipure_initcall(pci_realloc_setup_params);
7067