History

Merge branch 'remotes/lorenzo/pci/endpoint'

- Use notification chain instead of EPF linkup ops for EPC events (Kishon Vijay Abraham I) - Protect concurrent allocation in endpoint outbound address region (Kishon Vijay Abraham I) - Protect concurrent access to pci_epf_ops (Kishon Vijay Abraham I) - Assign function number for each PF in endpoint core (Kishon Vijay Abraham I) - Refactor endpoint mode core initialization (Vidya Sagar) - Add API to notify when core initialization completes (Vidya Sagar) - Add test framework support to defer core initialization (Vidya Sagar) - Update Tegra SoC ABI header to support uninitialization of UPHY PLL when in endpoint mode without reference clock (Vidya Sagar) - Add DT and driver support for Tegra194 PCIe endpoint nodes (Vidya Sagar) - Add endpoint test support for DMA data transfer (Kishon Vijay Abraham I) - Print throughput information in endpoint test (Kishon Vijay Abraham I) - Use streaming DMA APIs for endpoint test buffer allocation (Kishon Vijay Abraham I) - Add endpoint test command line option for DMA (Kishon Vijay Abraham I) - When stopping a controller via configfs, clear endpoint "start" entry to prevent WARN_ON (Kunihiko Hayashi) - Update endpoint ->set_msix() to pay attention to MSI-X BAR Indicator and offset when finding MSI-X tables (Kishon Vijay Abraham I) - MSI-X tables are in local memory, not in the PCI address space. Update pcie-designware-ep to account for this (Kishon Vijay Abraham I) - Allow AM654 PCIe Endpoint to raise MSI-X interrupts (Kishon Vijay Abraham I) - Avoid using module parameter to determine irqtype for endpoint test (Kishon Vijay Abraham I) - Add ioctl to clear IRQ for endpoint test (Kishon Vijay Abraham I) - Add endpoint test 'e' option to clear IRQ (Kishon Vijay Abraham I) - Bump limit on number of endpoint test devices from 10 to 10,000 (Kishon Vijay Abraham I) - Use full pci-endpoint-test name in request_irq() for easier profiling (Kishon Vijay Abraham I) - Reduce log level of -EPROBE_DEFER error messages to debug (Thierry Reding) * remotes/lorenzo/pci/endpoint: misc: pci_endpoint_test: remove duplicate macro PCI_ENDPOINT_TEST_STATUS PCI: tegra: Print -EPROBE_DEFER error message at debug level misc: pci_endpoint_test: Use full pci-endpoint-test name in request_irq() misc: pci_endpoint_test: Fix to support > 10 pci-endpoint-test devices tools: PCI: Add 'e' to clear IRQ misc: pci_endpoint_test: Add ioctl to clear IRQ misc: pci_endpoint_test: Avoid using module parameter to determine irqtype PCI: keystone: Allow AM654 PCIe Endpoint to raise MSI-X interrupt PCI: dwc: Fix dw_pcie_ep_raise_msix_irq() to get correct MSI-X table address PCI: endpoint: Fix ->set_msix() to take BIR and offset as arguments misc: pci_endpoint_test: Add support to get DMA option from userspace tools: PCI: Add 'd' command line option to support DMA misc: pci_endpoint_test: Use streaming DMA APIs for buffer allocation PCI: endpoint: functions/pci-epf-test: Print throughput information PCI: endpoint: functions/pci-epf-test: Add DMA support to transfer data PCI: endpoint: Fix clearing start entry in configfs PCI: tegra: Add support for PCIe endpoint mode in Tegra194 dt-bindings: PCI: tegra: Add DT support for PCIe EP nodes in Tegra194 soc/tegra: bpmp: Update ABI header PCI: pci-epf-test: Add support to defer core initialization PCI: dwc: Add API to notify core initialization completion PCI: endpoint: Add notification for core init completion PCI: dwc: Refactor core initialization code for EP mode PCI: endpoint: Add core init notifying feature PCI: endpoint: Assign function number for each PF in EPC core PCI: endpoint: Protect concurrent access to pci_epf_ops with mutex PCI: endpoint: Fix for concurrent memory allocation in OB address region PCI: endpoint: Replace spinlock with mutex PCI: endpoint: Use notification chain mechanism to notify EPC events to EPF

Bjorn Helgaas committed 6 years ago

Commit b16f2ab2 parents cc36a45 e48ba3e17 files · +1655 −308Browse files

Unified · Split

