Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'remotes/lorenzo/pci/endpoint'

- Use memcpy_fromio()/memcpy_toio() instead of plain memcpy() in PCI
endpoint framework (Wen Yang)

- Add interface to discover supported endpoint features to replace a
bitfield that wasn't flexible enough (Kishon Vijay Abraham I)

- Implement the new supported-feature interface for designware-plat,
dra7xx, rockchip, cadence (Kishon Vijay Abraham I)

- Fix issues with 64-bit BAR in endpoints (Kishon Vijay Abraham I)

- Add layerscape endpoint mode support (Xiaowei Bao)

* remotes/lorenzo/pci/endpoint:
misc: pci_endpoint_test: Add the layerscape EP device support
PCI: layerscape: Add EP mode support
arm64: dts: Add the PCIE EP node in dts
dt-bindings: add DT binding for the layerscape PCIe controller with EP mode
PCI: endpoint: Remove features member in struct pci_epc
PCI: designware-plat: Remove setting epc->features in Designware plat EP driver
PCI: rockchip: Remove pci_epf_linkup() from Rockchip EP driver
PCI: cadence: Remove pci_epf_linkup() from Cadence EP driver
PCI: pci-epf-test: Use pci_epc_get_features() to get EPC features
PCI: pci-epf-test: Do not allocate next BARs memory if current BAR is 64Bit
PCI: pci-epf-test: Remove setting epf_bar flags in function driver
PCI: endpoint: Fix pci_epf_alloc_space() to set correct MEM TYPE flags
PCI: endpoint: Add helper to get first unreserved BAR
PCI: cadence: Populate ->get_features() cdns_pcie_epc_ops
PCI: rockchip: Populate ->get_features() dw_pcie_ep_ops
PCI: pci-dra7xx: Populate ->get_features() dw_pcie_ep_ops
PCI: designware-plat: Populate ->get_features() dw_pcie_ep_ops
PCI: dwc: Add ->get_features() callback function to dw_pcie_ep_ops
PCI: endpoint: Add new pci_epc_ops to get EPC features
PCI: endpoint: functions: Use memcpy_fromio()/memcpy_toio()

