diff options
Diffstat (limited to 'drivers/pci/controller')
| -rw-r--r-- | drivers/pci/controller/cadence/pcie-cadence-ep.c | 7 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pci-dra7xx.c | 9 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pci-imx6.c | 10 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pci-keystone.c | 11 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pci-layerscape-ep.c | 9 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-artpec6.c | 15 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-designware-ep.c | 238 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-designware-plat.c | 11 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-designware.h | 14 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-keembay.c | 18 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-qcom-ep.c | 4 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-rcar-gen4.c | 28 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-tegra194.c | 8 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-uniphier-ep.c | 15 | ||||
| -rw-r--r-- | drivers/pci/controller/pcie-mt7621.c | 2 | ||||
| -rw-r--r-- | drivers/pci/controller/pcie-rcar-ep.c | 2 | ||||
| -rw-r--r-- | drivers/pci/controller/pcie-rockchip-ep.c | 10 | 
17 files changed, 306 insertions, 105 deletions
| diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c index 81c50dc64da9..e0cc4560dfde 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c @@ -99,14 +99,11 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,  		ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS;  	} else {  		bool is_prefetch = !!(flags & PCI_BASE_ADDRESS_MEM_PREFETCH); -		bool is_64bits = sz > SZ_2G; +		bool is_64bits = !!(flags & PCI_BASE_ADDRESS_MEM_TYPE_64);  		if (is_64bits && (bar & 1))  			return -EINVAL; -		if (is_64bits && !(flags & PCI_BASE_ADDRESS_MEM_TYPE_64)) -			epf_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64; -  		if (is_64bits && is_prefetch)  			ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS;  		else if (is_prefetch) @@ -746,6 +743,8 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)  	spin_lock_init(&ep->lock); +	pci_epc_init_notify(epc); +  	return 0;   free_epc_mem: diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c index 0e406677060d..d2d17d37d3e0 100644 --- a/drivers/pci/controller/dwc/pci-dra7xx.c +++ b/drivers/pci/controller/dwc/pci-dra7xx.c @@ -467,6 +467,15 @@ static int dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,  		return ret;  	} +	ret = dw_pcie_ep_init_registers(ep); +	if (ret) { +		dev_err(dev, "Failed to initialize DWC endpoint registers\n"); +		dw_pcie_ep_deinit(ep); +		return ret; +	} + +	dw_pcie_ep_init_notify(ep); +  	return 0;  } diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 99a60270b26c..917c69edee1d 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -1123,6 +1123,16 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,  		dev_err(dev, "failed to initialize endpoint\n");  		return ret;  	} + +	ret = dw_pcie_ep_init_registers(ep); +	if (ret) { +		dev_err(dev, "Failed to initialize DWC endpoint registers\n"); +		dw_pcie_ep_deinit(ep); +		return ret; +	} + +	dw_pcie_ep_init_notify(ep); +  	/* Start LTSSM. */  	imx6_pcie_ltssm_enable(dev); diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c index 844de4418724..d3a7d14ee685 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c @@ -1286,6 +1286,15 @@ static int ks_pcie_probe(struct platform_device *pdev)  		ret = dw_pcie_ep_init(&pci->ep);  		if (ret < 0)  			goto err_get_sync; + +		ret = dw_pcie_ep_init_registers(&pci->ep); +		if (ret) { +			dev_err(dev, "Failed to initialize DWC endpoint registers\n"); +			goto err_ep_init; +		} + +		dw_pcie_ep_init_notify(&pci->ep); +  		break;  	default:  		dev_err(dev, "INVALID device type %d\n", mode); @@ -1295,6 +1304,8 @@ static int ks_pcie_probe(struct platform_device *pdev)  	return 0; +err_ep_init: +	dw_pcie_ep_deinit(&pci->ep);  err_get_sync:  	pm_runtime_put(dev);  	pm_runtime_disable(dev); diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c index 1f6ee1460ec2..7dde6d5fa4d8 100644 --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c @@ -279,6 +279,15 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)  	if (ret)  		return ret; +	ret = dw_pcie_ep_init_registers(&pci->ep); +	if (ret) { +		dev_err(dev, "Failed to initialize DWC endpoint registers\n"); +		dw_pcie_ep_deinit(&pci->ep); +		return ret; +	} + +	dw_pcie_ep_init_notify(&pci->ep); +  	return ls_pcie_ep_interrupt_init(pcie, pdev);  } diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c index 9ed0a9ba7619..a4630b92489b 100644 --- a/drivers/pci/controller/dwc/pcie-artpec6.c +++ b/drivers/pci/controller/dwc/pcie-artpec6.c @@ -441,7 +441,20 @@ static int artpec6_pcie_probe(struct platform_device *pdev)  		pci->ep.ops = &pcie_ep_ops; -		return dw_pcie_ep_init(&pci->ep); +		ret = dw_pcie_ep_init(&pci->ep); +		if (ret) +			return ret; + +		ret = dw_pcie_ep_init_registers(&pci->ep); +		if (ret) { +			dev_err(dev, "Failed to initialize DWC endpoint registers\n"); +			dw_pcie_ep_deinit(&pci->ep); +			return ret; +		} + +		dw_pcie_ep_init_notify(&pci->ep); + +		break;  	default:  		dev_err(dev, "INVALID device type %d\n", artpec6_pcie->mode);  	} diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 746a11dcb67f..47391d7d3a73 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -15,6 +15,10 @@  #include <linux/pci-epc.h>  #include <linux/pci-epf.h> +/** + * dw_pcie_ep_linkup - Notify EPF drivers about Link Up event + * @ep: DWC EP device + */  void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)  {  	struct pci_epc *epc = ep->epc; @@ -23,6 +27,10 @@ void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)  }  EXPORT_SYMBOL_GPL(dw_pcie_ep_linkup); +/** + * dw_pcie_ep_init_notify - Notify EPF drivers about EPC initialization complete + * @ep: DWC EP device + */  void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep)  {  	struct pci_epc *epc = ep->epc; @@ -31,6 +39,14 @@ void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep)  }  EXPORT_SYMBOL_GPL(dw_pcie_ep_init_notify); +/** + * dw_pcie_ep_get_func_from_ep - Get the struct dw_pcie_ep_func corresponding to + *				 the endpoint function + * @ep: DWC EP device + * @func_no: Function number of the endpoint device + * + * Return: struct dw_pcie_ep_func if success, NULL otherwise. + */  struct dw_pcie_ep_func *  dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no)  { @@ -61,6 +77,11 @@ static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, u8 func_no,  	dw_pcie_dbi_ro_wr_dis(pci);  } +/** + * dw_pcie_ep_reset_bar - Reset endpoint BAR + * @pci: DWC PCI device + * @bar: BAR number of the endpoint + */  void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)  {  	u8 func_no, funcs; @@ -440,6 +461,13 @@ static const struct pci_epc_ops epc_ops = {  	.get_features		= dw_pcie_ep_get_features,  }; +/** + * dw_pcie_ep_raise_intx_irq - Raise INTx IRQ to the host + * @ep: DWC EP device + * @func_no: Function number of the endpoint + * + * Return: 0 if success, errono otherwise. + */  int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no)  {  	struct dw_pcie *pci = to_dw_pcie_from_ep(ep); @@ -451,6 +479,14 @@ int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no)  }  EXPORT_SYMBOL_GPL(dw_pcie_ep_raise_intx_irq); +/** + * dw_pcie_ep_raise_msi_irq - Raise MSI IRQ to the host + * @ep: DWC EP device + * @func_no: Function number of the endpoint + * @interrupt_num: Interrupt number to be raised + * + * Return: 0 if success, errono otherwise. + */  int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,  			     u8 interrupt_num)  { @@ -500,6 +536,15 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,  }  EXPORT_SYMBOL_GPL(dw_pcie_ep_raise_msi_irq); +/** + * dw_pcie_ep_raise_msix_irq_doorbell - Raise MSI-X to the host using Doorbell + *					method + * @ep: DWC EP device + * @func_no: Function number of the endpoint device + * @interrupt_num: Interrupt number to be raised + * + * Return: 0 if success, errno otherwise. + */  int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,  				       u16 interrupt_num)  { @@ -519,6 +564,14 @@ int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,  	return 0;  } +/** + * dw_pcie_ep_raise_msix_irq - Raise MSI-X to the host + * @ep: DWC EP device + * @func_no: Function number of the endpoint device + * @interrupt_num: Interrupt number to be raised + * + * Return: 0 if success, errno otherwise. + */  int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,  			      u16 interrupt_num)  { @@ -566,22 +619,42 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,  	return 0;  } -void dw_pcie_ep_exit(struct dw_pcie_ep *ep) +/** + * dw_pcie_ep_cleanup - Cleanup DWC EP resources after fundamental reset + * @ep: DWC EP device + * + * Cleans up the DWC EP specific resources like eDMA etc... after fundamental + * reset like PERST#. Note that this API is only applicable for drivers + * supporting PERST# or any other methods of fundamental reset. + */ +void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep)  {  	struct dw_pcie *pci = to_dw_pcie_from_ep(ep); -	struct pci_epc *epc = ep->epc;  	dw_pcie_edma_remove(pci); +	ep->epc->init_complete = false; +} +EXPORT_SYMBOL_GPL(dw_pcie_ep_cleanup); + +/** + * dw_pcie_ep_deinit - Deinitialize the endpoint device + * @ep: DWC EP device + * + * Deinitialize the endpoint device. EPC device is not destroyed since that will + * be taken care by Devres. + */ +void dw_pcie_ep_deinit(struct dw_pcie_ep *ep) +{ +	struct pci_epc *epc = ep->epc; + +	dw_pcie_ep_cleanup(ep);  	pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,  			      epc->mem->window.page_size);  	pci_epc_mem_exit(epc); - -	if (ep->ops->deinit) -		ep->ops->deinit(ep);  } -EXPORT_SYMBOL_GPL(dw_pcie_ep_exit); +EXPORT_SYMBOL_GPL(dw_pcie_ep_deinit);  static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap)  { @@ -601,14 +674,27 @@ static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap)  	return 0;  } -int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep) +/** + * dw_pcie_ep_init_registers - Initialize DWC EP specific registers + * @ep: DWC EP device + * + * Initialize the registers (CSRs) specific to DWC EP. This API should be called + * only when the endpoint receives an active refclk (either from host or + * generated locally). + */ +int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)  {  	struct dw_pcie *pci = to_dw_pcie_from_ep(ep); +	struct dw_pcie_ep_func *ep_func; +	struct device *dev = pci->dev; +	struct pci_epc *epc = ep->epc;  	unsigned int offset, ptm_cap_base;  	unsigned int nbars;  	u8 hdr_type; +	u8 func_no; +	int i, ret; +	void *addr;  	u32 reg; -	int i;  	hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE) &  		   PCI_HEADER_TYPE_MASK; @@ -619,6 +705,58 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)  		return -EIO;  	} +	dw_pcie_version_detect(pci); + +	dw_pcie_iatu_detect(pci); + +	ret = dw_pcie_edma_detect(pci); +	if (ret) +		return ret; + +	if (!ep->ib_window_map) { +		ep->ib_window_map = devm_bitmap_zalloc(dev, pci->num_ib_windows, +						       GFP_KERNEL); +		if (!ep->ib_window_map) +			goto err_remove_edma; +	} + +	if (!ep->ob_window_map) { +		ep->ob_window_map = devm_bitmap_zalloc(dev, pci->num_ob_windows, +						       GFP_KERNEL); +		if (!ep->ob_window_map) +			goto err_remove_edma; +	} + +	if (!ep->outbound_addr) { +		addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t), +				    GFP_KERNEL); +		if (!addr) +			goto err_remove_edma; +		ep->outbound_addr = addr; +	} + +	for (func_no = 0; func_no < epc->max_functions; func_no++) { + +		ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); +		if (ep_func) +			continue; + +		ep_func = devm_kzalloc(dev, sizeof(*ep_func), GFP_KERNEL); +		if (!ep_func) +			goto err_remove_edma; + +		ep_func->func_no = func_no; +		ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no, +							      PCI_CAP_ID_MSI); +		ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no, +							       PCI_CAP_ID_MSIX); + +		list_add_tail(&ep_func->list, &ep->func_list); +	} + +	if (ep->ops->init) +		ep->ops->init(ep); +  	offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);  	ptm_cap_base = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM); @@ -658,22 +796,32 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)  	dw_pcie_dbi_ro_wr_dis(pci);  	return 0; + +err_remove_edma: +	dw_pcie_edma_remove(pci); + +	return ret;  } -EXPORT_SYMBOL_GPL(dw_pcie_ep_init_complete); +EXPORT_SYMBOL_GPL(dw_pcie_ep_init_registers); +/** + * dw_pcie_ep_init - Initialize the endpoint device + * @ep: DWC EP device + * + * Initialize the endpoint device. Allocate resources and create the EPC + * device with the endpoint framework. + * + * Return: 0 if success, errno otherwise. + */  int dw_pcie_ep_init(struct dw_pcie_ep *ep)  {  	int ret; -	void *addr; -	u8 func_no;  	struct resource *res;  	struct pci_epc *epc;  	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);  	struct device *dev = pci->dev;  	struct platform_device *pdev = to_platform_device(dev);  	struct device_node *np = dev->of_node; -	const struct pci_epc_features *epc_features; -	struct dw_pcie_ep_func *ep_func;  	INIT_LIST_HEAD(&ep->func_list); @@ -691,26 +839,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)  	if (ep->ops->pre_init)  		ep->ops->pre_init(ep); -	dw_pcie_version_detect(pci); - -	dw_pcie_iatu_detect(pci); - -	ep->ib_window_map = devm_bitmap_zalloc(dev, pci->num_ib_windows, -					       GFP_KERNEL); -	if (!ep->ib_window_map) -		return -ENOMEM; - -	ep->ob_window_map = devm_bitmap_zalloc(dev, pci->num_ob_windows, -					       GFP_KERNEL); -	if (!ep->ob_window_map) -		return -ENOMEM; - -	addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t), -			    GFP_KERNEL); -	if (!addr) -		return -ENOMEM; -	ep->outbound_addr = addr; -  	epc = devm_pci_epc_create(dev, &epc_ops);  	if (IS_ERR(epc)) {  		dev_err(dev, "Failed to create epc device\n"); @@ -724,28 +852,11 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)  	if (ret < 0)  		epc->max_functions = 1; -	for (func_no = 0; func_no < epc->max_functions; func_no++) { -		ep_func = devm_kzalloc(dev, sizeof(*ep_func), GFP_KERNEL); -		if (!ep_func) -			return -ENOMEM; - -		ep_func->func_no = func_no; -		ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no, -							      PCI_CAP_ID_MSI); -		ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no, -							       PCI_CAP_ID_MSIX); - -		list_add_tail(&ep_func->list, &ep->func_list); -	} - -	if (ep->ops->init) -		ep->ops->init(ep); -  	ret = pci_epc_mem_init(epc, ep->phys_base, ep->addr_size,  			       ep->page_size);  	if (ret < 0) {  		dev_err(dev, "Failed to initialize address space\n"); -		goto err_ep_deinit; +		return ret;  	}  	ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys, @@ -756,36 +867,11 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)  		goto err_exit_epc_mem;  	} -	ret = dw_pcie_edma_detect(pci); -	if (ret) -		goto err_free_epc_mem; - -	if (ep->ops->get_features) { -		epc_features = ep->ops->get_features(ep); -		if (epc_features->core_init_notifier) -			return 0; -	} - -	ret = dw_pcie_ep_init_complete(ep); -	if (ret) -		goto err_remove_edma; -  	return 0; -err_remove_edma: -	dw_pcie_edma_remove(pci); - -err_free_epc_mem: -	pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem, -			      epc->mem->window.page_size); -  err_exit_epc_mem:  	pci_epc_mem_exit(epc); -err_ep_deinit: -	if (ep->ops->deinit) -		ep->ops->deinit(ep); -  	return ret;  }  EXPORT_SYMBOL_GPL(dw_pcie_ep_init); diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c index 778588b4be70..8490c5d6ff9f 100644 --- a/drivers/pci/controller/dwc/pcie-designware-plat.c +++ b/drivers/pci/controller/dwc/pcie-designware-plat.c @@ -145,6 +145,17 @@ static int dw_plat_pcie_probe(struct platform_device *pdev)  		pci->ep.ops = &pcie_ep_ops;  		ret = dw_pcie_ep_init(&pci->ep); +		if (ret) +			return ret; + +		ret = dw_pcie_ep_init_registers(&pci->ep); +		if (ret) { +			dev_err(dev, "Failed to initialize DWC endpoint registers\n"); +			dw_pcie_ep_deinit(&pci->ep); +		} + +		dw_pcie_ep_init_notify(&pci->ep); +  		break;  	default:  		dev_err(dev, "INVALID device type %d\n", dw_plat_pcie->mode); diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 26dae4837462..f8e5431a207b 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -333,7 +333,6 @@ struct dw_pcie_rp {  struct dw_pcie_ep_ops {  	void	(*pre_init)(struct dw_pcie_ep *ep);  	void	(*init)(struct dw_pcie_ep *ep); -	void	(*deinit)(struct dw_pcie_ep *ep);  	int	(*raise_irq)(struct dw_pcie_ep *ep, u8 func_no,  			     unsigned int type, u16 interrupt_num);  	const struct pci_epc_features* (*get_features)(struct dw_pcie_ep *ep); @@ -670,9 +669,10 @@ static inline void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus,  #ifdef CONFIG_PCIE_DW_EP  void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);  int dw_pcie_ep_init(struct dw_pcie_ep *ep); -int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep); +int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep);  void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep); -void dw_pcie_ep_exit(struct dw_pcie_ep *ep); +void dw_pcie_ep_deinit(struct dw_pcie_ep *ep); +void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep);  int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no);  int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,  			     u8 interrupt_num); @@ -693,7 +693,7 @@ static inline int dw_pcie_ep_init(struct dw_pcie_ep *ep)  	return 0;  } -static inline int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep) +static inline int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)  {  	return 0;  } @@ -702,7 +702,11 @@ static inline void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep)  {  } -static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep) +static inline void dw_pcie_ep_deinit(struct dw_pcie_ep *ep) +{ +} + +static inline void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep)  {  } diff --git a/drivers/pci/controller/dwc/pcie-keembay.c b/drivers/pci/controller/dwc/pcie-keembay.c index 5e8e54f597dd..98bbc83182b4 100644 --- a/drivers/pci/controller/dwc/pcie-keembay.c +++ b/drivers/pci/controller/dwc/pcie-keembay.c @@ -396,6 +396,7 @@ static int keembay_pcie_probe(struct platform_device *pdev)  	struct keembay_pcie *pcie;  	struct dw_pcie *pci;  	enum dw_pcie_device_mode mode; +	int ret;  	data = device_get_match_data(dev);  	if (!data) @@ -430,11 +431,26 @@ static int keembay_pcie_probe(struct platform_device *pdev)  			return -ENODEV;  		pci->ep.ops = &keembay_pcie_ep_ops; -		return dw_pcie_ep_init(&pci->ep); +		ret = dw_pcie_ep_init(&pci->ep); +		if (ret) +			return ret; + +		ret = dw_pcie_ep_init_registers(&pci->ep); +		if (ret) { +			dev_err(dev, "Failed to initialize DWC endpoint registers\n"); +			dw_pcie_ep_deinit(&pci->ep); +			return ret; +		} + +		dw_pcie_ep_init_notify(&pci->ep); + +		break;  	default:  		dev_err(dev, "Invalid device type %d\n", pcie->mode);  		return -ENODEV;  	} + +	return 0;  }  static const struct keembay_pcie_of_data keembay_pcie_rc_of_data = { diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 36e5e80cd22f..2fb8c15e7a91 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -463,7 +463,7 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)  	      PARF_INT_ALL_LINK_UP | PARF_INT_ALL_EDMA;  	writel_relaxed(val, pcie_ep->parf + PARF_INT_ALL_MASK); -	ret = dw_pcie_ep_init_complete(&pcie_ep->pci.ep); +	ret = dw_pcie_ep_init_registers(&pcie_ep->pci.ep);  	if (ret) {  		dev_err(dev, "Failed to complete initialization: %d\n", ret);  		goto err_disable_resources; @@ -507,6 +507,7 @@ static void qcom_pcie_perst_assert(struct dw_pcie *pci)  		return;  	} +	dw_pcie_ep_cleanup(&pci->ep);  	qcom_pcie_disable_resources(pcie_ep);  	pcie_ep->link_status = QCOM_PCIE_EP_LINK_DISABLED;  } @@ -774,7 +775,6 @@ static void qcom_pcie_ep_init_debugfs(struct qcom_pcie_ep *pcie_ep)  static const struct pci_epc_features qcom_pcie_epc_features = {  	.linkup_notifier = true, -	.core_init_notifier = true,  	.msi_capable = true,  	.msix_capable = false,  	.align = SZ_4K, diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c index 0be760ed420b..cfeccc2f9ee1 100644 --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c @@ -352,11 +352,8 @@ static void rcar_gen4_pcie_ep_init(struct dw_pcie_ep *ep)  		dw_pcie_ep_reset_bar(pci, bar);  } -static void rcar_gen4_pcie_ep_deinit(struct dw_pcie_ep *ep) +static void rcar_gen4_pcie_ep_deinit(struct rcar_gen4_pcie *rcar)  { -	struct dw_pcie *dw = to_dw_pcie_from_ep(ep); -	struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw); -  	writel(0, rcar->base + PCIEDMAINTSTSEN);  	rcar_gen4_pcie_common_deinit(rcar);  } @@ -410,7 +407,6 @@ static unsigned int rcar_gen4_pcie_ep_get_dbi2_offset(struct dw_pcie_ep *ep,  static const struct dw_pcie_ep_ops pcie_ep_ops = {  	.pre_init = rcar_gen4_pcie_ep_pre_init,  	.init = rcar_gen4_pcie_ep_init, -	.deinit = rcar_gen4_pcie_ep_deinit,  	.raise_irq = rcar_gen4_pcie_ep_raise_irq,  	.get_features = rcar_gen4_pcie_ep_get_features,  	.get_dbi_offset = rcar_gen4_pcie_ep_get_dbi_offset, @@ -420,18 +416,36 @@ static const struct dw_pcie_ep_ops pcie_ep_ops = {  static int rcar_gen4_add_dw_pcie_ep(struct rcar_gen4_pcie *rcar)  {  	struct dw_pcie_ep *ep = &rcar->dw.ep; +	struct device *dev = rcar->dw.dev; +	int ret;  	if (!IS_ENABLED(CONFIG_PCIE_RCAR_GEN4_EP))  		return -ENODEV;  	ep->ops = &pcie_ep_ops; -	return dw_pcie_ep_init(ep); +	ret = dw_pcie_ep_init(ep); +	if (ret) { +		rcar_gen4_pcie_ep_deinit(rcar); +		return ret; +	} + +	ret = dw_pcie_ep_init_registers(ep); +	if (ret) { +		dev_err(dev, "Failed to initialize DWC endpoint registers\n"); +		dw_pcie_ep_deinit(ep); +		rcar_gen4_pcie_ep_deinit(rcar); +	} + +	dw_pcie_ep_init_notify(ep); + +	return ret;  }  static void rcar_gen4_remove_dw_pcie_ep(struct rcar_gen4_pcie *rcar)  { -	dw_pcie_ep_exit(&rcar->dw.ep); +	dw_pcie_ep_deinit(&rcar->dw.ep); +	rcar_gen4_pcie_ep_deinit(rcar);  }  /* Common */ diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index 1f7b662cb8e1..93f5433c5c55 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -1715,6 +1715,8 @@ static void pex_ep_event_pex_rst_assert(struct tegra_pcie_dw *pcie)  	if (ret)  		dev_err(pcie->dev, "Failed to go Detect state: %d\n", ret); +	dw_pcie_ep_cleanup(&pcie->pci.ep); +  	reset_control_assert(pcie->core_rst);  	tegra_pcie_disable_phy(pcie); @@ -1895,7 +1897,7 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie)  	val = (upper_32_bits(ep->msi_mem_phys) & MSIX_ADDR_MATCH_HIGH_OFF_MASK);  	dw_pcie_writel_dbi(pci, MSIX_ADDR_MATCH_HIGH_OFF, val); -	ret = dw_pcie_ep_init_complete(ep); +	ret = dw_pcie_ep_init_registers(ep);  	if (ret) {  		dev_err(dev, "Failed to complete initialization: %d\n", ret);  		goto fail_init_complete; @@ -2004,7 +2006,6 @@ static int tegra_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,  static const struct pci_epc_features tegra_pcie_epc_features = {  	.linkup_notifier = true, -	.core_init_notifier = true,  	.msi_capable = false,  	.msix_capable = false,  	.bar[BAR_0] = { .type = BAR_FIXED, .fixed_size = SZ_1M, @@ -2273,11 +2274,14 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)  		ret = tegra_pcie_config_ep(pcie, pdev);  		if (ret < 0)  			goto fail; +		else +			return 0;  		break;  	default:  		dev_err(dev, "Invalid PCIe device type %d\n",  			pcie->of_data->mode); +		ret = -EINVAL;  	}  fail: diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c index 639bc2e12476..a2b844268e28 100644 --- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c +++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c @@ -399,7 +399,20 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)  		return ret;  	priv->pci.ep.ops = &uniphier_pcie_ep_ops; -	return dw_pcie_ep_init(&priv->pci.ep); +	ret = dw_pcie_ep_init(&priv->pci.ep); +	if (ret) +		return ret; + +	ret = dw_pcie_ep_init_registers(&priv->pci.ep); +	if (ret) { +		dev_err(dev, "Failed to initialize DWC endpoint registers\n"); +		dw_pcie_ep_deinit(&priv->pci.ep); +		return ret; +	} + +	dw_pcie_ep_init_notify(&priv->pci.ep); + +	return 0;  }  static const struct uniphier_pcie_ep_soc_data uniphier_pro5_data = { diff --git a/drivers/pci/controller/pcie-mt7621.c b/drivers/pci/controller/pcie-mt7621.c index 79e225edb42a..d97b956e6e57 100644 --- a/drivers/pci/controller/pcie-mt7621.c +++ b/drivers/pci/controller/pcie-mt7621.c @@ -202,7 +202,7 @@ static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie,  	struct mt7621_pcie_port *port;  	struct device *dev = pcie->dev;  	struct platform_device *pdev = to_platform_device(dev); -	char name[10]; +	char name[11];  	int err;  	port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c index 05967c6c0b42..047e2cef5afc 100644 --- a/drivers/pci/controller/pcie-rcar-ep.c +++ b/drivers/pci/controller/pcie-rcar-ep.c @@ -542,6 +542,8 @@ static int rcar_pcie_ep_probe(struct platform_device *pdev)  		goto err_pm_put;  	} +	pci_epc_init_notify(epc); +  	return 0;  err_pm_put: diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c index c9046e97a1d2..136274533656 100644 --- a/drivers/pci/controller/pcie-rockchip-ep.c +++ b/drivers/pci/controller/pcie-rockchip-ep.c @@ -98,10 +98,8 @@ static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,  	/* All functions share the same vendor ID with function 0 */  	if (fn == 0) { -		u32 vid_regs = (hdr->vendorid & GENMASK(15, 0)) | -			       (hdr->subsys_vendor_id & GENMASK(31, 16)) << 16; - -		rockchip_pcie_write(rockchip, vid_regs, +		rockchip_pcie_write(rockchip, +				    hdr->vendorid | hdr->subsys_vendor_id << 16,  				    PCIE_CORE_CONFIG_VENDOR);  	} @@ -153,7 +151,7 @@ static int rockchip_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,  		ctrl = ROCKCHIP_PCIE_CORE_BAR_CFG_CTRL_IO_32BITS;  	} else {  		bool is_prefetch = !!(flags & PCI_BASE_ADDRESS_MEM_PREFETCH); -		bool is_64bits = sz > SZ_2G; +		bool is_64bits = !!(flags & PCI_BASE_ADDRESS_MEM_TYPE_64);  		if (is_64bits && (bar & 1))  			return -EINVAL; @@ -609,6 +607,8 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)  	rockchip_pcie_write(rockchip, PCIE_CLIENT_CONF_ENABLE,  			    PCIE_CLIENT_CONFIG); +	pci_epc_init_notify(epc); +  	return 0;  err_epc_mem_exit:  	pci_epc_mem_exit(epc); | 
