diff options
Diffstat (limited to 'drivers/pci')
33 files changed, 938 insertions, 506 deletions
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 73e4af400a5a..be3f631c3f75 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_PCI_IOV) += iov.o  #  obj-$(CONFIG_ALPHA) += setup-irq.o  obj-$(CONFIG_ARM) += setup-irq.o +obj-$(CONFIG_ARM64) += setup-irq.o  obj-$(CONFIG_UNICORE32) += setup-irq.o  obj-$(CONFIG_SUPERH) += setup-irq.o  obj-$(CONFIG_MIPS) += setup-irq.o diff --git a/drivers/pci/access.c b/drivers/pci/access.c index d9b64a175990..769f7e35f1a2 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -439,6 +439,56 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops = {  	.release = pci_vpd_pci22_release,  }; +static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count, +			       void *arg) +{ +	struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn)); +	ssize_t ret; + +	if (!tdev) +		return -ENODEV; + +	ret = pci_read_vpd(tdev, pos, count, arg); +	pci_dev_put(tdev); +	return ret; +} + +static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count, +				const void *arg) +{ +	struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn)); +	ssize_t ret; + +	if (!tdev) +		return -ENODEV; + +	ret = pci_write_vpd(tdev, pos, count, arg); +	pci_dev_put(tdev); +	return ret; +} + +static const struct pci_vpd_ops pci_vpd_f0_ops = { +	.read = pci_vpd_f0_read, +	.write = pci_vpd_f0_write, +	.release = pci_vpd_pci22_release, +}; + +static int pci_vpd_f0_dev_check(struct pci_dev *dev) +{ +	struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn)); +	int ret = 0; + +	if (!tdev) +		return -ENODEV; +	if (!tdev->vpd || !tdev->multifunction || +	    dev->class != tdev->class || dev->vendor != tdev->vendor || +	    dev->device != tdev->device) +		ret = -ENODEV; + +	pci_dev_put(tdev); +	return ret; +} +  int pci_vpd_pci22_init(struct pci_dev *dev)  {  	struct pci_vpd_pci22 *vpd; @@ -447,12 +497,21 @@ int pci_vpd_pci22_init(struct pci_dev *dev)  	cap = pci_find_capability(dev, PCI_CAP_ID_VPD);  	if (!cap)  		return -ENODEV; +	if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) { +		int ret = pci_vpd_f0_dev_check(dev); + +		if (ret) +			return ret; +	}  	vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC);  	if (!vpd)  		return -ENOMEM;  	vpd->base.len = PCI_VPD_PCI22_SIZE; -	vpd->base.ops = &pci_vpd_pci22_ops; +	if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) +		vpd->base.ops = &pci_vpd_f0_ops; +	else +		vpd->base.ops = &pci_vpd_pci22_ops;  	mutex_init(&vpd->lock);  	vpd->cap = cap;  	vpd->busy = false; @@ -531,6 +590,14 @@ static inline int pcie_cap_version(const struct pci_dev *dev)  	return pcie_caps_reg(dev) & PCI_EXP_FLAGS_VERS;  } +static bool pcie_downstream_port(const struct pci_dev *dev) +{ +	int type = pci_pcie_type(dev); + +	return type == PCI_EXP_TYPE_ROOT_PORT || +	       type == PCI_EXP_TYPE_DOWNSTREAM; +} +  bool pcie_cap_has_lnkctl(const struct pci_dev *dev)  {  	int type = pci_pcie_type(dev); @@ -546,10 +613,7 @@ bool pcie_cap_has_lnkctl(const struct pci_dev *dev)  static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev)  { -	int type = pci_pcie_type(dev); - -	return (type == PCI_EXP_TYPE_ROOT_PORT || -		type == PCI_EXP_TYPE_DOWNSTREAM) && +	return pcie_downstream_port(dev) &&  	       pcie_caps_reg(dev) & PCI_EXP_FLAGS_SLOT;  } @@ -628,10 +692,9 @@ int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val)  	 * State bit in the Slot Status register of Downstream Ports,  	 * which must be hardwired to 1b.  (PCIe Base Spec 3.0, sec 7.8)  	 */ -	if (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA && -		 pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { +	if (pci_is_pcie(dev) && pcie_downstream_port(dev) && +	    pos == PCI_EXP_SLTSTA)  		*val = PCI_EXP_SLTSTA_PDS; -	}  	return 0;  } @@ -657,10 +720,9 @@ int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val)  		return ret;  	} -	if (pci_is_pcie(dev) && pos == PCI_EXP_SLTCTL && -		 pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { +	if (pci_is_pcie(dev) && pcie_downstream_port(dev) && +	    pos == PCI_EXP_SLTSTA)  		*val = PCI_EXP_SLTSTA_PDS; -	}  	return 0;  } diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c index a8099d4d0c9d..eeb9fb2b47aa 100644 --- a/drivers/pci/ats.c +++ b/drivers/pci/ats.c @@ -17,34 +17,15 @@  #include "pci.h" -static int ats_alloc_one(struct pci_dev *dev, int ps) +void pci_ats_init(struct pci_dev *dev)  {  	int pos; -	u16 cap; -	struct pci_ats *ats;  	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS);  	if (!pos) -		return -ENODEV; - -	ats = kzalloc(sizeof(*ats), GFP_KERNEL); -	if (!ats) -		return -ENOMEM; - -	ats->pos = pos; -	ats->stu = ps; -	pci_read_config_word(dev, pos + PCI_ATS_CAP, &cap); -	ats->qdep = PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) : -					    PCI_ATS_MAX_QDEP; -	dev->ats = ats; - -	return 0; -} +		return; -static void ats_free_one(struct pci_dev *dev) -{ -	kfree(dev->ats); -	dev->ats = NULL; +	dev->ats_cap = pos;  }  /** @@ -56,43 +37,36 @@ static void ats_free_one(struct pci_dev *dev)   */  int pci_enable_ats(struct pci_dev *dev, int ps)  { -	int rc;  	u16 ctrl; +	struct pci_dev *pdev; -	BUG_ON(dev->ats && dev->ats->is_enabled); - -	if (ps < PCI_ATS_MIN_STU) +	if (!dev->ats_cap)  		return -EINVAL; -	if (dev->is_physfn || dev->is_virtfn) { -		struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn; - -		mutex_lock(&pdev->sriov->lock); -		if (pdev->ats) -			rc = pdev->ats->stu == ps ? 0 : -EINVAL; -		else -			rc = ats_alloc_one(pdev, ps); - -		if (!rc) -			pdev->ats->ref_cnt++; -		mutex_unlock(&pdev->sriov->lock); -		if (rc) -			return rc; -	} +	if (WARN_ON(dev->ats_enabled)) +		return -EBUSY; -	if (!dev->is_physfn) { -		rc = ats_alloc_one(dev, ps); -		if (rc) -			return rc; -	} +	if (ps < PCI_ATS_MIN_STU) +		return -EINVAL; +	/* +	 * Note that enabling ATS on a VF fails unless it's already enabled +	 * with the same STU on the PF. +	 */  	ctrl = PCI_ATS_CTRL_ENABLE; -	if (!dev->is_virtfn) -		ctrl |= PCI_ATS_CTRL_STU(ps - PCI_ATS_MIN_STU); -	pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl); - -	dev->ats->is_enabled = 1; +	if (dev->is_virtfn) { +		pdev = pci_physfn(dev); +		if (pdev->ats_stu != ps) +			return -EINVAL; + +		atomic_inc(&pdev->ats_ref_cnt);  /* count enabled VFs */ +	} else { +		dev->ats_stu = ps; +		ctrl |= PCI_ATS_CTRL_STU(dev->ats_stu - PCI_ATS_MIN_STU); +	} +	pci_write_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, ctrl); +	dev->ats_enabled = 1;  	return 0;  }  EXPORT_SYMBOL_GPL(pci_enable_ats); @@ -103,28 +77,25 @@ EXPORT_SYMBOL_GPL(pci_enable_ats);   */  void pci_disable_ats(struct pci_dev *dev)  { +	struct pci_dev *pdev;  	u16 ctrl; -	BUG_ON(!dev->ats || !dev->ats->is_enabled); - -	pci_read_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, &ctrl); -	ctrl &= ~PCI_ATS_CTRL_ENABLE; -	pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl); - -	dev->ats->is_enabled = 0; +	if (WARN_ON(!dev->ats_enabled)) +		return; -	if (dev->is_physfn || dev->is_virtfn) { -		struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn; +	if (atomic_read(&dev->ats_ref_cnt)) +		return;		/* VFs still enabled */ -		mutex_lock(&pdev->sriov->lock); -		pdev->ats->ref_cnt--; -		if (!pdev->ats->ref_cnt) -			ats_free_one(pdev); -		mutex_unlock(&pdev->sriov->lock); +	if (dev->is_virtfn) { +		pdev = pci_physfn(dev); +		atomic_dec(&pdev->ats_ref_cnt);  	} -	if (!dev->is_physfn) -		ats_free_one(dev); +	pci_read_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, &ctrl); +	ctrl &= ~PCI_ATS_CTRL_ENABLE; +	pci_write_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, ctrl); + +	dev->ats_enabled = 0;  }  EXPORT_SYMBOL_GPL(pci_disable_ats); @@ -132,16 +103,13 @@ void pci_restore_ats_state(struct pci_dev *dev)  {  	u16 ctrl; -	if (!pci_ats_enabled(dev)) +	if (!dev->ats_enabled)  		return; -	if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS)) -		BUG();  	ctrl = PCI_ATS_CTRL_ENABLE;  	if (!dev->is_virtfn) -		ctrl |= PCI_ATS_CTRL_STU(dev->ats->stu - PCI_ATS_MIN_STU); - -	pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl); +		ctrl |= PCI_ATS_CTRL_STU(dev->ats_stu - PCI_ATS_MIN_STU); +	pci_write_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, ctrl);  }  EXPORT_SYMBOL_GPL(pci_restore_ats_state); @@ -159,23 +127,16 @@ EXPORT_SYMBOL_GPL(pci_restore_ats_state);   */  int pci_ats_queue_depth(struct pci_dev *dev)  { -	int pos;  	u16 cap; +	if (!dev->ats_cap) +		return -EINVAL; +  	if (dev->is_virtfn)  		return 0; -	if (dev->ats) -		return dev->ats->qdep; - -	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS); -	if (!pos) -		return -ENODEV; - -	pci_read_config_word(dev, pos + PCI_ATS_CAP, &cap); - -	return PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) : -				       PCI_ATS_MAX_QDEP; +	pci_read_config_word(dev, dev->ats_cap + PCI_ATS_CAP, &cap); +	return PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) : PCI_ATS_MAX_QDEP;  }  EXPORT_SYMBOL_GPL(pci_ats_queue_depth); diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index c132bddc03f3..d5e58bae95cf 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -53,7 +53,7 @@ config PCI_RCAR_GEN2_PCIE  config PCI_HOST_GENERIC  	bool "Generic PCI host controller" -	depends on ARM && OF +	depends on (ARM || ARM64) && OF  	help  	  Say Y here if you want to support a simple generic PCI host  	  controller, such as the one emulated by kvmtool. @@ -117,7 +117,7 @@ config PCI_VERSATILE  config PCIE_IPROC  	tristate "Broadcom iProc PCIe controller" -	depends on OF && ARM +	depends on OF && (ARM || ARM64)  	default n  	help  	  This enables the iProc PCIe core controller support for Broadcom's @@ -135,8 +135,8 @@ config PCIE_IPROC_PLATFORM  	  through the generic platform bus interface  config PCIE_IPROC_BCMA -	bool "Broadcom iProc PCIe BCMA bus driver" -	depends on ARCH_BCM_IPROC || (ARM && COMPILE_TEST) +	tristate "Broadcom iProc PCIe BCMA bus driver" +	depends on ARM && (ARCH_BCM_IPROC || COMPILE_TEST)  	select PCIE_IPROC  	select BCMA  	select PCI_DOMAINS diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c index 80db09e47800..199e29a044cd 100644 --- a/drivers/pci/host/pci-dra7xx.c +++ b/drivers/pci/host/pci-dra7xx.c @@ -17,6 +17,7 @@  #include <linux/irqdomain.h>  #include <linux/kernel.h>  #include <linux/module.h> +#include <linux/of_gpio.h>  #include <linux/pci.h>  #include <linux/phy/phy.h>  #include <linux/platform_device.h> @@ -83,6 +84,17 @@ static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset,  	writel(value, pcie->base + offset);  } +static inline u32 dra7xx_pcie_readl_rc(struct pcie_port *pp, u32 offset) +{ +	return readl(pp->dbi_base + offset); +} + +static inline void dra7xx_pcie_writel_rc(struct pcie_port *pp, u32 offset, +					 u32 value) +{ +	writel(value, pp->dbi_base + offset); +} +  static int dra7xx_pcie_link_up(struct pcie_port *pp)  {  	struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp); @@ -155,7 +167,6 @@ static int dra7xx_pcie_intx_map(struct irq_domain *domain, unsigned int irq,  {  	irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);  	irq_set_chip_data(irq, domain->host_data); -	set_irq_flags(irq, IRQF_VALID);  	return 0;  } @@ -325,6 +336,9 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)  	struct device *dev = &pdev->dev;  	struct device_node *np = dev->of_node;  	char name[10]; +	int gpio_sel; +	enum of_gpio_flags flags; +	unsigned long gpio_flags;  	dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL);  	if (!dra7xx) @@ -382,9 +396,25 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)  	pm_runtime_enable(dev);  	ret = pm_runtime_get_sync(dev); -	if (IS_ERR_VALUE(ret)) { +	if (ret < 0) {  		dev_err(dev, "pm_runtime_get_sync failed\n"); -		goto err_phy; +		goto err_get_sync; +	} + +	gpio_sel = of_get_gpio_flags(dev->of_node, 0, &flags); +	if (gpio_is_valid(gpio_sel)) { +		gpio_flags = (flags & OF_GPIO_ACTIVE_LOW) ? +				GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH; +		ret = devm_gpio_request_one(dev, gpio_sel, gpio_flags, +					    "pcie_reset"); +		if (ret) { +			dev_err(&pdev->dev, "gpio%d request failed, ret %d\n", +				gpio_sel, ret); +			goto err_gpio; +		} +	} else if (gpio_sel == -EPROBE_DEFER) { +		ret = -EPROBE_DEFER; +		goto err_gpio;  	}  	reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD); @@ -395,12 +425,14 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)  	ret = dra7xx_add_pcie_port(dra7xx, pdev);  	if (ret < 0) -		goto err_add_port; +		goto err_gpio;  	return 0; -err_add_port: +err_gpio:  	pm_runtime_put(dev); + +err_get_sync:  	pm_runtime_disable(dev);  err_phy: @@ -431,6 +463,85 @@ static int __exit dra7xx_pcie_remove(struct platform_device *pdev)  	return 0;  } +#ifdef CONFIG_PM_SLEEP +static int dra7xx_pcie_suspend(struct device *dev) +{ +	struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev); +	struct pcie_port *pp = &dra7xx->pp; +	u32 val; + +	/* clear MSE */ +	val = dra7xx_pcie_readl_rc(pp, PCI_COMMAND); +	val &= ~PCI_COMMAND_MEMORY; +	dra7xx_pcie_writel_rc(pp, PCI_COMMAND, val); + +	return 0; +} + +static int dra7xx_pcie_resume(struct device *dev) +{ +	struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev); +	struct pcie_port *pp = &dra7xx->pp; +	u32 val; + +	/* set MSE */ +	val = dra7xx_pcie_readl_rc(pp, PCI_COMMAND); +	val |= PCI_COMMAND_MEMORY; +	dra7xx_pcie_writel_rc(pp, PCI_COMMAND, val); + +	return 0; +} + +static int dra7xx_pcie_suspend_noirq(struct device *dev) +{ +	struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev); +	int count = dra7xx->phy_count; + +	while (count--) { +		phy_power_off(dra7xx->phy[count]); +		phy_exit(dra7xx->phy[count]); +	} + +	return 0; +} + +static int dra7xx_pcie_resume_noirq(struct device *dev) +{ +	struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev); +	int phy_count = dra7xx->phy_count; +	int ret; +	int i; + +	for (i = 0; i < phy_count; i++) { +		ret = phy_init(dra7xx->phy[i]); +		if (ret < 0) +			goto err_phy; + +		ret = phy_power_on(dra7xx->phy[i]); +		if (ret < 0) { +			phy_exit(dra7xx->phy[i]); +			goto err_phy; +		} +	} + +	return 0; + +err_phy: +	while (--i >= 0) { +		phy_power_off(dra7xx->phy[i]); +		phy_exit(dra7xx->phy[i]); +	} + +	return ret; +} +#endif + +static const struct dev_pm_ops dra7xx_pcie_pm_ops = { +	SET_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend, dra7xx_pcie_resume) +	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend_noirq, +				      dra7xx_pcie_resume_noirq) +}; +  static const struct of_device_id of_dra7xx_pcie_match[] = {  	{ .compatible = "ti,dra7-pcie", },  	{}, @@ -442,6 +553,7 @@ static struct platform_driver dra7xx_pcie_driver = {  	.driver = {  		.name	= "dra7-pcie",  		.of_match_table = of_dra7xx_pcie_match, +		.pm	= &dra7xx_pcie_pm_ops,  	},  }; diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c index ba46e581db99..265dd25169bf 100644 --- a/drivers/pci/host/pci-host-generic.c +++ b/drivers/pci/host/pci-host-generic.c @@ -38,7 +38,16 @@ struct gen_pci_cfg_windows {  	const struct gen_pci_cfg_bus_ops	*ops;  }; +/* + * ARM pcibios functions expect the ARM struct pci_sys_data as the PCI + * sysdata.  Add pci_sys_data as the first element in struct gen_pci so + * that when we use a gen_pci pointer as sysdata, it is also a pointer to + * a struct pci_sys_data. + */  struct gen_pci { +#ifdef CONFIG_ARM +	struct pci_sys_data			sys; +#endif  	struct pci_host_bridge			host;  	struct gen_pci_cfg_windows		cfg;  	struct list_head			resources; @@ -48,8 +57,7 @@ static void __iomem *gen_pci_map_cfg_bus_cam(struct pci_bus *bus,  					     unsigned int devfn,  					     int where)  { -	struct pci_sys_data *sys = bus->sysdata; -	struct gen_pci *pci = sys->private_data; +	struct gen_pci *pci = bus->sysdata;  	resource_size_t idx = bus->number - pci->cfg.bus_range->start;  	return pci->cfg.win[idx] + ((devfn << 8) | where); @@ -64,8 +72,7 @@ static void __iomem *gen_pci_map_cfg_bus_ecam(struct pci_bus *bus,  					      unsigned int devfn,  					      int where)  { -	struct pci_sys_data *sys = bus->sysdata; -	struct gen_pci *pci = sys->private_data; +	struct gen_pci *pci = bus->sysdata;  	resource_size_t idx = bus->number - pci->cfg.bus_range->start;  	return pci->cfg.win[idx] + ((devfn << 12) | where); @@ -198,13 +205,6 @@ static int gen_pci_parse_map_cfg_windows(struct gen_pci *pci)  	return 0;  } -static int gen_pci_setup(int nr, struct pci_sys_data *sys) -{ -	struct gen_pci *pci = sys->private_data; -	list_splice_init(&pci->resources, &sys->resources); -	return 1; -} -  static int gen_pci_probe(struct platform_device *pdev)  {  	int err; @@ -214,13 +214,7 @@ static int gen_pci_probe(struct platform_device *pdev)  	struct device *dev = &pdev->dev;  	struct device_node *np = dev->of_node;  	struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); -	struct hw_pci hw = { -		.nr_controllers	= 1, -		.private_data	= (void **)&pci, -		.setup		= gen_pci_setup, -		.map_irq	= of_irq_parse_and_map_pci, -		.ops		= &gen_pci_ops, -	}; +	struct pci_bus *bus, *child;  	if (!pci)  		return -ENOMEM; @@ -258,7 +252,27 @@ static int gen_pci_probe(struct platform_device *pdev)  		return err;  	} -	pci_common_init_dev(dev, &hw); +	/* Do not reassign resources if probe only */ +	if (!pci_has_flag(PCI_PROBE_ONLY)) +		pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS); + +	bus = pci_scan_root_bus(dev, 0, &gen_pci_ops, pci, &pci->resources); +	if (!bus) { +		dev_err(dev, "Scanning rootbus failed"); +		return -ENODEV; +	} + +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); + +	if (!pci_has_flag(PCI_PROBE_ONLY)) { +		pci_bus_size_bridges(bus); +		pci_bus_assign_resources(bus); + +		list_for_each_entry(child, &bus->children, node) +			pcie_bus_configure_settings(child); +	} + +	pci_bus_add_devices(bus);  	return 0;  } diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index 233a196c6e66..8f3a9813c4e5 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -117,11 +117,7 @@ static int pcie_phy_wait_ack(void __iomem *dbi_base, int addr)  	val = addr << PCIE_PHY_CTRL_DATA_LOC;  	writel(val, dbi_base + PCIE_PHY_CTRL); -	ret = pcie_phy_poll_ack(dbi_base, 0); -	if (ret) -		return ret; - -	return 0; +	return pcie_phy_poll_ack(dbi_base, 0);  }  /* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */ @@ -148,11 +144,7 @@ static int pcie_phy_read(void __iomem *dbi_base, int addr , int *data)  	/* deassert Read signal */  	writel(0x00, dbi_base + PCIE_PHY_CTRL); -	ret = pcie_phy_poll_ack(dbi_base, 0); -	if (ret) -		return ret; - -	return 0; +	return pcie_phy_poll_ack(dbi_base, 0);  }  static int pcie_phy_write(void __iomem *dbi_base, int addr, int data) diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c index f34892e0edb4..e71da991949b 100644 --- a/drivers/pci/host/pci-keystone-dw.c +++ b/drivers/pci/host/pci-keystone-dw.c @@ -104,14 +104,13 @@ static void ks_dw_pcie_msi_irq_ack(struct irq_data *d)  {  	u32 offset, reg_offset, bit_pos;  	struct keystone_pcie *ks_pcie; -	unsigned int irq = d->irq;  	struct msi_desc *msi;  	struct pcie_port *pp; -	msi = irq_get_msi_desc(irq); -	pp = sys_to_pcie(msi->dev->bus->sysdata); +	msi = irq_data_get_msi_desc(d); +	pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));  	ks_pcie = to_keystone_pcie(pp); -	offset = irq - irq_linear_revmap(pp->irq_domain, 0); +	offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);  	update_reg_offset_bit_pos(offset, ®_offset, &bit_pos);  	writel(BIT(bit_pos), @@ -142,15 +141,14 @@ void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq)  static void ks_dw_pcie_msi_irq_mask(struct irq_data *d)  {  	struct keystone_pcie *ks_pcie; -	unsigned int irq = d->irq;  	struct msi_desc *msi;  	struct pcie_port *pp;  	u32 offset; -	msi = irq_get_msi_desc(irq); -	pp = sys_to_pcie(msi->dev->bus->sysdata); +	msi = irq_data_get_msi_desc(d); +	pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));  	ks_pcie = to_keystone_pcie(pp); -	offset = irq - irq_linear_revmap(pp->irq_domain, 0); +	offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);  	/* Mask the end point if PVM implemented */  	if (IS_ENABLED(CONFIG_PCI_MSI)) { @@ -164,15 +162,14 @@ static void ks_dw_pcie_msi_irq_mask(struct irq_data *d)  static void ks_dw_pcie_msi_irq_unmask(struct irq_data *d)  {  	struct keystone_pcie *ks_pcie; -	unsigned int irq = d->irq;  	struct msi_desc *msi;  	struct pcie_port *pp;  	u32 offset; -	msi = irq_get_msi_desc(irq); -	pp = sys_to_pcie(msi->dev->bus->sysdata); +	msi = irq_data_get_msi_desc(d); +	pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));  	ks_pcie = to_keystone_pcie(pp); -	offset = irq - irq_linear_revmap(pp->irq_domain, 0); +	offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);  	/* Mask the end point if PVM implemented */  	if (IS_ENABLED(CONFIG_PCI_MSI)) { @@ -196,7 +193,6 @@ static int ks_dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,  	irq_set_chip_and_handler(irq, &ks_dw_pcie_msi_irq_chip,  				 handle_level_irq);  	irq_set_chip_data(irq, domain->host_data); -	set_irq_flags(irq, IRQF_VALID);  	return 0;  } @@ -277,7 +273,6 @@ static int ks_dw_pcie_init_legacy_irq_map(struct irq_domain *d,  	irq_set_chip_and_handler(irq, &ks_dw_pcie_legacy_irq_chip,  				 handle_level_irq);  	irq_set_chip_data(irq, d->host_data); -	set_irq_flags(irq, IRQF_VALID);  	return 0;  } diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c index 734da589cdfb..81253e70b1c5 100644 --- a/drivers/pci/host/pci-keystone.c +++ b/drivers/pci/host/pci-keystone.c @@ -110,8 +110,9 @@ static int ks_pcie_establish_link(struct keystone_pcie *ks_pcie)  	return -EINVAL;  } -static void ks_pcie_msi_irq_handler(unsigned int irq, struct irq_desc *desc) +static void ks_pcie_msi_irq_handler(unsigned int __irq, struct irq_desc *desc)  { +	unsigned int irq = irq_desc_get_irq(desc);  	struct keystone_pcie *ks_pcie = irq_desc_get_handler_data(desc);  	u32 offset = irq - ks_pcie->msi_host_irqs[0];  	struct pcie_port *pp = &ks_pcie->pp; @@ -137,8 +138,10 @@ static void ks_pcie_msi_irq_handler(unsigned int irq, struct irq_desc *desc)   * Traverse through pending legacy interrupts and invoke handler for each. Also   * takes care of interrupt controller level mask/ack operation.   */ -static void ks_pcie_legacy_irq_handler(unsigned int irq, struct irq_desc *desc) +static void ks_pcie_legacy_irq_handler(unsigned int __irq, +				       struct irq_desc *desc)  { +	unsigned int irq = irq_desc_get_irq(desc);  	struct keystone_pcie *ks_pcie = irq_desc_get_handler_data(desc);  	struct pcie_port *pp = &ks_pcie->pp;  	u32 irq_offset = irq - ks_pcie->legacy_host_irqs[0]; @@ -212,9 +215,9 @@ static void ks_pcie_setup_interrupts(struct keystone_pcie *ks_pcie)  	/* Legacy IRQ */  	for (i = 0; i < ks_pcie->num_legacy_host_irqs; i++) { -		irq_set_handler_data(ks_pcie->legacy_host_irqs[i], ks_pcie); -		irq_set_chained_handler(ks_pcie->legacy_host_irqs[i], -					ks_pcie_legacy_irq_handler); +		irq_set_chained_handler_and_data(ks_pcie->legacy_host_irqs[i], +						 ks_pcie_legacy_irq_handler, +						 ks_pcie);  	}  	ks_dw_pcie_enable_legacy_irqs(ks_pcie); diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 70aa09556ec5..67ec5e1c99db 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c @@ -879,6 +879,7 @@ static void mvebu_pcie_msi_enable(struct mvebu_pcie *pcie)  		return;  	pcie->msi = of_pci_find_msi_chip_by_node(msi_node); +	of_node_put(msi_node);  	if (pcie->msi)  		pcie->msi->dev = &pcie->pdev->dev; diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 10c05718dbfd..81df0c1fe063 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -1248,7 +1248,6 @@ static int tegra_msi_map(struct irq_domain *domain, unsigned int irq,  {  	irq_set_chip_and_handler(irq, &tegra_msi_irq_chip, handle_simple_irq);  	irq_set_chip_data(irq, domain->host_data); -	set_irq_flags(irq, IRQF_VALID);  	tegra_cpuidle_pcie_irqs_in_use(); diff --git a/drivers/pci/host/pci-xgene-msi.c b/drivers/pci/host/pci-xgene-msi.c index 2d31d4d6fd08..996327cfa1e1 100644 --- a/drivers/pci/host/pci-xgene-msi.c +++ b/drivers/pci/host/pci-xgene-msi.c @@ -40,8 +40,8 @@ struct xgene_msi_group {  struct xgene_msi {  	struct device_node	*node; -	struct msi_controller	mchip; -	struct irq_domain	*domain; +	struct irq_domain	*inner_domain; +	struct irq_domain	*msi_domain;  	u64			msi_addr;  	void __iomem		*msi_regs;  	unsigned long		*bitmap; @@ -223,7 +223,6 @@ static int xgene_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,  	irq_domain_set_info(domain, virq, msi_irq,  			    &xgene_msi_bottom_irq_chip, domain->host_data,  			    handle_simple_irq, NULL, NULL); -	set_irq_flags(virq, IRQF_VALID);  	return 0;  } @@ -252,17 +251,17 @@ static const struct irq_domain_ops msi_domain_ops = {  static int xgene_allocate_domains(struct xgene_msi *msi)  { -	msi->domain = irq_domain_add_linear(NULL, NR_MSI_VEC, -					    &msi_domain_ops, msi); -	if (!msi->domain) +	msi->inner_domain = irq_domain_add_linear(NULL, NR_MSI_VEC, +						  &msi_domain_ops, msi); +	if (!msi->inner_domain)  		return -ENOMEM; -	msi->mchip.domain = pci_msi_create_irq_domain(msi->mchip.of_node, -						      &xgene_msi_domain_info, -						      msi->domain); +	msi->msi_domain = pci_msi_create_irq_domain(msi->node, +						    &xgene_msi_domain_info, +						    msi->inner_domain); -	if (!msi->mchip.domain) { -		irq_domain_remove(msi->domain); +	if (!msi->msi_domain) { +		irq_domain_remove(msi->inner_domain);  		return -ENOMEM;  	} @@ -271,10 +270,10 @@ static int xgene_allocate_domains(struct xgene_msi *msi)  static void xgene_free_domains(struct xgene_msi *msi)  { -	if (msi->mchip.domain) -		irq_domain_remove(msi->mchip.domain); -	if (msi->domain) -		irq_domain_remove(msi->domain); +	if (msi->msi_domain) +		irq_domain_remove(msi->msi_domain); +	if (msi->inner_domain) +		irq_domain_remove(msi->inner_domain);  }  static int xgene_msi_init_allocator(struct xgene_msi *xgene_msi) @@ -340,7 +339,7 @@ static void xgene_msi_isr(unsigned int irq, struct irq_desc *desc)  			 * CPU0  			 */  			hw_irq = hwirq_to_canonical_hwirq(hw_irq); -			virq = irq_find_mapping(xgene_msi->domain, hw_irq); +			virq = irq_find_mapping(xgene_msi->inner_domain, hw_irq);  			WARN_ON(!virq);  			if (virq != 0)  				generic_handle_irq(virq); @@ -368,10 +367,8 @@ static int xgene_msi_remove(struct platform_device *pdev)  	for (i = 0; i < NR_HW_IRQS; i++) {  		virq = msi->msi_groups[i].gic_irq; -		if (virq != 0) { -			irq_set_chained_handler(virq, NULL); -			irq_set_handler_data(virq, NULL); -		} +		if (virq != 0) +			irq_set_chained_handler_and_data(virq, NULL, NULL);  	}  	kfree(msi->msi_groups); @@ -421,8 +418,8 @@ static int xgene_msi_hwirq_alloc(unsigned int cpu)  		}  		if (err) { -			irq_set_chained_handler(msi_group->gic_irq, NULL); -			irq_set_handler_data(msi_group->gic_irq, NULL); +			irq_set_chained_handler_and_data(msi_group->gic_irq, +							 NULL, NULL);  			return err;  		}  	} @@ -441,8 +438,8 @@ static void xgene_msi_hwirq_free(unsigned int cpu)  		if (!msi_group->gic_irq)  			continue; -		irq_set_chained_handler(msi_group->gic_irq, NULL); -		irq_set_handler_data(msi_group->gic_irq, NULL); +		irq_set_chained_handler_and_data(msi_group->gic_irq, NULL, +						 NULL);  	}  } @@ -497,7 +494,7 @@ static int xgene_msi_probe(struct platform_device *pdev)  		goto error;  	}  	xgene_msi->msi_addr = res->start; - +	xgene_msi->node = pdev->dev.of_node;  	xgene_msi->num_cpus = num_possible_cpus();  	rc = xgene_msi_init_allocator(xgene_msi); @@ -561,19 +558,10 @@ static int xgene_msi_probe(struct platform_device *pdev)  	cpu_notifier_register_done(); -	xgene_msi->mchip.of_node = pdev->dev.of_node; -	rc = of_pci_msi_chip_add(&xgene_msi->mchip); -	if (rc) { -		dev_err(&pdev->dev, "failed to add MSI controller chip\n"); -		goto error_notifier; -	} -  	dev_info(&pdev->dev, "APM X-Gene PCIe MSI driver loaded\n");  	return 0; -error_notifier: -	unregister_hotcpu_notifier(&xgene_msi_cpu_notifier);  error:  	xgene_msi_remove(pdev);  	return rc; @@ -582,7 +570,6 @@ error:  static struct platform_driver xgene_msi_driver = {  	.driver = {  		.name = "xgene-msi", -		.owner = THIS_MODULE,  		.of_match_table = xgene_msi_match_table,  	},  	.probe = xgene_msi_probe, diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c index a9dfb70d623a..0236ab9d5720 100644 --- a/drivers/pci/host/pci-xgene.c +++ b/drivers/pci/host/pci-xgene.c @@ -321,8 +321,16 @@ static int xgene_pcie_map_ranges(struct xgene_pcie_port *port,  				return ret;  			break;  		case IORESOURCE_MEM: -			xgene_pcie_setup_ob_reg(port, res, OMR1BARL, res->start, -						res->start - window->offset); +			if (res->flags & IORESOURCE_PREFETCH) +				xgene_pcie_setup_ob_reg(port, res, OMR2BARL, +							res->start, +							res->start - +							window->offset); +			else +				xgene_pcie_setup_ob_reg(port, res, OMR1BARL, +							res->start, +							res->start - +							window->offset);  			break;  		case IORESOURCE_BUS:  			break; @@ -514,6 +522,7 @@ static int xgene_pcie_msi_enable(struct pci_bus *bus)  	if (!bus->msi)  		return -ENODEV; +	of_node_put(msi_node);  	bus->msi->dev = &bus->dev;  	return 0;  } diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 69486be7181e..52aa6e34002b 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -255,7 +255,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)  {  	int irq, pos0, i; -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); +	struct pcie_port *pp = sys_to_pcie(msi_desc_to_pci_sysdata(desc));  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,  				       order_base_2(no_irqs)); @@ -326,8 +326,8 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,  static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)  {  	struct irq_data *data = irq_get_irq_data(irq); -	struct msi_desc *msi = irq_data_get_msi(data); -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata); +	struct msi_desc *msi = irq_data_get_msi_desc(data); +	struct pcie_port *pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));  	clear_irq_range(pp, irq, 1, data->hwirq);  } @@ -350,7 +350,6 @@ static int dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,  {  	irq_set_chip_and_handler(irq, &dw_msi_irq_chip, handle_simple_irq);  	irq_set_chip_data(irq, domain->host_data); -	set_irq_flags(irq, IRQF_VALID);  	return 0;  } @@ -388,7 +387,7 @@ int dw_pcie_host_init(struct pcie_port *pp)  		addrp = of_get_address(np, index, NULL, NULL);  		pp->cfg0_mod_base = of_read_number(addrp, ns);  		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; -	} else { +	} else if (!pp->va_cfg0_base) {  		dev_err(pp->dev, "missing *config* reg space\n");  	} @@ -526,7 +525,6 @@ int dw_pcie_host_init(struct pcie_port *pp)  #ifdef CONFIG_PCI_MSI  	dw_pcie_msi_chip.dev = pp->dev; -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;  #endif  	dw_pci.nr_controllers = 1; @@ -708,8 +706,15 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)  	struct pcie_port *pp = sys_to_pcie(sys);  	pp->root_bus_nr = sys->busnr; -	bus = pci_scan_root_bus(pp->dev, sys->busnr, -				  &dw_pcie_ops, sys, &sys->resources); + +	if (IS_ENABLED(CONFIG_PCI_MSI)) +		bus = pci_scan_root_bus_msi(pp->dev, sys->busnr, &dw_pcie_ops, +					    sys, &sys->resources, +					    &dw_pcie_msi_chip); +	else +		bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops, +					sys, &sys->resources); +  	if (!bus)  		return NULL; diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c index d77481ea553e..fe2efb141a9b 100644 --- a/drivers/pci/host/pcie-iproc.c +++ b/drivers/pci/host/pcie-iproc.c @@ -58,9 +58,17 @@  #define SYS_RC_INTX_EN               0x330  #define SYS_RC_INTX_MASK             0xf -static inline struct iproc_pcie *sys_to_pcie(struct pci_sys_data *sys) +static inline struct iproc_pcie *iproc_data(struct pci_bus *bus)  { -	return sys->private_data; +	struct iproc_pcie *pcie; +#ifdef CONFIG_ARM +	struct pci_sys_data *sys = bus->sysdata; + +	pcie = sys->private_data; +#else +	pcie = bus->sysdata; +#endif +	return pcie;  }  /** @@ -71,8 +79,7 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,  					    unsigned int devfn,  					    int where)  { -	struct pci_sys_data *sys = bus->sysdata; -	struct iproc_pcie *pcie = sys_to_pcie(sys); +	struct iproc_pcie *pcie = iproc_data(bus);  	unsigned slot = PCI_SLOT(devfn);  	unsigned fn = PCI_FUNC(devfn);  	unsigned busno = bus->number; @@ -186,32 +193,34 @@ static void iproc_pcie_enable(struct iproc_pcie *pcie)  int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)  {  	int ret; +	void *sysdata;  	struct pci_bus *bus;  	if (!pcie || !pcie->dev || !pcie->base)  		return -EINVAL; -	if (pcie->phy) { -		ret = phy_init(pcie->phy); -		if (ret) { -			dev_err(pcie->dev, "unable to initialize PCIe PHY\n"); -			return ret; -		} - -		ret = phy_power_on(pcie->phy); -		if (ret) { -			dev_err(pcie->dev, "unable to power on PCIe PHY\n"); -			goto err_exit_phy; -		} +	ret = phy_init(pcie->phy); +	if (ret) { +		dev_err(pcie->dev, "unable to initialize PCIe PHY\n"); +		return ret; +	} +	ret = phy_power_on(pcie->phy); +	if (ret) { +		dev_err(pcie->dev, "unable to power on PCIe PHY\n"); +		goto err_exit_phy;  	}  	iproc_pcie_reset(pcie); +#ifdef CONFIG_ARM  	pcie->sysdata.private_data = pcie; +	sysdata = &pcie->sysdata; +#else +	sysdata = pcie; +#endif -	bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops, -				  &pcie->sysdata, res); +	bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops, sysdata, res);  	if (!bus) {  		dev_err(pcie->dev, "unable to create PCI root bus\n");  		ret = -ENOMEM; @@ -229,7 +238,9 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)  	pci_scan_child_bus(bus);  	pci_assign_unassigned_bus_resources(bus); +#ifdef CONFIG_ARM  	pci_fixup_irqs(pci_common_swizzle, pcie->map_irq); +#endif  	pci_bus_add_devices(bus);  	return 0; @@ -239,12 +250,9 @@ err_rm_root_bus:  	pci_remove_root_bus(bus);  err_power_off_phy: -	if (pcie->phy) -		phy_power_off(pcie->phy); +	phy_power_off(pcie->phy);  err_exit_phy: -	if (pcie->phy) -		phy_exit(pcie->phy); - +	phy_exit(pcie->phy);  	return ret;  }  EXPORT_SYMBOL(iproc_pcie_setup); @@ -254,10 +262,8 @@ int iproc_pcie_remove(struct iproc_pcie *pcie)  	pci_stop_root_bus(pcie->root_bus);  	pci_remove_root_bus(pcie->root_bus); -	if (pcie->phy) { -		phy_power_off(pcie->phy); -		phy_exit(pcie->phy); -	} +	phy_power_off(pcie->phy); +	phy_exit(pcie->phy);  	return 0;  } diff --git a/drivers/pci/host/pcie-iproc.h b/drivers/pci/host/pcie-iproc.h index ba0a108309cc..c9e4c10a462e 100644 --- a/drivers/pci/host/pcie-iproc.h +++ b/drivers/pci/host/pcie-iproc.h @@ -21,7 +21,7 @@   * @dev: pointer to device data structure   * @base: PCIe host controller I/O register base   * @resources: linked list of all PCI resources - * @sysdata: Per PCI controller data + * @sysdata: Per PCI controller data (ARM-specific)   * @root_bus: pointer to root bus   * @phy: optional PHY device that controls the Serdes   * @irqs: interrupt IDs @@ -29,7 +29,9 @@  struct iproc_pcie {  	struct device *dev;  	void __iomem *base; +#ifdef CONFIG_ARM  	struct pci_sys_data sysdata; +#endif  	struct pci_bus *root_bus;  	struct phy *phy;  	int irqs[IPROC_PCIE_MAX_NUM_IRQS]; diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index c086210f2ffd..7678fe0820d7 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c @@ -664,7 +664,6 @@ static int rcar_msi_map(struct irq_domain *domain, unsigned int irq,  {  	irq_set_chip_and_handler(irq, &rcar_msi_irq_chip, handle_simple_irq);  	irq_set_chip_data(irq, domain->host_data); -	set_irq_flags(irq, IRQF_VALID);  	return 0;  } diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c index c49fbdc0f6e4..98d2683181bc 100644 --- a/drivers/pci/host/pcie-spear13xx.c +++ b/drivers/pci/host/pcie-spear13xx.c @@ -223,8 +223,7 @@ static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg)  	status = readl(&app_reg->int_sts);  	if (status & MSI_CTRL_INT) { -		if (!IS_ENABLED(CONFIG_PCI_MSI)) -			BUG(); +		BUG_ON(!IS_ENABLED(CONFIG_PCI_MSI));  		dw_handle_msi_irq(pp);  	} diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c index f1a06a091ccb..3c7a0d580b1e 100644 --- a/drivers/pci/host/pcie-xilinx.c +++ b/drivers/pci/host/pcie-xilinx.c @@ -227,18 +227,16 @@ static struct pci_ops xilinx_pcie_ops = {   */  static void xilinx_pcie_destroy_msi(unsigned int irq)  { -	struct irq_desc *desc;  	struct msi_desc *msi;  	struct xilinx_pcie_port *port; -	desc = irq_to_desc(irq); -	msi = irq_desc_get_msi_desc(desc); -	port = sys_to_pcie(msi->dev->bus->sysdata); - -	if (!test_bit(irq, msi_irq_in_use)) +	if (!test_bit(irq, msi_irq_in_use)) { +		msi = irq_get_msi_desc(irq); +		port = sys_to_pcie(msi_desc_to_pci_sysdata(msi));  		dev_err(port->dev, "Trying to free unused MSI#%d\n", irq); -	else +	} else {  		clear_bit(irq, msi_irq_in_use); +	}  }  /** @@ -338,7 +336,6 @@ static int xilinx_pcie_msi_map(struct irq_domain *domain, unsigned int irq,  {  	irq_set_chip_and_handler(irq, &xilinx_msi_irq_chip, handle_simple_irq);  	irq_set_chip_data(irq, domain->host_data); -	set_irq_flags(irq, IRQF_VALID);  	return 0;  } @@ -377,7 +374,6 @@ static int xilinx_pcie_intx_map(struct irq_domain *domain, unsigned int irq,  {  	irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);  	irq_set_chip_data(irq, domain->host_data); -	set_irq_flags(irq, IRQF_VALID);  	return 0;  } @@ -449,14 +445,17 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data)  			return IRQ_HANDLED;  		} -		/* Clear interrupt FIFO register 1 */ -		pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK, -			   XILINX_PCIE_REG_RPIFR1); +		if (!(val & XILINX_PCIE_RPIFR1_MSI_INTR)) { +			/* Clear interrupt FIFO register 1 */ +			pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK, +				   XILINX_PCIE_REG_RPIFR1); -		/* Handle INTx Interrupt */ -		val = ((val & XILINX_PCIE_RPIFR1_INTR_MASK) >> -			XILINX_PCIE_RPIFR1_INTR_SHIFT) + 1; -		generic_handle_irq(irq_find_mapping(port->irq_domain, val)); +			/* Handle INTx Interrupt */ +			val = ((val & XILINX_PCIE_RPIFR1_INTR_MASK) >> +				XILINX_PCIE_RPIFR1_INTR_SHIFT) + 1; +			generic_handle_irq(irq_find_mapping(port->irq_domain, +							    val)); +		}  	}  	if (status & XILINX_PCIE_INTR_MSI) { @@ -647,9 +646,15 @@ static struct pci_bus *xilinx_pcie_scan_bus(int nr, struct pci_sys_data *sys)  	struct pci_bus *bus;  	port->root_busno = sys->busnr; -	bus = pci_scan_root_bus(port->dev, sys->busnr, &xilinx_pcie_ops, -				sys, &sys->resources); +	if (IS_ENABLED(CONFIG_PCI_MSI)) +		bus = pci_scan_root_bus_msi(port->dev, sys->busnr, +					    &xilinx_pcie_ops, sys, +					    &sys->resources, +					    &xilinx_pcie_msi_chip); +	else +		bus = pci_scan_root_bus(port->dev, sys->busnr, +					&xilinx_pcie_ops, sys, &sys->resources);  	return bus;  } @@ -847,7 +852,6 @@ static int xilinx_pcie_probe(struct platform_device *pdev)  #ifdef CONFIG_PCI_MSI  	xilinx_pcie_msi_chip.dev = port->dev; -	hw.msi_ctrl = &xilinx_pcie_msi_chip;  #endif  	pci_common_init_dev(dev, &hw); diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 56d8486dc167..d1fab97d6b01 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c @@ -83,12 +83,12 @@ GET_STATUS(attention_status, u8)  GET_STATUS(latch_status, u8)  GET_STATUS(adapter_status, u8) -static ssize_t power_read_file(struct pci_slot *slot, char *buf) +static ssize_t power_read_file(struct pci_slot *pci_slot, char *buf)  {  	int retval;  	u8 value; -	retval = get_power_status(slot->hotplug, &value); +	retval = get_power_status(pci_slot->hotplug, &value);  	if (retval)  		return retval; @@ -140,22 +140,22 @@ static struct pci_slot_attribute hotplug_slot_attr_power = {  	.store = power_write_file  }; -static ssize_t attention_read_file(struct pci_slot *slot, char *buf) +static ssize_t attention_read_file(struct pci_slot *pci_slot, char *buf)  {  	int retval;  	u8 value; -	retval = get_attention_status(slot->hotplug, &value); +	retval = get_attention_status(pci_slot->hotplug, &value);  	if (retval)  		return retval;  	return sprintf(buf, "%d\n", value);  } -static ssize_t attention_write_file(struct pci_slot *slot, const char *buf, +static ssize_t attention_write_file(struct pci_slot *pci_slot, const char *buf,  				    size_t count)  { -	struct hotplug_slot_ops *ops = slot->hotplug->ops; +	struct hotplug_slot_ops *ops = pci_slot->hotplug->ops;  	unsigned long lattention;  	u8 attention;  	int retval = 0; @@ -169,7 +169,7 @@ static ssize_t attention_write_file(struct pci_slot *slot, const char *buf,  		goto exit;  	}  	if (ops->set_attention_status) -		retval = ops->set_attention_status(slot->hotplug, attention); +		retval = ops->set_attention_status(pci_slot->hotplug, attention);  	module_put(ops->owner);  exit: @@ -184,12 +184,12 @@ static struct pci_slot_attribute hotplug_slot_attr_attention = {  	.store = attention_write_file  }; -static ssize_t latch_read_file(struct pci_slot *slot, char *buf) +static ssize_t latch_read_file(struct pci_slot *pci_slot, char *buf)  {  	int retval;  	u8 value; -	retval = get_latch_status(slot->hotplug, &value); +	retval = get_latch_status(pci_slot->hotplug, &value);  	if (retval)  		return retval; @@ -201,12 +201,12 @@ static struct pci_slot_attribute hotplug_slot_attr_latch = {  	.show = latch_read_file,  }; -static ssize_t presence_read_file(struct pci_slot *slot, char *buf) +static ssize_t presence_read_file(struct pci_slot *pci_slot, char *buf)  {  	int retval;  	u8 value; -	retval = get_adapter_status(slot->hotplug, &value); +	retval = get_adapter_status(pci_slot->hotplug, &value);  	if (retval)  		return retval; @@ -307,43 +307,43 @@ static bool has_test_file(struct pci_slot *pci_slot)  	return false;  } -static int fs_add_slot(struct pci_slot *slot) +static int fs_add_slot(struct pci_slot *pci_slot)  {  	int retval = 0;  	/* Create symbolic link to the hotplug driver module */ -	pci_hp_create_module_link(slot); +	pci_hp_create_module_link(pci_slot); -	if (has_power_file(slot)) { -		retval = sysfs_create_file(&slot->kobj, +	if (has_power_file(pci_slot)) { +		retval = sysfs_create_file(&pci_slot->kobj,  					   &hotplug_slot_attr_power.attr);  		if (retval)  			goto exit_power;  	} -	if (has_attention_file(slot)) { -		retval = sysfs_create_file(&slot->kobj, +	if (has_attention_file(pci_slot)) { +		retval = sysfs_create_file(&pci_slot->kobj,  					   &hotplug_slot_attr_attention.attr);  		if (retval)  			goto exit_attention;  	} -	if (has_latch_file(slot)) { -		retval = sysfs_create_file(&slot->kobj, +	if (has_latch_file(pci_slot)) { +		retval = sysfs_create_file(&pci_slot->kobj,  					   &hotplug_slot_attr_latch.attr);  		if (retval)  			goto exit_latch;  	} -	if (has_adapter_file(slot)) { -		retval = sysfs_create_file(&slot->kobj, +	if (has_adapter_file(pci_slot)) { +		retval = sysfs_create_file(&pci_slot->kobj,  					   &hotplug_slot_attr_presence.attr);  		if (retval)  			goto exit_adapter;  	} -	if (has_test_file(slot)) { -		retval = sysfs_create_file(&slot->kobj, +	if (has_test_file(pci_slot)) { +		retval = sysfs_create_file(&pci_slot->kobj,  					   &hotplug_slot_attr_test.attr);  		if (retval)  			goto exit_test; @@ -352,45 +352,45 @@ static int fs_add_slot(struct pci_slot *slot)  	goto exit;  exit_test: -	if (has_adapter_file(slot)) -		sysfs_remove_file(&slot->kobj, +	if (has_adapter_file(pci_slot)) +		sysfs_remove_file(&pci_slot->kobj,  				  &hotplug_slot_attr_presence.attr);  exit_adapter: -	if (has_latch_file(slot)) -		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr); +	if (has_latch_file(pci_slot)) +		sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_latch.attr);  exit_latch: -	if (has_attention_file(slot)) -		sysfs_remove_file(&slot->kobj, +	if (has_attention_file(pci_slot)) +		sysfs_remove_file(&pci_slot->kobj,  				  &hotplug_slot_attr_attention.attr);  exit_attention: -	if (has_power_file(slot)) -		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr); +	if (has_power_file(pci_slot)) +		sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_power.attr);  exit_power: -	pci_hp_remove_module_link(slot); +	pci_hp_remove_module_link(pci_slot);  exit:  	return retval;  } -static void fs_remove_slot(struct pci_slot *slot) +static void fs_remove_slot(struct pci_slot *pci_slot)  { -	if (has_power_file(slot)) -		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr); +	if (has_power_file(pci_slot)) +		sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_power.attr); -	if (has_attention_file(slot)) -		sysfs_remove_file(&slot->kobj, +	if (has_attention_file(pci_slot)) +		sysfs_remove_file(&pci_slot->kobj,  				  &hotplug_slot_attr_attention.attr); -	if (has_latch_file(slot)) -		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr); +	if (has_latch_file(pci_slot)) +		sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_latch.attr); -	if (has_adapter_file(slot)) -		sysfs_remove_file(&slot->kobj, +	if (has_adapter_file(pci_slot)) +		sysfs_remove_file(&pci_slot->kobj,  				  &hotplug_slot_attr_presence.attr); -	if (has_test_file(slot)) -		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); +	if (has_test_file(pci_slot)) +		sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_test.attr); -	pci_hp_remove_module_link(slot); +	pci_hp_remove_module_link(pci_slot);  }  static struct hotplug_slot *get_slot_from_name(const char *name) @@ -467,37 +467,37 @@ EXPORT_SYMBOL_GPL(__pci_hp_register);  /**   * pci_hp_deregister - deregister a hotplug_slot with the PCI hotplug subsystem - * @hotplug: pointer to the &struct hotplug_slot to deregister + * @slot: pointer to the &struct hotplug_slot to deregister   *   * The @slot must have been registered with the pci hotplug subsystem   * previously with a call to pci_hp_register().   *   * Returns 0 if successful, anything else for an error.   */ -int pci_hp_deregister(struct hotplug_slot *hotplug) +int pci_hp_deregister(struct hotplug_slot *slot)  {  	struct hotplug_slot *temp; -	struct pci_slot *slot; +	struct pci_slot *pci_slot; -	if (!hotplug) +	if (!slot)  		return -ENODEV;  	mutex_lock(&pci_hp_mutex); -	temp = get_slot_from_name(hotplug_slot_name(hotplug)); -	if (temp != hotplug) { +	temp = get_slot_from_name(hotplug_slot_name(slot)); +	if (temp != slot) {  		mutex_unlock(&pci_hp_mutex);  		return -ENODEV;  	} -	list_del(&hotplug->slot_list); +	list_del(&slot->slot_list); -	slot = hotplug->pci_slot; -	fs_remove_slot(slot); -	dbg("Removed slot %s from the list\n", hotplug_slot_name(hotplug)); +	pci_slot = slot->pci_slot; +	fs_remove_slot(pci_slot); +	dbg("Removed slot %s from the list\n", hotplug_slot_name(slot)); -	hotplug->release(hotplug); -	slot->hotplug = NULL; -	pci_destroy_slot(slot); +	slot->release(slot); +	pci_slot->hotplug = NULL; +	pci_destroy_slot(pci_slot);  	mutex_unlock(&pci_hp_mutex);  	return 0; @@ -506,7 +506,7 @@ EXPORT_SYMBOL_GPL(pci_hp_deregister);  /**   * pci_hp_change_slot_info - changes the slot's information structure in the core - * @hotplug: pointer to the slot whose info has changed + * @slot: pointer to the slot whose info has changed   * @info: pointer to the info copy into the slot's info structure   *   * @slot must have been registered with the pci @@ -514,13 +514,13 @@ EXPORT_SYMBOL_GPL(pci_hp_deregister);   *   * Returns 0 if successful, anything else for an error.   */ -int pci_hp_change_slot_info(struct hotplug_slot *hotplug, +int pci_hp_change_slot_info(struct hotplug_slot *slot,  			    struct hotplug_slot_info *info)  { -	if (!hotplug || !info) +	if (!slot || !info)  		return -ENODEV; -	memcpy(hotplug->info, info, sizeof(struct hotplug_slot_info)); +	memcpy(slot->info, info, sizeof(struct hotplug_slot_info));  	return 0;  } diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 57cd1327346f..62d6fe6c3714 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -101,18 +101,12 @@ struct controller {  	unsigned int power_fault_detected;  }; -#define INT_BUTTON_IGNORE		0  #define INT_PRESENCE_ON			1  #define INT_PRESENCE_OFF		2 -#define INT_SWITCH_CLOSE		3 -#define INT_SWITCH_OPEN			4 -#define INT_POWER_FAULT			5 -#define INT_POWER_FAULT_CLEAR		6 -#define INT_BUTTON_PRESS		7 -#define INT_BUTTON_RELEASE		8 -#define INT_BUTTON_CANCEL		9 -#define INT_LINK_UP			10 -#define INT_LINK_DOWN			11 +#define INT_POWER_FAULT			3 +#define INT_BUTTON_PRESS		4 +#define INT_LINK_UP			5 +#define INT_LINK_DOWN			6  #define STATIC_STATE			0  #define BLINKINGON_STATE		1 diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 2913f7e68a10..5c24e938042f 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -109,21 +109,23 @@ static int pcie_poll_cmd(struct controller *ctrl, int timeout)  	struct pci_dev *pdev = ctrl_dev(ctrl);  	u16 slot_status; -	pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); -	if (slot_status & PCI_EXP_SLTSTA_CC) { -		pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, -					   PCI_EXP_SLTSTA_CC); -		return 1; -	} -	while (timeout > 0) { -		msleep(10); -		timeout -= 10; +	while (true) {  		pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); +		if (slot_status == (u16) ~0) { +			ctrl_info(ctrl, "%s: no response from device\n", +				  __func__); +			return 0; +		} +  		if (slot_status & PCI_EXP_SLTSTA_CC) {  			pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,  						   PCI_EXP_SLTSTA_CC);  			return 1;  		} +		if (timeout < 0) +			break; +		msleep(10); +		timeout -= 10;  	}  	return 0;	/* timeout */  } @@ -190,6 +192,11 @@ static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd,  	pcie_wait_cmd(ctrl);  	pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl); +	if (slot_ctrl == (u16) ~0) { +		ctrl_info(ctrl, "%s: no response from device\n", __func__); +		goto out; +	} +  	slot_ctrl &= ~mask;  	slot_ctrl |= (cmd & mask);  	ctrl->cmd_busy = 1; @@ -205,6 +212,7 @@ static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd,  	if (wait)  		pcie_wait_cmd(ctrl); +out:  	mutex_unlock(&ctrl->ctrl_lock);  } @@ -535,7 +543,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)  	struct pci_dev *dev;  	struct slot *slot = ctrl->slot;  	u16 detected, intr_loc; -	u8 open, present; +	u8 present;  	bool link;  	/* @@ -546,9 +554,14 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)  	intr_loc = 0;  	do {  		pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &detected); +		if (detected == (u16) ~0) { +			ctrl_info(ctrl, "%s: no response from device\n", +				  __func__); +			return IRQ_HANDLED; +		}  		detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | -			     PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | +			     PCI_EXP_SLTSTA_PDC |  			     PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC);  		detected &= ~intr_loc;  		intr_loc |= detected; @@ -581,15 +594,6 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)  	if (!(intr_loc & ~PCI_EXP_SLTSTA_CC))  		return IRQ_HANDLED; -	/* Check MRL Sensor Changed */ -	if (intr_loc & PCI_EXP_SLTSTA_MRLSC) { -		pciehp_get_latch_status(slot, &open); -		ctrl_info(ctrl, "Latch %s on Slot(%s)\n", -			  open ? "open" : "close", slot_name(slot)); -		pciehp_queue_interrupt_event(slot, open ? INT_SWITCH_OPEN : -					     INT_SWITCH_CLOSE); -	} -  	/* Check Attention Button Pressed */  	if (intr_loc & PCI_EXP_SLTSTA_ABP) {  		ctrl_info(ctrl, "Button pressed on Slot(%s)\n", @@ -649,13 +653,11 @@ void pcie_enable_notification(struct controller *ctrl)  		cmd |= PCI_EXP_SLTCTL_ABPE;  	else  		cmd |= PCI_EXP_SLTCTL_PDCE; -	if (MRL_SENS(ctrl)) -		cmd |= PCI_EXP_SLTCTL_MRLSCE;  	if (!pciehp_poll_mode)  		cmd |= PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE;  	mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | -		PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | +		PCI_EXP_SLTCTL_PFDE |  		PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE |  		PCI_EXP_SLTCTL_DLLSCE); diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index f66be868ad21..d4497141d083 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -39,14 +39,13 @@ struct irq_domain * __weak arch_get_pci_msi_domain(struct pci_dev *dev)  static struct irq_domain *pci_msi_get_domain(struct pci_dev *dev)  { -	struct irq_domain *domain = NULL; +	struct irq_domain *domain; -	if (dev->bus->msi) -		domain = dev->bus->msi->domain; -	if (!domain) -		domain = arch_get_pci_msi_domain(dev); +	domain = dev_get_msi_domain(&dev->dev); +	if (domain) +		return domain; -	return domain; +	return arch_get_pci_msi_domain(dev);  }  static int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) @@ -77,24 +76,9 @@ static void pci_msi_teardown_msi_irqs(struct pci_dev *dev)  /* Arch hooks */ -struct msi_controller * __weak pcibios_msi_controller(struct pci_dev *dev) -{ -	return NULL; -} - -static struct msi_controller *pci_msi_controller(struct pci_dev *dev) -{ -	struct msi_controller *msi_ctrl = dev->bus->msi; - -	if (msi_ctrl) -		return msi_ctrl; - -	return pcibios_msi_controller(dev); -} -  int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)  { -	struct msi_controller *chip = pci_msi_controller(dev); +	struct msi_controller *chip = dev->bus->msi;  	int err;  	if (!chip || !chip->setup_irq) @@ -131,7 +115,7 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)  	if (type == PCI_CAP_ID_MSI && nvec > 1)  		return 1; -	list_for_each_entry(entry, &dev->msi_list, list) { +	for_each_pci_msi_entry(entry, dev) {  		ret = arch_setup_msi_irq(dev, entry);  		if (ret < 0)  			return ret; @@ -151,7 +135,7 @@ void default_teardown_msi_irqs(struct pci_dev *dev)  	int i;  	struct msi_desc *entry; -	list_for_each_entry(entry, &dev->msi_list, list) +	for_each_pci_msi_entry(entry, dev)  		if (entry->irq)  			for (i = 0; i < entry->nvec_used; i++)  				arch_teardown_msi_irq(entry->irq + i); @@ -168,7 +152,7 @@ static void default_restore_msi_irq(struct pci_dev *dev, int irq)  	entry = NULL;  	if (dev->msix_enabled) { -		list_for_each_entry(entry, &dev->msi_list, list) { +		for_each_pci_msi_entry(entry, dev) {  			if (irq == entry->irq)  				break;  		} @@ -208,7 +192,8 @@ u32 __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)  	mask_bits &= ~mask;  	mask_bits |= flag; -	pci_write_config_dword(desc->dev, desc->mask_pos, mask_bits); +	pci_write_config_dword(msi_desc_to_pci_dev(desc), desc->mask_pos, +			       mask_bits);  	return mask_bits;  } @@ -249,7 +234,7 @@ static void msix_mask_irq(struct msi_desc *desc, u32 flag)  static void msi_set_mask_bit(struct irq_data *data, u32 flag)  { -	struct msi_desc *desc = irq_data_get_msi(data); +	struct msi_desc *desc = irq_data_get_msi_desc(data);  	if (desc->msi_attrib.is_msix) {  		msix_mask_irq(desc, flag); @@ -282,13 +267,15 @@ void default_restore_msi_irqs(struct pci_dev *dev)  {  	struct msi_desc *entry; -	list_for_each_entry(entry, &dev->msi_list, list) +	for_each_pci_msi_entry(entry, dev)  		default_restore_msi_irq(dev, entry->irq);  }  void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)  { -	BUG_ON(entry->dev->current_state != PCI_D0); +	struct pci_dev *dev = msi_desc_to_pci_dev(entry); + +	BUG_ON(dev->current_state != PCI_D0);  	if (entry->msi_attrib.is_msix) {  		void __iomem *base = entry->mask_base + @@ -298,7 +285,6 @@ void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)  		msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR);  		msg->data = readl(base + PCI_MSIX_ENTRY_DATA);  	} else { -		struct pci_dev *dev = entry->dev;  		int pos = dev->msi_cap;  		u16 data; @@ -318,7 +304,9 @@ void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)  void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)  { -	if (entry->dev->current_state != PCI_D0) { +	struct pci_dev *dev = msi_desc_to_pci_dev(entry); + +	if (dev->current_state != PCI_D0) {  		/* Don't touch the hardware now */  	} else if (entry->msi_attrib.is_msix) {  		void __iomem *base; @@ -329,7 +317,6 @@ void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)  		writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR);  		writel(msg->data, base + PCI_MSIX_ENTRY_DATA);  	} else { -		struct pci_dev *dev = entry->dev;  		int pos = dev->msi_cap;  		u16 msgctl; @@ -363,21 +350,22 @@ EXPORT_SYMBOL_GPL(pci_write_msi_msg);  static void free_msi_irqs(struct pci_dev *dev)  { +	struct list_head *msi_list = dev_to_msi_list(&dev->dev);  	struct msi_desc *entry, *tmp;  	struct attribute **msi_attrs;  	struct device_attribute *dev_attr;  	int i, count = 0; -	list_for_each_entry(entry, &dev->msi_list, list) +	for_each_pci_msi_entry(entry, dev)  		if (entry->irq)  			for (i = 0; i < entry->nvec_used; i++)  				BUG_ON(irq_has_action(entry->irq + i));  	pci_msi_teardown_msi_irqs(dev); -	list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) { +	list_for_each_entry_safe(entry, tmp, msi_list, list) {  		if (entry->msi_attrib.is_msix) { -			if (list_is_last(&entry->list, &dev->msi_list)) +			if (list_is_last(&entry->list, msi_list))  				iounmap(entry->mask_base);  		} @@ -402,18 +390,6 @@ static void free_msi_irqs(struct pci_dev *dev)  	}  } -static struct msi_desc *alloc_msi_entry(struct pci_dev *dev) -{ -	struct msi_desc *desc = kzalloc(sizeof(*desc), GFP_KERNEL); -	if (!desc) -		return NULL; - -	INIT_LIST_HEAD(&desc->list); -	desc->dev = dev; - -	return desc; -} -  static void pci_intx_for_msi(struct pci_dev *dev, int enable)  {  	if (!(dev->dev_flags & PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG)) @@ -448,7 +424,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev)  	if (!dev->msix_enabled)  		return; -	BUG_ON(list_empty(&dev->msi_list)); +	BUG_ON(list_empty(dev_to_msi_list(&dev->dev)));  	/* route the table */  	pci_intx_for_msi(dev, 0); @@ -456,7 +432,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev)  				PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL);  	arch_restore_msi_irqs(dev); -	list_for_each_entry(entry, &dev->msi_list, list) +	for_each_pci_msi_entry(entry, dev)  		msix_mask_irq(entry, entry->masked);  	pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0); @@ -501,7 +477,7 @@ static int populate_msi_sysfs(struct pci_dev *pdev)  	int count = 0;  	/* Determine how many msi entries we have */ -	list_for_each_entry(entry, &pdev->msi_list, list) +	for_each_pci_msi_entry(entry, pdev)  		++num_msi;  	if (!num_msi)  		return 0; @@ -510,7 +486,7 @@ static int populate_msi_sysfs(struct pci_dev *pdev)  	msi_attrs = kzalloc(sizeof(void *) * (num_msi + 1), GFP_KERNEL);  	if (!msi_attrs)  		return -ENOMEM; -	list_for_each_entry(entry, &pdev->msi_list, list) { +	for_each_pci_msi_entry(entry, pdev) {  		msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL);  		if (!msi_dev_attr)  			goto error_attrs; @@ -568,7 +544,7 @@ static struct msi_desc *msi_setup_entry(struct pci_dev *dev, int nvec)  	struct msi_desc *entry;  	/* MSI Entry Initialization */ -	entry = alloc_msi_entry(dev); +	entry = alloc_msi_entry(&dev->dev);  	if (!entry)  		return NULL; @@ -599,7 +575,7 @@ static int msi_verify_entries(struct pci_dev *dev)  {  	struct msi_desc *entry; -	list_for_each_entry(entry, &dev->msi_list, list) { +	for_each_pci_msi_entry(entry, dev) {  		if (!dev->no_64bit_msi || !entry->msg.address_hi)  			continue;  		dev_err(&dev->dev, "Device has broken 64-bit MSI but arch" @@ -636,7 +612,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)  	mask = msi_mask(entry->msi_attrib.multi_cap);  	msi_mask_irq(entry, mask, mask); -	list_add_tail(&entry->list, &dev->msi_list); +	list_add_tail(&entry->list, dev_to_msi_list(&dev->dev));  	/* Configure MSI capability structure */  	ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI); @@ -665,6 +641,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)  	pci_msi_set_enable(dev, 1);  	dev->msi_enabled = 1; +	pcibios_free_irq(dev);  	dev->irq = entry->irq;  	return 0;  } @@ -696,7 +673,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base,  	int i;  	for (i = 0; i < nvec; i++) { -		entry = alloc_msi_entry(dev); +		entry = alloc_msi_entry(&dev->dev);  		if (!entry) {  			if (!i)  				iounmap(base); @@ -713,7 +690,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base,  		entry->mask_base		= base;  		entry->nvec_used		= 1; -		list_add_tail(&entry->list, &dev->msi_list); +		list_add_tail(&entry->list, dev_to_msi_list(&dev->dev));  	}  	return 0; @@ -725,7 +702,7 @@ static void msix_program_entries(struct pci_dev *dev,  	struct msi_desc *entry;  	int i = 0; -	list_for_each_entry(entry, &dev->msi_list, list) { +	for_each_pci_msi_entry(entry, dev) {  		int offset = entries[i].entry * PCI_MSIX_ENTRY_SIZE +  						PCI_MSIX_ENTRY_VECTOR_CTRL; @@ -792,9 +769,9 @@ static int msix_capability_init(struct pci_dev *dev,  	/* Set MSI-X enabled bits and unmask the function */  	pci_intx_for_msi(dev, 0);  	dev->msix_enabled = 1; -  	pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0); +	pcibios_free_irq(dev);  	return 0;  out_avail: @@ -806,7 +783,7 @@ out_avail:  		struct msi_desc *entry;  		int avail = 0; -		list_for_each_entry(entry, &dev->msi_list, list) { +		for_each_pci_msi_entry(entry, dev) {  			if (entry->irq != 0)  				avail++;  		} @@ -895,8 +872,8 @@ void pci_msi_shutdown(struct pci_dev *dev)  	if (!pci_msi_enable || !dev || !dev->msi_enabled)  		return; -	BUG_ON(list_empty(&dev->msi_list)); -	desc = list_first_entry(&dev->msi_list, struct msi_desc, list); +	BUG_ON(list_empty(dev_to_msi_list(&dev->dev))); +	desc = first_pci_msi_entry(dev);  	pci_msi_set_enable(dev, 0);  	pci_intx_for_msi(dev, 1); @@ -909,6 +886,7 @@ void pci_msi_shutdown(struct pci_dev *dev)  	/* Restore dev->irq to its default pin-assertion irq */  	dev->irq = desc->msi_attrib.default_irq; +	pcibios_alloc_irq(dev);  }  void pci_disable_msi(struct pci_dev *dev) @@ -1001,7 +979,7 @@ void pci_msix_shutdown(struct pci_dev *dev)  		return;  	/* Return the device with MSI-X masked as initial states */ -	list_for_each_entry(entry, &dev->msi_list, list) { +	for_each_pci_msi_entry(entry, dev) {  		/* Keep cached states to be restored */  		__pci_msix_desc_mask_irq(entry, 1);  	} @@ -1009,6 +987,7 @@ void pci_msix_shutdown(struct pci_dev *dev)  	pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0);  	pci_intx_for_msi(dev, 1);  	dev->msix_enabled = 0; +	pcibios_alloc_irq(dev);  }  void pci_disable_msix(struct pci_dev *dev) @@ -1040,7 +1019,6 @@ EXPORT_SYMBOL(pci_msi_enabled);  void pci_msi_init_pci_dev(struct pci_dev *dev)  { -	INIT_LIST_HEAD(&dev->msi_list);  }  /** @@ -1137,6 +1115,19 @@ int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,  }  EXPORT_SYMBOL(pci_enable_msix_range); +struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc) +{ +	return to_pci_dev(desc->dev); +} + +void *msi_desc_to_pci_sysdata(struct msi_desc *desc) +{ +	struct pci_dev *dev = msi_desc_to_pci_dev(desc); + +	return dev->bus->sysdata; +} +EXPORT_SYMBOL_GPL(msi_desc_to_pci_sysdata); +  #ifdef CONFIG_PCI_MSI_IRQ_DOMAIN  /**   * pci_msi_domain_write_msg - Helper to write MSI message to PCI config space @@ -1145,7 +1136,7 @@ EXPORT_SYMBOL(pci_enable_msix_range);   */  void pci_msi_domain_write_msg(struct irq_data *irq_data, struct msi_msg *msg)  { -	struct msi_desc *desc = irq_data->msi_desc; +	struct msi_desc *desc = irq_data_get_msi_desc(irq_data);  	/*  	 * For MSI-X desc->irq is always equal to irq_data->irq. For @@ -1269,12 +1260,19 @@ struct irq_domain *pci_msi_create_irq_domain(struct device_node *node,  					     struct msi_domain_info *info,  					     struct irq_domain *parent)  { +	struct irq_domain *domain; +  	if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS)  		pci_msi_domain_update_dom_ops(info);  	if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)  		pci_msi_domain_update_chip_ops(info); -	return msi_create_irq_domain(node, info, parent); +	domain = msi_create_irq_domain(node, info, parent); +	if (!domain) +		return NULL; + +	domain->bus_token = DOMAIN_BUS_PCI_MSI; +	return domain;  }  /** diff --git a/drivers/pci/of.c b/drivers/pci/of.c index f0929934bb7a..2e99a500cb83 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -9,6 +9,7 @@   * 2 of the License, or (at your option) any later version.   */ +#include <linux/irqdomain.h>  #include <linux/kernel.h>  #include <linux/pci.h>  #include <linux/of.h> @@ -59,3 +60,32 @@ struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus)  		return of_node_get(bus->bridge->parent->of_node);  	return NULL;  } + +struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus) +{ +#ifdef CONFIG_IRQ_DOMAIN +	struct device_node *np; +	struct irq_domain *d; + +	if (!bus->dev.of_node) +		return NULL; + +	/* Start looking for a phandle to an MSI controller. */ +	np = of_parse_phandle(bus->dev.of_node, "msi-parent", 0); + +	/* +	 * If we don't have an msi-parent property, look for a domain +	 * directly attached to the host bridge. +	 */ +	if (!np) +		np = bus->dev.of_node; + +	d = irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI); +	if (d) +		return d; + +	return irq_find_host(np); +#else +	return NULL; +#endif +} diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 314a625b78d6..a32ba753e413 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -594,7 +594,7 @@ static struct acpi_device *acpi_pci_find_companion(struct device *dev)  /**   * pci_acpi_optimize_delay - optimize PCI D3 and D3cold delay from ACPI   * @pdev: the PCI device whose delay is to be updated - * @adev: the companion ACPI device of this PCI device + * @handle: ACPI handle of this device   *   * Update the d3_delay and d3cold_delay of a PCI device from the ACPI _DSM   * control method of either the device itself or the PCI host bridge. diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 3cb2210de553..dd652f2ae03d 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -388,18 +388,31 @@ static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)  	return error;  } +int __weak pcibios_alloc_irq(struct pci_dev *dev) +{ +	return 0; +} + +void __weak pcibios_free_irq(struct pci_dev *dev) +{ +} +  static int pci_device_probe(struct device *dev)  { -	int error = 0; -	struct pci_driver *drv; -	struct pci_dev *pci_dev; +	int error; +	struct pci_dev *pci_dev = to_pci_dev(dev); +	struct pci_driver *drv = to_pci_driver(dev->driver); + +	error = pcibios_alloc_irq(pci_dev); +	if (error < 0) +		return error; -	drv = to_pci_driver(dev->driver); -	pci_dev = to_pci_dev(dev);  	pci_dev_get(pci_dev);  	error = __pci_device_probe(drv, pci_dev); -	if (error) +	if (error) { +		pcibios_free_irq(pci_dev);  		pci_dev_put(pci_dev); +	}  	return error;  } @@ -415,6 +428,7 @@ static int pci_device_remove(struct device *dev)  			drv->remove(pci_dev);  			pm_runtime_put_noidle(dev);  		} +		pcibios_free_irq(pci_dev);  		pci_dev->driver = NULL;  	} @@ -453,7 +467,7 @@ static void pci_device_shutdown(struct device *dev)  	pci_msi_shutdown(pci_dev);  	pci_msix_shutdown(pci_dev); -#ifdef CONFIG_KEXEC +#ifdef CONFIG_KEXEC_CORE  	/*  	 * If this is a kexec reboot, turn off Bus Master bit on the  	 * device to tell it to not continue to do DMA. Don't touch diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 0008c950452c..6a9a1116f1eb 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -81,7 +81,7 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE;  unsigned long pci_hotplug_io_size  = DEFAULT_HOTPLUG_IO_SIZE;  unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE; -enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_TUNE_OFF; +enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_DEFAULT;  /*   * The default CLS is used if arch didn't set CLS explicitly and not @@ -138,9 +138,22 @@ void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar)  	return ioremap_nocache(res->start, resource_size(res));  }  EXPORT_SYMBOL_GPL(pci_ioremap_bar); + +void __iomem *pci_ioremap_wc_bar(struct pci_dev *pdev, int bar) +{ +	/* +	 * Make sure the BAR is actually a memory resource, not an IO resource +	 */ +	if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { +		WARN_ON(1); +		return NULL; +	} +	return ioremap_wc(pci_resource_start(pdev, bar), +			  pci_resource_len(pdev, bar)); +} +EXPORT_SYMBOL_GPL(pci_ioremap_wc_bar);  #endif -#define PCI_FIND_CAP_TTL	48  static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,  				   u8 pos, int cap, int *ttl) @@ -196,8 +209,6 @@ static int __pci_bus_find_cap_start(struct pci_bus *bus,  		return PCI_CAPABILITY_LIST;  	case PCI_HEADER_TYPE_CARDBUS:  		return PCI_CB_CAPABILITY_LIST; -	default: -		return 0;  	}  	return 0; @@ -972,7 +983,7 @@ static int pci_save_pcix_state(struct pci_dev *dev)  	struct pci_cap_saved_state *save_state;  	pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); -	if (pos <= 0) +	if (!pos)  		return 0;  	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX); @@ -995,7 +1006,7 @@ static void pci_restore_pcix_state(struct pci_dev *dev)  	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX);  	pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); -	if (!save_state || pos <= 0) +	if (!save_state || !pos)  		return;  	cap = (u16 *)&save_state->cap.data[0]; @@ -1092,6 +1103,9 @@ void pci_restore_state(struct pci_dev *dev)  	pci_restore_pcix_state(dev);  	pci_restore_msi_state(dev); + +	/* Restore ACS and IOV configuration state */ +	pci_enable_acs(dev);  	pci_restore_iov_state(dev);  	dev->state_saved = false; @@ -2159,7 +2173,7 @@ static int _pci_add_cap_save_buffer(struct pci_dev *dev, u16 cap,  	else  		pos = pci_find_capability(dev, cap); -	if (pos <= 0) +	if (!pos)  		return 0;  	save_state = kzalloc(sizeof(*save_state) + size, GFP_KERNEL); diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 4ff0ff1c4088..24ba9dc8910a 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -4,6 +4,8 @@  #define PCI_CFG_SPACE_SIZE	256  #define PCI_CFG_SPACE_EXP_SIZE	4096 +#define PCI_FIND_CAP_TTL	48 +  extern const unsigned char pcie_link_speed[];  bool pcie_cap_has_lnkctl(const struct pci_dev *dev); diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 2f0ce668a775..88122dc2e1b1 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -448,7 +448,7 @@ static int resume_iter(struct device *dev, void *data)  }  /** - * pcie_port_device_suspend - resume port services associated with a PCIe port + * pcie_port_device_resume - resume port services associated with a PCIe port   * @dev: PCI Express port to handle   */  int pcie_port_device_resume(struct device *dev) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index cefd636681b6..0b2be174d981 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -326,8 +326,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)  		struct resource *res = &dev->resource[PCI_ROM_RESOURCE];  		dev->rom_base_reg = rom;  		res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH | -				IORESOURCE_READONLY | IORESOURCE_CACHEABLE | -				IORESOURCE_SIZEALIGN; +				IORESOURCE_READONLY | IORESOURCE_SIZEALIGN;  		__pci_read_base(dev, pci_bar_mem32, res, rom);  	}  } @@ -661,6 +660,35 @@ static void pci_set_bus_speed(struct pci_bus *bus)  	}  } +static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus) +{ +	struct irq_domain *d; + +	/* +	 * Any firmware interface that can resolve the msi_domain +	 * should be called from here. +	 */ +	d = pci_host_bridge_of_msi_domain(bus); + +	return d; +} + +static void pci_set_bus_msi_domain(struct pci_bus *bus) +{ +	struct irq_domain *d; + +	/* +	 * Either bus is the root, and we must obtain it from the +	 * firmware, or we inherit it from the bridge device. +	 */ +	if (pci_is_root_bus(bus)) +		d = pci_host_bridge_msi_domain(bus); +	else +		d = dev_get_msi_domain(&bus->self->dev); + +	dev_set_msi_domain(&bus->dev, d); +} +  static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,  					   struct pci_dev *bridge, int busnr)  { @@ -714,6 +742,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,  	bridge->subordinate = child;  add_dev: +	pci_set_bus_msi_domain(child);  	ret = device_register(&child->dev);  	WARN_ON(ret < 0); @@ -826,6 +855,9 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)  			child->bridge_ctl = bctl;  		} +		/* Read and initialize bridge resources */ +		pci_read_bridge_bases(child); +  		cmax = pci_scan_child_bus(child);  		if (cmax > subordinate)  			dev_warn(&dev->dev, "bridge has subordinate %02x but max busn %02x\n", @@ -886,6 +918,9 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)  		if (!is_cardbus) {  			child->bridge_ctl = bctl; + +			/* Read and initialize bridge resources */ +			pci_read_bridge_bases(child);  			max = pci_scan_child_bus(child);  		} else {  			/* @@ -997,7 +1032,12 @@ void set_pcie_port_type(struct pci_dev *pdev)  	else if (type == PCI_EXP_TYPE_UPSTREAM ||  		 type == PCI_EXP_TYPE_DOWNSTREAM) {  		parent = pci_upstream_bridge(pdev); -		if (!parent->has_secondary_link) + +		/* +		 * Usually there's an upstream device (Root Port or Switch +		 * Downstream Port), but we can't assume one exists. +		 */ +		if (parent && !parent->has_secondary_link)  			pdev->has_secondary_link = 1;  	}  } @@ -1103,7 +1143,7 @@ int pci_cfg_space_size(struct pci_dev *dev)  #define LEGACY_IO_RESOURCE	(IORESOURCE_IO | IORESOURCE_PCI_FIXED) -static void pci_msi_setup_pci_dev(struct pci_dev *dev) +void pci_msi_setup_pci_dev(struct pci_dev *dev)  {  	/*  	 * Disable the MSI hardware to avoid screaming interrupts @@ -1133,7 +1173,6 @@ int pci_setup_device(struct pci_dev *dev)  {  	u32 class;  	u8 hdr_type; -	struct pci_slot *slot;  	int pos = 0;  	struct pci_bus_region region;  	struct resource *res; @@ -1149,10 +1188,7 @@ int pci_setup_device(struct pci_dev *dev)  	dev->error_state = pci_channel_io_normal;  	set_pcie_port_type(dev); -	list_for_each_entry(slot, &dev->bus->slots, list) -		if (PCI_SLOT(dev->devfn) == slot->number) -			dev->slot = slot; - +	pci_dev_assign_slot(dev);  	/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)  	   set this higher, assuming the system even supports it.  */  	dev->dma_mask = 0xffffffff; @@ -1268,13 +1304,51 @@ int pci_setup_device(struct pci_dev *dev)  	bad:  		dev_err(&dev->dev, "ignoring class %#08x (doesn't match header type %02x)\n",  			dev->class, dev->hdr_type); -		dev->class = PCI_CLASS_NOT_DEFINED; +		dev->class = PCI_CLASS_NOT_DEFINED << 8;  	}  	/* We found a fine healthy device, go go go... */  	return 0;  } +static void pci_configure_mps(struct pci_dev *dev) +{ +	struct pci_dev *bridge = pci_upstream_bridge(dev); +	int mps, p_mps, rc; + +	if (!pci_is_pcie(dev) || !bridge || !pci_is_pcie(bridge)) +		return; + +	mps = pcie_get_mps(dev); +	p_mps = pcie_get_mps(bridge); + +	if (mps == p_mps) +		return; + +	if (pcie_bus_config == PCIE_BUS_TUNE_OFF) { +		dev_warn(&dev->dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n", +			 mps, pci_name(bridge), p_mps); +		return; +	} + +	/* +	 * Fancier MPS configuration is done later by +	 * pcie_bus_configure_settings() +	 */ +	if (pcie_bus_config != PCIE_BUS_DEFAULT) +		return; + +	rc = pcie_set_mps(dev, p_mps); +	if (rc) { +		dev_warn(&dev->dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n", +			 p_mps); +		return; +	} + +	dev_info(&dev->dev, "Max Payload Size set to %d (was %d, max %d)\n", +		 p_mps, mps, 128 << dev->pcie_mpss); +} +  static struct hpp_type0 pci_default_type0 = {  	.revision = 1,  	.cache_line_size = 8, @@ -1396,6 +1470,8 @@ static void pci_configure_device(struct pci_dev *dev)  	struct hotplug_params hpp;  	int ret; +	pci_configure_mps(dev); +  	memset(&hpp, 0, sizeof(hpp));  	ret = pci_get_hp_params(dev, &hpp);  	if (ret) @@ -1540,10 +1616,24 @@ static void pci_init_capabilities(struct pci_dev *dev)  	/* Single Root I/O Virtualization */  	pci_iov_init(dev); +	/* Address Translation Services */ +	pci_ats_init(dev); +  	/* Enable ACS P2P upstream forwarding */  	pci_enable_acs(dev);  } +static void pci_set_msi_domain(struct pci_dev *dev) +{ +	/* +	 * If no domain has been set through the pcibios_add_device +	 * callback, inherit the default from the bus device. +	 */ +	if (!dev_get_msi_domain(&dev->dev)) +		dev_set_msi_domain(&dev->dev, +				   dev_get_msi_domain(&dev->bus->dev)); +} +  void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)  {  	int ret; @@ -1585,6 +1675,9 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)  	ret = pcibios_add_device(dev);  	WARN_ON(ret < 0); +	/* Setup MSI irq domain */ +	pci_set_msi_domain(dev); +  	/* Notifier could use PCI capabilities */  	dev->match_driver = false;  	ret = device_add(&dev->dev); @@ -1791,22 +1884,6 @@ static void pcie_write_mrrs(struct pci_dev *dev)  		dev_err(&dev->dev, "MRRS was unable to be configured with a safe value.  If problems are experienced, try running with pci=pcie_bus_safe\n");  } -static void pcie_bus_detect_mps(struct pci_dev *dev) -{ -	struct pci_dev *bridge = dev->bus->self; -	int mps, p_mps; - -	if (!bridge) -		return; - -	mps = pcie_get_mps(dev); -	p_mps = pcie_get_mps(bridge); - -	if (mps != p_mps) -		dev_warn(&dev->dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n", -			 mps, pci_name(bridge), p_mps); -} -  static int pcie_bus_configure_set(struct pci_dev *dev, void *data)  {  	int mps, orig_mps; @@ -1814,10 +1891,9 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data)  	if (!pci_is_pcie(dev))  		return 0; -	if (pcie_bus_config == PCIE_BUS_TUNE_OFF) { -		pcie_bus_detect_mps(dev); +	if (pcie_bus_config == PCIE_BUS_TUNE_OFF || +	    pcie_bus_config == PCIE_BUS_DEFAULT)  		return 0; -	}  	mps = 128 << *(u8 *)data;  	orig_mps = pcie_get_mps(dev); @@ -1975,6 +2051,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,  	b->bridge = get_device(&bridge->dev);  	device_enable_async_suspend(b->bridge);  	pci_set_bus_of_node(b); +	pci_set_bus_msi_domain(b);  	if (!parent)  		set_dev_node(b->bridge, pcibus_to_node(b)); @@ -2096,8 +2173,9 @@ void pci_bus_release_busn_res(struct pci_bus *b)  			res, ret ? "can not be" : "is");  } -struct pci_bus *pci_scan_root_bus(struct device *parent, int bus, -		struct pci_ops *ops, void *sysdata, struct list_head *resources) +struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus, +		struct pci_ops *ops, void *sysdata, +		struct list_head *resources, struct msi_controller *msi)  {  	struct resource_entry *window;  	bool found = false; @@ -2114,6 +2192,8 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,  	if (!b)  		return NULL; +	b->msi = msi; +  	if (!found) {  		dev_info(&b->dev,  		 "No busn resource found for root bus, will use [bus %02x-ff]\n", @@ -2128,6 +2208,13 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,  	return b;  } + +struct pci_bus *pci_scan_root_bus(struct device *parent, int bus, +		struct pci_ops *ops, void *sysdata, struct list_head *resources) +{ +	return pci_scan_root_bus_msi(parent, bus, ops, sysdata, resources, +				     NULL); +}  EXPORT_SYMBOL(pci_scan_root_bus);  struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e9fd0e90fa3b..6a30252cd79f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -163,7 +163,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82439TX,	quirk_   *	VIA Apollo KT133 needs PCI latency patch   *	Made according to a windows driver based patch by George E. Breese   *	see PCI Latency Adjust on http://www.viahardware.com/download/viatweak.shtm - *	and http://www.georgebreese.com/net/software/#PCI   *	Also see http://www.au-ja.org/review-kt133a-1-en.phtml for   *	the info on which Mr Breese based his work.   * @@ -424,10 +423,12 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI,	PCI_DEVICE_ID_ATI_RS100,   quirk_ati_   */  static void quirk_amd_nl_class(struct pci_dev *pdev)  { -	/* -	 * Use 'USB Device' (0x0c03fe) instead of PCI header provided -	 */ -	pdev->class = 0x0c03fe; +	u32 class = pdev->class; + +	/* Use "USB Device (not host controller)" class */ +	pdev->class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe; +	dev_info(&pdev->dev, "PCI class overridden (%#08x -> %#08x) so dwc3 driver can claim this instead of xhci\n", +		 class, pdev->class);  }  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB,  		quirk_amd_nl_class); @@ -1569,6 +1570,18 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB3  #endif +static void quirk_jmicron_async_suspend(struct pci_dev *dev) +{ +	if (dev->multifunction) { +		device_disable_async_suspend(&dev->dev); +		dev_info(&dev->dev, "async suspend disabled to avoid multi-function power-on ordering issue\n"); +	} +} +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE, 8, quirk_jmicron_async_suspend); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_CLASS_STORAGE_SATA_AHCI, 0, quirk_jmicron_async_suspend); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_JMICRON, 0x2362, quirk_jmicron_async_suspend); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_JMICRON, 0x236f, quirk_jmicron_async_suspend); +  #ifdef CONFIG_X86_IO_APIC  static void quirk_alder_ioapic(struct pci_dev *pdev)  { @@ -1894,6 +1907,15 @@ static void quirk_netmos(struct pci_dev *dev)  DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID,  			 PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos); +static void quirk_f0_vpd_link(struct pci_dev *dev) +{ +	if (!dev->multifunction || !PCI_FUNC(dev->devfn)) +		return; +	dev->dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0; +} +DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, +			      PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link); +  static void quirk_e100_interrupt(struct pci_dev *dev)  {  	u16 command, pmcsr; @@ -1986,14 +2008,18 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s);  static void fixup_rev1_53c810(struct pci_dev *dev)  { -	/* rev 1 ncr53c810 chips don't set the class at all which means +	u32 class = dev->class; + +	/* +	 * rev 1 ncr53c810 chips don't set the class at all which means  	 * they don't get their resources remapped. Fix that here.  	 */ +	if (class) +		return; -	if (dev->class == PCI_CLASS_NOT_DEFINED) { -		dev_info(&dev->dev, "NCR 53c810 rev 1 detected; setting PCI class\n"); -		dev->class = PCI_CLASS_STORAGE_SCSI; -	} +	dev->class = PCI_CLASS_STORAGE_SCSI << 8; +	dev_info(&dev->dev, "NCR 53c810 rev 1 PCI class overridden (%#08x -> %#08x)\n", +		 class, dev->class);  }  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810); @@ -2241,7 +2267,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9601, quirk_amd_780_apc_msi);   * return 1 if a HT MSI capability is found and enabled */  static int msi_ht_cap_enabled(struct pci_dev *dev)  { -	int pos, ttl = 48; +	int pos, ttl = PCI_FIND_CAP_TTL;  	pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);  	while (pos && ttl--) { @@ -2300,7 +2326,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,  /* Force enable MSI mapping capability on HT bridges */  static void ht_enable_msi_mapping(struct pci_dev *dev)  { -	int pos, ttl = 48; +	int pos, ttl = PCI_FIND_CAP_TTL;  	pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);  	while (pos && ttl--) { @@ -2379,7 +2405,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA,  static int ht_check_msi_mapping(struct pci_dev *dev)  { -	int pos, ttl = 48; +	int pos, ttl = PCI_FIND_CAP_TTL;  	int found = 0;  	/* check if there is HT MSI cap or enabled on this device */ @@ -2504,7 +2530,7 @@ out:  static void ht_disable_msi_mapping(struct pci_dev *dev)  { -	int pos, ttl = 48; +	int pos, ttl = PCI_FIND_CAP_TTL;  	pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);  	while (pos && ttl--) { @@ -2829,12 +2855,15 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors);  static void fixup_ti816x_class(struct pci_dev *dev)  { +	u32 class = dev->class; +  	/* TI 816x devices do not have class code set when in PCIe boot mode */ -	dev_info(&dev->dev, "Setting PCI class for 816x PCIe device\n"); -	dev->class = PCI_CLASS_MULTIMEDIA_VIDEO; +	dev->class = PCI_CLASS_MULTIMEDIA_VIDEO << 8; +	dev_info(&dev->dev, "PCI class overridden (%#08x -> %#08x)\n", +		 class, dev->class);  }  DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_TI, 0xb800, -				 PCI_CLASS_NOT_DEFINED, 0, fixup_ti816x_class); +			      PCI_CLASS_NOT_DEFINED, 8, fixup_ti816x_class);  /* Some PCIe devices do not work reliably with the claimed maximum   * payload size supported. @@ -2862,7 +2891,8 @@ static void quirk_intel_mc_errata(struct pci_dev *dev)  	int err;  	u16 rcc; -	if (pcie_bus_config == PCIE_BUS_TUNE_OFF) +	if (pcie_bus_config == PCIE_BUS_TUNE_OFF || +	    pcie_bus_config == PCIE_BUS_DEFAULT)  		return;  	/* Intel errata specifies bits to change but does not say what they are. @@ -3028,7 +3058,16 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c26, quirk_remove_d3_delay);  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c4e, quirk_remove_d3_delay);  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c02, quirk_remove_d3_delay);  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c22, quirk_remove_d3_delay); - +/* Intel Cherrytrail devices do not need 10ms d3_delay */ +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2280, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b0, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b8, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22d8, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22dc, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b5, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3_delay);  /*   * Some devices may pass our check in pci_intx_mask_supported if   * PCI_COMMAND_INTX_DISABLE works though they actually do not properly @@ -3326,28 +3365,6 @@ fs_initcall_sync(pci_apply_final_quirks);   * reset a single function if other methods (e.g. FLR, PM D0->D3) are   * not available.   */ -static int reset_intel_generic_dev(struct pci_dev *dev, int probe) -{ -	int pos; - -	/* only implement PCI_CLASS_SERIAL_USB at present */ -	if (dev->class == PCI_CLASS_SERIAL_USB) { -		pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); -		if (!pos) -			return -ENOTTY; - -		if (probe) -			return 0; - -		pci_write_config_byte(dev, pos + 0x4, 1); -		msleep(100); - -		return 0; -	} else { -		return -ENOTTY; -	} -} -  static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe)  {  	/* @@ -3506,8 +3523,6 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {  		reset_ivb_igd },  	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M2_VGA,  		reset_ivb_igd }, -	{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, -		reset_intel_generic_dev },  	{ PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID,  		reset_chelsio_generic_dev },  	{ 0 } @@ -3655,6 +3670,28 @@ DECLARE_PCI_FIXUP_HEADER(0x1283, 0x8892, quirk_use_pcie_bridge_dma_alias);  DECLARE_PCI_FIXUP_HEADER(0x8086, 0x244e, quirk_use_pcie_bridge_dma_alias);  /* + * Intersil/Techwell TW686[4589]-based video capture cards have an empty (zero) + * class code.  Fix it. + */ +static void quirk_tw686x_class(struct pci_dev *pdev) +{ +	u32 class = pdev->class; + +	/* Use "Multimedia controller" class */ +	pdev->class = (PCI_CLASS_MULTIMEDIA_OTHER << 8) | 0x01; +	dev_info(&pdev->dev, "TW686x PCI class overridden (%#08x -> %#08x)\n", +		 class, pdev->class); +} +DECLARE_PCI_FIXUP_CLASS_EARLY(0x1797, 0x6864, PCI_CLASS_NOT_DEFINED, 8, +			      quirk_tw686x_class); +DECLARE_PCI_FIXUP_CLASS_EARLY(0x1797, 0x6865, PCI_CLASS_NOT_DEFINED, 8, +			      quirk_tw686x_class); +DECLARE_PCI_FIXUP_CLASS_EARLY(0x1797, 0x6868, PCI_CLASS_NOT_DEFINED, 8, +			      quirk_tw686x_class); +DECLARE_PCI_FIXUP_CLASS_EARLY(0x1797, 0x6869, PCI_CLASS_NOT_DEFINED, 8, +			      quirk_tw686x_class); + +/*   * AMD has indicated that the devices below do not support peer-to-peer   * in any system where they are found in the southbridge with an AMD   * IOMMU in the system.  Multifunction devices that do not support @@ -3848,6 +3885,9 @@ static const struct pci_dev_acs_enabled {  	{ PCI_VENDOR_ID_INTEL, 0x105F, pci_quirk_mf_endpoint_acs },  	{ PCI_VENDOR_ID_INTEL, 0x1060, pci_quirk_mf_endpoint_acs },  	{ PCI_VENDOR_ID_INTEL, 0x10D9, pci_quirk_mf_endpoint_acs }, +	/* I219 */ +	{ PCI_VENDOR_ID_INTEL, 0x15b7, pci_quirk_mf_endpoint_acs }, +	{ PCI_VENDOR_ID_INTEL, 0x15b8, pci_quirk_mf_endpoint_acs },  	/* Intel PCH root ports */  	{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs },  	{ 0x19a2, 0x710, pci_quirk_mf_endpoint_acs }, /* Emulex BE3-R */ @@ -4008,3 +4048,88 @@ void pci_dev_specific_enable_acs(struct pci_dev *dev)  		}  	}  } + +/* + * The PCI capabilities list for Intel DH895xCC VFs (device id 0x0443) with + * QuickAssist Technology (QAT) is prematurely terminated in hardware.  The + * Next Capability pointer in the MSI Capability Structure should point to + * the PCIe Capability Structure but is incorrectly hardwired as 0 terminating + * the list. + */ +static void quirk_intel_qat_vf_cap(struct pci_dev *pdev) +{ +	int pos, i = 0; +	u8 next_cap; +	u16 reg16, *cap; +	struct pci_cap_saved_state *state; + +	/* Bail if the hardware bug is fixed */ +	if (pdev->pcie_cap || pci_find_capability(pdev, PCI_CAP_ID_EXP)) +		return; + +	/* Bail if MSI Capability Structure is not found for some reason */ +	pos = pci_find_capability(pdev, PCI_CAP_ID_MSI); +	if (!pos) +		return; + +	/* +	 * Bail if Next Capability pointer in the MSI Capability Structure +	 * is not the expected incorrect 0x00. +	 */ +	pci_read_config_byte(pdev, pos + 1, &next_cap); +	if (next_cap) +		return; + +	/* +	 * PCIe Capability Structure is expected to be at 0x50 and should +	 * terminate the list (Next Capability pointer is 0x00).  Verify +	 * Capability Id and Next Capability pointer is as expected. +	 * Open-code some of set_pcie_port_type() and pci_cfg_space_size_ext() +	 * to correctly set kernel data structures which have already been +	 * set incorrectly due to the hardware bug. +	 */ +	pos = 0x50; +	pci_read_config_word(pdev, pos, ®16); +	if (reg16 == (0x0000 | PCI_CAP_ID_EXP)) { +		u32 status; +#ifndef PCI_EXP_SAVE_REGS +#define PCI_EXP_SAVE_REGS     7 +#endif +		int size = PCI_EXP_SAVE_REGS * sizeof(u16); + +		pdev->pcie_cap = pos; +		pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); +		pdev->pcie_flags_reg = reg16; +		pci_read_config_word(pdev, pos + PCI_EXP_DEVCAP, ®16); +		pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD; + +		pdev->cfg_size = PCI_CFG_SPACE_EXP_SIZE; +		if (pci_read_config_dword(pdev, PCI_CFG_SPACE_SIZE, &status) != +		    PCIBIOS_SUCCESSFUL || (status == 0xffffffff)) +			pdev->cfg_size = PCI_CFG_SPACE_SIZE; + +		if (pci_find_saved_cap(pdev, PCI_CAP_ID_EXP)) +			return; + +		/* +		 * Save PCIE cap +		 */ +		state = kzalloc(sizeof(*state) + size, GFP_KERNEL); +		if (!state) +			return; + +		state->cap.cap_nr = PCI_CAP_ID_EXP; +		state->cap.cap_extended = 0; +		state->cap.size = size; +		cap = (u16 *)&state->cap.data[0]; +		pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap[i++]); +		pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &cap[i++]); +		pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &cap[i++]); +		pcie_capability_read_word(pdev, PCI_EXP_RTCTL,  &cap[i++]); +		pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &cap[i++]); +		pcie_capability_read_word(pdev, PCI_EXP_LNKCTL2, &cap[i++]); +		pcie_capability_read_word(pdev, PCI_EXP_SLTCTL2, &cap[i++]); +		hlist_add_head(&state->next, &pdev->saved_cap_space); +	} +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap); diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 396c200b9ddb..429d34c348b9 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c @@ -14,6 +14,7 @@  struct kset *pci_slots_kset;  EXPORT_SYMBOL_GPL(pci_slots_kset); +static DEFINE_MUTEX(pci_slot_mutex);  static ssize_t pci_slot_attr_show(struct kobject *kobj,  					struct attribute *attr, char *buf) @@ -106,9 +107,11 @@ static void pci_slot_release(struct kobject *kobj)  	dev_dbg(&slot->bus->dev, "dev %02x, released physical slot %s\n",  		slot->number, pci_slot_name(slot)); +	down_read(&pci_bus_sem);  	list_for_each_entry(dev, &slot->bus->devices, bus_list)  		if (PCI_SLOT(dev->devfn) == slot->number)  			dev->slot = NULL; +	up_read(&pci_bus_sem);  	list_del(&slot->list); @@ -191,12 +194,22 @@ static int rename_slot(struct pci_slot *slot, const char *name)  	return result;  } +void pci_dev_assign_slot(struct pci_dev *dev) +{ +	struct pci_slot *slot; + +	mutex_lock(&pci_slot_mutex); +	list_for_each_entry(slot, &dev->bus->slots, list) +		if (PCI_SLOT(dev->devfn) == slot->number) +			dev->slot = slot; +	mutex_unlock(&pci_slot_mutex); +} +  static struct pci_slot *get_slot(struct pci_bus *parent, int slot_nr)  {  	struct pci_slot *slot; -	/* -	 * We already hold pci_bus_sem so don't worry -	 */ + +	/* We already hold pci_slot_mutex */  	list_for_each_entry(slot, &parent->slots, list)  		if (slot->number == slot_nr) {  			kobject_get(&slot->kobj); @@ -253,7 +266,7 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,  	int err = 0;  	char *slot_name = NULL; -	down_write(&pci_bus_sem); +	mutex_lock(&pci_slot_mutex);  	if (slot_nr == -1)  		goto placeholder; @@ -301,16 +314,18 @@ placeholder:  	INIT_LIST_HEAD(&slot->list);  	list_add(&slot->list, &parent->slots); +	down_read(&pci_bus_sem);  	list_for_each_entry(dev, &parent->devices, bus_list)  		if (PCI_SLOT(dev->devfn) == slot_nr)  			dev->slot = slot; +	up_read(&pci_bus_sem);  	dev_dbg(&parent->dev, "dev %02x, created physical slot %s\n",  		slot_nr, pci_slot_name(slot));  out:  	kfree(slot_name); -	up_write(&pci_bus_sem); +	mutex_unlock(&pci_slot_mutex);  	return slot;  err:  	kfree(slot); @@ -332,9 +347,9 @@ void pci_destroy_slot(struct pci_slot *slot)  	dev_dbg(&slot->bus->dev, "dev %02x, dec refcount to %d\n",  		slot->number, atomic_read(&slot->kobj.kref.refcount) - 1); -	down_write(&pci_bus_sem); +	mutex_lock(&pci_slot_mutex);  	kobject_put(&slot->kobj); -	up_write(&pci_bus_sem); +	mutex_unlock(&pci_slot_mutex);  }  EXPORT_SYMBOL_GPL(pci_destroy_slot); diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 8b7a900cd28b..c777b97207d5 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -265,7 +265,7 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,  	}  	i = 0; -	list_for_each_entry(entry, &dev->msi_list, list) { +	for_each_pci_msi_entry(entry, dev) {  		op.msix_entries[i].entry = entry->msi_attrib.entry_nr;  		/* Vector is useless at this point. */  		op.msix_entries[i].vector = -1;  |