diff options
Diffstat (limited to 'drivers/pci/controller')
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-designware.c | 8 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-designware.h | 3 | ||||
| -rw-r--r-- | drivers/pci/controller/pci-hyperv.c | 39 | ||||
| -rw-r--r-- | drivers/pci/controller/pci-mvebu.c | 52 | ||||
| -rw-r--r-- | drivers/pci/controller/pcie-cadence.c | 4 | ||||
| -rw-r--r-- | drivers/pci/controller/vmd.c | 4 | 
6 files changed, 94 insertions, 16 deletions
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 778c4f76a884..2153956a0b20 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -135,7 +135,7 @@ static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index,  		if (val & PCIE_ATU_ENABLE)  			return; -		usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX); +		mdelay(LINK_WAIT_IATU);  	}  	dev_err(pci->dev, "Outbound iATU is not being enabled\n");  } @@ -178,7 +178,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,  		if (val & PCIE_ATU_ENABLE)  			return; -		usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX); +		mdelay(LINK_WAIT_IATU);  	}  	dev_err(pci->dev, "Outbound iATU is not being enabled\n");  } @@ -236,7 +236,7 @@ static int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, int index,  		if (val & PCIE_ATU_ENABLE)  			return 0; -		usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX); +		mdelay(LINK_WAIT_IATU);  	}  	dev_err(pci->dev, "Inbound iATU is not being enabled\n"); @@ -282,7 +282,7 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int bar,  		if (val & PCIE_ATU_ENABLE)  			return 0; -		usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX); +		mdelay(LINK_WAIT_IATU);  	}  	dev_err(pci->dev, "Inbound iATU is not being enabled\n"); diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 96126fd8403c..9f1a5e399b70 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -26,8 +26,7 @@  /* Parameters for the waiting for iATU enabled routine */  #define LINK_WAIT_MAX_IATU_RETRIES	5 -#define LINK_WAIT_IATU_MIN		9000 -#define LINK_WAIT_IATU_MAX		10000 +#define LINK_WAIT_IATU			9  /* Synopsys-specific PCIe configuration registers */  #define PCIE_PORT_LINK_CONTROL		0x710 diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index c00f82cc54aa..9ba4d12c179c 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@ -89,6 +89,9 @@ static enum pci_protocol_version_t pci_protocol_version;  #define STATUS_REVISION_MISMATCH 0xC0000059 +/* space for 32bit serial number as string */ +#define SLOT_NAME_SIZE 11 +  /*   * Message Types   */ @@ -494,6 +497,7 @@ struct hv_pci_dev {  	struct list_head list_entry;  	refcount_t refs;  	enum hv_pcichild_state state; +	struct pci_slot *pci_slot;  	struct pci_function_description desc;  	bool reported_missing;  	struct hv_pcibus_device *hbus; @@ -1457,6 +1461,36 @@ static void prepopulate_bars(struct hv_pcibus_device *hbus)  	spin_unlock_irqrestore(&hbus->device_list_lock, flags);  } +/* + * Assign entries in sysfs pci slot directory. + * + * Note that this function does not need to lock the children list + * because it is called from pci_devices_present_work which + * is serialized with hv_eject_device_work because they are on the + * same ordered workqueue. Therefore hbus->children list will not change + * even when pci_create_slot sleeps. + */ +static void hv_pci_assign_slots(struct hv_pcibus_device *hbus) +{ +	struct hv_pci_dev *hpdev; +	char name[SLOT_NAME_SIZE]; +	int slot_nr; + +	list_for_each_entry(hpdev, &hbus->children, list_entry) { +		if (hpdev->pci_slot) +			continue; + +		slot_nr = PCI_SLOT(wslot_to_devfn(hpdev->desc.win_slot.slot)); +		snprintf(name, SLOT_NAME_SIZE, "%u", hpdev->desc.ser); +		hpdev->pci_slot = pci_create_slot(hbus->pci_bus, slot_nr, +					  name, NULL); +		if (IS_ERR(hpdev->pci_slot)) { +			pr_warn("pci_create slot %s failed\n", name); +			hpdev->pci_slot = NULL; +		} +	} +} +  /**   * create_root_hv_pci_bus() - Expose a new root PCI bus   * @hbus:	Root PCI bus, as understood by this driver @@ -1480,6 +1514,7 @@ static int create_root_hv_pci_bus(struct hv_pcibus_device *hbus)  	pci_lock_rescan_remove();  	pci_scan_child_bus(hbus->pci_bus);  	pci_bus_assign_resources(hbus->pci_bus); +	hv_pci_assign_slots(hbus);  	pci_bus_add_devices(hbus->pci_bus);  	pci_unlock_rescan_remove();  	hbus->state = hv_pcibus_installed; @@ -1742,6 +1777,7 @@ static void pci_devices_present_work(struct work_struct *work)  		 */  		pci_lock_rescan_remove();  		pci_scan_child_bus(hbus->pci_bus); +		hv_pci_assign_slots(hbus);  		pci_unlock_rescan_remove();  		break; @@ -1858,6 +1894,9 @@ static void hv_eject_device_work(struct work_struct *work)  	list_del(&hpdev->list_entry);  	spin_unlock_irqrestore(&hpdev->hbus->device_list_lock, flags); +	if (hpdev->pci_slot) +		pci_destroy_slot(hpdev->pci_slot); +  	memset(&ctxt, 0, sizeof(ctxt));  	ejct_pkt = (struct pci_eject_response *)&ctxt.pkt.message;  	ejct_pkt->message_type.type = PCI_EJECTION_COMPLETE; diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c index 50eb0729385b..a41d79b8d46a 100644 --- a/drivers/pci/controller/pci-mvebu.c +++ b/drivers/pci/controller/pci-mvebu.c @@ -1145,7 +1145,6 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie)  {  	struct device *dev = &pcie->pdev->dev;  	struct device_node *np = dev->of_node; -	unsigned int i;  	int ret;  	INIT_LIST_HEAD(&pcie->resources); @@ -1179,13 +1178,58 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie)  					 resource_size(&pcie->io) - 1);  		pcie->realio.name = "PCI I/O"; +		pci_add_resource(&pcie->resources, &pcie->realio); +	} + +	return devm_request_pci_bus_resources(dev, &pcie->resources); +} + +/* + * This is a copy of pci_host_probe(), except that it does the I/O + * remap as the last step, once we are sure we won't fail. + * + * It should be removed once the I/O remap error handling issue has + * been sorted out. + */ +static int mvebu_pci_host_probe(struct pci_host_bridge *bridge) +{ +	struct mvebu_pcie *pcie; +	struct pci_bus *bus, *child; +	int ret; + +	ret = pci_scan_root_bus_bridge(bridge); +	if (ret < 0) { +		dev_err(bridge->dev.parent, "Scanning root bridge failed"); +		return ret; +	} + +	pcie = pci_host_bridge_priv(bridge); +	if (resource_size(&pcie->io) != 0) { +		unsigned int i; +  		for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K)  			pci_ioremap_io(i, pcie->io.start + i); +	} -		pci_add_resource(&pcie->resources, &pcie->realio); +	bus = bridge->bus; + +	/* +	 * We insert PCI resources into the iomem_resource and +	 * ioport_resource trees in either pci_bus_claim_resources() +	 * or pci_bus_assign_resources(). +	 */ +	if (pci_has_flag(PCI_PROBE_ONLY)) { +		pci_bus_claim_resources(bus); +	} else { +		pci_bus_size_bridges(bus); +		pci_bus_assign_resources(bus); + +		list_for_each_entry(child, &bus->children, node) +			pcie_bus_configure_settings(child);  	} -	return devm_request_pci_bus_resources(dev, &pcie->resources); +	pci_bus_add_devices(bus); +	return 0;  }  static int mvebu_pcie_probe(struct platform_device *pdev) @@ -1268,7 +1312,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev)  	bridge->align_resource = mvebu_pcie_align_resource;  	bridge->msi = pcie->msi; -	return pci_host_probe(bridge); +	return mvebu_pci_host_probe(bridge);  }  static const struct of_device_id mvebu_pcie_of_match_table[] = { diff --git a/drivers/pci/controller/pcie-cadence.c b/drivers/pci/controller/pcie-cadence.c index 86f1b002c846..975bcdd6b5c0 100644 --- a/drivers/pci/controller/pcie-cadence.c +++ b/drivers/pci/controller/pcie-cadence.c @@ -180,11 +180,11 @@ int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie)  		return 0;  	} -	phy = devm_kzalloc(dev, sizeof(*phy) * phy_count, GFP_KERNEL); +	phy = devm_kcalloc(dev, phy_count, sizeof(*phy), GFP_KERNEL);  	if (!phy)  		return -ENOMEM; -	link = devm_kzalloc(dev, sizeof(*link) * phy_count, GFP_KERNEL); +	link = devm_kcalloc(dev, phy_count, sizeof(*link), GFP_KERNEL);  	if (!link)  		return -ENOMEM; diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c index fd2dbd7eed7b..f31ed62d518c 100644 --- a/drivers/pci/controller/vmd.c +++ b/drivers/pci/controller/vmd.c @@ -404,12 +404,10 @@ static int vmd_dma_supported(struct device *dev, u64 mask)  	return vmd_dma_ops(dev)->dma_supported(to_vmd_dev(dev), mask);  } -#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK  static u64 vmd_get_required_mask(struct device *dev)  {  	return vmd_dma_ops(dev)->get_required_mask(to_vmd_dev(dev));  } -#endif  static void vmd_teardown_dma_ops(struct vmd_dev *vmd)  { @@ -450,9 +448,7 @@ static void vmd_setup_dma_ops(struct vmd_dev *vmd)  	ASSIGN_VMD_DMA_OPS(source, dest, sync_sg_for_device);  	ASSIGN_VMD_DMA_OPS(source, dest, mapping_error);  	ASSIGN_VMD_DMA_OPS(source, dest, dma_supported); -#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK  	ASSIGN_VMD_DMA_OPS(source, dest, get_required_mask); -#endif  	add_dma_domain(domain);  }  #undef ASSIGN_VMD_DMA_OPS  | 