+397 -68
+3
Documentation/devicetree/bindings/pci/layerscape-pci.txt
··· 13 13 14 14 Required properties: 15 15 - compatible: should contain the platform identifier such as: 16 + RC mode: 16 17 "fsl,ls1021a-pcie" 17 18 "fsl,ls2080a-pcie", "fsl,ls2085a-pcie" 18 19 "fsl,ls2088a-pcie" ··· 21 20 "fsl,ls1046a-pcie" 22 21 "fsl,ls1043a-pcie" 23 22 "fsl,ls1012a-pcie" 23 + EP mode: 24 + "fsl,ls1046a-pcie-ep", "fsl,ls-pcie-ep" 24 25 - reg: base addresses and lengths of the PCIe controller register blocks. 25 26 - interrupts: A list of interrupt outputs of the controller. Must contain an 26 27 entry for each entry in the interrupt-names property.
+33 -1
arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
··· 657 657 status = "disabled"; 658 658 }; 659 659 660 + pcie_ep@3400000 { 661 + compatible = "fsl,ls1046a-pcie-ep","fsl,ls-pcie-ep"; 662 + reg = <0x00 0x03400000 0x0 0x00100000 663 + 0x40 0x00000000 0x8 0x00000000>; 664 + reg-names = "regs", "addr_space"; 665 + num-ib-windows = <6>; 666 + num-ob-windows = <8>; 667 + num-lanes = <2>; 668 + status = "disabled"; 669 + }; 670 + 660 671 pcie@3500000 { 661 672 compatible = "fsl,ls1046a-pcie"; 662 673 reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ ··· 691 680 <0000 0 0 2 &gic GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, 692 681 <0000 0 0 3 &gic GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, 693 682 <0000 0 0 4 &gic GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; 683 + status = "disabled"; 684 + }; 685 + 686 + pcie_ep@3500000 { 687 + compatible = "fsl,ls1046a-pcie-ep","fsl,ls-pcie-ep"; 688 + reg = <0x00 0x03500000 0x0 0x00100000 689 + 0x48 0x00000000 0x8 0x00000000>; 690 + reg-names = "regs", "addr_space"; 691 + num-ib-windows = <6>; 692 + num-ob-windows = <8>; 693 + num-lanes = <2>; 694 694 status = "disabled"; 695 695 }; 696 696 ··· 731 709 status = "disabled"; 732 710 }; 733 711 712 + pcie_ep@3600000 { 713 + compatible = "fsl,ls1046a-pcie-ep", "fsl,ls-pcie-ep"; 714 + reg = <0x00 0x03600000 0x0 0x00100000 715 + 0x50 0x00000000 0x8 0x00000000>; 716 + reg-names = "regs", "addr_space"; 717 + num-ib-windows = <6>; 718 + num-ob-windows = <8>; 719 + num-lanes = <2>; 720 + status = "disabled"; 721 + }; 722 + 734 723 qdma: dma-controller@8380000 { 735 724 compatible = "fsl,ls1046a-qdma", "fsl,ls1021a-qdma"; 736 725 reg = <0x0 0x8380000 0x0 0x1000>, /* Controller regs */ ··· 762 729 queue-sizes = <64 64>; 763 730 big-endian; 764 731 }; 765 - 766 732 }; 767 733 768 734 reserved-memory {
+1
drivers/misc/pci_endpoint_test.c
··· 788 788 static const struct pci_device_id pci_endpoint_test_tbl[] = { 789 789 { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) }, 790 790 { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) }, 791 + { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x81c0) }, 791 792 { PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, 0xedda) }, 792 793 { } 793 794 };
+1 -1
drivers/pci/controller/dwc/Makefile
··· 8 8 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o 9 9 obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o 10 10 obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o 11 - obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o 11 + obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o pci-layerscape-ep.o 12 12 obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o 13 13 obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o 14 14 obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
+13
drivers/pci/controller/dwc/pci-dra7xx.c
··· 394 394 return 0; 395 395 } 396 396 397 + static const struct pci_epc_features dra7xx_pcie_epc_features = { 398 + .linkup_notifier = true, 399 + .msi_capable = true, 400 + .msix_capable = false, 401 + }; 402 + 403 + static const struct pci_epc_features* 404 + dra7xx_pcie_get_features(struct dw_pcie_ep *ep) 405 + { 406 + return &dra7xx_pcie_epc_features; 407 + } 408 + 397 409 static struct dw_pcie_ep_ops pcie_ep_ops = { 398 410 .ep_init = dra7xx_pcie_ep_init, 399 411 .raise_irq = dra7xx_pcie_raise_irq, 412 + .get_features = dra7xx_pcie_get_features, 400 413 }; 401 414 402 415 static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
+156
drivers/pci/controller/dwc/pci-layerscape-ep.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * PCIe controller EP driver for Freescale Layerscape SoCs 4 + * 5 + * Copyright (C) 2018 NXP Semiconductor. 6 + * 7 + * Author: Xiaowei Bao <xiaowei.bao@nxp.com> 8 + */ 9 + 10 + #include <linux/kernel.h> 11 + #include <linux/init.h> 12 + #include <linux/of_pci.h> 13 + #include <linux/of_platform.h> 14 + #include <linux/of_address.h> 15 + #include <linux/pci.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/resource.h> 18 + 19 + #include "pcie-designware.h" 20 + 21 + #define PCIE_DBI2_OFFSET 0x1000 /* DBI2 base address*/ 22 + 23 + struct ls_pcie_ep { 24 + struct dw_pcie *pci; 25 + }; 26 + 27 + #define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev) 28 + 29 + static int ls_pcie_establish_link(struct dw_pcie *pci) 30 + { 31 + return 0; 32 + } 33 + 34 + static const struct dw_pcie_ops ls_pcie_ep_ops = { 35 + .start_link = ls_pcie_establish_link, 36 + }; 37 + 38 + static const struct of_device_id ls_pcie_ep_of_match[] = { 39 + { .compatible = "fsl,ls-pcie-ep",}, 40 + { }, 41 + }; 42 + 43 + static const struct pci_epc_features ls_pcie_epc_features = { 44 + .linkup_notifier = false, 45 + .msi_capable = true, 46 + .msix_capable = false, 47 + }; 48 + 49 + static const struct pci_epc_features* 50 + ls_pcie_ep_get_features(struct dw_pcie_ep *ep) 51 + { 52 + return &ls_pcie_epc_features; 53 + } 54 + 55 + static void ls_pcie_ep_init(struct dw_pcie_ep *ep) 56 + { 57 + struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 58 + enum pci_barno bar; 59 + 60 + for (bar = BAR_0; bar <= BAR_5; bar++) 61 + dw_pcie_ep_reset_bar(pci, bar); 62 + } 63 + 64 + static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, 65 + enum pci_epc_irq_type type, u16 interrupt_num) 66 + { 67 + struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 68 + 69 + switch (type) { 70 + case PCI_EPC_IRQ_LEGACY: 71 + return dw_pcie_ep_raise_legacy_irq(ep, func_no); 72 + case PCI_EPC_IRQ_MSI: 73 + return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); 74 + case PCI_EPC_IRQ_MSIX: 75 + return dw_pcie_ep_raise_msix_irq(ep, func_no, interrupt_num); 76 + default: 77 + dev_err(pci->dev, "UNKNOWN IRQ type\n"); 78 + return -EINVAL; 79 + } 80 + } 81 + 82 + static struct dw_pcie_ep_ops pcie_ep_ops = { 83 + .ep_init = ls_pcie_ep_init, 84 + .raise_irq = ls_pcie_ep_raise_irq, 85 + .get_features = ls_pcie_ep_get_features, 86 + }; 87 + 88 + static int __init ls_add_pcie_ep(struct ls_pcie_ep *pcie, 89 + struct platform_device *pdev) 90 + { 91 + struct dw_pcie *pci = pcie->pci; 92 + struct device *dev = pci->dev; 93 + struct dw_pcie_ep *ep; 94 + struct resource *res; 95 + int ret; 96 + 97 + ep = &pci->ep; 98 + ep->ops = &pcie_ep_ops; 99 + 100 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); 101 + if (!res) 102 + return -EINVAL; 103 + 104 + ep->phys_base = res->start; 105 + ep->addr_size = resource_size(res); 106 + 107 + ret = dw_pcie_ep_init(ep); 108 + if (ret) { 109 + dev_err(dev, "failed to initialize endpoint\n"); 110 + return ret; 111 + } 112 + 113 + return 0; 114 + } 115 + 116 + static int __init ls_pcie_ep_probe(struct platform_device *pdev) 117 + { 118 + struct device *dev = &pdev->dev; 119 + struct dw_pcie *pci; 120 + struct ls_pcie_ep *pcie; 121 + struct resource *dbi_base; 122 + int ret; 123 + 124 + pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); 125 + if (!pcie) 126 + return -ENOMEM; 127 + 128 + pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); 129 + if (!pci) 130 + return -ENOMEM; 131 + 132 + dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); 133 + pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base); 134 + if (IS_ERR(pci->dbi_base)) 135 + return PTR_ERR(pci->dbi_base); 136 + 137 + pci->dbi_base2 = pci->dbi_base + PCIE_DBI2_OFFSET; 138 + pci->dev = dev; 139 + pci->ops = &ls_pcie_ep_ops; 140 + pcie->pci = pci; 141 + 142 + platform_set_drvdata(pdev, pcie); 143 + 144 + ret = ls_add_pcie_ep(pcie, pdev); 145 + 146 + return ret; 147 + } 148 + 149 + static struct platform_driver ls_pcie_ep_driver = { 150 + .driver = { 151 + .name = "layerscape-pcie-ep", 152 + .of_match_table = ls_pcie_ep_of_match, 153 + .suppress_bind_attrs = true, 154 + }, 155 + }; 156 + builtin_platform_driver_probe(ls_pcie_ep_driver, ls_pcie_ep_probe);
+12
drivers/pci/controller/dwc/pcie-designware-ep.c
··· 355 355 return pci->ops->start_link(pci); 356 356 } 357 357 358 + static const struct pci_epc_features* 359 + dw_pcie_ep_get_features(struct pci_epc *epc, u8 func_no) 360 + { 361 + struct dw_pcie_ep *ep = epc_get_drvdata(epc); 362 + 363 + if (!ep->ops->get_features) 364 + return NULL; 365 + 366 + return ep->ops->get_features(ep); 367 + } 368 + 358 369 static const struct pci_epc_ops epc_ops = { 359 370 .write_header = dw_pcie_ep_write_header, 360 371 .set_bar = dw_pcie_ep_set_bar, ··· 379 368 .raise_irq = dw_pcie_ep_raise_irq, 380 369 .start = dw_pcie_ep_start, 381 370 .stop = dw_pcie_ep_stop, 371 + .get_features = dw_pcie_ep_get_features, 382 372 }; 383 373 384 374 int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no)
+13 -4
drivers/pci/controller/dwc/pcie-designware-plat.c
··· 68 68 static void dw_plat_pcie_ep_init(struct dw_pcie_ep *ep) 69 69 { 70 70 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 71 - struct pci_epc *epc = ep->epc; 72 71 enum pci_barno bar; 73 72 74 73 for (bar = BAR_0; bar <= BAR_5; bar++) 75 74 dw_pcie_ep_reset_bar(pci, bar); 76 - 77 - epc->features |= EPC_FEATURE_NO_LINKUP_NOTIFIER; 78 - epc->features |= EPC_FEATURE_MSIX_AVAILABLE; 79 75 } 80 76 81 77 static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, ··· 94 98 return 0; 95 99 } 96 100 101 + static const struct pci_epc_features dw_plat_pcie_epc_features = { 102 + .linkup_notifier = false, 103 + .msi_capable = true, 104 + .msix_capable = true, 105 + }; 106 + 107 + static const struct pci_epc_features* 108 + dw_plat_pcie_get_features(struct dw_pcie_ep *ep) 109 + { 110 + return &dw_plat_pcie_epc_features; 111 + } 112 + 97 113 static struct dw_pcie_ep_ops pcie_ep_ops = { 98 114 .ep_init = dw_plat_pcie_ep_init, 99 115 .raise_irq = dw_plat_pcie_ep_raise_irq, 116 + .get_features = dw_plat_pcie_get_features, 100 117 }; 101 118 102 119 static int dw_plat_add_pcie_port(struct dw_plat_pcie *dw_plat_pcie,
+1
drivers/pci/controller/dwc/pcie-designware.h
··· 195 195 void (*ep_init)(struct dw_pcie_ep *ep); 196 196 int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no, 197 197 enum pci_epc_irq_type type, u16 interrupt_num); 198 + const struct pci_epc_features* (*get_features)(struct dw_pcie_ep *ep); 198 199 }; 199 200 200 201 struct dw_pcie_ep {
+13 -12
drivers/pci/controller/pcie-cadence-ep.c
··· 396 396 cfg |= BIT(epf->func_no); 397 397 cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, cfg); 398 398 399 - /* 400 - * The PCIe links are automatically established by the controller 401 - * once for all at powerup: the software can neither start nor stop 402 - * those links later at runtime. 403 - * 404 - * Then we only have to notify the EP core that our links are already 405 - * established. However we don't call directly pci_epc_linkup() because 406 - * we've already locked the epc->lock. 407 - */ 408 - list_for_each_entry(epf, &epc->pci_epf, list) 409 - pci_epf_linkup(epf); 410 - 411 399 return 0; 400 + } 401 + 402 + static const struct pci_epc_features cdns_pcie_epc_features = { 403 + .linkup_notifier = false, 404 + .msi_capable = true, 405 + .msix_capable = false, 406 + }; 407 + 408 + static const struct pci_epc_features* 409 + cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no) 410 + { 411 + return &cdns_pcie_epc_features; 412 412 } 413 413 414 414 static const struct pci_epc_ops cdns_pcie_epc_ops = { ··· 421 421 .get_msi = cdns_pcie_ep_get_msi, 422 422 .raise_irq = cdns_pcie_ep_raise_irq, 423 423 .start = cdns_pcie_ep_start, 424 + .get_features = cdns_pcie_ep_get_features, 424 425 }; 425 426 426 427 static const struct of_device_id cdns_pcie_ep_of_match[] = {
+13 -3
drivers/pci/controller/pcie-rockchip-ep.c
··· 499 499 500 500 rockchip_pcie_write(rockchip, cfg, PCIE_CORE_PHY_FUNC_CFG); 501 501 502 - list_for_each_entry(epf, &epc->pci_epf, list) 503 - pci_epf_linkup(epf); 504 - 505 502 return 0; 503 + } 504 + 505 + static const struct pci_epc_features rockchip_pcie_epc_features = { 506 + .linkup_notifier = false, 507 + .msi_capable = true, 508 + .msix_capable = false, 509 + }; 510 + 511 + static const struct pci_epc_features* 512 + rockchip_pcie_ep_get_features(struct pci_epc *epc, u8 func_no) 513 + { 514 + return &rockchip_pcie_epc_features; 506 515 } 507 516 508 517 static const struct pci_epc_ops rockchip_pcie_epc_ops = { ··· 524 515 .get_msi = rockchip_pcie_ep_get_msi, 525 516 .raise_irq = rockchip_pcie_ep_raise_irq, 526 517 .start = rockchip_pcie_ep_start, 518 + .get_features = rockchip_pcie_ep_get_features, 527 519 }; 528 520 529 521 static int rockchip_pcie_parse_ep_dt(struct rockchip_pcie *rockchip,
+59 -38
drivers/pci/endpoint/functions/pci-epf-test.c
··· 47 47 void *reg[6]; 48 48 struct pci_epf *epf; 49 49 enum pci_barno test_reg_bar; 50 - bool linkup_notifier; 51 - bool msix_available; 52 50 struct delayed_work cmd_handler; 51 + const struct pci_epc_features *epc_features; 53 52 }; 54 53 55 54 struct pci_epf_test_reg { ··· 68 69 .deviceid = PCI_ANY_ID, 69 70 .baseclass_code = PCI_CLASS_OTHERS, 70 71 .interrupt_pin = PCI_INTERRUPT_INTA, 71 - }; 72 - 73 - struct pci_epf_test_data { 74 - enum pci_barno test_reg_bar; 75 - bool linkup_notifier; 76 72 }; 77 73 78 74 static size_t bar_size[] = { 512, 512, 1024, 16384, 131072, 1048576 }; ··· 169 175 goto err_map_addr; 170 176 } 171 177 172 - memcpy(buf, src_addr, reg->size); 178 + memcpy_fromio(buf, src_addr, reg->size); 173 179 174 180 crc32 = crc32_le(~0, buf, reg->size); 175 181 if (crc32 != reg->checksum) ··· 224 230 get_random_bytes(buf, reg->size); 225 231 reg->checksum = crc32_le(~0, buf, reg->size); 226 232 227 - memcpy(dst_addr, buf, reg->size); 233 + memcpy_toio(dst_addr, buf, reg->size); 228 234 229 235 /* 230 236 * wait 1ms inorder for the write to complete. Without this delay L3 ··· 396 402 struct device *dev = &epf->dev; 397 403 struct pci_epf_test *epf_test = epf_get_drvdata(epf); 398 404 enum pci_barno test_reg_bar = epf_test->test_reg_bar; 405 + const struct pci_epc_features *epc_features; 406 + 407 + epc_features = epf_test->epc_features; 399 408 400 409 for (bar = BAR_0; bar <= BAR_5; bar++) { 401 410 epf_bar = &epf->bar[bar]; 402 411 403 - epf_bar->flags |= upper_32_bits(epf_bar->size) ? 404 - PCI_BASE_ADDRESS_MEM_TYPE_64 : 405 - PCI_BASE_ADDRESS_MEM_TYPE_32; 412 + if (!!(epc_features->reserved_bar & (1 << bar))) 413 + continue; 406 414 407 415 ret = pci_epc_set_bar(epc, epf->func_no, epf_bar); 408 416 if (ret) { ··· 429 433 { 430 434 struct pci_epf_test *epf_test = epf_get_drvdata(epf); 431 435 struct device *dev = &epf->dev; 436 + struct pci_epf_bar *epf_bar; 432 437 void *base; 433 438 int bar; 434 439 enum pci_barno test_reg_bar = epf_test->test_reg_bar; 440 + const struct pci_epc_features *epc_features; 441 + 442 + epc_features = epf_test->epc_features; 435 443 436 444 base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg), 437 445 test_reg_bar); ··· 446 446 epf_test->reg[test_reg_bar] = base; 447 447 448 448 for (bar = BAR_0; bar <= BAR_5; bar++) { 449 + epf_bar = &epf->bar[bar]; 449 450 if (bar == test_reg_bar) 450 451 continue; 452 + 453 + if (!!(epc_features->reserved_bar & (1 << bar))) 454 + continue; 455 + 451 456 base = pci_epf_alloc_space(epf, bar_size[bar], bar); 452 457 if (!base) 453 458 dev_err(dev, "Failed to allocate space for BAR%d\n", 454 459 bar); 455 460 epf_test->reg[bar] = base; 461 + if (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) 462 + bar++; 456 463 } 457 464 458 465 return 0; 466 + } 467 + 468 + static void pci_epf_configure_bar(struct pci_epf *epf, 469 + const struct pci_epc_features *epc_features) 470 + { 471 + struct pci_epf_bar *epf_bar; 472 + bool bar_fixed_64bit; 473 + int i; 474 + 475 + for (i = BAR_0; i <= BAR_5; i++) { 476 + epf_bar = &epf->bar[i]; 477 + bar_fixed_64bit = !!(epc_features->bar_fixed_64bit & (1 << i)); 478 + if (bar_fixed_64bit) 479 + epf_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64; 480 + if (epc_features->bar_fixed_size[i]) 481 + bar_size[i] = epc_features->bar_fixed_size[i]; 482 + } 459 483 } 460 484 461 485 static int pci_epf_test_bind(struct pci_epf *epf) ··· 487 463 int ret; 488 464 struct pci_epf_test *epf_test = epf_get_drvdata(epf); 489 465 struct pci_epf_header *header = epf->header; 466 + const struct pci_epc_features *epc_features; 467 + enum pci_barno test_reg_bar = BAR_0; 490 468 struct pci_epc *epc = epf->epc; 491 469 struct device *dev = &epf->dev; 470 + bool linkup_notifier = false; 471 + bool msix_capable = false; 472 + bool msi_capable = true; 492 473 493 474 if (WARN_ON_ONCE(!epc)) 494 475 return -EINVAL; 495 476 496 - if (epc->features & EPC_FEATURE_NO_LINKUP_NOTIFIER) 497 - epf_test->linkup_notifier = false; 498 - else 499 - epf_test->linkup_notifier = true; 477 + epc_features = pci_epc_get_features(epc, epf->func_no); 478 + if (epc_features) { 479 + linkup_notifier = epc_features->linkup_notifier; 480 + msix_capable = epc_features->msix_capable; 481 + msi_capable = epc_features->msi_capable; 482 + test_reg_bar = pci_epc_get_first_free_bar(epc_features); 483 + pci_epf_configure_bar(epf, epc_features); 484 + } 500 485 501 - epf_test->msix_available = epc->features & EPC_FEATURE_MSIX_AVAILABLE; 502 - 503 - epf_test->test_reg_bar = EPC_FEATURE_GET_BAR(epc->features); 486 + epf_test->test_reg_bar = test_reg_bar; 487 + epf_test->epc_features = epc_features; 504 488 505 489 ret = pci_epc_write_header(epc, epf->func_no, header); 506 490 if (ret) { ··· 524 492 if (ret) 525 493 return ret; 526 494 527 - ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts); 528 - if (ret) { 529 - dev_err(dev, "MSI configuration failed\n"); 530 - return ret; 495 + if (msi_capable) { 496 + ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts); 497 + if (ret) { 498 + dev_err(dev, "MSI configuration failed\n"); 499 + return ret; 500 + } 531 501 } 532 502 533 - if (epf_test->msix_available) { 503 + if (msix_capable) { 534 504 ret = pci_epc_set_msix(epc, epf->func_no, epf->msix_interrupts); 535 505 if (ret) { 536 506 dev_err(dev, "MSI-X configuration failed\n"); ··· 540 506 } 541 507 } 542 508 543 - if (!epf_test->linkup_notifier) 509 + if (!linkup_notifier) 544 510 queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work); 545 511 546 512 return 0; ··· 557 523 { 558 524 struct pci_epf_test *epf_test; 559 525 struct device *dev = &epf->dev; 560 - const struct pci_epf_device_id *match; 561 - struct pci_epf_test_data *data; 562 - enum pci_barno test_reg_bar = BAR_0; 563 - bool linkup_notifier = true; 564 - 565 - match = pci_epf_match_device(pci_epf_test_ids, epf); 566 - data = (struct pci_epf_test_data *)match->driver_data; 567 - if (data) { 568 - test_reg_bar = data->test_reg_bar; 569 - linkup_notifier = data->linkup_notifier; 570 - } 571 526 572 527 epf_test = devm_kzalloc(dev, sizeof(*epf_test), GFP_KERNEL); 573 528 if (!epf_test) ··· 564 541 565 542 epf->header = &test_header; 566 543 epf_test->epf = epf; 567 - epf_test->test_reg_bar = test_reg_bar; 568 - epf_test->linkup_notifier = linkup_notifier; 569 544 570 545 INIT_DELAYED_WORK(&epf_test->cmd_handler, pci_epf_test_cmd_handler); 571 546
+53
drivers/pci/endpoint/pci-epc-core.c
··· 84 84 EXPORT_SYMBOL_GPL(pci_epc_get); 85 85 86 86 /** 87 + * pci_epc_get_first_free_bar() - helper to get first unreserved BAR 88 + * @epc_features: pci_epc_features structure that holds the reserved bar bitmap 89 + * 90 + * Invoke to get the first unreserved BAR that can be used for endpoint 91 + * function. For any incorrect value in reserved_bar return '0'. 92 + */ 93 + unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features 94 + *epc_features) 95 + { 96 + int free_bar; 97 + 98 + if (!epc_features) 99 + return 0; 100 + 101 + free_bar = ffz(epc_features->reserved_bar); 102 + if (free_bar > 5) 103 + return 0; 104 + 105 + return free_bar; 106 + } 107 + EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar); 108 + 109 + /** 110 + * pci_epc_get_features() - get the features supported by EPC 111 + * @epc: the features supported by *this* EPC device will be returned 112 + * @func_no: the features supported by the EPC device specific to the 113 + * endpoint function with func_no will be returned 114 + * 115 + * Invoke to get the features provided by the EPC which may be 116 + * specific to an endpoint function. Returns pci_epc_features on success 117 + * and NULL for any failures. 118 + */ 119 + const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc, 120 + u8 func_no) 121 + { 122 + const struct pci_epc_features *epc_features; 123 + unsigned long flags; 124 + 125 + if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions) 126 + return NULL; 127 + 128 + if (!epc->ops->get_features) 129 + return NULL; 130 + 131 + spin_lock_irqsave(&epc->lock, flags); 132 + epc_features = epc->ops->get_features(epc, func_no); 133 + spin_unlock_irqrestore(&epc->lock, flags); 134 + 135 + return epc_features; 136 + } 137 + EXPORT_SYMBOL_GPL(pci_epc_get_features); 138 + 139 + /** 87 140 * pci_epc_stop() - stop the PCI link 88 141 * @epc: the link of the EPC device that has to be stopped 89 142 *
+3 -1
drivers/pci/endpoint/pci-epf-core.c
··· 131 131 epf->bar[bar].phys_addr = phys_addr; 132 132 epf->bar[bar].size = size; 133 133 epf->bar[bar].barno = bar; 134 - epf->bar[bar].flags = PCI_BASE_ADDRESS_SPACE_MEMORY; 134 + epf->bar[bar].flags |= upper_32_bits(size) ? 135 + PCI_BASE_ADDRESS_MEM_TYPE_64 : 136 + PCI_BASE_ADDRESS_MEM_TYPE_32; 135 137 136 138 return space; 137 139 }
+23 -8
include/linux/pci-epc.h
··· 59 59 enum pci_epc_irq_type type, u16 interrupt_num); 60 60 int (*start)(struct pci_epc *epc); 61 61 void (*stop)(struct pci_epc *epc); 62 + const struct pci_epc_features* (*get_features)(struct pci_epc *epc, 63 + u8 func_no); 62 64 struct module *owner; 63 65 }; 64 66 ··· 99 97 struct config_group *group; 100 98 /* spinlock to protect against concurrent access of EP controller */ 101 99 spinlock_t lock; 102 - unsigned int features; 103 100 }; 104 101 105 - #define EPC_FEATURE_NO_LINKUP_NOTIFIER BIT(0) 106 - #define EPC_FEATURE_BAR_MASK (BIT(1) | BIT(2) | BIT(3)) 107 - #define EPC_FEATURE_MSIX_AVAILABLE BIT(4) 108 - #define EPC_FEATURE_SET_BAR(features, bar) \ 109 - (features |= (EPC_FEATURE_BAR_MASK & (bar << 1))) 110 - #define EPC_FEATURE_GET_BAR(features) \ 111 - ((features & EPC_FEATURE_BAR_MASK) >> 1) 102 + /** 103 + * struct pci_epc_features - features supported by a EPC device per function 104 + * @linkup_notifier: indicate if the EPC device can notify EPF driver on link up 105 + * @msi_capable: indicate if the endpoint function has MSI capability 106 + * @msix_capable: indicate if the endpoint function has MSI-X capability 107 + * @reserved_bar: bitmap to indicate reserved BAR unavailable to function driver 108 + * @bar_fixed_64bit: bitmap to indicate fixed 64bit BARs 109 + * @bar_fixed_size: Array specifying the size supported by each BAR 110 + */ 111 + struct pci_epc_features { 112 + unsigned int linkup_notifier : 1; 113 + unsigned int msi_capable : 1; 114 + unsigned int msix_capable : 1; 115 + u8 reserved_bar; 116 + u8 bar_fixed_64bit; 117 + u64 bar_fixed_size[BAR_5 + 1]; 118 + }; 112 119 113 120 #define to_pci_epc(device) container_of((device), struct pci_epc, dev) 114 121 ··· 169 158 enum pci_epc_irq_type type, u16 interrupt_num); 170 159 int pci_epc_start(struct pci_epc *epc); 171 160 void pci_epc_stop(struct pci_epc *epc); 161 + const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc, 162 + u8 func_no); 163 + unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features 164 + *epc_features); 172 165 struct pci_epc *pci_epc_get(const char *epc_name); 173 166 void pci_epc_put(struct pci_epc *epc); 174 167