17 files
  1. Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt +99 −26
  2. drivers/misc/pci_endpoint_test.c +179 −34
  3. drivers/pci/controller/dwc/Kconfig +26 −3
  4. drivers/pci/controller/dwc/pci-keystone.c +4 −1
  5. drivers/pci/controller/dwc/pcie-designware-ep.c +85 −59
  6. drivers/pci/controller/dwc/pcie-designware.h +12 −0
  7. drivers/pci/controller/dwc/pcie-tegra194.c +695 −17
  8. drivers/pci/endpoint/functions/pci-epf-test.c +356 −46
  9. drivers/pci/endpoint/pci-ep-cfs.c +6 −22
  10. drivers/pci/endpoint/pci-epc-core.c +75 −62
  11. drivers/pci/endpoint/pci-epc-mem.c +8 −2
  12. drivers/pci/endpoint/pci-epf-core.c +13 −22
  13. include/linux/pci-epc.h +22 −5
  14. include/linux/pci-epf.h +25 −4
  15. include/soc/tegra/bpmp-abi.h +9 −1
  16. include/uapi/linux/pcitest.h +8 −0
  17. tools/pci/pcitest.c +33 −4
Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt+99−26
@@ -1,11 +1,11 @@
1NVIDIA Tegra PCIe controller (Synopsys DesignWare Core based)1NVIDIA Tegra PCIe controller (Synopsys DesignWare Core based)
2 2
3This PCIe host controller is based on the Synopsis Designware PCIe IP3This PCIe controller is based on the Synopsis Designware PCIe IP
4and thus inherits all the common properties defined in designware-pcie.txt.4and thus inherits all the common properties defined in designware-pcie.txt.
5Some of the controller instances are dual mode where in they can work either
6in root port mode or endpoint mode but one at a time.
5 7
6Required properties:8Required properties:
7- compatible: For Tegra19x, must contain "nvidia,tegra194-pcie".
8- device_type: Must be "pci"
9- power-domains: A phandle to the node that controls power to the respective9- power-domains: A phandle to the node that controls power to the respective
10 PCIe controller and a specifier name for the PCIe controller. Following are10 PCIe controller and a specifier name for the PCIe controller. Following are
11 the specifiers for the different PCIe controllers11 the specifiers for the different PCIe controllers
@@ -32,6 +32,32 @@ Required properties: · 20 unmodified lines
32 entry for each entry in the interrupt-names property.32 entry for each entry in the interrupt-names property.
33- interrupt-names: Must include the following entries:33- interrupt-names: Must include the following entries:
34 "intr": The Tegra interrupt that is asserted for controller interrupts34 "intr": The Tegra interrupt that is asserted for controller interrupts
35- clocks: Must contain an entry for each entry in clock-names.
36 See ../clocks/clock-bindings.txt for details.
37- clock-names: Must include the following entries:
38 - core
39- resets: Must contain an entry for each entry in reset-names.
40 See ../reset/reset.txt for details.
41- reset-names: Must include the following entries:
42 - apb
43 - core
44- phys: Must contain a phandle to P2U PHY for each entry in phy-names.
45- phy-names: Must include an entry for each active lane.
46 "p2u-N": where N ranges from 0 to one less than the total number of lanes
47- nvidia,bpmp: Must contain a pair of phandle to BPMP controller node followed
48 by controller-id. Following are the controller ids for each controller.
49 0: C0
50 1: C1
51 2: C2
52 3: C3
53 4: C4
54 5: C5
55- vddio-pex-ctl-supply: Regulator supply for PCIe side band signals
56
57RC mode:
58- compatible: Tegra19x must contain "nvidia,tegra194-pcie"
59- device_type: Must be "pci" for RC mode
60- interrupt-names: Must include the following entries:
35 "msi": The Tegra interrupt that is asserted when an MSI is received61 "msi": The Tegra interrupt that is asserted when an MSI is received
36- bus-range: Range of bus numbers associated with this controller62- bus-range: Range of bus numbers associated with this controller
37- #address-cells: Address representation for root ports (must be 3)63- #address-cells: Address representation for root ports (must be 3)
@@ -60,27 +86,15 @@ Required properties: · 22 unmodified lines
60- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties86- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties
61 Please refer to the standard PCI bus binding document for a more detailed87 Please refer to the standard PCI bus binding document for a more detailed
62 explanation.88 explanation.
63- clocks: Must contain an entry for each entry in clock-names.89
64 See ../clocks/clock-bindings.txt for details.90EP mode:
65- clock-names: Must include the following entries:91In Tegra194, Only controllers C0, C4 & C5 support EP mode.
66 - core92- compatible: Tegra19x must contain "nvidia,tegra194-pcie-ep"
67- resets: Must contain an entry for each entry in reset-names.93- reg-names: Must include the following entries:
68 See ../reset/reset.txt for details.94 "addr_space": Used to map remote RC address space
69- reset-names: Must include the following entries:95- reset-gpios: Must contain a phandle to a GPIO controller followed by
70 - apb96 GPIO that is being used as PERST input signal. Please refer to pci.txt
71 - core97 document.
72- phys: Must contain a phandle to P2U PHY for each entry in phy-names.
73- phy-names: Must include an entry for each active lane.
74 "p2u-N": where N ranges from 0 to one less than the total number of lanes
75- nvidia,bpmp: Must contain a pair of phandle to BPMP controller node followed
76 by controller-id. Following are the controller ids for each controller.
77 0: C0
78 1: C1
79 2: C2
80 3: C3
81 4: C4
82 5: C5
83- vddio-pex-ctl-supply: Regulator supply for PCIe side band signals
84 98
85Optional properties:99Optional properties:
86- pinctrl-names: A list of pinctrl state names.100- pinctrl-names: A list of pinctrl state names.
@@ -104,6 +118,8 @@ Optional properties: · 17 unmodified lines
104 specified in microseconds118 specified in microseconds
105- nvidia,aspm-l0s-entrance-latency-us: ASPM L0s entrance latency to be119- nvidia,aspm-l0s-entrance-latency-us: ASPM L0s entrance latency to be
106 specified in microseconds120 specified in microseconds
121
122RC mode:
107- vpcie3v3-supply: A phandle to the regulator node that supplies 3.3V to the slot123- vpcie3v3-supply: A phandle to the regulator node that supplies 3.3V to the slot
108 if the platform has one such slot. (Ex:- x16 slot owned by C5 controller124 if the platform has one such slot. (Ex:- x16 slot owned by C5 controller
109 in p2972-0000 platform).125 in p2972-0000 platform).
@@ -111,11 +127,18 @@ Optional properties: · 1 unmodified line
111 if the platform has one such slot. (Ex:- x16 slot owned by C5 controller127 if the platform has one such slot. (Ex:- x16 slot owned by C5 controller
112 in p2972-0000 platform).128 in p2972-0000 platform).
113 129
130EP mode:
131- nvidia,refclk-select-gpios: Must contain a phandle to a GPIO controller
132 followed by GPIO that is being used to enable REFCLK to controller from host
133
134NOTE:- On Tegra194's P2972-0000 platform, only C5 controller can be enabled to
135operate in the endpoint mode because of the way the platform is designed.
136
114Examples:137Examples:
115=========138=========
116 139
117Tegra194:140Tegra194 RC mode:
118--------141-----------------
119 142
120 pcie@14180000 {143 pcie@14180000 {
121 compatible = "nvidia,tegra194-pcie", "snps,dw-pcie";144 compatible = "nvidia,tegra194-pcie", "snps,dw-pcie";
@@ -169,3 +192,53 @@ Tegra194: · 47 unmodified lines
169 <&p2u_hsio_5>;192 <&p2u_hsio_5>;
170 phy-names = "p2u-0", "p2u-1", "p2u-2", "p2u-3";193 phy-names = "p2u-0", "p2u-1", "p2u-2", "p2u-3";
171 };194 };
195
196Tegra194 EP mode:
197-----------------
198
199 pcie_ep@141a0000 {
200 compatible = "nvidia,tegra194-pcie-ep", "snps,dw-pcie-ep";
201 power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8A>;
202 reg = <0x00 0x141a0000 0x0 0x00020000 /* appl registers (128K) */
203 0x00 0x3a040000 0x0 0x00040000 /* iATU_DMA reg space (256K) */
204 0x00 0x3a080000 0x0 0x00040000 /* DBI reg space (256K) */
205 0x1c 0x00000000 0x4 0x00000000>; /* Address Space (16G) */
206 reg-names = "appl", "atu_dma", "dbi", "addr_space";
207
208 num-lanes = <8>;
209 num-ib-windows = <2>;
210 num-ob-windows = <8>;
211
212 pinctrl-names = "default";
213 pinctrl-0 = <&clkreq_c5_bi_dir_state>;
214
215 clocks = <&bpmp TEGRA194_CLK_PEX1_CORE_5>;
216 clock-names = "core";
217
218 resets = <&bpmp TEGRA194_RESET_PEX1_CORE_5_APB>,
219 <&bpmp TEGRA194_RESET_PEX1_CORE_5>;
220 reset-names = "apb", "core";
221
222 interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
223 interrupt-names = "intr";
224
225 nvidia,bpmp = <&bpmp 5>;
226
227 nvidia,aspm-cmrt-us = <60>;
228 nvidia,aspm-pwr-on-t-us = <20>;
229 nvidia,aspm-l0s-entrance-latency-us = <3>;
230
231 vddio-pex-ctl-supply = <&vdd_1v8ao>;
232
233 reset-gpios = <&gpio TEGRA194_MAIN_GPIO(GG, 1) GPIO_ACTIVE_LOW>;
234
235 nvidia,refclk-select-gpios = <&gpio_aon TEGRA194_AON_GPIO(AA, 5)
236 GPIO_ACTIVE_HIGH>;
237
238 phys = <&p2u_nvhs_0>, <&p2u_nvhs_1>, <&p2u_nvhs_2>,
239 <&p2u_nvhs_3>, <&p2u_nvhs_4>, <&p2u_nvhs_5>,
240 <&p2u_nvhs_6>, <&p2u_nvhs_7>;
241
242 phy-names = "p2u-0", "p2u-1", "p2u-2", "p2u-3", "p2u-4",
243 "p2u-5", "p2u-6", "p2u-7";
244 };
drivers/misc/pci_endpoint_test.c+179−34
@@ -17,6 +17,7 @@ · 16 unmodified lines
17#include <linux/mutex.h>17#include <linux/mutex.h>
18#include <linux/random.h>18#include <linux/random.h>
19#include <linux/slab.h>19#include <linux/slab.h>
20#include <linux/uaccess.h>
20#include <linux/pci.h>21#include <linux/pci.h>
21#include <linux/pci_ids.h>22#include <linux/pci_ids.h>
22 23
@@ -64,6 +65,9 @@ · 41 unmodified lines
64#define PCI_ENDPOINT_TEST_IRQ_TYPE 0x2465#define PCI_ENDPOINT_TEST_IRQ_TYPE 0x24
65#define PCI_ENDPOINT_TEST_IRQ_NUMBER 0x2866#define PCI_ENDPOINT_TEST_IRQ_NUMBER 0x28
66 67
68#define PCI_ENDPOINT_TEST_FLAGS 0x2c
69#define FLAG_USE_DMA BIT(0)
70
67#define PCI_DEVICE_ID_TI_AM654 0xb00c71#define PCI_DEVICE_ID_TI_AM654 0xb00c
68 72
69#define is_am654_pci_dev(pdev) \73#define is_am654_pci_dev(pdev) \
@@ -98,11 +102,13 @@ struct pci_endpoint_test { · 28 unmodified lines
98 struct completion irq_raised;102 struct completion irq_raised;
99 int last_irq;103 int last_irq;
100 int num_irqs;104 int num_irqs;
105 int irq_type;
101 /* mutex to protect the ioctls */106 /* mutex to protect the ioctls */
102 struct mutex mutex;107 struct mutex mutex;
103 struct miscdevice miscdev;108 struct miscdevice miscdev;
104 enum pci_barno test_reg_bar;109 enum pci_barno test_reg_bar;
105 size_t alignment;110 size_t alignment;
111 const char *name;
106};112};
107 113
108struct pci_endpoint_test_data {114struct pci_endpoint_test_data {
@@ -157,6 +163,7 @@ static void pci_endpoint_test_free_irq_vectors(struct pci_endpoint_test *test) · 48 unmodified lines
157 struct pci_dev *pdev = test->pdev;163 struct pci_dev *pdev = test->pdev;
158 164
159 pci_free_irq_vectors(pdev);165 pci_free_irq_vectors(pdev);
166 test->irq_type = IRQ_TYPE_UNDEFINED;
160}167}
161 168
162static bool pci_endpoint_test_alloc_irq_vectors(struct pci_endpoint_test *test,169static bool pci_endpoint_test_alloc_irq_vectors(struct pci_endpoint_test *test,
@@ -191,6 +198,8 @@ static bool pci_endpoint_test_alloc_irq_vectors(struct pci_endpoint_test *test, · 28 unmodified lines
191 irq = 0;198 irq = 0;
192 res = false;199 res = false;
193 }200 }
201
202 test->irq_type = type;
194 test->num_irqs = irq;203 test->num_irqs = irq;
195 204
196 return res;205 return res;
@@ -218,7 +227,7 @@ static bool pci_endpoint_test_request_irq(struct pci_endpoint_test *test) · 21 unmodified lines
218 for (i = 0; i < test->num_irqs; i++) {227 for (i = 0; i < test->num_irqs; i++) {
219 err = devm_request_irq(dev, pci_irq_vector(pdev, i),228 err = devm_request_irq(dev, pci_irq_vector(pdev, i),
220 pci_endpoint_test_irqhandler,229 pci_endpoint_test_irqhandler,
221 IRQF_SHARED, DRV_MODULE_NAME, test);230 IRQF_SHARED, test->name, test);
222 if (err)231 if (err)
223 goto fail;232 goto fail;
224 }233 }
@@ -315,11 +324,16 @@ static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test, · 90 unmodified lines
315 return false;324 return false;
316}325}
317 326
318static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)327static bool pci_endpoint_test_copy(struct pci_endpoint_test *test,
328 unsigned long arg)
319{329{
330 struct pci_endpoint_test_xfer_param param;
320 bool ret = false;331 bool ret = false;
321 void *src_addr;332 void *src_addr;
322 void *dst_addr;333 void *dst_addr;
334 u32 flags = 0;
335 bool use_dma;
336 size_t size;
323 dma_addr_t src_phys_addr;337 dma_addr_t src_phys_addr;
324 dma_addr_t dst_phys_addr;338 dma_addr_t dst_phys_addr;
325 struct pci_dev *pdev = test->pdev;339 struct pci_dev *pdev = test->pdev;
@@ -330,25 +344,46 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) · 4 unmodified lines
330 dma_addr_t orig_dst_phys_addr;344 dma_addr_t orig_dst_phys_addr;
331 size_t offset;345 size_t offset;
332 size_t alignment = test->alignment;346 size_t alignment = test->alignment;
347 int irq_type = test->irq_type;
333 u32 src_crc32;348 u32 src_crc32;
334 u32 dst_crc32;349 u32 dst_crc32;
350 int err;
335 351
352 err = copy_from_user(&param, (void __user *)arg, sizeof(param));
353 if (err) {
354 dev_err(dev, "Failed to get transfer param\n");
355 return false;
356 }
357
358 size = param.size;
336 if (size > SIZE_MAX - alignment)359 if (size > SIZE_MAX - alignment)
337 goto err;360 goto err;
338 361
362 use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
363 if (use_dma)
364 flags |= FLAG_USE_DMA;
365
339 if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {366 if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
340 dev_err(dev, "Invalid IRQ type option\n");367 dev_err(dev, "Invalid IRQ type option\n");
341 goto err;368 goto err;
342 }369 }
343 370
344 orig_src_addr = dma_alloc_coherent(dev, size + alignment,371 orig_src_addr = kzalloc(size + alignment, GFP_KERNEL);
345 &orig_src_phys_addr, GFP_KERNEL);
346 if (!orig_src_addr) {372 if (!orig_src_addr) {
347 dev_err(dev, "Failed to allocate source buffer\n");373 dev_err(dev, "Failed to allocate source buffer\n");
348 ret = false;374 ret = false;
349 goto err;375 goto err;
350 }376 }
351 377
378 get_random_bytes(orig_src_addr, size + alignment);
379 orig_src_phys_addr = dma_map_single(dev, orig_src_addr,
380 size + alignment, DMA_TO_DEVICE);
381 if (dma_mapping_error(dev, orig_src_phys_addr)) {
382 dev_err(dev, "failed to map source buffer address\n");
383 ret = false;
384 goto err_src_phys_addr;
385 }
386
352 if (alignment && !IS_ALIGNED(orig_src_phys_addr, alignment)) {387 if (alignment && !IS_ALIGNED(orig_src_phys_addr, alignment)) {
353 src_phys_addr = PTR_ALIGN(orig_src_phys_addr, alignment);388 src_phys_addr = PTR_ALIGN(orig_src_phys_addr, alignment);
354 offset = src_phys_addr - orig_src_phys_addr;389 offset = src_phys_addr - orig_src_phys_addr;
@@ -364,15 +399,21 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) · 9 unmodified lines
364 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_SRC_ADDR,399 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_SRC_ADDR,
365 upper_32_bits(src_phys_addr));400 upper_32_bits(src_phys_addr));
366 401
367 get_random_bytes(src_addr, size);
368 src_crc32 = crc32_le(~0, src_addr, size);402 src_crc32 = crc32_le(~0, src_addr, size);
369 403
370 orig_dst_addr = dma_alloc_coherent(dev, size + alignment,404 orig_dst_addr = kzalloc(size + alignment, GFP_KERNEL);
371 &orig_dst_phys_addr, GFP_KERNEL);
372 if (!orig_dst_addr) {405 if (!orig_dst_addr) {
373 dev_err(dev, "Failed to allocate destination address\n");406 dev_err(dev, "Failed to allocate destination address\n");
374 ret = false;407 ret = false;
375 goto err_orig_src_addr;408 goto err_dst_addr;
409 }
410
411 orig_dst_phys_addr = dma_map_single(dev, orig_dst_addr,
412 size + alignment, DMA_FROM_DEVICE);
413 if (dma_mapping_error(dev, orig_dst_phys_addr)) {
414 dev_err(dev, "failed to map destination buffer address\n");
415 ret = false;
416 goto err_dst_phys_addr;
376 }417 }
377 418
378 if (alignment && !IS_ALIGNED(orig_dst_phys_addr, alignment)) {419 if (alignment && !IS_ALIGNED(orig_dst_phys_addr, alignment)) {
@@ -392,6 +433,7 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) · 13 unmodified lines
392 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE,433 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE,
393 size);434 size);
394 435
436 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags);
395 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);437 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
396 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);438 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
397 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,439 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
@@ -399,24 +441,34 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) · 1 unmodified line
399 441
400 wait_for_completion(&test->irq_raised);442 wait_for_completion(&test->irq_raised);
401 443
444 dma_unmap_single(dev, orig_dst_phys_addr, size + alignment,
445 DMA_FROM_DEVICE);
446
402 dst_crc32 = crc32_le(~0, dst_addr, size);447 dst_crc32 = crc32_le(~0, dst_addr, size);
403 if (dst_crc32 == src_crc32)448 if (dst_crc32 == src_crc32)
404 ret = true;449 ret = true;
405 450
406 dma_free_coherent(dev, size + alignment, orig_dst_addr,451err_dst_phys_addr:
407 orig_dst_phys_addr);452 kfree(orig_dst_addr);
408 453
409err_orig_src_addr:454err_dst_addr:
410 dma_free_coherent(dev, size + alignment, orig_src_addr,455 dma_unmap_single(dev, orig_src_phys_addr, size + alignment,
411 orig_src_phys_addr);456 DMA_TO_DEVICE);
457
458err_src_phys_addr:
459 kfree(orig_src_addr);
412 460
413err:461err:
414 return ret;462 return ret;
415}463}
416 464
417static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)465static bool pci_endpoint_test_write(struct pci_endpoint_test *test,
466 unsigned long arg)
418{467{
468 struct pci_endpoint_test_xfer_param param;
419 bool ret = false;469 bool ret = false;
470 u32 flags = 0;
471 bool use_dma;
420 u32 reg;472 u32 reg;
421 void *addr;473 void *addr;
422 dma_addr_t phys_addr;474 dma_addr_t phys_addr;
@@ -426,24 +478,47 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) · 3 unmodified lines
426 dma_addr_t orig_phys_addr;478 dma_addr_t orig_phys_addr;
427 size_t offset;479 size_t offset;
428 size_t alignment = test->alignment;480 size_t alignment = test->alignment;
481 int irq_type = test->irq_type;
482 size_t size;
429 u32 crc32;483 u32 crc32;
484 int err;
485
486 err = copy_from_user(&param, (void __user *)arg, sizeof(param));
487 if (err != 0) {
488 dev_err(dev, "Failed to get transfer param\n");
489 return false;
490 }
430 491
492 size = param.size;
431 if (size > SIZE_MAX - alignment)493 if (size > SIZE_MAX - alignment)
432 goto err;494 goto err;
433 495
496 use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
497 if (use_dma)
498 flags |= FLAG_USE_DMA;
499
434 if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {500 if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
435 dev_err(dev, "Invalid IRQ type option\n");501 dev_err(dev, "Invalid IRQ type option\n");
436 goto err;502 goto err;
437 }503 }
438 504
439 orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr,505 orig_addr = kzalloc(size + alignment, GFP_KERNEL);
440 GFP_KERNEL);
441 if (!orig_addr) {506 if (!orig_addr) {
442 dev_err(dev, "Failed to allocate address\n");507 dev_err(dev, "Failed to allocate address\n");
443 ret = false;508 ret = false;
444 goto err;509 goto err;
445 }510 }
446 511
512 get_random_bytes(orig_addr, size + alignment);
513
514 orig_phys_addr = dma_map_single(dev, orig_addr, size + alignment,
515 DMA_TO_DEVICE);
516 if (dma_mapping_error(dev, orig_phys_addr)) {
517 dev_err(dev, "failed to map source buffer address\n");
518 ret = false;
519 goto err_phys_addr;
520 }
521
447 if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) {522 if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) {
448 phys_addr = PTR_ALIGN(orig_phys_addr, alignment);523 phys_addr = PTR_ALIGN(orig_phys_addr, alignment);
449 offset = phys_addr - orig_phys_addr;524 offset = phys_addr - orig_phys_addr;
@@ -453,8 +528,6 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) · 3 unmodified lines
453 addr = orig_addr;528 addr = orig_addr;
454 }529 }
455 530
456 get_random_bytes(addr, size);
457
458 crc32 = crc32_le(~0, addr, size);531 crc32 = crc32_le(~0, addr, size);
459 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_CHECKSUM,532 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_CHECKSUM,
460 crc32);533 crc32);
@@ -466,6 +539,7 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) · 5 unmodified lines
466 539
467 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);540 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
468 541
542 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags);
469 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);543 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
470 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);544 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
471 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,545 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
@@ -477,15 +551,24 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) · 5 unmodified lines
477 if (reg & STATUS_READ_SUCCESS)551 if (reg & STATUS_READ_SUCCESS)
478 ret = true;552 ret = true;
479 553
480 dma_free_coherent(dev, size + alignment, orig_addr, orig_phys_addr);554 dma_unmap_single(dev, orig_phys_addr, size + alignment,
555 DMA_TO_DEVICE);
556
557err_phys_addr:
558 kfree(orig_addr);
481 559
482err:560err:
483 return ret;561 return ret;
484}562}
485 563
486static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size)564static bool pci_endpoint_test_read(struct pci_endpoint_test *test,
565 unsigned long arg)
487{566{
567 struct pci_endpoint_test_xfer_param param;
488 bool ret = false;568 bool ret = false;
569 u32 flags = 0;
570 bool use_dma;
571 size_t size;
489 void *addr;572 void *addr;
490 dma_addr_t phys_addr;573 dma_addr_t phys_addr;
491 struct pci_dev *pdev = test->pdev;574 struct pci_dev *pdev = test->pdev;
@@ -494,24 +577,44 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size) · 2 unmodified lines
494 dma_addr_t orig_phys_addr;577 dma_addr_t orig_phys_addr;
495 size_t offset;578 size_t offset;
496 size_t alignment = test->alignment;579 size_t alignment = test->alignment;
580 int irq_type = test->irq_type;
497 u32 crc32;581 u32 crc32;
582 int err;
583
584 err = copy_from_user(&param, (void __user *)arg, sizeof(param));
585 if (err) {
586 dev_err(dev, "Failed to get transfer param\n");
587 return false;
588 }
498 589
590 size = param.size;
499 if (size > SIZE_MAX - alignment)591 if (size > SIZE_MAX - alignment)
500 goto err;592 goto err;
501 593
594 use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
595 if (use_dma)
596 flags |= FLAG_USE_DMA;
597
502 if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {598 if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
503 dev_err(dev, "Invalid IRQ type option\n");599 dev_err(dev, "Invalid IRQ type option\n");
504 goto err;600 goto err;
505 }601 }
506 602
507 orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr,603 orig_addr = kzalloc(size + alignment, GFP_KERNEL);
508 GFP_KERNEL);
509 if (!orig_addr) {604 if (!orig_addr) {
510 dev_err(dev, "Failed to allocate destination address\n");605 dev_err(dev, "Failed to allocate destination address\n");
511 ret = false;606 ret = false;
512 goto err;607 goto err;
513 }608 }
514 609
610 orig_phys_addr = dma_map_single(dev, orig_addr, size + alignment,
611 DMA_FROM_DEVICE);
612 if (dma_mapping_error(dev, orig_phys_addr)) {
613 dev_err(dev, "failed to map source buffer address\n");
614 ret = false;
615 goto err_phys_addr;
616 }
617
515 if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) {618 if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) {
516 phys_addr = PTR_ALIGN(orig_phys_addr, alignment);619 phys_addr = PTR_ALIGN(orig_phys_addr, alignment);
517 offset = phys_addr - orig_phys_addr;620 offset = phys_addr - orig_phys_addr;
@@ -528,6 +631,7 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size) · 10 unmodified lines
528 631
529 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);632 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
530 633
634 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags);
531 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);635 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
532 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);636 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
533 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,637 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
@@ -535,15 +639,26 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size) · 1 unmodified line
535 639
536 wait_for_completion(&test->irq_raised);640 wait_for_completion(&test->irq_raised);
537 641
642 dma_unmap_single(dev, orig_phys_addr, size + alignment,
643 DMA_FROM_DEVICE);
644
538 crc32 = crc32_le(~0, addr, size);645 crc32 = crc32_le(~0, addr, size);
539 if (crc32 == pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CHECKSUM))646 if (crc32 == pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CHECKSUM))
540 ret = true;647 ret = true;
541 648
542 dma_free_coherent(dev, size + alignment, orig_addr, orig_phys_addr);649err_phys_addr:
650 kfree(orig_addr);
543err:651err:
544 return ret;652 return ret;
545}653}
546 654
655static bool pci_endpoint_test_clear_irq(struct pci_endpoint_test *test)
656{
657 pci_endpoint_test_release_irq(test);
658 pci_endpoint_test_free_irq_vectors(test);
659 return true;
660}
661
547static bool pci_endpoint_test_set_irq(struct pci_endpoint_test *test,662static bool pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
548 int req_irq_type)663 int req_irq_type)
549{664{
@@ -555,7 +670,7 @@ static bool pci_endpoint_test_set_irq(struct pci_endpoint_test *test, · 5 unmodified lines
555 return false;670 return false;
556 }671 }
557 672
558 if (irq_type == req_irq_type)673 if (test->irq_type == req_irq_type)
559 return true;674 return true;
560 675
561 pci_endpoint_test_release_irq(test);676 pci_endpoint_test_release_irq(test);
@@ -567,12 +682,10 @@ static bool pci_endpoint_test_set_irq(struct pci_endpoint_test *test, · 5 unmodified lines
567 if (!pci_endpoint_test_request_irq(test))682 if (!pci_endpoint_test_request_irq(test))
568 goto err;683 goto err;
569 684
570 irq_type = req_irq_type;
571 return true;685 return true;
572 686
573err:687err:
574 pci_endpoint_test_free_irq_vectors(test);688 pci_endpoint_test_free_irq_vectors(test);
575 irq_type = IRQ_TYPE_UNDEFINED;
576 return false;689 return false;
577}690}
578 691
@@ -616,6 +729,9 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd, · 37 unmodified lines
616 case PCITEST_GET_IRQTYPE:729 case PCITEST_GET_IRQTYPE:
617 ret = irq_type;730 ret = irq_type;
618 break;731 break;
732 case PCITEST_CLEAR_IRQ:
733 ret = pci_endpoint_test_clear_irq(test);
734 break;
619 }735 }
620 736
621ret:737ret:
@@ -633,7 +749,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, · 11 unmodified lines
633{749{
634 int err;750 int err;
635 int id;751 int id;
636 char name[20];752 char name[24];
637 enum pci_barno bar;753 enum pci_barno bar;
638 void __iomem *base;754 void __iomem *base;
639 struct device *dev = &pdev->dev;755 struct device *dev = &pdev->dev;
@@ -652,6 +768,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, · 12 unmodified lines
652 test->test_reg_bar = 0;768 test->test_reg_bar = 0;
653 test->alignment = 0;769 test->alignment = 0;
654 test->pdev = pdev;770 test->pdev = pdev;
771 test->irq_type = IRQ_TYPE_UNDEFINED;
655 772
656 if (no_msi)773 if (no_msi)
657 irq_type = IRQ_TYPE_LEGACY;774 irq_type = IRQ_TYPE_LEGACY;
@@ -667,6 +784,12 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, · 9 unmodified lines
667 init_completion(&test->irq_raised);784 init_completion(&test->irq_raised);
668 mutex_init(&test->mutex);785 mutex_init(&test->mutex);
669 786
787 if ((dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(48)) != 0) &&
788 dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)) != 0) {
789 dev_err(dev, "Cannot set DMA mask\n");
790 return -EINVAL;
791 }
792
670 err = pci_enable_device(pdev);793 err = pci_enable_device(pdev);
671 if (err) {794 if (err) {
672 dev_err(dev, "Cannot enable PCI device\n");795 dev_err(dev, "Cannot enable PCI device\n");
@@ -684,9 +807,6 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, · 11 unmodified lines
684 if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type))807 if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type))
685 goto err_disable_irq;808 goto err_disable_irq;
686 809
687 if (!pci_endpoint_test_request_irq(test))
688 goto err_disable_irq;
689
690 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {810 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
691 if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {811 if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
692 base = pci_ioremap_bar(pdev, bar);812 base = pci_ioremap_bar(pdev, bar);
@@ -716,12 +836,21 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, · 23 unmodified lines
716 }836 }
717 837
718 snprintf(name, sizeof(name), DRV_MODULE_NAME ".%d", id);838 snprintf(name, sizeof(name), DRV_MODULE_NAME ".%d", id);
839 test->name = kstrdup(name, GFP_KERNEL);
840 if (!test->name) {
841 err = -ENOMEM;
842 goto err_ida_remove;
843 }
844
845 if (!pci_endpoint_test_request_irq(test))
846 goto err_kfree_test_name;
847
719 misc_device = &test->miscdev;848 misc_device = &test->miscdev;
720 misc_device->minor = MISC_DYNAMIC_MINOR;849 misc_device->minor = MISC_DYNAMIC_MINOR;
721 misc_device->name = kstrdup(name, GFP_KERNEL);850 misc_device->name = kstrdup(name, GFP_KERNEL);
722 if (!misc_device->name) {851 if (!misc_device->name) {
723 err = -ENOMEM;852 err = -ENOMEM;
724 goto err_ida_remove;853 goto err_release_irq;
725 }854 }
726 misc_device->fops = &pci_endpoint_test_fops,855 misc_device->fops = &pci_endpoint_test_fops,
727 856
@@ -736,6 +865,12 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, · 8 unmodified lines
736err_kfree_name:865err_kfree_name:
737 kfree(misc_device->name);866 kfree(misc_device->name);
738 867
868err_release_irq:
869 pci_endpoint_test_release_irq(test);
870
871err_kfree_test_name:
872 kfree(test->name);
873
739err_ida_remove:874err_ida_remove:
740 ida_simple_remove(&pci_endpoint_test_ida, id);875 ida_simple_remove(&pci_endpoint_test_ida, id);
741 876
@@ -744,7 +879,6 @@ err_iounmap: · 2 unmodified lines
744 if (test->bar[bar])879 if (test->bar[bar])
745 pci_iounmap(pdev, test->bar[bar]);880 pci_iounmap(pdev, test->bar[bar]);
746 }881 }
747 pci_endpoint_test_release_irq(test);
748 882
749err_disable_irq:883err_disable_irq:
750 pci_endpoint_test_free_irq_vectors(test);884 pci_endpoint_test_free_irq_vectors(test);
@@ -770,6 +904,7 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev) · 19 unmodified lines
770 904
771 misc_deregister(&test->miscdev);905 misc_deregister(&test->miscdev);
772 kfree(misc_device->name);906 kfree(misc_device->name);
907 kfree(test->name);
773 ida_simple_remove(&pci_endpoint_test_ida, id);908 ida_simple_remove(&pci_endpoint_test_ida, id);
774 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {909 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
775 if (test->bar[bar])910 if (test->bar[bar])
@@ -783,6 +918,12 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev) · 7 unmodified lines
783 pci_disable_device(pdev);918 pci_disable_device(pdev);
784}919}
785 920
921static const struct pci_endpoint_test_data default_data = {
922 .test_reg_bar = BAR_0,
923 .alignment = SZ_4K,
924 .irq_type = IRQ_TYPE_MSI,
925};
926
786static const struct pci_endpoint_test_data am654_data = {927static const struct pci_endpoint_test_data am654_data = {
787 .test_reg_bar = BAR_2,928 .test_reg_bar = BAR_2,
788 .alignment = SZ_64K,929 .alignment = SZ_64K,
@@ -790,8 +931,12 @@ static const struct pci_endpoint_test_data am654_data = { · 1 unmodified line
790};931};
791 932
792static const struct pci_device_id pci_endpoint_test_tbl[] = {933static const struct pci_device_id pci_endpoint_test_tbl[] = {
793 { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) },934 { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x),
794 { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) },935 .driver_data = (kernel_ulong_t)&default_data,
936 },
937 { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x),
938 .driver_data = (kernel_ulong_t)&default_data,
939 },
795 { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x81c0) },940 { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x81c0) },
796 { PCI_DEVICE_DATA(SYNOPSYS, EDDA, NULL) },941 { PCI_DEVICE_DATA(SYNOPSYS, EDDA, NULL) },
797 { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654),942 { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654),
drivers/pci/controller/dwc/Kconfig+26−3
@@ -248,14 +248,37 @@ config PCI_MESON · 247 unmodified lines
248 implement the driver.248 implement the driver.
249 249
250config PCIE_TEGRA194250config PCIE_TEGRA194
251 tristate "NVIDIA Tegra194 (and later) PCIe controller"251 tristate
252
253config PCIE_TEGRA194_HOST
254 tristate "NVIDIA Tegra194 (and later) PCIe controller - Host Mode"
252 depends on ARCH_TEGRA_194_SOC || COMPILE_TEST255 depends on ARCH_TEGRA_194_SOC || COMPILE_TEST
253 depends on PCI_MSI_IRQ_DOMAIN256 depends on PCI_MSI_IRQ_DOMAIN
254 select PCIE_DW_HOST257 select PCIE_DW_HOST
255 select PHY_TEGRA194_P2U258 select PHY_TEGRA194_P2U
259 select PCIE_TEGRA194
260 help
261 Enables support for the PCIe controller in the NVIDIA Tegra194 SoC to
262 work in host mode. There are two instances of PCIe controllers in
263 Tegra194. This controller can work either as EP or RC. In order to
264 enable host-specific features PCIE_TEGRA194_HOST must be selected and
265 in order to enable device-specific features PCIE_TEGRA194_EP must be
266 selected. This uses the DesignWare core.
267
268config PCIE_TEGRA194_EP
269 tristate "NVIDIA Tegra194 (and later) PCIe controller - Endpoint Mode"
270 depends on ARCH_TEGRA_194_SOC || COMPILE_TEST
271 depends on PCI_ENDPOINT
272 select PCIE_DW_EP
273 select PHY_TEGRA194_P2U
274 select PCIE_TEGRA194
256 help275 help
257 Say Y here if you want support for DesignWare core based PCIe host276 Enables support for the PCIe controller in the NVIDIA Tegra194 SoC to
258 controller found in NVIDIA Tegra194 SoC.277 work in host mode. There are two instances of PCIe controllers in
278 Tegra194. This controller can work either as EP or RC. In order to
279 enable host-specific features PCIE_TEGRA194_HOST must be selected and
280 in order to enable device-specific features PCIE_TEGRA194_EP must be
281 selected. This uses the DesignWare core.
259 282
260config PCIE_UNIPHIER283config PCIE_UNIPHIER
261 bool "Socionext UniPhier PCIe controllers"284 bool "Socionext UniPhier PCIe controllers"
drivers/pci/controller/dwc/pci-keystone.c+4−1
@@ -959,6 +959,9 @@ static int ks_pcie_am654_raise_irq(struct dw_pcie_ep *ep, u8 func_no, · 958 unmodified lines
959 case PCI_EPC_IRQ_MSI:959 case PCI_EPC_IRQ_MSI:
960 dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);960 dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
961 break;961 break;
962 case PCI_EPC_IRQ_MSIX:
963 dw_pcie_ep_raise_msix_irq(ep, func_no, interrupt_num);
964 break;
962 default:965 default:
963 dev_err(pci->dev, "UNKNOWN IRQ type\n");966 dev_err(pci->dev, "UNKNOWN IRQ type\n");
964 return -EINVAL;967 return -EINVAL;
@@ -970,7 +973,7 @@ static int ks_pcie_am654_raise_irq(struct dw_pcie_ep *ep, u8 func_no, · 5 unmodified lines
970static const struct pci_epc_features ks_pcie_am654_epc_features = {973static const struct pci_epc_features ks_pcie_am654_epc_features = {
971 .linkup_notifier = false,974 .linkup_notifier = false,
972 .msi_capable = true,975 .msi_capable = true,
973 .msix_capable = false,976 .msix_capable = true,
974 .reserved_bar = 1 << BAR_0 | 1 << BAR_1,977 .reserved_bar = 1 << BAR_0 | 1 << BAR_1,
975 .bar_fixed_64bit = 1 << BAR_0,978 .bar_fixed_64bit = 1 << BAR_0,
976 .bar_fixed_size[2] = SZ_1M,979 .bar_fixed_size[2] = SZ_1M,
drivers/pci/controller/dwc/pcie-designware-ep.c+85−59
@@ -18,6 +18,15 @@ void dw_pcie_ep_linkup(struct dw_pcie_ep *ep) · 17 unmodified lines
18 18
19 pci_epc_linkup(epc);19 pci_epc_linkup(epc);
20}20}
21EXPORT_SYMBOL_GPL(dw_pcie_ep_linkup);
22
23void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep)
24{
25 struct pci_epc *epc = ep->epc;
26
27 pci_epc_init_notify(epc);
28}
29EXPORT_SYMBOL_GPL(dw_pcie_ep_init_notify);
21 30
22static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar,31static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar,
23 int flags)32 int flags)
@@ -125,6 +134,7 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no, · 101 unmodified lines
125 134
126 dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND);135 dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND);
127 clear_bit(atu_index, ep->ib_window_map);136 clear_bit(atu_index, ep->ib_window_map);
137 ep->epf_bar[bar] = NULL;
128}138}
129 139
130static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,140static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
@@ -158,6 +168,7 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, · 27 unmodified lines
158 dw_pcie_writel_dbi(pci, reg + 4, 0);168 dw_pcie_writel_dbi(pci, reg + 4, 0);
159 }169 }
160 170
171 ep->epf_bar[bar] = epf_bar;
161 dw_pcie_dbi_ro_wr_dis(pci);172 dw_pcie_dbi_ro_wr_dis(pci);
162 173
163 return 0;174 return 0;
@@ -269,7 +280,8 @@ static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no) · 105 unmodified lines
269 return val;280 return val;
270}281}
271 282
272static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts)283static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
284 enum pci_barno bir, u32 offset)
273{285{
274 struct dw_pcie_ep *ep = epc_get_drvdata(epc);286 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
275 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);287 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -278,12 +290,22 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts) · 2 unmodified lines
278 if (!ep->msix_cap)290 if (!ep->msix_cap)
279 return -EINVAL;291 return -EINVAL;
280 292
293 dw_pcie_dbi_ro_wr_en(pci);
294
281 reg = ep->msix_cap + PCI_MSIX_FLAGS;295 reg = ep->msix_cap + PCI_MSIX_FLAGS;
282 val = dw_pcie_readw_dbi(pci, reg);296 val = dw_pcie_readw_dbi(pci, reg);
283 val &= ~PCI_MSIX_FLAGS_QSIZE;297 val &= ~PCI_MSIX_FLAGS_QSIZE;
284 val |= interrupts;298 val |= interrupts;
285 dw_pcie_dbi_ro_wr_en(pci);
286 dw_pcie_writew_dbi(pci, reg, val);299 dw_pcie_writew_dbi(pci, reg, val);
300
301 reg = ep->msix_cap + PCI_MSIX_TABLE;
302 val = offset | bir;
303 dw_pcie_writel_dbi(pci, reg, val);
304
305 reg = ep->msix_cap + PCI_MSIX_PBA;
306 val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
307 dw_pcie_writel_dbi(pci, reg, val);
308
287 dw_pcie_dbi_ro_wr_dis(pci);309 dw_pcie_dbi_ro_wr_dis(pci);
288 310
289 return 0;311 return 0;
@@ -409,55 +431,41 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, · 119 unmodified lines
409 u16 interrupt_num)431 u16 interrupt_num)
410{432{
411 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);433 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
434 struct pci_epf_msix_tbl *msix_tbl;
412 struct pci_epc *epc = ep->epc;435 struct pci_epc *epc = ep->epc;
413 u16 tbl_offset, bir;436 struct pci_epf_bar *epf_bar;
414 u32 bar_addr_upper, bar_addr_lower;
415 u32 msg_addr_upper, msg_addr_lower;
416 u32 reg, msg_data, vec_ctrl;437 u32 reg, msg_data, vec_ctrl;
417 u64 tbl_addr, msg_addr, reg_u64;438 unsigned int aligned_offset;
418 void __iomem *msix_tbl;439 u32 tbl_offset;
440 u64 msg_addr;
419 int ret;441 int ret;
442 u8 bir;
420 443
421 reg = ep->msix_cap + PCI_MSIX_TABLE;444 reg = ep->msix_cap + PCI_MSIX_TABLE;
422 tbl_offset = dw_pcie_readl_dbi(pci, reg);445 tbl_offset = dw_pcie_readl_dbi(pci, reg);
423 bir = (tbl_offset & PCI_MSIX_TABLE_BIR);446 bir = (tbl_offset & PCI_MSIX_TABLE_BIR);
424 tbl_offset &= PCI_MSIX_TABLE_OFFSET;447 tbl_offset &= PCI_MSIX_TABLE_OFFSET;
425 448
426 reg = PCI_BASE_ADDRESS_0 + (4 * bir);449 epf_bar = ep->epf_bar[bir];
427 bar_addr_upper = 0;450 msix_tbl = epf_bar->addr;
428 bar_addr_lower = dw_pcie_readl_dbi(pci, reg);451 msix_tbl = (struct pci_epf_msix_tbl *)((char *)msix_tbl + tbl_offset);
429 reg_u64 = (bar_addr_lower & PCI_BASE_ADDRESS_MEM_TYPE_MASK);
430 if (reg_u64 == PCI_BASE_ADDRESS_MEM_TYPE_64)
431 bar_addr_upper = dw_pcie_readl_dbi(pci, reg + 4);
432
433 tbl_addr = ((u64) bar_addr_upper) << 32 | bar_addr_lower;
434 tbl_addr += (tbl_offset + ((interrupt_num - 1) * PCI_MSIX_ENTRY_SIZE));
435 tbl_addr &= PCI_BASE_ADDRESS_MEM_MASK;
436
437 msix_tbl = ioremap(ep->phys_base + tbl_addr,
438 PCI_MSIX_ENTRY_SIZE);
439 if (!msix_tbl)
440 return -EINVAL;
441
442 msg_addr_lower = readl(msix_tbl + PCI_MSIX_ENTRY_LOWER_ADDR);
443 msg_addr_upper = readl(msix_tbl + PCI_MSIX_ENTRY_UPPER_ADDR);
444 msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower;
445 msg_data = readl(msix_tbl + PCI_MSIX_ENTRY_DATA);
446 vec_ctrl = readl(msix_tbl + PCI_MSIX_ENTRY_VECTOR_CTRL);
447 452
448 iounmap(msix_tbl);453 msg_addr = msix_tbl[(interrupt_num - 1)].msg_addr;
454 msg_data = msix_tbl[(interrupt_num - 1)].msg_data;
455 vec_ctrl = msix_tbl[(interrupt_num - 1)].vector_ctrl;
449 456
450 if (vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) {457 if (vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) {
451 dev_dbg(pci->dev, "MSI-X entry ctrl set\n");458 dev_dbg(pci->dev, "MSI-X entry ctrl set\n");
452 return -EPERM;459 return -EPERM;
453 }460 }
454 461
455 ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,462 aligned_offset = msg_addr & (epc->mem->page_size - 1);
463 ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
456 epc->mem->page_size);464 epc->mem->page_size);
457 if (ret)465 if (ret)
458 return ret;466 return ret;
459 467
460 writel(msg_data, ep->msi_mem);468 writel(msg_data, ep->msi_mem + aligned_offset);
461 469
462 dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys);470 dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys);
463 471
@@ -492,19 +500,54 @@ static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap) · 28 unmodified lines
492 return 0;500 return 0;
493}501}
494 502
495int dw_pcie_ep_init(struct dw_pcie_ep *ep)503int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
496{504{
505 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
506 unsigned int offset;
507 unsigned int nbars;
508 u8 hdr_type;
509 u32 reg;
497 int i;510 int i;
511
512 hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE);
513 if (hdr_type != PCI_HEADER_TYPE_NORMAL) {
514 dev_err(pci->dev,
515 "PCIe controller is not set to EP mode (hdr_type:0x%x)!\n",
516 hdr_type);
517 return -EIO;
518 }
519
520 ep->msi_cap = dw_pcie_find_capability(pci, PCI_CAP_ID_MSI);
521
522 ep->msix_cap = dw_pcie_find_capability(pci, PCI_CAP_ID_MSIX);
523
524 offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
525 if (offset) {
526 reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
527 nbars = (reg & PCI_REBAR_CTRL_NBAR_MASK) >>
528 PCI_REBAR_CTRL_NBAR_SHIFT;
529
530 dw_pcie_dbi_ro_wr_en(pci);
531 for (i = 0; i < nbars; i++, offset += PCI_REBAR_CTRL)
532 dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, 0x0);
533 dw_pcie_dbi_ro_wr_dis(pci);
534 }
535
536 dw_pcie_setup(pci);
537
538 return 0;
539}
540EXPORT_SYMBOL_GPL(dw_pcie_ep_init_complete);
541
542int dw_pcie_ep_init(struct dw_pcie_ep *ep)
543{
498 int ret;544 int ret;
499 u32 reg;
500 void *addr;545 void *addr;
501 u8 hdr_type;
502 unsigned int nbars;
503 unsigned int offset;
504 struct pci_epc *epc;546 struct pci_epc *epc;
505 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);547 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
506 struct device *dev = pci->dev;548 struct device *dev = pci->dev;
507 struct device_node *np = dev->of_node;549 struct device_node *np = dev->of_node;
550 const struct pci_epc_features *epc_features;
508 551
509 if (!pci->dbi_base || !pci->dbi_base2) {552 if (!pci->dbi_base || !pci->dbi_base2) {
510 dev_err(dev, "dbi_base/dbi_base2 is not populated\n");553 dev_err(dev, "dbi_base/dbi_base2 is not populated\n");
@@ -563,13 +606,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) · 52 unmodified lines
563 if (ep->ops->ep_init)606 if (ep->ops->ep_init)
564 ep->ops->ep_init(ep);607 ep->ops->ep_init(ep);
565 608
566 hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE);
567 if (hdr_type != PCI_HEADER_TYPE_NORMAL) {
568 dev_err(pci->dev, "PCIe controller is not set to EP mode (hdr_type:0x%x)!\n",
569 hdr_type);
570 return -EIO;
571 }
572
573 ret = of_property_read_u8(np, "max-functions", &epc->max_functions);609 ret = of_property_read_u8(np, "max-functions", &epc->max_functions);
574 if (ret < 0)610 if (ret < 0)
575 epc->max_functions = 1;611 epc->max_functions = 1;
@@ -587,23 +623,13 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) · 11 unmodified lines
587 dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n");623 dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n");
588 return -ENOMEM;624 return -ENOMEM;
589 }625 }
590 ep->msi_cap = dw_pcie_find_capability(pci, PCI_CAP_ID_MSI);
591
592 ep->msix_cap = dw_pcie_find_capability(pci, PCI_CAP_ID_MSIX);
593
594 offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
595 if (offset) {
596 reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
597 nbars = (reg & PCI_REBAR_CTRL_NBAR_MASK) >>
598 PCI_REBAR_CTRL_NBAR_SHIFT;
599 626
600 dw_pcie_dbi_ro_wr_en(pci);627 if (ep->ops->get_features) {
601 for (i = 0; i < nbars; i++, offset += PCI_REBAR_CTRL)628 epc_features = ep->ops->get_features(ep);
602 dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, 0x0);629 if (epc_features->core_init_notifier)
603 dw_pcie_dbi_ro_wr_dis(pci);630 return 0;
604 }631 }
605 632
606 dw_pcie_setup(pci);633 return dw_pcie_ep_init_complete(ep);
607
608 return 0;
609}634}
635EXPORT_SYMBOL_GPL(dw_pcie_ep_init);
drivers/pci/controller/dwc/pcie-designware.h+12−0
@@ -233,6 +233,7 @@ struct dw_pcie_ep { · 232 unmodified lines
233 phys_addr_t msi_mem_phys;233 phys_addr_t msi_mem_phys;
234 u8 msi_cap; /* MSI capability offset */234 u8 msi_cap; /* MSI capability offset */
235 u8 msix_cap; /* MSI-X capability offset */235 u8 msix_cap; /* MSI-X capability offset */
236 struct pci_epf_bar *epf_bar[PCI_STD_NUM_BARS];
236};237};
237 238
238struct dw_pcie_ops {239struct dw_pcie_ops {
@@ -411,6 +412,8 @@ static inline int dw_pcie_allocate_domains(struct pcie_port *pp) · 172 unmodified lines
411#ifdef CONFIG_PCIE_DW_EP412#ifdef CONFIG_PCIE_DW_EP
412void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);413void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);
413int dw_pcie_ep_init(struct dw_pcie_ep *ep);414int dw_pcie_ep_init(struct dw_pcie_ep *ep);
415int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep);
416void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep);
414void dw_pcie_ep_exit(struct dw_pcie_ep *ep);417void dw_pcie_ep_exit(struct dw_pcie_ep *ep);
415int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no);418int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no);
416int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,419int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
@@ -428,6 +431,15 @@ static inline int dw_pcie_ep_init(struct dw_pcie_ep *ep) · 11 unmodified lines
428 return 0;431 return 0;
429}432}
430 433
434static inline int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
435{
436 return 0;
437}
438
439static inline void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep)
440{
441}
442
431static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep)443static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
432{444{
433}445}
drivers/pci/controller/dwc/pcie-tegra194.c+695−17
@@ -11,6 +11,7 @@ · 10 unmodified lines
11#include <linux/debugfs.h>11#include <linux/debugfs.h>
12#include <linux/delay.h>12#include <linux/delay.h>
13#include <linux/gpio.h>13#include <linux/gpio.h>
14#include <linux/gpio/consumer.h>
14#include <linux/interrupt.h>15#include <linux/interrupt.h>
15#include <linux/iopoll.h>16#include <linux/iopoll.h>
16#include <linux/kernel.h>17#include <linux/kernel.h>
@@ -53,6 +54,7 @@ · 36 unmodified lines
53#define APPL_INTR_EN_L0_0_LINK_STATE_INT_EN BIT(0)54#define APPL_INTR_EN_L0_0_LINK_STATE_INT_EN BIT(0)
54#define APPL_INTR_EN_L0_0_MSI_RCV_INT_EN BIT(4)55#define APPL_INTR_EN_L0_0_MSI_RCV_INT_EN BIT(4)
55#define APPL_INTR_EN_L0_0_INT_INT_EN BIT(8)56#define APPL_INTR_EN_L0_0_INT_INT_EN BIT(8)
57#define APPL_INTR_EN_L0_0_PCI_CMD_EN_INT_EN BIT(15)
56#define APPL_INTR_EN_L0_0_CDM_REG_CHK_INT_EN BIT(19)58#define APPL_INTR_EN_L0_0_CDM_REG_CHK_INT_EN BIT(19)
57#define APPL_INTR_EN_L0_0_SYS_INTR_EN BIT(30)59#define APPL_INTR_EN_L0_0_SYS_INTR_EN BIT(30)
58#define APPL_INTR_EN_L0_0_SYS_MSI_INTR_EN BIT(31)60#define APPL_INTR_EN_L0_0_SYS_MSI_INTR_EN BIT(31)
@@ -60,19 +62,26 @@ · 1 unmodified line
60#define APPL_INTR_STATUS_L0 0xC62#define APPL_INTR_STATUS_L0 0xC
61#define APPL_INTR_STATUS_L0_LINK_STATE_INT BIT(0)63#define APPL_INTR_STATUS_L0_LINK_STATE_INT BIT(0)
62#define APPL_INTR_STATUS_L0_INT_INT BIT(8)64#define APPL_INTR_STATUS_L0_INT_INT BIT(8)
65#define APPL_INTR_STATUS_L0_PCI_CMD_EN_INT BIT(15)
66#define APPL_INTR_STATUS_L0_PEX_RST_INT BIT(16)
63#define APPL_INTR_STATUS_L0_CDM_REG_CHK_INT BIT(18)67#define APPL_INTR_STATUS_L0_CDM_REG_CHK_INT BIT(18)
64 68
65#define APPL_INTR_EN_L1_0_0 0x1C69#define APPL_INTR_EN_L1_0_0 0x1C
66#define APPL_INTR_EN_L1_0_0_LINK_REQ_RST_NOT_INT_EN BIT(1)70#define APPL_INTR_EN_L1_0_0_LINK_REQ_RST_NOT_INT_EN BIT(1)
71#define APPL_INTR_EN_L1_0_0_RDLH_LINK_UP_INT_EN BIT(3)
72#define APPL_INTR_EN_L1_0_0_HOT_RESET_DONE_INT_EN BIT(30)
67 73
68#define APPL_INTR_STATUS_L1_0_0 0x2074#define APPL_INTR_STATUS_L1_0_0 0x20
69#define APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED BIT(1)75#define APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED BIT(1)
76#define APPL_INTR_STATUS_L1_0_0_RDLH_LINK_UP_CHGED BIT(3)
77#define APPL_INTR_STATUS_L1_0_0_HOT_RESET_DONE BIT(30)
70 78
71#define APPL_INTR_STATUS_L1_1 0x2C79#define APPL_INTR_STATUS_L1_1 0x2C
72#define APPL_INTR_STATUS_L1_2 0x3080#define APPL_INTR_STATUS_L1_2 0x30
73#define APPL_INTR_STATUS_L1_3 0x3481#define APPL_INTR_STATUS_L1_3 0x34
74#define APPL_INTR_STATUS_L1_6 0x3C82#define APPL_INTR_STATUS_L1_6 0x3C
75#define APPL_INTR_STATUS_L1_7 0x4083#define APPL_INTR_STATUS_L1_7 0x40
84#define APPL_INTR_STATUS_L1_15_CFG_BME_CHGED BIT(1)
76 85
77#define APPL_INTR_EN_L1_8_0 0x4486#define APPL_INTR_EN_L1_8_0 0x44
78#define APPL_INTR_EN_L1_8_BW_MGT_INT_EN BIT(2)87#define APPL_INTR_EN_L1_8_BW_MGT_INT_EN BIT(2)
@@ -103,8 +112,12 @@ · 24 unmodified lines
103#define APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMP_ERR BIT(1)112#define APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMP_ERR BIT(1)
104#define APPL_INTR_STATUS_L1_18_CDM_REG_CHK_LOGIC_ERR BIT(0)113#define APPL_INTR_STATUS_L1_18_CDM_REG_CHK_LOGIC_ERR BIT(0)
105 114
115#define APPL_MSI_CTRL_1 0xAC
116
106#define APPL_MSI_CTRL_2 0xB0117#define APPL_MSI_CTRL_2 0xB0
107 118
119#define APPL_LEGACY_INTX 0xB8
120
108#define APPL_LTR_MSG_1 0xC4121#define APPL_LTR_MSG_1 0xC4
109#define LTR_MSG_REQ BIT(15)122#define LTR_MSG_REQ BIT(15)
110#define LTR_MST_NO_SNOOP_SHIFT 16123#define LTR_MST_NO_SNOOP_SHIFT 16
@@ -205,6 +218,13 @@ · 94 unmodified lines
205#define AMBA_ERROR_RESPONSE_CRS_OKAY_FFFFFFFF 1218#define AMBA_ERROR_RESPONSE_CRS_OKAY_FFFFFFFF 1
206#define AMBA_ERROR_RESPONSE_CRS_OKAY_FFFF0001 2219#define AMBA_ERROR_RESPONSE_CRS_OKAY_FFFF0001 2
207 220
221#define MSIX_ADDR_MATCH_LOW_OFF 0x940
222#define MSIX_ADDR_MATCH_LOW_OFF_EN BIT(0)
223#define MSIX_ADDR_MATCH_LOW_OFF_MASK GENMASK(31, 2)
224
225#define MSIX_ADDR_MATCH_HIGH_OFF 0x944
226#define MSIX_ADDR_MATCH_HIGH_OFF_MASK GENMASK(31, 0)
227
208#define PORT_LOGIC_MSIX_DOORBELL 0x948228#define PORT_LOGIC_MSIX_DOORBELL 0x948
209 229
210#define CAP_SPCIE_CAP_OFF 0x154230#define CAP_SPCIE_CAP_OFF 0x154
@@ -223,6 +243,13 @@ · 12 unmodified lines
223#define GEN3_CORE_CLK_FREQ 250000000243#define GEN3_CORE_CLK_FREQ 250000000
224#define GEN4_CORE_CLK_FREQ 500000000244#define GEN4_CORE_CLK_FREQ 500000000
225 245
246#define LTR_MSG_TIMEOUT (100 * 1000)
247
248#define PERST_DEBOUNCE_TIME (5 * 1000)
249
250#define EP_STATE_DISABLED 0
251#define EP_STATE_ENABLED 1
252
226static const unsigned int pcie_gen_freq[] = {253static const unsigned int pcie_gen_freq[] = {
227 GEN1_CORE_CLK_FREQ,254 GEN1_CORE_CLK_FREQ,
228 GEN2_CORE_CLK_FREQ,255 GEN2_CORE_CLK_FREQ,
@@ -260,6 +287,8 @@ struct tegra_pcie_dw { · 31 unmodified lines
260 struct dw_pcie pci;287 struct dw_pcie pci;
261 struct tegra_bpmp *bpmp;288 struct tegra_bpmp *bpmp;
262 289
290 enum dw_pcie_device_mode mode;
291
263 bool supports_clkreq;292 bool supports_clkreq;
264 bool enable_cdm_check;293 bool enable_cdm_check;
265 bool link_state;294 bool link_state;
@@ -283,6 +312,16 @@ struct tegra_pcie_dw { · 17 unmodified lines
283 struct phy **phys;312 struct phy **phys;
284 313
285 struct dentry *debugfs;314 struct dentry *debugfs;
315
316 /* Endpoint mode specific */
317 struct gpio_desc *pex_rst_gpiod;
318 struct gpio_desc *pex_refclk_sel_gpiod;
319 unsigned int pex_rst_irq;
320 int ep_state;
321};
322
323struct tegra_pcie_dw_of_data {
324 enum dw_pcie_device_mode mode;
286};325};
287 326
288static inline struct tegra_pcie_dw *to_tegra_pcie(struct dw_pcie *pci)327static inline struct tegra_pcie_dw *to_tegra_pcie(struct dw_pcie *pci)
@@ -339,8 +378,9 @@ static void apply_bad_link_workaround(struct pcie_port *pp) · 50 unmodified lines
339 }378 }
340}379}
341 380
342static irqreturn_t tegra_pcie_rp_irq_handler(struct tegra_pcie_dw *pcie)381static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg)
343{382{
383 struct tegra_pcie_dw *pcie = arg;
344 struct dw_pcie *pci = &pcie->pci;384 struct dw_pcie *pci = &pcie->pci;
345 struct pcie_port *pp = &pci->pp;385 struct pcie_port *pp = &pci->pp;
346 u32 val, tmp;386 u32 val, tmp;
@@ -411,11 +451,121 @@ static irqreturn_t tegra_pcie_rp_irq_handler(struct tegra_pcie_dw *pcie) · 64 unmodified lines
411 return IRQ_HANDLED;451 return IRQ_HANDLED;
412}452}
413 453
414static irqreturn_t tegra_pcie_irq_handler(int irq, void *arg)454static void pex_ep_event_hot_rst_done(struct tegra_pcie_dw *pcie)
455{
456 u32 val;
457
458 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L0);
459 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_0_0);
460 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_1);
461 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_2);
462 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_3);
463 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_6);
464 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_7);
465 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_8_0);
466 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_9);
467 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_10);
468 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_11);
469 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_13);
470 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_14);
471 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_15);
472 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_17);
473 appl_writel(pcie, 0xFFFFFFFF, APPL_MSI_CTRL_2);
474
475 val = appl_readl(pcie, APPL_CTRL);
476 val |= APPL_CTRL_LTSSM_EN;
477 appl_writel(pcie, val, APPL_CTRL);
478}
479
480static irqreturn_t tegra_pcie_ep_irq_thread(int irq, void *arg)
415{481{
416 struct tegra_pcie_dw *pcie = arg;482 struct tegra_pcie_dw *pcie = arg;
483 struct dw_pcie *pci = &pcie->pci;
484 u32 val, speed;
485
486 speed = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA) &
487 PCI_EXP_LNKSTA_CLS;
488 clk_set_rate(pcie->core_clk, pcie_gen_freq[speed - 1]);
417 489
418 return tegra_pcie_rp_irq_handler(pcie);490 /* If EP doesn't advertise L1SS, just return */
491 val = dw_pcie_readl_dbi(pci, pcie->cfg_link_cap_l1sub);
492 if (!(val & (PCI_L1SS_CAP_ASPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_2)))
493 return IRQ_HANDLED;
494
495 /* Check if BME is set to '1' */
496 val = dw_pcie_readl_dbi(pci, PCI_COMMAND);
497 if (val & PCI_COMMAND_MASTER) {
498 ktime_t timeout;
499
500 /* 110us for both snoop and no-snoop */
501 val = 110 | (2 << PCI_LTR_SCALE_SHIFT) | LTR_MSG_REQ;
502 val |= (val << LTR_MST_NO_SNOOP_SHIFT);
503 appl_writel(pcie, val, APPL_LTR_MSG_1);
504
505 /* Send LTR upstream */
506 val = appl_readl(pcie, APPL_LTR_MSG_2);
507 val |= APPL_LTR_MSG_2_LTR_MSG_REQ_STATE;
508 appl_writel(pcie, val, APPL_LTR_MSG_2);
509
510 timeout = ktime_add_us(ktime_get(), LTR_MSG_TIMEOUT);
511 for (;;) {
512 val = appl_readl(pcie, APPL_LTR_MSG_2);
513 if (!(val & APPL_LTR_MSG_2_LTR_MSG_REQ_STATE))
514 break;
515 if (ktime_after(ktime_get(), timeout))
516 break;
517 usleep_range(1000, 1100);
518 }
519 if (val & APPL_LTR_MSG_2_LTR_MSG_REQ_STATE)
520 dev_err(pcie->dev, "Failed to send LTR message\n");
521 }
522
523 return IRQ_HANDLED;
524}
525
526static irqreturn_t tegra_pcie_ep_hard_irq(int irq, void *arg)
527{
528 struct tegra_pcie_dw *pcie = arg;
529 struct dw_pcie_ep *ep = &pcie->pci.ep;
530 int spurious = 1;
531 u32 val, tmp;
532
533 val = appl_readl(pcie, APPL_INTR_STATUS_L0);
534 if (val & APPL_INTR_STATUS_L0_LINK_STATE_INT) {
535 val = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0);
536 appl_writel(pcie, val, APPL_INTR_STATUS_L1_0_0);
537
538 if (val & APPL_INTR_STATUS_L1_0_0_HOT_RESET_DONE)
539 pex_ep_event_hot_rst_done(pcie);
540
541 if (val & APPL_INTR_STATUS_L1_0_0_RDLH_LINK_UP_CHGED) {
542 tmp = appl_readl(pcie, APPL_LINK_STATUS);
543 if (tmp & APPL_LINK_STATUS_RDLH_LINK_UP) {
544 dev_dbg(pcie->dev, "Link is up with Host\n");
545 dw_pcie_ep_linkup(ep);
546 }
547 }
548
549 spurious = 0;
550 }
551
552 if (val & APPL_INTR_STATUS_L0_PCI_CMD_EN_INT) {
553 val = appl_readl(pcie, APPL_INTR_STATUS_L1_15);
554 appl_writel(pcie, val, APPL_INTR_STATUS_L1_15);
555
556 if (val & APPL_INTR_STATUS_L1_15_CFG_BME_CHGED)
557 return IRQ_WAKE_THREAD;
558
559 spurious = 0;
560 }
561
562 if (spurious) {
563 dev_warn(pcie->dev, "Random interrupt (STATUS = 0x%08X)\n",
564 val);
565 appl_writel(pcie, val, APPL_INTR_STATUS_L0);
566 }
567
568 return IRQ_HANDLED;
419}569}
420 570
421static int tegra_pcie_dw_rd_own_conf(struct pcie_port *pp, int where, int size,571static int tegra_pcie_dw_rd_own_conf(struct pcie_port *pp, int where, int size,
@@ -884,8 +1034,26 @@ static void tegra_pcie_set_msi_vec_num(struct pcie_port *pp) · 462 unmodified lines
884 pp->num_vectors = MAX_MSI_IRQS;1034 pp->num_vectors = MAX_MSI_IRQS;
885}1035}
886 1036
1037static int tegra_pcie_dw_start_link(struct dw_pcie *pci)
1038{
1039 struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
1040
1041 enable_irq(pcie->pex_rst_irq);
1042
1043 return 0;
1044}
1045
1046static void tegra_pcie_dw_stop_link(struct dw_pcie *pci)
1047{
1048 struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
1049
1050 disable_irq(pcie->pex_rst_irq);
1051}
1052
887static const struct dw_pcie_ops tegra_dw_pcie_ops = {1053static const struct dw_pcie_ops tegra_dw_pcie_ops = {
888 .link_up = tegra_pcie_dw_link_up,1054 .link_up = tegra_pcie_dw_link_up,
1055 .start_link = tegra_pcie_dw_start_link,
1056 .stop_link = tegra_pcie_dw_stop_link,
889};1057};
890 1058
891static struct dw_pcie_host_ops tegra_pcie_dw_host_ops = {1059static struct dw_pcie_host_ops tegra_pcie_dw_host_ops = {
@@ -986,6 +1154,40 @@ static int tegra_pcie_dw_parse_dt(struct tegra_pcie_dw *pcie) · 94 unmodified lines
986 pcie->enable_cdm_check =1154 pcie->enable_cdm_check =
987 of_property_read_bool(np, "snps,enable-cdm-check");1155 of_property_read_bool(np, "snps,enable-cdm-check");
988 1156
1157 if (pcie->mode == DW_PCIE_RC_TYPE)
1158 return 0;
1159
1160 /* Endpoint mode specific DT entries */
1161 pcie->pex_rst_gpiod = devm_gpiod_get(pcie->dev, "reset", GPIOD_IN);
1162 if (IS_ERR(pcie->pex_rst_gpiod)) {
1163 int err = PTR_ERR(pcie->pex_rst_gpiod);
1164 const char *level = KERN_ERR;
1165
1166 if (err == -EPROBE_DEFER)
1167 level = KERN_DEBUG;
1168
1169 dev_printk(level, pcie->dev,
1170 dev_fmt("Failed to get PERST GPIO: %d\n"),
1171 err);
1172 return err;
1173 }
1174
1175 pcie->pex_refclk_sel_gpiod = devm_gpiod_get(pcie->dev,
1176 "nvidia,refclk-select",
1177 GPIOD_OUT_HIGH);
1178 if (IS_ERR(pcie->pex_refclk_sel_gpiod)) {
1179 int err = PTR_ERR(pcie->pex_refclk_sel_gpiod);
1180 const char *level = KERN_ERR;
1181
1182 if (err == -EPROBE_DEFER)
1183 level = KERN_DEBUG;
1184
1185 dev_printk(level, pcie->dev,
1186 dev_fmt("Failed to get REFCLK select GPIOs: %d\n"),
1187 err);
1188 pcie->pex_refclk_sel_gpiod = NULL;
1189 }
1190
989 return 0;1191 return 0;
990}1192}
991 1193
@@ -1017,6 +1219,34 @@ static int tegra_pcie_bpmp_set_ctrl_state(struct tegra_pcie_dw *pcie, · 25 unmodified lines
1017 return tegra_bpmp_transfer(pcie->bpmp, &msg);1219 return tegra_bpmp_transfer(pcie->bpmp, &msg);
1018}1220}
1019 1221
1222static int tegra_pcie_bpmp_set_pll_state(struct tegra_pcie_dw *pcie,
1223 bool enable)
1224{
1225 struct mrq_uphy_response resp;
1226 struct tegra_bpmp_message msg;
1227 struct mrq_uphy_request req;
1228
1229 memset(&req, 0, sizeof(req));
1230 memset(&resp, 0, sizeof(resp));
1231
1232 if (enable) {
1233 req.cmd = CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT;
1234 req.ep_ctrlr_pll_init.ep_controller = pcie->cid;
1235 } else {
1236 req.cmd = CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF;
1237 req.ep_ctrlr_pll_off.ep_controller = pcie->cid;
1238 }
1239
1240 memset(&msg, 0, sizeof(msg));
1241 msg.mrq = MRQ_UPHY;
1242 msg.tx.data = &req;
1243 msg.tx.size = sizeof(req);
1244 msg.rx.data = &resp;
1245 msg.rx.size = sizeof(resp);
1246
1247 return tegra_bpmp_transfer(pcie->bpmp, &msg);
1248}
1249
1020static void tegra_pcie_downstream_dev_to_D0(struct tegra_pcie_dw *pcie)1250static void tegra_pcie_downstream_dev_to_D0(struct tegra_pcie_dw *pcie)
1021{1251{
1022 struct pcie_port *pp = &pcie->pci.pp;1252 struct pcie_port *pp = &pcie->pci.pp;
@@ -1427,8 +1657,396 @@ fail_pm_get_sync: · 404 unmodified lines
1427 return ret;1657 return ret;
1428}1658}
1429 1659
1660static void pex_ep_event_pex_rst_assert(struct tegra_pcie_dw *pcie)
1661{
1662 u32 val;
1663 int ret;
1664
1665 if (pcie->ep_state == EP_STATE_DISABLED)
1666 return;
1667
1668 /* Disable LTSSM */
1669 val = appl_readl(pcie, APPL_CTRL);
1670 val &= ~APPL_CTRL_LTSSM_EN;
1671 appl_writel(pcie, val, APPL_CTRL);
1672
1673 ret = readl_poll_timeout(pcie->appl_base + APPL_DEBUG, val,
1674 ((val & APPL_DEBUG_LTSSM_STATE_MASK) >>
1675 APPL_DEBUG_LTSSM_STATE_SHIFT) ==
1676 LTSSM_STATE_PRE_DETECT,
1677 1, LTSSM_TIMEOUT);
1678 if (ret)
1679 dev_err(pcie->dev, "Failed to go Detect state: %d\n", ret);
1680
1681 reset_control_assert(pcie->core_rst);
1682
1683 tegra_pcie_disable_phy(pcie);
1684
1685 reset_control_assert(pcie->core_apb_rst);
1686
1687 clk_disable_unprepare(pcie->core_clk);
1688
1689 pm_runtime_put_sync(pcie->dev);
1690
1691 ret = tegra_pcie_bpmp_set_pll_state(pcie, false);
1692 if (ret)
1693 dev_err(pcie->dev, "Failed to turn off UPHY: %d\n", ret);
1694
1695 pcie->ep_state = EP_STATE_DISABLED;
1696 dev_dbg(pcie->dev, "Uninitialization of endpoint is completed\n");
1697}
1698
1699static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie)
1700{
1701 struct dw_pcie *pci = &pcie->pci;
1702 struct dw_pcie_ep *ep = &pci->ep;
1703 struct device *dev = pcie->dev;
1704 u32 val;
1705 int ret;
1706
1707 if (pcie->ep_state == EP_STATE_ENABLED)
1708 return;
1709
1710 ret = pm_runtime_get_sync(dev);
1711 if (ret < 0) {
1712 dev_err(dev, "Failed to get runtime sync for PCIe dev: %d\n",
1713 ret);
1714 return;
1715 }
1716
1717 ret = tegra_pcie_bpmp_set_pll_state(pcie, true);
1718 if (ret) {
1719 dev_err(dev, "Failed to init UPHY for PCIe EP: %d\n", ret);
1720 goto fail_pll_init;
1721 }
1722
1723 ret = clk_prepare_enable(pcie->core_clk);
1724 if (ret) {
1725 dev_err(dev, "Failed to enable core clock: %d\n", ret);
1726 goto fail_core_clk_enable;
1727 }
1728
1729 ret = reset_control_deassert(pcie->core_apb_rst);
1730 if (ret) {
1731 dev_err(dev, "Failed to deassert core APB reset: %d\n", ret);
1732 goto fail_core_apb_rst;
1733 }
1734
1735 ret = tegra_pcie_enable_phy(pcie);
1736 if (ret) {
1737 dev_err(dev, "Failed to enable PHY: %d\n", ret);
1738 goto fail_phy;
1739 }
1740
1741 /* Clear any stale interrupt statuses */
1742 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L0);
1743 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_0_0);
1744 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_1);
1745 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_2);
1746 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_3);
1747 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_6);
1748 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_7);
1749 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_8_0);
1750 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_9);
1751 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_10);
1752 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_11);
1753 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_13);
1754 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_14);
1755 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_15);
1756 appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_17);
1757
1758 /* configure this core for EP mode operation */
1759 val = appl_readl(pcie, APPL_DM_TYPE);
1760 val &= ~APPL_DM_TYPE_MASK;
1761 val |= APPL_DM_TYPE_EP;
1762 appl_writel(pcie, val, APPL_DM_TYPE);
1763
1764 appl_writel(pcie, 0x0, APPL_CFG_SLCG_OVERRIDE);
1765
1766 val = appl_readl(pcie, APPL_CTRL);
1767 val |= APPL_CTRL_SYS_PRE_DET_STATE;
1768 val |= APPL_CTRL_HW_HOT_RST_EN;
1769 appl_writel(pcie, val, APPL_CTRL);
1770
1771 val = appl_readl(pcie, APPL_CFG_MISC);
1772 val |= APPL_CFG_MISC_SLV_EP_MODE;
1773 val |= (APPL_CFG_MISC_ARCACHE_VAL << APPL_CFG_MISC_ARCACHE_SHIFT);
1774 appl_writel(pcie, val, APPL_CFG_MISC);
1775
1776 val = appl_readl(pcie, APPL_PINMUX);
1777 val |= APPL_PINMUX_CLK_OUTPUT_IN_OVERRIDE_EN;
1778 val |= APPL_PINMUX_CLK_OUTPUT_IN_OVERRIDE;
1779 appl_writel(pcie, val, APPL_PINMUX);
1780
1781 appl_writel(pcie, pcie->dbi_res->start & APPL_CFG_BASE_ADDR_MASK,
1782 APPL_CFG_BASE_ADDR);
1783
1784 appl_writel(pcie, pcie->atu_dma_res->start &
1785 APPL_CFG_IATU_DMA_BASE_ADDR_MASK,
1786 APPL_CFG_IATU_DMA_BASE_ADDR);
1787
1788 val = appl_readl(pcie, APPL_INTR_EN_L0_0);
1789 val |= APPL_INTR_EN_L0_0_SYS_INTR_EN;
1790 val |= APPL_INTR_EN_L0_0_LINK_STATE_INT_EN;
1791 val |= APPL_INTR_EN_L0_0_PCI_CMD_EN_INT_EN;
1792 appl_writel(pcie, val, APPL_INTR_EN_L0_0);
1793
1794 val = appl_readl(pcie, APPL_INTR_EN_L1_0_0);
1795 val |= APPL_INTR_EN_L1_0_0_HOT_RESET_DONE_INT_EN;
1796 val |= APPL_INTR_EN_L1_0_0_RDLH_LINK_UP_INT_EN;
1797 appl_writel(pcie, val, APPL_INTR_EN_L1_0_0);
1798
1799 reset_control_deassert(pcie->core_rst);
1800
1801 if (pcie->update_fc_fixup) {
1802 val = dw_pcie_readl_dbi(pci, CFG_TIMER_CTRL_MAX_FUNC_NUM_OFF);
1803 val |= 0x1 << CFG_TIMER_CTRL_ACK_NAK_SHIFT;
1804 dw_pcie_writel_dbi(pci, CFG_TIMER_CTRL_MAX_FUNC_NUM_OFF, val);
1805 }
1806
1807 config_gen3_gen4_eq_presets(pcie);
1808
1809 init_host_aspm(pcie);
1810
1811 /* Disable ASPM-L1SS advertisement if there is no CLKREQ routing */
1812 if (!pcie->supports_clkreq) {
1813 disable_aspm_l11(pcie);
1814 disable_aspm_l12(pcie);
1815 }
1816
1817 val = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
1818 val &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
1819 dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, val);
1820
1821 /* Configure N_FTS & FTS */
1822 val = dw_pcie_readl_dbi(pci, PORT_LOGIC_ACK_F_ASPM_CTRL);
1823 val &= ~(N_FTS_MASK << N_FTS_SHIFT);
1824 val |= N_FTS_VAL << N_FTS_SHIFT;
1825 dw_pcie_writel_dbi(pci, PORT_LOGIC_ACK_F_ASPM_CTRL, val);
1826
1827 val = dw_pcie_readl_dbi(pci, PORT_LOGIC_GEN2_CTRL);
1828 val &= ~FTS_MASK;
1829 val |= FTS_VAL;
1830 dw_pcie_writel_dbi(pci, PORT_LOGIC_GEN2_CTRL, val);
1831
1832 /* Configure Max Speed from DT */
1833 if (pcie->max_speed && pcie->max_speed != -EINVAL) {
1834 val = dw_pcie_readl_dbi(pci, pcie->pcie_cap_base +
1835 PCI_EXP_LNKCAP);
1836 val &= ~PCI_EXP_LNKCAP_SLS;
1837 val |= pcie->max_speed;
1838 dw_pcie_writel_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP,
1839 val);
1840 }
1841
1842 pcie->pcie_cap_base = dw_pcie_find_capability(&pcie->pci,
1843 PCI_CAP_ID_EXP);
1844 clk_set_rate(pcie->core_clk, GEN4_CORE_CLK_FREQ);
1845
1846 val = (ep->msi_mem_phys & MSIX_ADDR_MATCH_LOW_OFF_MASK);
1847 val |= MSIX_ADDR_MATCH_LOW_OFF_EN;
1848 dw_pcie_writel_dbi(pci, MSIX_ADDR_MATCH_LOW_OFF, val);
1849 val = (lower_32_bits(ep->msi_mem_phys) & MSIX_ADDR_MATCH_HIGH_OFF_MASK);
1850 dw_pcie_writel_dbi(pci, MSIX_ADDR_MATCH_HIGH_OFF, val);
1851
1852 ret = dw_pcie_ep_init_complete(ep);
1853 if (ret) {
1854 dev_err(dev, "Failed to complete initialization: %d\n", ret);
1855 goto fail_init_complete;
1856 }
1857
1858 dw_pcie_ep_init_notify(ep);
1859
1860 /* Enable LTSSM */
1861 val = appl_readl(pcie, APPL_CTRL);
1862 val |= APPL_CTRL_LTSSM_EN;
1863 appl_writel(pcie, val, APPL_CTRL);
1864
1865 pcie->ep_state = EP_STATE_ENABLED;
1866 dev_dbg(dev, "Initialization of endpoint is completed\n");
1867
1868 return;
1869
1870fail_init_complete:
1871 reset_control_assert(pcie->core_rst);
1872 tegra_pcie_disable_phy(pcie);
1873fail_phy:
1874 reset_control_assert(pcie->core_apb_rst);
1875fail_core_apb_rst:
1876 clk_disable_unprepare(pcie->core_clk);
1877fail_core_clk_enable:
1878 tegra_pcie_bpmp_set_pll_state(pcie, false);
1879fail_pll_init:
1880 pm_runtime_put_sync(dev);
1881}
1882
1883static irqreturn_t tegra_pcie_ep_pex_rst_irq(int irq, void *arg)
1884{
1885 struct tegra_pcie_dw *pcie = arg;
1886
1887 if (gpiod_get_value(pcie->pex_rst_gpiod))
1888 pex_ep_event_pex_rst_assert(pcie);
1889 else
1890 pex_ep_event_pex_rst_deassert(pcie);
1891
1892 return IRQ_HANDLED;
1893}
1894
1895static int tegra_pcie_ep_raise_legacy_irq(struct tegra_pcie_dw *pcie, u16 irq)
1896{
1897 /* Tegra194 supports only INTA */
1898 if (irq > 1)
1899 return -EINVAL;
1900
1901 appl_writel(pcie, 1, APPL_LEGACY_INTX);
1902 usleep_range(1000, 2000);
1903 appl_writel(pcie, 0, APPL_LEGACY_INTX);
1904 return 0;
1905}
1906
1907static int tegra_pcie_ep_raise_msi_irq(struct tegra_pcie_dw *pcie, u16 irq)
1908{
1909 if (unlikely(irq > 31))
1910 return -EINVAL;
1911
1912 appl_writel(pcie, (1 << irq), APPL_MSI_CTRL_1);
1913
1914 return 0;
1915}
1916
1917static int tegra_pcie_ep_raise_msix_irq(struct tegra_pcie_dw *pcie, u16 irq)
1918{
1919 struct dw_pcie_ep *ep = &pcie->pci.ep;
1920
1921 writel(irq, ep->msi_mem);
1922
1923 return 0;
1924}
1925
1926static int tegra_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
1927 enum pci_epc_irq_type type,
1928 u16 interrupt_num)
1929{
1930 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
1931 struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
1932
1933 switch (type) {
1934 case PCI_EPC_IRQ_LEGACY:
1935 return tegra_pcie_ep_raise_legacy_irq(pcie, interrupt_num);
1936
1937 case PCI_EPC_IRQ_MSI:
1938 return tegra_pcie_ep_raise_msi_irq(pcie, interrupt_num);
1939
1940 case PCI_EPC_IRQ_MSIX:
1941 return tegra_pcie_ep_raise_msix_irq(pcie, interrupt_num);
1942
1943 default:
1944 dev_err(pci->dev, "Unknown IRQ type\n");
1945 return -EPERM;
1946 }
1947
1948 return 0;
1949}
1950
1951static const struct pci_epc_features tegra_pcie_epc_features = {
1952 .linkup_notifier = true,
1953 .core_init_notifier = true,
1954 .msi_capable = false,
1955 .msix_capable = false,
1956 .reserved_bar = 1 << BAR_2 | 1 << BAR_3 | 1 << BAR_4 | 1 << BAR_5,
1957 .bar_fixed_64bit = 1 << BAR_0,
1958 .bar_fixed_size[0] = SZ_1M,
1959};
1960
1961static const struct pci_epc_features*
1962tegra_pcie_ep_get_features(struct dw_pcie_ep *ep)
1963{
1964 return &tegra_pcie_epc_features;
1965}
1966
1967static struct dw_pcie_ep_ops pcie_ep_ops = {
1968 .raise_irq = tegra_pcie_ep_raise_irq,
1969 .get_features = tegra_pcie_ep_get_features,
1970};
1971
1972static int tegra_pcie_config_ep(struct tegra_pcie_dw *pcie,
1973 struct platform_device *pdev)
1974{
1975 struct dw_pcie *pci = &pcie->pci;
1976 struct device *dev = pcie->dev;
1977 struct dw_pcie_ep *ep;
1978 struct resource *res;
1979 char *name;
1980 int ret;
1981
1982 ep = &pci->ep;
1983 ep->ops = &pcie_ep_ops;
1984
1985 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
1986 if (!res)
1987 return -EINVAL;
1988
1989 ep->phys_base = res->start;
1990 ep->addr_size = resource_size(res);
1991 ep->page_size = SZ_64K;
1992
1993 ret = gpiod_set_debounce(pcie->pex_rst_gpiod, PERST_DEBOUNCE_TIME);
1994 if (ret < 0) {
1995 dev_err(dev, "Failed to set PERST GPIO debounce time: %d\n",
1996 ret);
1997 return ret;
1998 }
1999
2000 ret = gpiod_to_irq(pcie->pex_rst_gpiod);
2001 if (ret < 0) {
2002 dev_err(dev, "Failed to get IRQ for PERST GPIO: %d\n", ret);
2003 return ret;
2004 }
2005 pcie->pex_rst_irq = (unsigned int)ret;
2006
2007 name = devm_kasprintf(dev, GFP_KERNEL, "tegra_pcie_%u_pex_rst_irq",
2008 pcie->cid);
2009 if (!name) {
2010 dev_err(dev, "Failed to create PERST IRQ string\n");
2011 return -ENOMEM;
2012 }
2013
2014 irq_set_status_flags(pcie->pex_rst_irq, IRQ_NOAUTOEN);
2015
2016 pcie->ep_state = EP_STATE_DISABLED;
2017
2018 ret = devm_request_threaded_irq(dev, pcie->pex_rst_irq, NULL,
2019 tegra_pcie_ep_pex_rst_irq,
2020 IRQF_TRIGGER_RISING |
2021 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2022 name, (void *)pcie);
2023 if (ret < 0) {
2024 dev_err(dev, "Failed to request IRQ for PERST: %d\n", ret);
2025 return ret;
2026 }
2027
2028 name = devm_kasprintf(dev, GFP_KERNEL, "tegra_pcie_%u_ep_work",
2029 pcie->cid);
2030 if (!name) {
2031 dev_err(dev, "Failed to create PCIe EP work thread string\n");
2032 return -ENOMEM;
2033 }
2034
2035 pm_runtime_enable(dev);
2036
2037 ret = dw_pcie_ep_init(ep);
2038 if (ret) {
2039 dev_err(dev, "Failed to initialize DWC Endpoint subsystem: %d\n",
2040 ret);
2041 return ret;
2042 }
2043
2044 return 0;
2045}
2046
1430static int tegra_pcie_dw_probe(struct platform_device *pdev)2047static int tegra_pcie_dw_probe(struct platform_device *pdev)
1431{2048{
2049 const struct tegra_pcie_dw_of_data *data;
1432 struct device *dev = &pdev->dev;2050 struct device *dev = &pdev->dev;
1433 struct resource *atu_dma_res;2051 struct resource *atu_dma_res;
1434 struct tegra_pcie_dw *pcie;2052 struct tegra_pcie_dw *pcie;
@@ -1440,6 +2058,8 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev) · 5 unmodified lines
1440 int ret;2058 int ret;
1441 u32 i;2059 u32 i;
1442 2060
2061 data = of_device_get_match_data(dev);
2062
1443 pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);2063 pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
1444 if (!pcie)2064 if (!pcie)
1445 return -ENOMEM;2065 return -ENOMEM;
@@ -1449,19 +2069,37 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev) · 3 unmodified lines
1449 pci->ops = &tegra_dw_pcie_ops;2069 pci->ops = &tegra_dw_pcie_ops;
1450 pp = &pci->pp;2070 pp = &pci->pp;
1451 pcie->dev = &pdev->dev;2071 pcie->dev = &pdev->dev;
2072 pcie->mode = (enum dw_pcie_device_mode)data->mode;
1452 2073
1453 ret = tegra_pcie_dw_parse_dt(pcie);2074 ret = tegra_pcie_dw_parse_dt(pcie);
1454 if (ret < 0) {2075 if (ret < 0) {
1455 dev_err(dev, "Failed to parse device tree: %d\n", ret);2076 const char *level = KERN_ERR;
2077
2078 if (ret == -EPROBE_DEFER)
2079 level = KERN_DEBUG;
2080
2081 dev_printk(level, dev,
2082 dev_fmt("Failed to parse device tree: %d\n"),
2083 ret);
1456 return ret;2084 return ret;
1457 }2085 }
1458 2086
1459 ret = tegra_pcie_get_slot_regulators(pcie);2087 ret = tegra_pcie_get_slot_regulators(pcie);
1460 if (ret < 0) {2088 if (ret < 0) {
1461 dev_err(dev, "Failed to get slot regulators: %d\n", ret);2089 const char *level = KERN_ERR;
2090
2091 if (ret == -EPROBE_DEFER)
2092 level = KERN_DEBUG;
2093
2094 dev_printk(level, dev,
2095 dev_fmt("Failed to get slot regulators: %d\n"),
2096 ret);
1462 return ret;2097 return ret;
1463 }2098 }
1464 2099
2100 if (pcie->pex_refclk_sel_gpiod)
2101 gpiod_set_value(pcie->pex_refclk_sel_gpiod, 1);
2102
1465 pcie->pex_ctl_supply = devm_regulator_get(dev, "vddio-pex-ctl");2103 pcie->pex_ctl_supply = devm_regulator_get(dev, "vddio-pex-ctl");
1466 if (IS_ERR(pcie->pex_ctl_supply)) {2104 if (IS_ERR(pcie->pex_ctl_supply)) {
1467 ret = PTR_ERR(pcie->pex_ctl_supply);2105 ret = PTR_ERR(pcie->pex_ctl_supply);
@@ -1557,24 +2195,49 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev) · 89 unmodified lines
1557 return -ENODEV;2195 return -ENODEV;
1558 }2196 }
1559 2197
1560 ret = devm_request_irq(dev, pp->irq, tegra_pcie_irq_handler,
1561 IRQF_SHARED, "tegra-pcie-intr", pcie);
1562 if (ret) {
1563 dev_err(dev, "Failed to request IRQ %d: %d\n", pp->irq, ret);
1564 return ret;
1565 }
1566
1567 pcie->bpmp = tegra_bpmp_get(dev);2198 pcie->bpmp = tegra_bpmp_get(dev);
1568 if (IS_ERR(pcie->bpmp))2199 if (IS_ERR(pcie->bpmp))
1569 return PTR_ERR(pcie->bpmp);2200 return PTR_ERR(pcie->bpmp);
1570 2201
1571 platform_set_drvdata(pdev, pcie);2202 platform_set_drvdata(pdev, pcie);
1572 2203
1573 ret = tegra_pcie_config_rp(pcie);2204 switch (pcie->mode) {
1574 if (ret && ret != -ENOMEDIUM)2205 case DW_PCIE_RC_TYPE:
1575 goto fail;2206 ret = devm_request_irq(dev, pp->irq, tegra_pcie_rp_irq_handler,
1576 else2207 IRQF_SHARED, "tegra-pcie-intr", pcie);
1577 return 0;2208 if (ret) {
2209 dev_err(dev, "Failed to request IRQ %d: %d\n", pp->irq,
2210 ret);
2211 goto fail;
2212 }
2213
2214 ret = tegra_pcie_config_rp(pcie);
2215 if (ret && ret != -ENOMEDIUM)
2216 goto fail;
2217 else
2218 return 0;
2219 break;
2220
2221 case DW_PCIE_EP_TYPE:
2222 ret = devm_request_threaded_irq(dev, pp->irq,
2223 tegra_pcie_ep_hard_irq,
2224 tegra_pcie_ep_irq_thread,
2225 IRQF_SHARED | IRQF_ONESHOT,
2226 "tegra-pcie-ep-intr", pcie);
2227 if (ret) {
2228 dev_err(dev, "Failed to request IRQ %d: %d\n", pp->irq,
2229 ret);
2230 goto fail;
2231 }
2232
2233 ret = tegra_pcie_config_ep(pcie, pdev);
2234 if (ret < 0)
2235 goto fail;
2236 break;
2237
2238 default:
2239 dev_err(dev, "Invalid PCIe device type %d\n", pcie->mode);
2240 }
1578 2241
1579fail:2242fail:
1580 tegra_bpmp_put(pcie->bpmp);2243 tegra_bpmp_put(pcie->bpmp);
@@ -1593,6 +2256,8 @@ static int tegra_pcie_dw_remove(struct platform_device *pdev) · 12 unmodified lines
1593 pm_runtime_put_sync(pcie->dev);2256 pm_runtime_put_sync(pcie->dev);
1594 pm_runtime_disable(pcie->dev);2257 pm_runtime_disable(pcie->dev);
1595 tegra_bpmp_put(pcie->bpmp);2258 tegra_bpmp_put(pcie->bpmp);
2259 if (pcie->pex_refclk_sel_gpiod)
2260 gpiod_set_value(pcie->pex_refclk_sel_gpiod, 0);
1596 2261
1597 return 0;2262 return 0;
1598}2263}
@@ -1697,9 +2362,22 @@ static void tegra_pcie_dw_shutdown(struct platform_device *pdev) · 98 unmodified lines
1697 __deinit_controller(pcie);2362 __deinit_controller(pcie);
1698}2363}
1699 2364
2365static const struct tegra_pcie_dw_of_data tegra_pcie_dw_rc_of_data = {
2366 .mode = DW_PCIE_RC_TYPE,
2367};
2368
2369static const struct tegra_pcie_dw_of_data tegra_pcie_dw_ep_of_data = {
2370 .mode = DW_PCIE_EP_TYPE,
2371};
2372
1700static const struct of_device_id tegra_pcie_dw_of_match[] = {2373static const struct of_device_id tegra_pcie_dw_of_match[] = {
1701 {2374 {
1702 .compatible = "nvidia,tegra194-pcie",2375 .compatible = "nvidia,tegra194-pcie",
2376 .data = &tegra_pcie_dw_rc_of_data,
2377 },
2378 {
2379 .compatible = "nvidia,tegra194-pcie-ep",
2380 .data = &tegra_pcie_dw_ep_of_data,
1703 },2381 },
1704 {},2382 {},
1705};2383};
drivers/pci/endpoint/functions/pci-epf-test.c+356−46
@@ -8,6 +8,7 @@ · 7 unmodified lines
8 8
9#include <linux/crc32.h>9#include <linux/crc32.h>
10#include <linux/delay.h>10#include <linux/delay.h>
11#include <linux/dmaengine.h>
11#include <linux/io.h>12#include <linux/io.h>
12#include <linux/module.h>13#include <linux/module.h>
13#include <linux/slab.h>14#include <linux/slab.h>
@@ -39,6 +40,8 @@ · 25 unmodified lines
39#define STATUS_SRC_ADDR_INVALID BIT(7)40#define STATUS_SRC_ADDR_INVALID BIT(7)
40#define STATUS_DST_ADDR_INVALID BIT(8)41#define STATUS_DST_ADDR_INVALID BIT(8)
41 42
43#define FLAG_USE_DMA BIT(0)
44
42#define TIMER_RESOLUTION 145#define TIMER_RESOLUTION 1
43 46
44static struct workqueue_struct *kpcitest_workqueue;47static struct workqueue_struct *kpcitest_workqueue;
@@ -47,7 +50,11 @@ struct pci_epf_test { · 2 unmodified lines
47 void *reg[PCI_STD_NUM_BARS];50 void *reg[PCI_STD_NUM_BARS];
48 struct pci_epf *epf;51 struct pci_epf *epf;
49 enum pci_barno test_reg_bar;52 enum pci_barno test_reg_bar;
53 size_t msix_table_offset;
50 struct delayed_work cmd_handler;54 struct delayed_work cmd_handler;
55 struct dma_chan *dma_chan;
56 struct completion transfer_complete;
57 bool dma_supported;
51 const struct pci_epc_features *epc_features;58 const struct pci_epc_features *epc_features;
52};59};
53 60
@@ -61,6 +68,7 @@ struct pci_epf_test_reg { · 7 unmodified lines
61 u32 checksum;68 u32 checksum;
62 u32 irq_type;69 u32 irq_type;
63 u32 irq_number;70 u32 irq_number;
71 u32 flags;
64} __packed;72} __packed;
65 73
66static struct pci_epf_header test_header = {74static struct pci_epf_header test_header = {
@@ -72,13 +80,156 @@ static struct pci_epf_header test_header = { · 5 unmodified lines
72 80
73static size_t bar_size[] = { 512, 512, 1024, 16384, 131072, 1048576 };81static size_t bar_size[] = { 512, 512, 1024, 16384, 131072, 1048576 };
74 82
83static void pci_epf_test_dma_callback(void *param)
84{
85 struct pci_epf_test *epf_test = param;
86
87 complete(&epf_test->transfer_complete);
88}
89
90/**
91 * pci_epf_test_data_transfer() - Function that uses dmaengine API to transfer
92 * data between PCIe EP and remote PCIe RC
93 * @epf_test: the EPF test device that performs the data transfer operation
94 * @dma_dst: The destination address of the data transfer. It can be a physical
95 * address given by pci_epc_mem_alloc_addr or DMA mapping APIs.
96 * @dma_src: The source address of the data transfer. It can be a physical
97 * address given by pci_epc_mem_alloc_addr or DMA mapping APIs.
98 * @len: The size of the data transfer
99 *
100 * Function that uses dmaengine API to transfer data between PCIe EP and remote
101 * PCIe RC. The source and destination address can be a physical address given
102 * by pci_epc_mem_alloc_addr or the one obtained using DMA mapping APIs.
103 *
104 * The function returns '0' on success and negative value on failure.
105 */
106static int pci_epf_test_data_transfer(struct pci_epf_test *epf_test,
107 dma_addr_t dma_dst, dma_addr_t dma_src,
108 size_t len)
109{
110 enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
111 struct dma_chan *chan = epf_test->dma_chan;
112 struct pci_epf *epf = epf_test->epf;
113 struct dma_async_tx_descriptor *tx;
114 struct device *dev = &epf->dev;
115 dma_cookie_t cookie;
116 int ret;
117
118 if (IS_ERR_OR_NULL(chan)) {
119 dev_err(dev, "Invalid DMA memcpy channel\n");
120 return -EINVAL;
121 }
122
123 tx = dmaengine_prep_dma_memcpy(chan, dma_dst, dma_src, len, flags);
124 if (!tx) {
125 dev_err(dev, "Failed to prepare DMA memcpy\n");
126 return -EIO;
127 }
128
129 tx->callback = pci_epf_test_dma_callback;
130 tx->callback_param = epf_test;
131 cookie = tx->tx_submit(tx);
132 reinit_completion(&epf_test->transfer_complete);
133
134 ret = dma_submit_error(cookie);
135 if (ret) {
136 dev_err(dev, "Failed to do DMA tx_submit %d\n", cookie);
137 return -EIO;
138 }
139
140 dma_async_issue_pending(chan);
141 ret = wait_for_completion_interruptible(&epf_test->transfer_complete);
142 if (ret < 0) {
143 dmaengine_terminate_sync(chan);
144 dev_err(dev, "DMA wait_for_completion_timeout\n");
145 return -ETIMEDOUT;
146 }
147
148 return 0;
149}
150
151/**
152 * pci_epf_test_init_dma_chan() - Function to initialize EPF test DMA channel
153 * @epf_test: the EPF test device that performs data transfer operation
154 *
155 * Function to initialize EPF test DMA channel.
156 */
157static int pci_epf_test_init_dma_chan(struct pci_epf_test *epf_test)
158{
159 struct pci_epf *epf = epf_test->epf;
160 struct device *dev = &epf->dev;
161 struct dma_chan *dma_chan;
162 dma_cap_mask_t mask;
163 int ret;
164
165 dma_cap_zero(mask);
166 dma_cap_set(DMA_MEMCPY, mask);
167
168 dma_chan = dma_request_chan_by_mask(&mask);
169 if (IS_ERR(dma_chan)) {
170 ret = PTR_ERR(dma_chan);
171 if (ret != -EPROBE_DEFER)
172 dev_err(dev, "Failed to get DMA channel\n");
173 return ret;
174 }
175 init_completion(&epf_test->transfer_complete);
176
177 epf_test->dma_chan = dma_chan;
178
179 return 0;
180}
181
182/**
183 * pci_epf_test_clean_dma_chan() - Function to cleanup EPF test DMA channel
184 * @epf: the EPF test device that performs data transfer operation
185 *
186 * Helper to cleanup EPF test DMA channel.
187 */
188static void pci_epf_test_clean_dma_chan(struct pci_epf_test *epf_test)
189{
190 dma_release_channel(epf_test->dma_chan);
191 epf_test->dma_chan = NULL;
192}
193
194static void pci_epf_test_print_rate(const char *ops, u64 size,
195 struct timespec64 *start,
196 struct timespec64 *end, bool dma)
197{
198 struct timespec64 ts;
199 u64 rate, ns;
200
201 ts = timespec64_sub(*end, *start);
202
203 /* convert both size (stored in 'rate') and time in terms of 'ns' */
204 ns = timespec64_to_ns(&ts);
205 rate = size * NSEC_PER_SEC;
206
207 /* Divide both size (stored in 'rate') and ns by a common factor */
208 while (ns > UINT_MAX) {
209 rate >>= 1;
210 ns >>= 1;
211 }
212
213 if (!ns)
214 return;
215
216 /* calculate the rate */
217 do_div(rate, (uint32_t)ns);
218
219 pr_info("\n%s => Size: %llu bytes\t DMA: %s\t Time: %llu.%09u seconds\t"
220 "Rate: %llu KB/s\n", ops, size, dma ? "YES" : "NO",
221 (u64)ts.tv_sec, (u32)ts.tv_nsec, rate / 1024);
222}
223
75static int pci_epf_test_copy(struct pci_epf_test *epf_test)224static int pci_epf_test_copy(struct pci_epf_test *epf_test)
76{225{
77 int ret;226 int ret;
227 bool use_dma;
78 void __iomem *src_addr;228 void __iomem *src_addr;
79 void __iomem *dst_addr;229 void __iomem *dst_addr;
80 phys_addr_t src_phys_addr;230 phys_addr_t src_phys_addr;
81 phys_addr_t dst_phys_addr;231 phys_addr_t dst_phys_addr;
232 struct timespec64 start, end;
82 struct pci_epf *epf = epf_test->epf;233 struct pci_epf *epf = epf_test->epf;
83 struct device *dev = &epf->dev;234 struct device *dev = &epf->dev;
84 struct pci_epc *epc = epf->epc;235 struct pci_epc *epc = epf->epc;
@@ -117,8 +268,26 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) · 32 unmodified lines
117 goto err_dst_addr;268 goto err_dst_addr;
118 }269 }
119 270
120 memcpy(dst_addr, src_addr, reg->size);271 ktime_get_ts64(&start);
272 use_dma = !!(reg->flags & FLAG_USE_DMA);
273 if (use_dma) {
274 if (!epf_test->dma_supported) {
275 dev_err(dev, "Cannot transfer data using DMA\n");
276 ret = -EINVAL;
277 goto err_map_addr;
278 }
279
280 ret = pci_epf_test_data_transfer(epf_test, dst_phys_addr,
281 src_phys_addr, reg->size);
282 if (ret)
283 dev_err(dev, "Data transfer failed\n");
284 } else {
285 memcpy(dst_addr, src_addr, reg->size);
286 }
287 ktime_get_ts64(&end);
288 pci_epf_test_print_rate("COPY", reg->size, &start, &end, use_dma);
121 289
290err_map_addr:
122 pci_epc_unmap_addr(epc, epf->func_no, dst_phys_addr);291 pci_epc_unmap_addr(epc, epf->func_no, dst_phys_addr);
123 292
124err_dst_addr:293err_dst_addr:
@@ -140,10 +309,14 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test) · 15 unmodified lines
140 void __iomem *src_addr;309 void __iomem *src_addr;
141 void *buf;310 void *buf;
142 u32 crc32;311 u32 crc32;
312 bool use_dma;
143 phys_addr_t phys_addr;313 phys_addr_t phys_addr;
314 phys_addr_t dst_phys_addr;
315 struct timespec64 start, end;
144 struct pci_epf *epf = epf_test->epf;316 struct pci_epf *epf = epf_test->epf;
145 struct device *dev = &epf->dev;317 struct device *dev = &epf->dev;
146 struct pci_epc *epc = epf->epc;318 struct pci_epc *epc = epf->epc;
319 struct device *dma_dev = epf->epc->dev.parent;
147 enum pci_barno test_reg_bar = epf_test->test_reg_bar;320 enum pci_barno test_reg_bar = epf_test->test_reg_bar;
148 struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];321 struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
149 322
@@ -169,12 +342,44 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test) · 19 unmodified lines
169 goto err_map_addr;342 goto err_map_addr;
170 }343 }
171 344
172 memcpy_fromio(buf, src_addr, reg->size);345 use_dma = !!(reg->flags & FLAG_USE_DMA);
346 if (use_dma) {
347 if (!epf_test->dma_supported) {
348 dev_err(dev, "Cannot transfer data using DMA\n");
349 ret = -EINVAL;
350 goto err_dma_map;
351 }
352
353 dst_phys_addr = dma_map_single(dma_dev, buf, reg->size,
354 DMA_FROM_DEVICE);
355 if (dma_mapping_error(dma_dev, dst_phys_addr)) {
356 dev_err(dev, "Failed to map destination buffer addr\n");
357 ret = -ENOMEM;
358 goto err_dma_map;
359 }
360
361 ktime_get_ts64(&start);
362 ret = pci_epf_test_data_transfer(epf_test, dst_phys_addr,
363 phys_addr, reg->size);
364 if (ret)
365 dev_err(dev, "Data transfer failed\n");
366 ktime_get_ts64(&end);
367
368 dma_unmap_single(dma_dev, dst_phys_addr, reg->size,
369 DMA_FROM_DEVICE);
370 } else {
371 ktime_get_ts64(&start);
372 memcpy_fromio(buf, src_addr, reg->size);
373 ktime_get_ts64(&end);
374 }
375
376 pci_epf_test_print_rate("READ", reg->size, &start, &end, use_dma);
173 377
174 crc32 = crc32_le(~0, buf, reg->size);378 crc32 = crc32_le(~0, buf, reg->size);
175 if (crc32 != reg->checksum)379 if (crc32 != reg->checksum)
176 ret = -EIO;380 ret = -EIO;
177 381
382err_dma_map:
178 kfree(buf);383 kfree(buf);
179 384
180err_map_addr:385err_map_addr:
@@ -192,10 +397,14 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) · 11 unmodified lines
192 int ret;397 int ret;
193 void __iomem *dst_addr;398 void __iomem *dst_addr;
194 void *buf;399 void *buf;
400 bool use_dma;
195 phys_addr_t phys_addr;401 phys_addr_t phys_addr;
402 phys_addr_t src_phys_addr;
403 struct timespec64 start, end;
196 struct pci_epf *epf = epf_test->epf;404 struct pci_epf *epf = epf_test->epf;
197 struct device *dev = &epf->dev;405 struct device *dev = &epf->dev;
198 struct pci_epc *epc = epf->epc;406 struct pci_epc *epc = epf->epc;
407 struct device *dma_dev = epf->epc->dev.parent;
199 enum pci_barno test_reg_bar = epf_test->test_reg_bar;408 enum pci_barno test_reg_bar = epf_test->test_reg_bar;
200 struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];409 struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
201 410
@@ -224,7 +433,38 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) · 22 unmodified lines
224 get_random_bytes(buf, reg->size);433 get_random_bytes(buf, reg->size);
225 reg->checksum = crc32_le(~0, buf, reg->size);434 reg->checksum = crc32_le(~0, buf, reg->size);
226 435
227 memcpy_toio(dst_addr, buf, reg->size);436 use_dma = !!(reg->flags & FLAG_USE_DMA);
437 if (use_dma) {
438 if (!epf_test->dma_supported) {
439 dev_err(dev, "Cannot transfer data using DMA\n");
440 ret = -EINVAL;
441 goto err_map_addr;
442 }
443
444 src_phys_addr = dma_map_single(dma_dev, buf, reg->size,
445 DMA_TO_DEVICE);
446 if (dma_mapping_error(dma_dev, src_phys_addr)) {
447 dev_err(dev, "Failed to map source buffer addr\n");
448 ret = -ENOMEM;
449 goto err_dma_map;
450 }
451
452 ktime_get_ts64(&start);
453 ret = pci_epf_test_data_transfer(epf_test, phys_addr,
454 src_phys_addr, reg->size);
455 if (ret)
456 dev_err(dev, "Data transfer failed\n");
457 ktime_get_ts64(&end);
458
459 dma_unmap_single(dma_dev, src_phys_addr, reg->size,
460 DMA_TO_DEVICE);
461 } else {
462 ktime_get_ts64(&start);
463 memcpy_toio(dst_addr, buf, reg->size);
464 ktime_get_ts64(&end);
465 }
466
467 pci_epf_test_print_rate("WRITE", reg->size, &start, &end, use_dma);
228 468
229 /*469 /*
230 * wait 1ms inorder for the write to complete. Without this delay L3470 * wait 1ms inorder for the write to complete. Without this delay L3
@@ -232,6 +472,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) · 1 unmodified line
232 */472 */
233 usleep_range(1000, 2000);473 usleep_range(1000, 2000);
234 474
475err_dma_map:
235 kfree(buf);476 kfree(buf);
236 477
237err_map_addr:478err_map_addr:
@@ -360,14 +601,6 @@ reset_handler: · 122 unmodified lines
360 msecs_to_jiffies(1));601 msecs_to_jiffies(1));
361}602}
362 603
363static void pci_epf_test_linkup(struct pci_epf *epf)
364{
365 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
366
367 queue_delayed_work(kpcitest_workqueue, &epf_test->cmd_handler,
368 msecs_to_jiffies(1));
369}
370
371static void pci_epf_test_unbind(struct pci_epf *epf)604static void pci_epf_test_unbind(struct pci_epf *epf)
372{605{
373 struct pci_epf_test *epf_test = epf_get_drvdata(epf);606 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
@@ -376,6 +609,7 @@ static void pci_epf_test_unbind(struct pci_epf *epf) · 2 unmodified lines
376 int bar;609 int bar;
377 610
378 cancel_delayed_work(&epf_test->cmd_handler);611 cancel_delayed_work(&epf_test->cmd_handler);
612 pci_epf_test_clean_dma_chan(epf_test);
379 pci_epc_stop(epc);613 pci_epc_stop(epc);
380 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {614 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
381 epf_bar = &epf->bar[bar];615 epf_bar = &epf->bar[bar];
@@ -424,11 +658,90 @@ static int pci_epf_test_set_bar(struct pci_epf *epf) · 42 unmodified lines
424 return 0;658 return 0;
425}659}
426 660
661static int pci_epf_test_core_init(struct pci_epf *epf)
662{
663 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
664 struct pci_epf_header *header = epf->header;
665 const struct pci_epc_features *epc_features;
666 struct pci_epc *epc = epf->epc;
667 struct device *dev = &epf->dev;
668 bool msix_capable = false;
669 bool msi_capable = true;
670 int ret;
671
672 epc_features = pci_epc_get_features(epc, epf->func_no);
673 if (epc_features) {
674 msix_capable = epc_features->msix_capable;
675 msi_capable = epc_features->msi_capable;
676 }
677
678 ret = pci_epc_write_header(epc, epf->func_no, header);
679 if (ret) {
680 dev_err(dev, "Configuration header write failed\n");
681 return ret;
682 }
683
684 ret = pci_epf_test_set_bar(epf);
685 if (ret)
686 return ret;
687
688 if (msi_capable) {
689 ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts);
690 if (ret) {
691 dev_err(dev, "MSI configuration failed\n");
692 return ret;
693 }
694 }
695
696 if (msix_capable) {
697 ret = pci_epc_set_msix(epc, epf->func_no, epf->msix_interrupts,
698 epf_test->test_reg_bar,
699 epf_test->msix_table_offset);
700 if (ret) {
701 dev_err(dev, "MSI-X configuration failed\n");
702 return ret;
703 }
704 }
705
706 return 0;
707}
708
709static int pci_epf_test_notifier(struct notifier_block *nb, unsigned long val,
710 void *data)
711{
712 struct pci_epf *epf = container_of(nb, struct pci_epf, nb);
713 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
714 int ret;
715
716 switch (val) {
717 case CORE_INIT:
718 ret = pci_epf_test_core_init(epf);
719 if (ret)
720 return NOTIFY_BAD;
721 break;
722
723 case LINK_UP:
724 queue_delayed_work(kpcitest_workqueue, &epf_test->cmd_handler,
725 msecs_to_jiffies(1));
726 break;
727
728 default:
729 dev_err(&epf->dev, "Invalid EPF test notifier event\n");
730 return NOTIFY_BAD;
731 }
732
733 return NOTIFY_OK;
734}
735
427static int pci_epf_test_alloc_space(struct pci_epf *epf)736static int pci_epf_test_alloc_space(struct pci_epf *epf)
428{737{
429 struct pci_epf_test *epf_test = epf_get_drvdata(epf);738 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
430 struct device *dev = &epf->dev;739 struct device *dev = &epf->dev;
431 struct pci_epf_bar *epf_bar;740 struct pci_epf_bar *epf_bar;
741 size_t msix_table_size = 0;
742 size_t test_reg_bar_size;
743 size_t pba_size = 0;
744 bool msix_capable;
432 void *base;745 void *base;
433 int bar, add;746 int bar, add;
434 enum pci_barno test_reg_bar = epf_test->test_reg_bar;747 enum pci_barno test_reg_bar = epf_test->test_reg_bar;
@@ -437,13 +750,25 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) · 2 unmodified lines
437 750
438 epc_features = epf_test->epc_features;751 epc_features = epf_test->epc_features;
439 752
440 if (epc_features->bar_fixed_size[test_reg_bar])753 test_reg_bar_size = ALIGN(sizeof(struct pci_epf_test_reg), 128);
754
755 msix_capable = epc_features->msix_capable;
756 if (msix_capable) {
757 msix_table_size = PCI_MSIX_ENTRY_SIZE * epf->msix_interrupts;
758 epf_test->msix_table_offset = test_reg_bar_size;
759 /* Align to QWORD or 8 Bytes */
760 pba_size = ALIGN(DIV_ROUND_UP(epf->msix_interrupts, 8), 8);
761 }
762 test_reg_size = test_reg_bar_size + msix_table_size + pba_size;
763
764 if (epc_features->bar_fixed_size[test_reg_bar]) {
765 if (test_reg_size > bar_size[test_reg_bar])
766 return -ENOMEM;
441 test_reg_size = bar_size[test_reg_bar];767 test_reg_size = bar_size[test_reg_bar];
442 else768 }
443 test_reg_size = sizeof(struct pci_epf_test_reg);
444 769
445 base = pci_epf_alloc_space(epf, test_reg_size,770 base = pci_epf_alloc_space(epf, test_reg_size, test_reg_bar,
446 test_reg_bar, epc_features->align);771 epc_features->align);
447 if (!base) {772 if (!base) {
448 dev_err(dev, "Failed to allocated register space\n");773 dev_err(dev, "Failed to allocated register space\n");
449 return -ENOMEM;774 return -ENOMEM;
@@ -492,14 +817,11 @@ static int pci_epf_test_bind(struct pci_epf *epf) · 42 unmodified lines
492{817{
493 int ret;818 int ret;
494 struct pci_epf_test *epf_test = epf_get_drvdata(epf);819 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
495 struct pci_epf_header *header = epf->header;
496 const struct pci_epc_features *epc_features;820 const struct pci_epc_features *epc_features;
497 enum pci_barno test_reg_bar = BAR_0;821 enum pci_barno test_reg_bar = BAR_0;
498 struct pci_epc *epc = epf->epc;822 struct pci_epc *epc = epf->epc;
499 struct device *dev = &epf->dev;
500 bool linkup_notifier = false;823 bool linkup_notifier = false;
501 bool msix_capable = false;824 bool core_init_notifier = false;
502 bool msi_capable = true;
503 825
504 if (WARN_ON_ONCE(!epc))826 if (WARN_ON_ONCE(!epc))
505 return -EINVAL;827 return -EINVAL;
@@ -507,8 +829,7 @@ static int pci_epf_test_bind(struct pci_epf *epf) · 1 unmodified line
507 epc_features = pci_epc_get_features(epc, epf->func_no);829 epc_features = pci_epc_get_features(epc, epf->func_no);
508 if (epc_features) {830 if (epc_features) {
509 linkup_notifier = epc_features->linkup_notifier;831 linkup_notifier = epc_features->linkup_notifier;
510 msix_capable = epc_features->msix_capable;832 core_init_notifier = epc_features->core_init_notifier;
511 msi_capable = epc_features->msi_capable;
512 test_reg_bar = pci_epc_get_first_free_bar(epc_features);833 test_reg_bar = pci_epc_get_first_free_bar(epc_features);
513 pci_epf_configure_bar(epf, epc_features);834 pci_epf_configure_bar(epf, epc_features);
514 }835 }
@@ -516,38 +837,28 @@ static int pci_epf_test_bind(struct pci_epf *epf) · 1 unmodified line
516 epf_test->test_reg_bar = test_reg_bar;837 epf_test->test_reg_bar = test_reg_bar;
517 epf_test->epc_features = epc_features;838 epf_test->epc_features = epc_features;
518 839
519 ret = pci_epc_write_header(epc, epf->func_no, header);
520 if (ret) {
521 dev_err(dev, "Configuration header write failed\n");
522 return ret;
523 }
524
525 ret = pci_epf_test_alloc_space(epf);840 ret = pci_epf_test_alloc_space(epf);
526 if (ret)841 if (ret)
527 return ret;842 return ret;
528 843
529 ret = pci_epf_test_set_bar(epf);844 if (!core_init_notifier) {
530 if (ret)845 ret = pci_epf_test_core_init(epf);
531 return ret;846 if (ret)
532
533 if (msi_capable) {
534 ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts);
535 if (ret) {
536 dev_err(dev, "MSI configuration failed\n");
537 return ret;847 return ret;
538 }
539 }848 }
540 849
541 if (msix_capable) {850 epf_test->dma_supported = true;
542 ret = pci_epc_set_msix(epc, epf->func_no, epf->msix_interrupts);
543 if (ret) {
544 dev_err(dev, "MSI-X configuration failed\n");
545 return ret;
546 }
547 }
548 851
549 if (!linkup_notifier)852 ret = pci_epf_test_init_dma_chan(epf_test);
853 if (ret)
854 epf_test->dma_supported = false;
855
856 if (linkup_notifier) {
857 epf->nb.notifier_call = pci_epf_test_notifier;
858 pci_epc_register_notifier(epc, &epf->nb);
859 } else {
550 queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work);860 queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work);
861 }
551 862
552 return 0;863 return 0;
553}864}
@@ -580,7 +891,6 @@ static int pci_epf_test_probe(struct pci_epf *epf) · 26 unmodified lines
580static struct pci_epf_ops ops = {891static struct pci_epf_ops ops = {
581 .unbind = pci_epf_test_unbind,892 .unbind = pci_epf_test_unbind,
582 .bind = pci_epf_test_bind,893 .bind = pci_epf_test_bind,
583 .linkup = pci_epf_test_linkup,
584};894};
585 895
586static struct pci_epf_driver test_driver = {896static struct pci_epf_driver test_driver = {
drivers/pci/endpoint/pci-ep-cfs.c+6−22
@@ -29,7 +29,6 @@ struct pci_epc_group { · 28 unmodified lines
29 struct config_group group;29 struct config_group group;
30 struct pci_epc *epc;30 struct pci_epc *epc;
31 bool start;31 bool start;
32 unsigned long function_num_map;
33};32};
34 33
35static inline struct pci_epf_group *to_pci_epf_group(struct config_item *item)34static inline struct pci_epf_group *to_pci_epf_group(struct config_item *item)
@@ -58,6 +57,7 @@ static ssize_t pci_epc_start_store(struct config_item *item, const char *page, · 22 unmodified lines
58 57
59 if (!start) {58 if (!start) {
60 pci_epc_stop(epc);59 pci_epc_stop(epc);
60 epc_group->start = 0;
61 return len;61 return len;
62 }62 }
63 63
@@ -89,37 +89,22 @@ static int pci_epc_epf_link(struct config_item *epc_item, · 25 unmodified lines
89 struct config_item *epf_item)89 struct config_item *epf_item)
90{90{
91 int ret;91 int ret;
92 u32 func_no = 0;
93 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);92 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
94 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);93 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
95 struct pci_epc *epc = epc_group->epc;94 struct pci_epc *epc = epc_group->epc;
96 struct pci_epf *epf = epf_group->epf;95 struct pci_epf *epf = epf_group->epf;
97 96
98 func_no = find_first_zero_bit(&epc_group->function_num_map,
99 BITS_PER_LONG);
100 if (func_no >= BITS_PER_LONG)
101 return -EINVAL;
102
103 set_bit(func_no, &epc_group->function_num_map);
104 epf->func_no = func_no;
105
106 ret = pci_epc_add_epf(epc, epf);97 ret = pci_epc_add_epf(epc, epf);
107 if (ret)98 if (ret)
108 goto err_add_epf;99 return ret;
109 100
110 ret = pci_epf_bind(epf);101 ret = pci_epf_bind(epf);
111 if (ret)102 if (ret) {
112 goto err_epf_bind;103 pci_epc_remove_epf(epc, epf);
104 return ret;
105 }
113 106
114 return 0;107 return 0;
115
116err_epf_bind:
117 pci_epc_remove_epf(epc, epf);
118
119err_add_epf:
120 clear_bit(func_no, &epc_group->function_num_map);
121
122 return ret;
123}108}
124 109
125static void pci_epc_epf_unlink(struct config_item *epc_item,110static void pci_epc_epf_unlink(struct config_item *epc_item,
@@ -134,7 +119,6 @@ static void pci_epc_epf_unlink(struct config_item *epc_item, · 8 unmodified lines
134 119
135 epc = epc_group->epc;120 epc = epc_group->epc;
136 epf = epf_group->epf;121 epf = epf_group->epf;
137 clear_bit(epf->func_no, &epc_group->function_num_map);
138 pci_epf_unbind(epf);122 pci_epf_unbind(epf);
139 pci_epc_remove_epf(epc, epf);123 pci_epc_remove_epf(epc, epf);
140}124}
drivers/pci/endpoint/pci-epc-core.c+75−62
@@ -120,7 +120,6 @@ const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc, · 119 unmodified lines
120 u8 func_no)120 u8 func_no)
121{121{
122 const struct pci_epc_features *epc_features;122 const struct pci_epc_features *epc_features;
123 unsigned long flags;
124 123
125 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)124 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
126 return NULL;125 return NULL;
@@ -128,9 +127,9 @@ const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc, · 1 unmodified line
128 if (!epc->ops->get_features)127 if (!epc->ops->get_features)
129 return NULL;128 return NULL;
130 129
131 spin_lock_irqsave(&epc->lock, flags);130 mutex_lock(&epc->lock);
132 epc_features = epc->ops->get_features(epc, func_no);131 epc_features = epc->ops->get_features(epc, func_no);
133 spin_unlock_irqrestore(&epc->lock, flags);132 mutex_unlock(&epc->lock);
134 133
135 return epc_features;134 return epc_features;
136}135}
@@ -144,14 +143,12 @@ EXPORT_SYMBOL_GPL(pci_epc_get_features); · 7 unmodified lines
144 */143 */
145void pci_epc_stop(struct pci_epc *epc)144void pci_epc_stop(struct pci_epc *epc)
146{145{
147 unsigned long flags;
148
149 if (IS_ERR(epc) || !epc->ops->stop)146 if (IS_ERR(epc) || !epc->ops->stop)
150 return;147 return;
151 148
152 spin_lock_irqsave(&epc->lock, flags);149 mutex_lock(&epc->lock);
153 epc->ops->stop(epc);150 epc->ops->stop(epc);
154 spin_unlock_irqrestore(&epc->lock, flags);151 mutex_unlock(&epc->lock);
155}152}
156EXPORT_SYMBOL_GPL(pci_epc_stop);153EXPORT_SYMBOL_GPL(pci_epc_stop);
157 154
@@ -164,7 +161,6 @@ EXPORT_SYMBOL_GPL(pci_epc_stop); · 6 unmodified lines
164int pci_epc_start(struct pci_epc *epc)161int pci_epc_start(struct pci_epc *epc)
165{162{
166 int ret;163 int ret;
167 unsigned long flags;
168 164
169 if (IS_ERR(epc))165 if (IS_ERR(epc))
170 return -EINVAL;166 return -EINVAL;
@@ -172,9 +168,9 @@ int pci_epc_start(struct pci_epc *epc) · 1 unmodified line
172 if (!epc->ops->start)168 if (!epc->ops->start)
173 return 0;169 return 0;
174 170
175 spin_lock_irqsave(&epc->lock, flags);171 mutex_lock(&epc->lock);
176 ret = epc->ops->start(epc);172 ret = epc->ops->start(epc);
177 spin_unlock_irqrestore(&epc->lock, flags);173 mutex_unlock(&epc->lock);
178 174
179 return ret;175 return ret;
180}176}
@@ -193,7 +189,6 @@ int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, · 12 unmodified lines
193 enum pci_epc_irq_type type, u16 interrupt_num)189 enum pci_epc_irq_type type, u16 interrupt_num)
194{190{
195 int ret;191 int ret;
196 unsigned long flags;
197 192
198 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)193 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
199 return -EINVAL;194 return -EINVAL;
@@ -201,9 +196,9 @@ int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, · 1 unmodified line
201 if (!epc->ops->raise_irq)196 if (!epc->ops->raise_irq)
202 return 0;197 return 0;
203 198
204 spin_lock_irqsave(&epc->lock, flags);199 mutex_lock(&epc->lock);
205 ret = epc->ops->raise_irq(epc, func_no, type, interrupt_num);200 ret = epc->ops->raise_irq(epc, func_no, type, interrupt_num);
206 spin_unlock_irqrestore(&epc->lock, flags);201 mutex_unlock(&epc->lock);
207 202
208 return ret;203 return ret;
209}204}
@@ -219,7 +214,6 @@ EXPORT_SYMBOL_GPL(pci_epc_raise_irq); · 9 unmodified lines
219int pci_epc_get_msi(struct pci_epc *epc, u8 func_no)214int pci_epc_get_msi(struct pci_epc *epc, u8 func_no)
220{215{
221 int interrupt;216 int interrupt;
222 unsigned long flags;
223 217
224 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)218 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
225 return 0;219 return 0;
@@ -227,9 +221,9 @@ int pci_epc_get_msi(struct pci_epc *epc, u8 func_no) · 1 unmodified line
227 if (!epc->ops->get_msi)221 if (!epc->ops->get_msi)
228 return 0;222 return 0;
229 223
230 spin_lock_irqsave(&epc->lock, flags);224 mutex_lock(&epc->lock);
231 interrupt = epc->ops->get_msi(epc, func_no);225 interrupt = epc->ops->get_msi(epc, func_no);
232 spin_unlock_irqrestore(&epc->lock, flags);226 mutex_unlock(&epc->lock);
233 227
234 if (interrupt < 0)228 if (interrupt < 0)
235 return 0;229 return 0;
@@ -252,7 +246,6 @@ int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts) · 16 unmodified lines
252{246{
253 int ret;247 int ret;
254 u8 encode_int;248 u8 encode_int;
255 unsigned long flags;
256 249
257 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions ||250 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions ||
258 interrupts > 32)251 interrupts > 32)
@@ -263,9 +256,9 @@ int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts) · 4 unmodified lines
263 256
264 encode_int = order_base_2(interrupts);257 encode_int = order_base_2(interrupts);
265 258
266 spin_lock_irqsave(&epc->lock, flags);259 mutex_lock(&epc->lock);
267 ret = epc->ops->set_msi(epc, func_no, encode_int);260 ret = epc->ops->set_msi(epc, func_no, encode_int);
268 spin_unlock_irqrestore(&epc->lock, flags);261 mutex_unlock(&epc->lock);
269 262
270 return ret;263 return ret;
271}264}
@@ -281,7 +274,6 @@ EXPORT_SYMBOL_GPL(pci_epc_set_msi); · 9 unmodified lines
281int pci_epc_get_msix(struct pci_epc *epc, u8 func_no)274int pci_epc_get_msix(struct pci_epc *epc, u8 func_no)
282{275{
283 int interrupt;276 int interrupt;
284 unsigned long flags;
285 277
286 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)278 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
287 return 0;279 return 0;
@@ -289,9 +281,9 @@ int pci_epc_get_msix(struct pci_epc *epc, u8 func_no) · 1 unmodified line
289 if (!epc->ops->get_msix)281 if (!epc->ops->get_msix)
290 return 0;282 return 0;
291 283
292 spin_lock_irqsave(&epc->lock, flags);284 mutex_lock(&epc->lock);
293 interrupt = epc->ops->get_msix(epc, func_no);285 interrupt = epc->ops->get_msix(epc, func_no);
294 spin_unlock_irqrestore(&epc->lock, flags);286 mutex_unlock(&epc->lock);
295 287
296 if (interrupt < 0)288 if (interrupt < 0)
297 return 0;289 return 0;
@@ -305,13 +297,15 @@ EXPORT_SYMBOL_GPL(pci_epc_get_msix); · 7 unmodified lines
305 * @epc: the EPC device on which MSI-X has to be configured297 * @epc: the EPC device on which MSI-X has to be configured
306 * @func_no: the endpoint function number in the EPC device298 * @func_no: the endpoint function number in the EPC device
307 * @interrupts: number of MSI-X interrupts required by the EPF299 * @interrupts: number of MSI-X interrupts required by the EPF
300 * @bir: BAR where the MSI-X table resides
301 * @offset: Offset pointing to the start of MSI-X table
308 *302 *
309 * Invoke to set the required number of MSI-X interrupts.303 * Invoke to set the required number of MSI-X interrupts.
310 */304 */
311int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts)305int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
306 enum pci_barno bir, u32 offset)
312{307{
313 int ret;308 int ret;
314 unsigned long flags;
315 309
316 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions ||310 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions ||
317 interrupts < 1 || interrupts > 2048)311 interrupts < 1 || interrupts > 2048)
@@ -320,9 +314,9 @@ int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts) · 2 unmodified lines
320 if (!epc->ops->set_msix)314 if (!epc->ops->set_msix)
321 return 0;315 return 0;
322 316
323 spin_lock_irqsave(&epc->lock, flags);317 mutex_lock(&epc->lock);
324 ret = epc->ops->set_msix(epc, func_no, interrupts - 1);318 ret = epc->ops->set_msix(epc, func_no, interrupts - 1, bir, offset);
325 spin_unlock_irqrestore(&epc->lock, flags);319 mutex_unlock(&epc->lock);
326 320
327 return ret;321 return ret;
328}322}
@@ -339,17 +333,15 @@ EXPORT_SYMBOL_GPL(pci_epc_set_msix); · 10 unmodified lines
339void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,333void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,
340 phys_addr_t phys_addr)334 phys_addr_t phys_addr)
341{335{
342 unsigned long flags;
343
344 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)336 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
345 return;337 return;
346 338
347 if (!epc->ops->unmap_addr)339 if (!epc->ops->unmap_addr)
348 return;340 return;
349 341
350 spin_lock_irqsave(&epc->lock, flags);342 mutex_lock(&epc->lock);
351 epc->ops->unmap_addr(epc, func_no, phys_addr);343 epc->ops->unmap_addr(epc, func_no, phys_addr);
352 spin_unlock_irqrestore(&epc->lock, flags);344 mutex_unlock(&epc->lock);
353}345}
354EXPORT_SYMBOL_GPL(pci_epc_unmap_addr);346EXPORT_SYMBOL_GPL(pci_epc_unmap_addr);
355 347
@@ -367,7 +359,6 @@ int pci_epc_map_addr(struct pci_epc *epc, u8 func_no, · 11 unmodified lines
367 phys_addr_t phys_addr, u64 pci_addr, size_t size)359 phys_addr_t phys_addr, u64 pci_addr, size_t size)
368{360{
369 int ret;361 int ret;
370 unsigned long flags;
371 362
372 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)363 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
373 return -EINVAL;364 return -EINVAL;
@@ -375,9 +366,9 @@ int pci_epc_map_addr(struct pci_epc *epc, u8 func_no, · 1 unmodified line
375 if (!epc->ops->map_addr)366 if (!epc->ops->map_addr)
376 return 0;367 return 0;
377 368
378 spin_lock_irqsave(&epc->lock, flags);369 mutex_lock(&epc->lock);
379 ret = epc->ops->map_addr(epc, func_no, phys_addr, pci_addr, size);370 ret = epc->ops->map_addr(epc, func_no, phys_addr, pci_addr, size);
380 spin_unlock_irqrestore(&epc->lock, flags);371 mutex_unlock(&epc->lock);
381 372
382 return ret;373 return ret;
383}374}
@@ -394,8 +385,6 @@ EXPORT_SYMBOL_GPL(pci_epc_map_addr); · 10 unmodified lines
394void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no,385void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no,
395 struct pci_epf_bar *epf_bar)386 struct pci_epf_bar *epf_bar)
396{387{
397 unsigned long flags;
398
399 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions ||388 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions ||
400 (epf_bar->barno == BAR_5 &&389 (epf_bar->barno == BAR_5 &&
401 epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64))390 epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64))
@@ -404,9 +393,9 @@ void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no, · 2 unmodified lines
404 if (!epc->ops->clear_bar)393 if (!epc->ops->clear_bar)
405 return;394 return;
406 395
407 spin_lock_irqsave(&epc->lock, flags);396 mutex_lock(&epc->lock);
408 epc->ops->clear_bar(epc, func_no, epf_bar);397 epc->ops->clear_bar(epc, func_no, epf_bar);
409 spin_unlock_irqrestore(&epc->lock, flags);398 mutex_unlock(&epc->lock);
410}399}
411EXPORT_SYMBOL_GPL(pci_epc_clear_bar);400EXPORT_SYMBOL_GPL(pci_epc_clear_bar);
412 401
@@ -422,7 +411,6 @@ int pci_epc_set_bar(struct pci_epc *epc, u8 func_no, · 9 unmodified lines
422 struct pci_epf_bar *epf_bar)411 struct pci_epf_bar *epf_bar)
423{412{
424 int ret;413 int ret;
425 unsigned long irq_flags;
426 int flags = epf_bar->flags;414 int flags = epf_bar->flags;
427 415
428 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions ||416 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions ||
@@ -437,9 +425,9 @@ int pci_epc_set_bar(struct pci_epc *epc, u8 func_no, · 8 unmodified lines
437 if (!epc->ops->set_bar)425 if (!epc->ops->set_bar)
438 return 0;426 return 0;
439 427
440 spin_lock_irqsave(&epc->lock, irq_flags);428 mutex_lock(&epc->lock);
441 ret = epc->ops->set_bar(epc, func_no, epf_bar);429 ret = epc->ops->set_bar(epc, func_no, epf_bar);
442 spin_unlock_irqrestore(&epc->lock, irq_flags);430 mutex_unlock(&epc->lock);
443 431
444 return ret;432 return ret;
445}433}
@@ -460,7 +448,6 @@ int pci_epc_write_header(struct pci_epc *epc, u8 func_no, · 14 unmodified lines
460 struct pci_epf_header *header)448 struct pci_epf_header *header)
461{449{
462 int ret;450 int ret;
463 unsigned long flags;
464 451
465 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)452 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
466 return -EINVAL;453 return -EINVAL;
@@ -468,9 +455,9 @@ int pci_epc_write_header(struct pci_epc *epc, u8 func_no, · 1 unmodified line
468 if (!epc->ops->write_header)455 if (!epc->ops->write_header)
469 return 0;456 return 0;
470 457
471 spin_lock_irqsave(&epc->lock, flags);458 mutex_lock(&epc->lock);
472 ret = epc->ops->write_header(epc, func_no, header);459 ret = epc->ops->write_header(epc, func_no, header);
473 spin_unlock_irqrestore(&epc->lock, flags);460 mutex_unlock(&epc->lock);
474 461
475 return ret;462 return ret;
476}463}
@@ -487,7 +474,8 @@ EXPORT_SYMBOL_GPL(pci_epc_write_header); · 10 unmodified lines
487 */474 */
488int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)475int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)
489{476{
490 unsigned long flags;477 u32 func_no;
478 int ret = 0;
491 479
492 if (epf->epc)480 if (epf->epc)
493 return -EBUSY;481 return -EBUSY;
@@ -495,16 +483,30 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf) · 1 unmodified line
495 if (IS_ERR(epc))483 if (IS_ERR(epc))
496 return -EINVAL;484 return -EINVAL;
497 485
498 if (epf->func_no > epc->max_functions - 1)486 mutex_lock(&epc->lock);
499 return -EINVAL;487 func_no = find_first_zero_bit(&epc->function_num_map,
488 BITS_PER_LONG);
489 if (func_no >= BITS_PER_LONG) {
490 ret = -EINVAL;
491 goto ret;
492 }
500 493
494 if (func_no > epc->max_functions - 1) {
495 dev_err(&epc->dev, "Exceeding max supported Function Number\n");
496 ret = -EINVAL;
497 goto ret;
498 }
499
500 set_bit(func_no, &epc->function_num_map);
501 epf->func_no = func_no;
501 epf->epc = epc;502 epf->epc = epc;
502 503
503 spin_lock_irqsave(&epc->lock, flags);
504 list_add_tail(&epf->list, &epc->pci_epf);504 list_add_tail(&epf->list, &epc->pci_epf);
505 spin_unlock_irqrestore(&epc->lock, flags);
506 505
507 return 0;506ret:
507 mutex_unlock(&epc->lock);
508
509 return ret;
508}510}
509EXPORT_SYMBOL_GPL(pci_epc_add_epf);511EXPORT_SYMBOL_GPL(pci_epc_add_epf);
510 512
@@ -517,15 +519,14 @@ EXPORT_SYMBOL_GPL(pci_epc_add_epf); · 6 unmodified lines
517 */519 */
518void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf)520void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf)
519{521{
520 unsigned long flags;
521
522 if (!epc || IS_ERR(epc) || !epf)522 if (!epc || IS_ERR(epc) || !epf)
523 return;523 return;
524 524
525 spin_lock_irqsave(&epc->lock, flags);525 mutex_lock(&epc->lock);
526 clear_bit(epf->func_no, &epc->function_num_map);
526 list_del(&epf->list);527 list_del(&epf->list);
527 epf->epc = NULL;528 epf->epc = NULL;
528 spin_unlock_irqrestore(&epc->lock, flags);529 mutex_unlock(&epc->lock);
529}530}
530EXPORT_SYMBOL_GPL(pci_epc_remove_epf);531EXPORT_SYMBOL_GPL(pci_epc_remove_epf);
531 532
@@ -539,19 +540,30 @@ EXPORT_SYMBOL_GPL(pci_epc_remove_epf); · 7 unmodified lines
539 */540 */
540void pci_epc_linkup(struct pci_epc *epc)541void pci_epc_linkup(struct pci_epc *epc)
541{542{
542 unsigned long flags;
543 struct pci_epf *epf;
544
545 if (!epc || IS_ERR(epc))543 if (!epc || IS_ERR(epc))
546 return;544 return;
547 545
548 spin_lock_irqsave(&epc->lock, flags);546 atomic_notifier_call_chain(&epc->notifier, LINK_UP, NULL);
549 list_for_each_entry(epf, &epc->pci_epf, list)
550 pci_epf_linkup(epf);
551 spin_unlock_irqrestore(&epc->lock, flags);
552}547}
553EXPORT_SYMBOL_GPL(pci_epc_linkup);548EXPORT_SYMBOL_GPL(pci_epc_linkup);
554 549
550/**
551 * pci_epc_init_notify() - Notify the EPF device that EPC device's core
552 * initialization is completed.
553 * @epc: the EPC device whose core initialization is completeds
554 *
555 * Invoke to Notify the EPF device that the EPC device's initialization
556 * is completed.
557 */
558void pci_epc_init_notify(struct pci_epc *epc)
559{
560 if (!epc || IS_ERR(epc))
561 return;
562
563 atomic_notifier_call_chain(&epc->notifier, CORE_INIT, NULL);
564}
565EXPORT_SYMBOL_GPL(pci_epc_init_notify);
566
555/**567/**
556 * pci_epc_destroy() - destroy the EPC device568 * pci_epc_destroy() - destroy the EPC device
557 * @epc: the EPC device that has to be destroyed569 * @epc: the EPC device that has to be destroyed
@@ -610,8 +622,9 @@ __pci_epc_create(struct device *dev, const struct pci_epc_ops *ops, · 52 unmodified lines
610 goto err_ret;622 goto err_ret;
611 }623 }
612 624
613 spin_lock_init(&epc->lock);625 mutex_init(&epc->lock);
614 INIT_LIST_HEAD(&epc->pci_epf);626 INIT_LIST_HEAD(&epc->pci_epf);
627 ATOMIC_INIT_NOTIFIER_HEAD(&epc->notifier);
615 628
616 device_initialize(&epc->dev);629 device_initialize(&epc->dev);
617 epc->dev.class = pci_epc_class;630 epc->dev.class = pci_epc_class;
drivers/pci/endpoint/pci-epc-mem.c+8−2
@@ -79,6 +79,7 @@ int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size, · 78 unmodified lines
79 mem->page_size = page_size;79 mem->page_size = page_size;
80 mem->pages = pages;80 mem->pages = pages;
81 mem->size = size;81 mem->size = size;
82 mutex_init(&mem->lock);
82 83
83 epc->mem = mem;84 epc->mem = mem;
84 85
@@ -122,7 +123,7 @@ void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc, · 37 unmodified lines
122 phys_addr_t *phys_addr, size_t size)123 phys_addr_t *phys_addr, size_t size)
123{124{
124 int pageno;125 int pageno;
125 void __iomem *virt_addr;126 void __iomem *virt_addr = NULL;
126 struct pci_epc_mem *mem = epc->mem;127 struct pci_epc_mem *mem = epc->mem;
127 unsigned int page_shift = ilog2(mem->page_size);128 unsigned int page_shift = ilog2(mem->page_size);
128 int order;129 int order;
@@ -130,15 +131,18 @@ void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc, · 1 unmodified line
130 size = ALIGN(size, mem->page_size);131 size = ALIGN(size, mem->page_size);
131 order = pci_epc_mem_get_order(mem, size);132 order = pci_epc_mem_get_order(mem, size);
132 133
134 mutex_lock(&mem->lock);
133 pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order);135 pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order);
134 if (pageno < 0)136 if (pageno < 0)
135 return NULL;137 goto ret;
136 138
137 *phys_addr = mem->phys_base + ((phys_addr_t)pageno << page_shift);139 *phys_addr = mem->phys_base + ((phys_addr_t)pageno << page_shift);
138 virt_addr = ioremap(*phys_addr, size);140 virt_addr = ioremap(*phys_addr, size);
139 if (!virt_addr)141 if (!virt_addr)
140 bitmap_release_region(mem->bitmap, pageno, order);142 bitmap_release_region(mem->bitmap, pageno, order);
141 143
144ret:
145 mutex_unlock(&mem->lock);
142 return virt_addr;146 return virt_addr;
143}147}
144EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr);148EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr);
@@ -164,7 +168,9 @@ void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr, · 19 unmodified lines
164 pageno = (phys_addr - mem->phys_base) >> page_shift;168 pageno = (phys_addr - mem->phys_base) >> page_shift;
165 size = ALIGN(size, mem->page_size);169 size = ALIGN(size, mem->page_size);
166 order = pci_epc_mem_get_order(mem, size);170 order = pci_epc_mem_get_order(mem, size);
171 mutex_lock(&mem->lock);
167 bitmap_release_region(mem->bitmap, pageno, order);172 bitmap_release_region(mem->bitmap, pageno, order);
173 mutex_unlock(&mem->lock);
168}174}
169EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr);175EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr);
170 176
drivers/pci/endpoint/pci-epf-core.c+13−22
@@ -20,26 +20,6 @@ static DEFINE_MUTEX(pci_epf_mutex); · 19 unmodified lines
20static struct bus_type pci_epf_bus_type;20static struct bus_type pci_epf_bus_type;
21static const struct device_type pci_epf_type;21static const struct device_type pci_epf_type;
22 22
23/**
24 * pci_epf_linkup() - Notify the function driver that EPC device has
25 * established a connection with the Root Complex.
26 * @epf: the EPF device bound to the EPC device which has established
27 * the connection with the host
28 *
29 * Invoke to notify the function driver that EPC device has established
30 * a connection with the Root Complex.
31 */
32void pci_epf_linkup(struct pci_epf *epf)
33{
34 if (!epf->driver) {
35 dev_WARN(&epf->dev, "epf device not bound to driver\n");
36 return;
37 }
38
39 epf->driver->ops->linkup(epf);
40}
41EXPORT_SYMBOL_GPL(pci_epf_linkup);
42
43/**23/**
44 * pci_epf_unbind() - Notify the function driver that the binding between the24 * pci_epf_unbind() - Notify the function driver that the binding between the
45 * EPF device and EPC device has been lost25 * EPF device and EPC device has been lost
@@ -55,7 +35,9 @@ void pci_epf_unbind(struct pci_epf *epf) · 9 unmodified lines
55 return;35 return;
56 }36 }
57 37
38 mutex_lock(&epf->lock);
58 epf->driver->ops->unbind(epf);39 epf->driver->ops->unbind(epf);
40 mutex_unlock(&epf->lock);
59 module_put(epf->driver->owner);41 module_put(epf->driver->owner);
60}42}
61EXPORT_SYMBOL_GPL(pci_epf_unbind);43EXPORT_SYMBOL_GPL(pci_epf_unbind);
@@ -69,6 +51,8 @@ EXPORT_SYMBOL_GPL(pci_epf_unbind); · 7 unmodified lines
69 */51 */
70int pci_epf_bind(struct pci_epf *epf)52int pci_epf_bind(struct pci_epf *epf)
71{53{
54 int ret;
55
72 if (!epf->driver) {56 if (!epf->driver) {
73 dev_WARN(&epf->dev, "epf device not bound to driver\n");57 dev_WARN(&epf->dev, "epf device not bound to driver\n");
74 return -EINVAL;58 return -EINVAL;
@@ -77,7 +61,11 @@ int pci_epf_bind(struct pci_epf *epf) · 2 unmodified lines
77 if (!try_module_get(epf->driver->owner))61 if (!try_module_get(epf->driver->owner))
78 return -EAGAIN;62 return -EAGAIN;
79 63
80 return epf->driver->ops->bind(epf);64 mutex_lock(&epf->lock);
65 ret = epf->driver->ops->bind(epf);
66 mutex_unlock(&epf->lock);
67
68 return ret;
81}69}
82EXPORT_SYMBOL_GPL(pci_epf_bind);70EXPORT_SYMBOL_GPL(pci_epf_bind);
83 71
@@ -99,6 +87,7 @@ void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar) · 15 unmodified lines
99 epf->bar[bar].phys_addr);87 epf->bar[bar].phys_addr);
100 88
101 epf->bar[bar].phys_addr = 0;89 epf->bar[bar].phys_addr = 0;
90 epf->bar[bar].addr = NULL;
102 epf->bar[bar].size = 0;91 epf->bar[bar].size = 0;
103 epf->bar[bar].barno = 0;92 epf->bar[bar].barno = 0;
104 epf->bar[bar].flags = 0;93 epf->bar[bar].flags = 0;
@@ -135,6 +124,7 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar, · 30 unmodified lines
135 }124 }
136 125
137 epf->bar[bar].phys_addr = phys_addr;126 epf->bar[bar].phys_addr = phys_addr;
127 epf->bar[bar].addr = space;
138 epf->bar[bar].size = size;128 epf->bar[bar].size = size;
139 epf->bar[bar].barno = bar;129 epf->bar[bar].barno = bar;
140 epf->bar[bar].flags |= upper_32_bits(size) ?130 epf->bar[bar].flags |= upper_32_bits(size) ?
@@ -214,7 +204,7 @@ int __pci_epf_register_driver(struct pci_epf_driver *driver, · 73 unmodified lines
214 if (!driver->ops)204 if (!driver->ops)
215 return -EINVAL;205 return -EINVAL;
216 206
217 if (!driver->ops->bind || !driver->ops->unbind || !driver->ops->linkup)207 if (!driver->ops->bind || !driver->ops->unbind)
218 return -EINVAL;208 return -EINVAL;
219 209
220 driver->driver.bus = &pci_epf_bus_type;210 driver->driver.bus = &pci_epf_bus_type;
@@ -272,6 +262,7 @@ struct pci_epf *pci_epf_create(const char *name) · 51 unmodified lines
272 device_initialize(dev);262 device_initialize(dev);
273 dev->bus = &pci_epf_bus_type;263 dev->bus = &pci_epf_bus_type;
274 dev->type = &pci_epf_type;264 dev->type = &pci_epf_type;
265 mutex_init(&epf->lock);
275 266
276 ret = dev_set_name(dev, "%s", name);267 ret = dev_set_name(dev, "%s", name);
277 if (ret) {268 if (ret) {
include/linux/pci-epc.h+22−5
@@ -53,7 +53,8 @@ struct pci_epc_ops { · 52 unmodified lines
53 phys_addr_t addr);53 phys_addr_t addr);
54 int (*set_msi)(struct pci_epc *epc, u8 func_no, u8 interrupts);54 int (*set_msi)(struct pci_epc *epc, u8 func_no, u8 interrupts);
55 int (*get_msi)(struct pci_epc *epc, u8 func_no);55 int (*get_msi)(struct pci_epc *epc, u8 func_no);
56 int (*set_msix)(struct pci_epc *epc, u8 func_no, u16 interrupts);56 int (*set_msix)(struct pci_epc *epc, u8 func_no, u16 interrupts,
57 enum pci_barno, u32 offset);
57 int (*get_msix)(struct pci_epc *epc, u8 func_no);58 int (*get_msix)(struct pci_epc *epc, u8 func_no);
58 int (*raise_irq)(struct pci_epc *epc, u8 func_no,59 int (*raise_irq)(struct pci_epc *epc, u8 func_no,
59 enum pci_epc_irq_type type, u16 interrupt_num);60 enum pci_epc_irq_type type, u16 interrupt_num);
@@ -71,6 +72,7 @@ struct pci_epc_ops { · 11 unmodified lines
71 * @bitmap: bitmap to manage the PCI address space72 * @bitmap: bitmap to manage the PCI address space
72 * @pages: number of bits representing the address region73 * @pages: number of bits representing the address region
73 * @page_size: size of each page74 * @page_size: size of each page
75 * @lock: mutex to protect bitmap
74 */76 */
75struct pci_epc_mem {77struct pci_epc_mem {
76 phys_addr_t phys_base;78 phys_addr_t phys_base;
@@ -78,6 +80,8 @@ struct pci_epc_mem { · 1 unmodified line
78 unsigned long *bitmap;80 unsigned long *bitmap;
79 size_t page_size;81 size_t page_size;
80 int pages;82 int pages;
83 /* mutex to protect against concurrent access for memory allocation*/
84 struct mutex lock;
81};85};
82 86
83/**87/**
@@ -88,7 +92,9 @@ struct pci_epc_mem { · 4 unmodified lines
88 * @mem: address space of the endpoint controller92 * @mem: address space of the endpoint controller
89 * @max_functions: max number of functions that can be configured in this EPC93 * @max_functions: max number of functions that can be configured in this EPC
90 * @group: configfs group representing the PCI EPC device94 * @group: configfs group representing the PCI EPC device
91 * @lock: spinlock to protect pci_epc ops95 * @lock: mutex to protect pci_epc ops
96 * @function_num_map: bitmap to manage physical function number
97 * @notifier: used to notify EPF of any EPC events (like linkup)
92 */98 */
93struct pci_epc {99struct pci_epc {
94 struct device dev;100 struct device dev;
@@ -97,8 +103,10 @@ struct pci_epc { · 2 unmodified lines
97 struct pci_epc_mem *mem;103 struct pci_epc_mem *mem;
98 u8 max_functions;104 u8 max_functions;
99 struct config_group *group;105 struct config_group *group;
100 /* spinlock to protect against concurrent access of EP controller */106 /* mutex to protect against concurrent access of EP controller */
101 spinlock_t lock;107 struct mutex lock;
108 unsigned long function_num_map;
109 struct atomic_notifier_head notifier;
102};110};
103 111
104/**112/**
@@ -113,6 +121,7 @@ struct pci_epc { · 8 unmodified lines
113 */121 */
114struct pci_epc_features {122struct pci_epc_features {
115 unsigned int linkup_notifier : 1;123 unsigned int linkup_notifier : 1;
124 unsigned int core_init_notifier : 1;
116 unsigned int msi_capable : 1;125 unsigned int msi_capable : 1;
117 unsigned int msix_capable : 1;126 unsigned int msix_capable : 1;
118 u8 reserved_bar;127 u8 reserved_bar;
@@ -141,6 +150,12 @@ static inline void *epc_get_drvdata(struct pci_epc *epc) · 22 unmodified lines
141 return dev_get_drvdata(&epc->dev);150 return dev_get_drvdata(&epc->dev);
142}151}
143 152
153static inline int
154pci_epc_register_notifier(struct pci_epc *epc, struct notifier_block *nb)
155{
156 return atomic_notifier_chain_register(&epc->notifier, nb);
157}
158
144struct pci_epc *159struct pci_epc *
145__devm_pci_epc_create(struct device *dev, const struct pci_epc_ops *ops,160__devm_pci_epc_create(struct device *dev, const struct pci_epc_ops *ops,
146 struct module *owner);161 struct module *owner);
@@ -151,6 +166,7 @@ void devm_pci_epc_destroy(struct device *dev, struct pci_epc *epc); · 4 unmodified lines
151void pci_epc_destroy(struct pci_epc *epc);166void pci_epc_destroy(struct pci_epc *epc);
152int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf);167int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf);
153void pci_epc_linkup(struct pci_epc *epc);168void pci_epc_linkup(struct pci_epc *epc);
169void pci_epc_init_notify(struct pci_epc *epc);
154void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf);170void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf);
155int pci_epc_write_header(struct pci_epc *epc, u8 func_no,171int pci_epc_write_header(struct pci_epc *epc, u8 func_no,
156 struct pci_epf_header *hdr);172 struct pci_epf_header *hdr);
@@ -165,7 +181,8 @@ void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no, · 8 unmodified lines
165 phys_addr_t phys_addr);181 phys_addr_t phys_addr);
166int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts);182int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts);
167int pci_epc_get_msi(struct pci_epc *epc, u8 func_no);183int pci_epc_get_msi(struct pci_epc *epc, u8 func_no);
168int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts);184int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
185 enum pci_barno, u32 offset);
169int pci_epc_get_msix(struct pci_epc *epc, u8 func_no);186int pci_epc_get_msix(struct pci_epc *epc, u8 func_no);
170int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,187int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
171 enum pci_epc_irq_type type, u16 interrupt_num);188 enum pci_epc_irq_type type, u16 interrupt_num);
include/linux/pci-epf.h+25−4
@@ -15,6 +15,11 @@ · 14 unmodified lines
15 15
16struct pci_epf;16struct pci_epf;
17 17
18enum pci_notify_event {
19 CORE_INIT,
20 LINK_UP,
21};
22
18enum pci_barno {23enum pci_barno {
19 BAR_0,24 BAR_0,
20 BAR_1,25 BAR_1,
@@ -55,13 +60,10 @@ struct pci_epf_header { · 34 unmodified lines
55 * @bind: ops to perform when a EPC device has been bound to EPF device60 * @bind: ops to perform when a EPC device has been bound to EPF device
56 * @unbind: ops to perform when a binding has been lost between a EPC device61 * @unbind: ops to perform when a binding has been lost between a EPC device
57 * and EPF device62 * and EPF device
58 * @linkup: ops to perform when the EPC device has established a connection with
59 * a host system
60 */63 */
61struct pci_epf_ops {64struct pci_epf_ops {
62 int (*bind)(struct pci_epf *epf);65 int (*bind)(struct pci_epf *epf);
63 void (*unbind)(struct pci_epf *epf);66 void (*unbind)(struct pci_epf *epf);
64 void (*linkup)(struct pci_epf *epf);
65};67};
66 68
67/**69/**
@@ -92,10 +94,12 @@ struct pci_epf_driver { · 24 unmodified lines
92/**94/**
93 * struct pci_epf_bar - represents the BAR of EPF device95 * struct pci_epf_bar - represents the BAR of EPF device
94 * @phys_addr: physical address that should be mapped to the BAR96 * @phys_addr: physical address that should be mapped to the BAR
97 * @addr: virtual address corresponding to the @phys_addr
95 * @size: the size of the address space present in BAR98 * @size: the size of the address space present in BAR
96 */99 */
97struct pci_epf_bar {100struct pci_epf_bar {
98 dma_addr_t phys_addr;101 dma_addr_t phys_addr;
102 void *addr;
99 size_t size;103 size_t size;
100 enum pci_barno barno;104 enum pci_barno barno;
101 int flags;105 int flags;
@@ -112,6 +116,8 @@ struct pci_epf_bar { · 10 unmodified lines
112 * @epc: the EPC device to which this EPF device is bound116 * @epc: the EPC device to which this EPF device is bound
113 * @driver: the EPF driver to which this EPF device is bound117 * @driver: the EPF driver to which this EPF device is bound
114 * @list: to add pci_epf as a list of PCI endpoint functions to pci_epc118 * @list: to add pci_epf as a list of PCI endpoint functions to pci_epc
119 * @nb: notifier block to notify EPF of any EPC events (like linkup)
120 * @lock: mutex to protect pci_epf_ops
115 */121 */
116struct pci_epf {122struct pci_epf {
117 struct device dev;123 struct device dev;
@@ -125,6 +131,22 @@ struct pci_epf { · 7 unmodified lines
125 struct pci_epc *epc;131 struct pci_epc *epc;
126 struct pci_epf_driver *driver;132 struct pci_epf_driver *driver;
127 struct list_head list;133 struct list_head list;
134 struct notifier_block nb;
135 /* mutex to protect against concurrent access of pci_epf_ops */
136 struct mutex lock;
137};
138
139/**
140 * struct pci_epf_msix_tbl - represents the MSIX table entry structure
141 * @msg_addr: Writes to this address will trigger MSIX interrupt in host
142 * @msg_data: Data that should be written to @msg_addr to trigger MSIX interrupt
143 * @vector_ctrl: Identifies if the function is prohibited from sending a message
144 * using this MSIX table entry
145 */
146struct pci_epf_msix_tbl {
147 u64 msg_addr;
148 u32 msg_data;
149 u32 vector_ctrl;
128};150};
129 151
130#define to_pci_epf(epf_dev) container_of((epf_dev), struct pci_epf, dev)152#define to_pci_epf(epf_dev) container_of((epf_dev), struct pci_epf, dev)
@@ -154,5 +176,4 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar, · 23 unmodified lines
154void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar);176void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar);
155int pci_epf_bind(struct pci_epf *epf);177int pci_epf_bind(struct pci_epf *epf);
156void pci_epf_unbind(struct pci_epf *epf);178void pci_epf_unbind(struct pci_epf *epf);
157void pci_epf_linkup(struct pci_epf *epf);
158#endif /* __LINUX_PCI_EPF_H */179#endif /* __LINUX_PCI_EPF_H */
include/soc/tegra/bpmp-abi.h+9−1
@@ -1,6 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0-only */1/* SPDX-License-Identifier: GPL-2.0-only */
2/*2/*
3 * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.3 * Copyright (c) 2014-2020, NVIDIA CORPORATION. All rights reserved.
4 */4 */
5 5
6#ifndef _ABI_BPMP_ABI_H_6#ifndef _ABI_BPMP_ABI_H_
@@ -2119,6 +2119,7 @@ enum { · 2112 unmodified lines
2119 CMD_UPHY_PCIE_LANE_MARGIN_STATUS = 2,2119 CMD_UPHY_PCIE_LANE_MARGIN_STATUS = 2,
2120 CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT = 3,2120 CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT = 3,
2121 CMD_UPHY_PCIE_CONTROLLER_STATE = 4,2121 CMD_UPHY_PCIE_CONTROLLER_STATE = 4,
2122 CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF = 5,
2122 CMD_UPHY_MAX,2123 CMD_UPHY_MAX,
2123};2124};
2124 2125
@@ -2151,6 +2152,11 @@ struct cmd_uphy_pcie_controller_state_request { · 26 unmodified lines
2151 uint8_t enable;2152 uint8_t enable;
2152} __ABI_PACKED;2153} __ABI_PACKED;
2153 2154
2155struct cmd_uphy_ep_controller_pll_off_request {
2156 /** @brief EP controller number, valid: 0, 4, 5 */
2157 uint8_t ep_controller;
2158} __ABI_PACKED;
2159
2154/**2160/**
2155 * @ingroup UPHY2161 * @ingroup UPHY
2156 * @brief Request with #MRQ_UPHY2162 * @brief Request with #MRQ_UPHY
@@ -2165,6 +2171,7 @@ struct cmd_uphy_pcie_controller_state_request { · 8 unmodified lines
2165 * |CMD_UPHY_PCIE_LANE_MARGIN_STATUS | |2171 * |CMD_UPHY_PCIE_LANE_MARGIN_STATUS | |
2166 * |CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT |cmd_uphy_ep_controller_pll_init_request |2172 * |CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT |cmd_uphy_ep_controller_pll_init_request |
2167 * |CMD_UPHY_PCIE_CONTROLLER_STATE |cmd_uphy_pcie_controller_state_request |2173 * |CMD_UPHY_PCIE_CONTROLLER_STATE |cmd_uphy_pcie_controller_state_request |
2174 * |CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF |cmd_uphy_ep_controller_pll_off_request |
2168 *2175 *
2169 */2176 */
2170 2177
@@ -2178,6 +2185,7 @@ struct mrq_uphy_request { · 7 unmodified lines
2178 struct cmd_uphy_margin_control_request uphy_set_margin_control;2185 struct cmd_uphy_margin_control_request uphy_set_margin_control;
2179 struct cmd_uphy_ep_controller_pll_init_request ep_ctrlr_pll_init;2186 struct cmd_uphy_ep_controller_pll_init_request ep_ctrlr_pll_init;
2180 struct cmd_uphy_pcie_controller_state_request controller_state;2187 struct cmd_uphy_pcie_controller_state_request controller_state;
2188 struct cmd_uphy_ep_controller_pll_off_request ep_ctrlr_pll_off;
2181 } __UNION_ANON;2189 } __UNION_ANON;
2182} __ABI_PACKED;2190} __ABI_PACKED;
2183 2191
include/uapi/linux/pcitest.h+8−0
@@ -19,5 +19,13 @@ · 18 unmodified lines
19#define PCITEST_MSIX _IOW('P', 0x7, int)19#define PCITEST_MSIX _IOW('P', 0x7, int)
20#define PCITEST_SET_IRQTYPE _IOW('P', 0x8, int)20#define PCITEST_SET_IRQTYPE _IOW('P', 0x8, int)
21#define PCITEST_GET_IRQTYPE _IO('P', 0x9)21#define PCITEST_GET_IRQTYPE _IO('P', 0x9)
22#define PCITEST_CLEAR_IRQ _IO('P', 0x10)
23
24#define PCITEST_FLAGS_USE_DMA 0x00000001
25
26struct pci_endpoint_test_xfer_param {
27 unsigned long size;
28 unsigned char flags;
29};
22 30
23#endif /* __UAPI_LINUX_PCITEST_H */31#endif /* __UAPI_LINUX_PCITEST_H */
tools/pci/pcitest.c+33−4
@@ -30,14 +30,17 @@ struct pci_test { · 29 unmodified lines
30 int irqtype;30 int irqtype;
31 bool set_irqtype;31 bool set_irqtype;
32 bool get_irqtype;32 bool get_irqtype;
33 bool clear_irq;
33 bool read;34 bool read;
34 bool write;35 bool write;
35 bool copy;36 bool copy;
36 unsigned long size;37 unsigned long size;
38 bool use_dma;
37};39};
38 40
39static int run_test(struct pci_test *test)41static int run_test(struct pci_test *test)
40{42{
43 struct pci_endpoint_test_xfer_param param;
41 int ret = -EINVAL;44 int ret = -EINVAL;
42 int fd;45 int fd;
43 46
@@ -74,6 +77,15 @@ static int run_test(struct pci_test *test) · 30 unmodified lines
74 fprintf(stdout, "%s\n", irq[ret]);77 fprintf(stdout, "%s\n", irq[ret]);
75 }78 }
76 79
80 if (test->clear_irq) {
81 ret = ioctl(fd, PCITEST_CLEAR_IRQ);
82 fprintf(stdout, "CLEAR IRQ:\t\t");
83 if (ret < 0)
84 fprintf(stdout, "FAILED\n");
85 else
86 fprintf(stdout, "%s\n", result[ret]);
87 }
88
77 if (test->legacyirq) {89 if (test->legacyirq) {
78 ret = ioctl(fd, PCITEST_LEGACY_IRQ, 0);90 ret = ioctl(fd, PCITEST_LEGACY_IRQ, 0);
79 fprintf(stdout, "LEGACY IRQ:\t");91 fprintf(stdout, "LEGACY IRQ:\t");
@@ -102,7 +114,10 @@ static int run_test(struct pci_test *test) · 22 unmodified lines
102 }114 }
103 115
104 if (test->write) {116 if (test->write) {
105 ret = ioctl(fd, PCITEST_WRITE, test->size);117 param.size = test->size;
118 if (test->use_dma)
119 param.flags = PCITEST_FLAGS_USE_DMA;
120 ret = ioctl(fd, PCITEST_WRITE, &param);
106 fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size);121 fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size);
107 if (ret < 0)122 if (ret < 0)
108 fprintf(stdout, "TEST FAILED\n");123 fprintf(stdout, "TEST FAILED\n");
@@ -111,7 +126,10 @@ static int run_test(struct pci_test *test) · 2 unmodified lines
111 }126 }
112 127
113 if (test->read) {128 if (test->read) {
114 ret = ioctl(fd, PCITEST_READ, test->size);129 param.size = test->size;
130 if (test->use_dma)
131 param.flags = PCITEST_FLAGS_USE_DMA;
132 ret = ioctl(fd, PCITEST_READ, &param);
115 fprintf(stdout, "READ (%7ld bytes):\t\t", test->size);133 fprintf(stdout, "READ (%7ld bytes):\t\t", test->size);
116 if (ret < 0)134 if (ret < 0)
117 fprintf(stdout, "TEST FAILED\n");135 fprintf(stdout, "TEST FAILED\n");
@@ -120,7 +138,10 @@ static int run_test(struct pci_test *test) · 2 unmodified lines
120 }138 }
121 139
122 if (test->copy) {140 if (test->copy) {
123 ret = ioctl(fd, PCITEST_COPY, test->size);141 param.size = test->size;
142 if (test->use_dma)
143 param.flags = PCITEST_FLAGS_USE_DMA;
144 ret = ioctl(fd, PCITEST_COPY, &param);
124 fprintf(stdout, "COPY (%7ld bytes):\t\t", test->size);145 fprintf(stdout, "COPY (%7ld bytes):\t\t", test->size);
125 if (ret < 0)146 if (ret < 0)
126 fprintf(stdout, "TEST FAILED\n");147 fprintf(stdout, "TEST FAILED\n");
@@ -153,7 +174,7 @@ int main(int argc, char **argv) · 26 unmodified lines
153 /* set default endpoint device */174 /* set default endpoint device */
154 test->device = "/dev/pci-endpoint-test.0";175 test->device = "/dev/pci-endpoint-test.0";
155 176
156 while ((c = getopt(argc, argv, "D:b:m:x:i:Ilhrwcs:")) != EOF)177 while ((c = getopt(argc, argv, "D:b:m:x:i:deIlhrwcs:")) != EOF)
157 switch (c) {178 switch (c) {
158 case 'D':179 case 'D':
159 test->device = optarg;180 test->device = optarg;
@@ -194,9 +215,15 @@ int main(int argc, char **argv) · 34 unmodified lines
194 case 'c':215 case 'c':
195 test->copy = true;216 test->copy = true;
196 continue;217 continue;
218 case 'e':
219 test->clear_irq = true;
220 continue;
197 case 's':221 case 's':
198 test->size = strtoul(optarg, NULL, 0);222 test->size = strtoul(optarg, NULL, 0);
199 continue;223 continue;
224 case 'd':
225 test->use_dma = true;
226 continue;
200 case 'h':227 case 'h':
201 default:228 default:
202usage:229usage:
@@ -208,7 +235,9 @@ usage: · 5 unmodified lines
208 "\t-m <msi num> MSI test (msi number between 1..32)\n"235 "\t-m <msi num> MSI test (msi number between 1..32)\n"
209 "\t-x <msix num> \tMSI-X test (msix number between 1..2048)\n"236 "\t-x <msix num> \tMSI-X test (msix number between 1..2048)\n"
210 "\t-i <irq type> \tSet IRQ type (0 - Legacy, 1 - MSI, 2 - MSI-X)\n"237 "\t-i <irq type> \tSet IRQ type (0 - Legacy, 1 - MSI, 2 - MSI-X)\n"
238 "\t-e Clear IRQ\n"
211 "\t-I Get current IRQ type configured\n"239 "\t-I Get current IRQ type configured\n"
240 "\t-d Use DMA\n"
212 "\t-l Legacy IRQ test\n"241 "\t-l Legacy IRQ test\n"
213 "\t-r Read buffer test\n"242 "\t-r Read buffer test\n"
214 "\t-w Write buffer test\n"243 "\t-w Write buffer test\n"

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t