aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/PCI/endpoint/function/binding/pci-test.txt2
-rw-r--r--Documentation/PCI/endpoint/pci-endpoint.txt4
-rw-r--r--Documentation/PCI/endpoint/pci-test-function.txt29
-rw-r--r--Documentation/PCI/endpoint/pci-test-howto.txt30
-rw-r--r--Documentation/ioctl/ioctl-number.txt1
-rw-r--r--Documentation/misc-devices/pci-endpoint-test.txt6
-rw-r--r--drivers/misc/pci_endpoint_test.c290
-rw-r--r--drivers/pci/controller/dwc/pci-dra7xx.c2
-rw-r--r--drivers/pci/controller/dwc/pci-exynos.c1
-rw-r--r--drivers/pci/controller/dwc/pci-imx6.c1
-rw-r--r--drivers/pci/controller/dwc/pci-keystone.c1
-rw-r--r--drivers/pci/controller/dwc/pcie-armada8k.c1
-rw-r--r--drivers/pci/controller/dwc/pcie-artpec6.c3
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-ep.c210
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-plat.c12
-rw-r--r--drivers/pci/controller/dwc/pcie-designware.h29
-rw-r--r--drivers/pci/controller/dwc/pcie-histb.c1
-rw-r--r--drivers/pci/controller/dwc/pcie-kirin.c28
-rw-r--r--drivers/pci/controller/dwc/pcie-qcom.c1
-rw-r--r--drivers/pci/controller/dwc/pcie-spear13xx.c1
-rw-r--r--drivers/pci/controller/pcie-cadence-ep.c3
-rw-r--r--drivers/pci/controller/pcie-rockchip-ep.c2
-rw-r--r--drivers/pci/endpoint/functions/pci-epf-test.c86
-rw-r--r--drivers/pci/endpoint/pci-ep-cfs.c24
-rw-r--r--drivers/pci/endpoint/pci-epc-core.c68
-rw-r--r--include/linux/pci-epc.h16
-rw-r--r--include/linux/pci-epf.h1
-rw-r--r--include/uapi/linux/pcitest.h3
-rw-r--r--tools/pci/pcitest.c51
-rw-r--r--tools/pci/pcitest.sh15
30 files changed, 763 insertions, 159 deletions
diff --git a/Documentation/PCI/endpoint/function/binding/pci-test.txt b/Documentation/PCI/endpoint/function/binding/pci-test.txt
index 3b68b955fb50..cd76ba47394b 100644
--- a/Documentation/PCI/endpoint/function/binding/pci-test.txt
+++ b/Documentation/PCI/endpoint/function/binding/pci-test.txt
@@ -15,3 +15,5 @@ subsys_id : don't care
15interrupt_pin : Should be 1 - INTA, 2 - INTB, 3 - INTC, 4 -INTD 15interrupt_pin : Should be 1 - INTA, 2 - INTB, 3 - INTC, 4 -INTD
16msi_interrupts : Should be 1 to 32 depending on the number of MSI interrupts 16msi_interrupts : Should be 1 to 32 depending on the number of MSI interrupts
17 to test 17 to test
18msix_interrupts : Should be 1 to 2048 depending on the number of MSI-X
19 interrupts to test
diff --git a/Documentation/PCI/endpoint/pci-endpoint.txt b/Documentation/PCI/endpoint/pci-endpoint.txt
index 9b1d66829290..e86a96b66a6a 100644
--- a/Documentation/PCI/endpoint/pci-endpoint.txt
+++ b/Documentation/PCI/endpoint/pci-endpoint.txt
@@ -44,7 +44,7 @@ by the PCI controller driver.
44 * clear_bar: ops to reset the BAR 44 * clear_bar: ops to reset the BAR
45 * alloc_addr_space: ops to allocate in PCI controller address space 45 * alloc_addr_space: ops to allocate in PCI controller address space
46 * free_addr_space: ops to free the allocated address space 46 * free_addr_space: ops to free the allocated address space
47 * raise_irq: ops to raise a legacy or MSI interrupt 47 * raise_irq: ops to raise a legacy, MSI or MSI-X interrupt
48 * start: ops to start the PCI link 48 * start: ops to start the PCI link
49 * stop: ops to stop the PCI link 49 * stop: ops to stop the PCI link
50 50
@@ -96,7 +96,7 @@ by the PCI endpoint function driver.
96*) pci_epc_raise_irq() 96*) pci_epc_raise_irq()
97 97
98 The PCI endpoint function driver should use pci_epc_raise_irq() to raise 98 The PCI endpoint function driver should use pci_epc_raise_irq() to raise
99 Legacy Interrupt or MSI Interrupt. 99 Legacy Interrupt, MSI or MSI-X Interrupt.
100 100
101*) pci_epc_mem_alloc_addr() 101*) pci_epc_mem_alloc_addr()
102 102
diff --git a/Documentation/PCI/endpoint/pci-test-function.txt b/Documentation/PCI/endpoint/pci-test-function.txt
index 0c519c9bf94a..5916f1f592bb 100644
--- a/Documentation/PCI/endpoint/pci-test-function.txt
+++ b/Documentation/PCI/endpoint/pci-test-function.txt
@@ -20,6 +20,8 @@ The PCI endpoint test device has the following registers:
20 5) PCI_ENDPOINT_TEST_DST_ADDR 20 5) PCI_ENDPOINT_TEST_DST_ADDR
21 6) PCI_ENDPOINT_TEST_SIZE 21 6) PCI_ENDPOINT_TEST_SIZE
22 7) PCI_ENDPOINT_TEST_CHECKSUM 22 7) PCI_ENDPOINT_TEST_CHECKSUM
23 8) PCI_ENDPOINT_TEST_IRQ_TYPE
24 9) PCI_ENDPOINT_TEST_IRQ_NUMBER
23 25
24*) PCI_ENDPOINT_TEST_MAGIC 26*) PCI_ENDPOINT_TEST_MAGIC
25 27
@@ -34,10 +36,10 @@ that the endpoint device must perform.
34Bitfield Description: 36Bitfield Description:
35 Bit 0 : raise legacy IRQ 37 Bit 0 : raise legacy IRQ
36 Bit 1 : raise MSI IRQ 38 Bit 1 : raise MSI IRQ
37 Bit 2 - 7 : MSI interrupt number 39 Bit 2 : raise MSI-X IRQ
38 Bit 8 : read command (read data from RC buffer) 40 Bit 3 : read command (read data from RC buffer)
39 Bit 9 : write command (write data to RC buffer) 41 Bit 4 : write command (write data to RC buffer)
40 Bit 10 : copy command (copy data from one RC buffer to another 42 Bit 5 : copy command (copy data from one RC buffer to another
41 RC buffer) 43 RC buffer)
42 44
43*) PCI_ENDPOINT_TEST_STATUS 45*) PCI_ENDPOINT_TEST_STATUS
@@ -64,3 +66,22 @@ COPY/READ command.
64 66
65This register contains the destination address (RC buffer address) for 67This register contains the destination address (RC buffer address) for
66the COPY/WRITE command. 68the COPY/WRITE command.
69
70*) PCI_ENDPOINT_TEST_IRQ_TYPE
71
72This register contains the interrupt type (Legacy/MSI) triggered
73for the READ/WRITE/COPY and raise IRQ (Legacy/MSI) commands.
74
75Possible types:
76 - Legacy : 0
77 - MSI : 1
78 - MSI-X : 2
79
80*) PCI_ENDPOINT_TEST_IRQ_NUMBER
81
82This register contains the triggered ID interrupt.
83
84Admissible values:
85 - Legacy : 0
86 - MSI : [1 .. 32]
87 - MSI-X : [1 .. 2048]
diff --git a/Documentation/PCI/endpoint/pci-test-howto.txt b/Documentation/PCI/endpoint/pci-test-howto.txt
index 75f48c3bb191..e40cf0fb58d7 100644
--- a/Documentation/PCI/endpoint/pci-test-howto.txt
+++ b/Documentation/PCI/endpoint/pci-test-howto.txt
@@ -45,9 +45,9 @@ The PCI endpoint framework populates the directory with the following
45configurable fields. 45configurable fields.
46 46
47 # ls functions/pci_epf_test/func1 47 # ls functions/pci_epf_test/func1
48 baseclass_code interrupt_pin revid subsys_vendor_id 48 baseclass_code interrupt_pin progif_code subsys_id
49 cache_line_size msi_interrupts subclass_code vendorid 49 cache_line_size msi_interrupts revid subsys_vendorid
50 deviceid progif_code subsys_id 50 deviceid msix_interrupts subclass_code vendorid
51 51
52The PCI endpoint function driver populates these entries with default values 52The PCI endpoint function driver populates these entries with default values
53when the device is bound to the driver. The pci-epf-test driver populates 53when the device is bound to the driver. The pci-epf-test driver populates
@@ -67,6 +67,7 @@ device, the following commands can be used.
67 # echo 0x104c > functions/pci_epf_test/func1/vendorid 67 # echo 0x104c > functions/pci_epf_test/func1/vendorid
68 # echo 0xb500 > functions/pci_epf_test/func1/deviceid 68 # echo 0xb500 > functions/pci_epf_test/func1/deviceid
69 # echo 16 > functions/pci_epf_test/func1/msi_interrupts 69 # echo 16 > functions/pci_epf_test/func1/msi_interrupts
70 # echo 8 > functions/pci_epf_test/func1/msix_interrupts
70 71
711.5 Binding pci-epf-test Device to EP Controller 721.5 Binding pci-epf-test Device to EP Controller
72 73
@@ -120,7 +121,9 @@ following commands.
120 121
121 Interrupt tests 122 Interrupt tests
122 123
124 SET IRQ TYPE TO LEGACY: OKAY
123 LEGACY IRQ: NOT OKAY 125 LEGACY IRQ: NOT OKAY
126 SET IRQ TYPE TO MSI: OKAY
124 MSI1: OKAY 127 MSI1: OKAY
125 MSI2: OKAY 128 MSI2: OKAY
126 MSI3: OKAY 129 MSI3: OKAY
@@ -153,9 +156,30 @@ following commands.
153 MSI30: NOT OKAY 156 MSI30: NOT OKAY
154 MSI31: NOT OKAY 157 MSI31: NOT OKAY
155 MSI32: NOT OKAY 158 MSI32: NOT OKAY
159 SET IRQ TYPE TO MSI-X: OKAY
160 MSI-X1: OKAY
161 MSI-X2: OKAY
162 MSI-X3: OKAY
163 MSI-X4: OKAY
164 MSI-X5: OKAY
165 MSI-X6: OKAY
166 MSI-X7: OKAY
167 MSI-X8: OKAY
168 MSI-X9: NOT OKAY
169 MSI-X10: NOT OKAY
170 MSI-X11: NOT OKAY
171 MSI-X12: NOT OKAY
172 MSI-X13: NOT OKAY
173 MSI-X14: NOT OKAY
174 MSI-X15: NOT OKAY
175 MSI-X16: NOT OKAY
176 [...]
177 MSI-X2047: NOT OKAY
178 MSI-X2048: NOT OKAY
156 179
157 Read Tests 180 Read Tests
158 181
182 SET IRQ TYPE TO MSI: OKAY
159 READ ( 1 bytes): OKAY 183 READ ( 1 bytes): OKAY
160 READ ( 1024 bytes): OKAY 184 READ ( 1024 bytes): OKAY
161 READ ( 1025 bytes): OKAY 185 READ ( 1025 bytes): OKAY
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index 480c8609dc58..c15c4f3bdd82 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -166,6 +166,7 @@ Code Seq#(hex) Include File Comments
166'P' all linux/soundcard.h conflict! 166'P' all linux/soundcard.h conflict!
167'P' 60-6F sound/sscape_ioctl.h conflict! 167'P' 60-6F sound/sscape_ioctl.h conflict!
168'P' 00-0F drivers/usb/class/usblp.c conflict! 168'P' 00-0F drivers/usb/class/usblp.c conflict!
169'P' 01-09 drivers/misc/pci_endpoint_test.c conflict!
169'Q' all linux/soundcard.h 170'Q' all linux/soundcard.h
170'R' 00-1F linux/random.h conflict! 171'R' 00-1F linux/random.h conflict!
171'R' 01 linux/rfkill.h conflict! 172'R' 01 linux/rfkill.h conflict!
diff --git a/Documentation/misc-devices/pci-endpoint-test.txt b/Documentation/misc-devices/pci-endpoint-test.txt
index 4ebc3594b32c..58ccca4416b1 100644
--- a/Documentation/misc-devices/pci-endpoint-test.txt
+++ b/Documentation/misc-devices/pci-endpoint-test.txt
@@ -10,6 +10,7 @@ The PCI driver for the test device performs the following tests
10 *) verifying addresses programmed in BAR 10 *) verifying addresses programmed in BAR
11 *) raise legacy IRQ 11 *) raise legacy IRQ
12 *) raise MSI IRQ 12 *) raise MSI IRQ
13 *) raise MSI-X IRQ
13 *) read data 14 *) read data
14 *) write data 15 *) write data
15 *) copy data 16 *) copy data
@@ -25,6 +26,11 @@ ioctl
25 PCITEST_LEGACY_IRQ: Tests legacy IRQ 26 PCITEST_LEGACY_IRQ: Tests legacy IRQ
26 PCITEST_MSI: Tests message signalled interrupts. The MSI number 27 PCITEST_MSI: Tests message signalled interrupts. The MSI number
27 to be tested should be passed as argument. 28 to be tested should be passed as argument.
29 PCITEST_MSIX: Tests message signalled interrupts. The MSI-X number
30 to be tested should be passed as argument.
31 PCITEST_SET_IRQTYPE: Changes driver IRQ type configuration. The IRQ type
32 should be passed as argument (0: Legacy, 1:MSI, 2:MSI-X).
33 PCITEST_GET_IRQTYPE: Gets driver IRQ type configuration.
28 PCITEST_WRITE: Perform write tests. The size of the buffer should be passed 34 PCITEST_WRITE: Perform write tests. The size of the buffer should be passed
29 as argument. 35 as argument.
30 PCITEST_READ: Perform read tests. The size of the buffer should be passed 36 PCITEST_READ: Perform read tests. The size of the buffer should be passed
diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 7b370466a227..896e2df9400f 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -35,38 +35,45 @@
35 35
36#include <uapi/linux/pcitest.h> 36#include <uapi/linux/pcitest.h>
37 37
38#define DRV_MODULE_NAME "pci-endpoint-test" 38#define DRV_MODULE_NAME "pci-endpoint-test"
39 39
40#define PCI_ENDPOINT_TEST_MAGIC 0x0 40#define IRQ_TYPE_UNDEFINED -1
41 41#define IRQ_TYPE_LEGACY 0
42#define PCI_ENDPOINT_TEST_COMMAND 0x4 42#define IRQ_TYPE_MSI 1
43#define COMMAND_RAISE_LEGACY_IRQ BIT(0) 43#define IRQ_TYPE_MSIX 2
44#define COMMAND_RAISE_MSI_IRQ BIT(1) 44
45#define MSI_NUMBER_SHIFT 2 45#define PCI_ENDPOINT_TEST_MAGIC 0x0
46/* 6 bits for MSI number */ 46
47#define COMMAND_READ BIT(8) 47#define PCI_ENDPOINT_TEST_COMMAND 0x4
48#define COMMAND_WRITE BIT(9) 48#define COMMAND_RAISE_LEGACY_IRQ BIT(0)
49#define COMMAND_COPY BIT(10) 49#define COMMAND_RAISE_MSI_IRQ BIT(1)
50 50#define COMMAND_RAISE_MSIX_IRQ BIT(2)
51#define PCI_ENDPOINT_TEST_STATUS 0x8 51#define COMMAND_READ BIT(3)
52#define STATUS_READ_SUCCESS BIT(0) 52#define COMMAND_WRITE BIT(4)
53#define STATUS_READ_FAIL BIT(1) 53#define COMMAND_COPY BIT(5)
54#define STATUS_WRITE_SUCCESS BIT(2) 54
55#define STATUS_WRITE_FAIL BIT(3) 55#define PCI_ENDPOINT_TEST_STATUS 0x8
56#define STATUS_COPY_SUCCESS BIT(4) 56#define STATUS_READ_SUCCESS BIT(0)
57#define STATUS_COPY_FAIL BIT(5) 57#define STATUS_READ_FAIL BIT(1)
58#define STATUS_IRQ_RAISED BIT(6) 58#define STATUS_WRITE_SUCCESS BIT(2)
59#define STATUS_SRC_ADDR_INVALID BIT(7) 59#define STATUS_WRITE_FAIL BIT(3)
60#define STATUS_DST_ADDR_INVALID BIT(8) 60#define STATUS_COPY_SUCCESS BIT(4)
61 61#define STATUS_COPY_FAIL BIT(5)
62#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR 0xc 62#define STATUS_IRQ_RAISED BIT(6)
63#define STATUS_SRC_ADDR_INVALID BIT(7)
64#define STATUS_DST_ADDR_INVALID BIT(8)
65
66#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR 0x0c
63#define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR 0x10 67#define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR 0x10
64 68
65#define PCI_ENDPOINT_TEST_LOWER_DST_ADDR 0x14 69#define PCI_ENDPOINT_TEST_LOWER_DST_ADDR 0x14
66#define PCI_ENDPOINT_TEST_UPPER_DST_ADDR 0x18 70#define PCI_ENDPOINT_TEST_UPPER_DST_ADDR 0x18
67 71
68#define PCI_ENDPOINT_TEST_SIZE 0x1c 72#define PCI_ENDPOINT_TEST_SIZE 0x1c
69#define PCI_ENDPOINT_TEST_CHECKSUM 0x20 73#define PCI_ENDPOINT_TEST_CHECKSUM 0x20
74
75#define PCI_ENDPOINT_TEST_IRQ_TYPE 0x24
76#define PCI_ENDPOINT_TEST_IRQ_NUMBER 0x28
70 77
71static DEFINE_IDA(pci_endpoint_test_ida); 78static DEFINE_IDA(pci_endpoint_test_ida);
72 79
@@ -77,6 +84,10 @@ static bool no_msi;
77module_param(no_msi, bool, 0444); 84module_param(no_msi, bool, 0444);
78MODULE_PARM_DESC(no_msi, "Disable MSI interrupt in pci_endpoint_test"); 85MODULE_PARM_DESC(no_msi, "Disable MSI interrupt in pci_endpoint_test");
79 86
87static int irq_type = IRQ_TYPE_MSI;
88module_param(irq_type, int, 0444);
89MODULE_PARM_DESC(irq_type, "IRQ mode selection in pci_endpoint_test (0 - Legacy, 1 - MSI, 2 - MSI-X)");
90
80enum pci_barno { 91enum pci_barno {
81 BAR_0, 92 BAR_0,
82 BAR_1, 93 BAR_1,
@@ -103,7 +114,7 @@ struct pci_endpoint_test {
103struct pci_endpoint_test_data { 114struct pci_endpoint_test_data {
104 enum pci_barno test_reg_bar; 115 enum pci_barno test_reg_bar;
105 size_t alignment; 116 size_t alignment;
106 bool no_msi; 117 int irq_type;
107}; 118};
108 119
109static inline u32 pci_endpoint_test_readl(struct pci_endpoint_test *test, 120static inline u32 pci_endpoint_test_readl(struct pci_endpoint_test *test,
@@ -147,6 +158,100 @@ static irqreturn_t pci_endpoint_test_irqhandler(int irq, void *dev_id)
147 return IRQ_HANDLED; 158 return IRQ_HANDLED;
148} 159}
149 160
161static void pci_endpoint_test_free_irq_vectors(struct pci_endpoint_test *test)
162{
163 struct pci_dev *pdev = test->pdev;
164
165 pci_free_irq_vectors(pdev);
166}
167
168static bool pci_endpoint_test_alloc_irq_vectors(struct pci_endpoint_test *test,
169 int type)
170{
171 int irq = -1;
172 struct pci_dev *pdev = test->pdev;
173 struct device *dev = &pdev->dev;
174 bool res = true;
175
176 switch (type) {
177 case IRQ_TYPE_LEGACY:
178 irq = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY);
179 if (irq < 0)
180 dev_err(dev, "Failed to get Legacy interrupt\n");
181 break;
182 case IRQ_TYPE_MSI:
183 irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI);
184 if (irq < 0)
185 dev_err(dev, "Failed to get MSI interrupts\n");
186 break;
187 case IRQ_TYPE_MSIX:
188 irq = pci_alloc_irq_vectors(pdev, 1, 2048, PCI_IRQ_MSIX);
189 if (irq < 0)
190 dev_err(dev, "Failed to get MSI-X interrupts\n");
191 break;
192 default:
193 dev_err(dev, "Invalid IRQ type selected\n");
194 }
195
196 if (irq < 0) {
197 irq = 0;
198 res = false;
199 }
200 test->num_irqs = irq;
201
202 return res;
203}
204
205static void pci_endpoint_test_release_irq(struct pci_endpoint_test *test)
206{
207 int i;
208 struct pci_dev *pdev = test->pdev;
209 struct device *dev = &pdev->dev;
210
211 for (i = 0; i < test->num_irqs; i++)
212 devm_free_irq(dev, pci_irq_vector(pdev, i), test);
213
214 test->num_irqs = 0;
215}
216
217static bool pci_endpoint_test_request_irq(struct pci_endpoint_test *test)
218{
219 int i;
220 int err;
221 struct pci_dev *pdev = test->pdev;
222 struct device *dev = &pdev->dev;
223
224 for (i = 0; i < test->num_irqs; i++) {
225 err = devm_request_irq(dev, pci_irq_vector(pdev, i),
226 pci_endpoint_test_irqhandler,
227 IRQF_SHARED, DRV_MODULE_NAME, test);
228 if (err)
229 goto fail;
230 }
231
232 return true;
233
234fail:
235 switch (irq_type) {
236 case IRQ_TYPE_LEGACY:
237 dev_err(dev, "Failed to request IRQ %d for Legacy\n",
238 pci_irq_vector(pdev, i));
239 break;
240 case IRQ_TYPE_MSI:
241 dev_err(dev, "Failed to request IRQ %d for MSI %d\n",
242 pci_irq_vector(pdev, i),
243 i + 1);
244 break;
245 case IRQ_TYPE_MSIX:
246 dev_err(dev, "Failed to request IRQ %d for MSI-X %d\n",
247 pci_irq_vector(pdev, i),
248 i + 1);
249 break;
250 }
251
252 return false;
253}
254
150static bool pci_endpoint_test_bar(struct pci_endpoint_test *test, 255static bool pci_endpoint_test_bar(struct pci_endpoint_test *test,
151 enum pci_barno barno) 256 enum pci_barno barno)
152{ 257{
@@ -179,6 +284,9 @@ static bool pci_endpoint_test_legacy_irq(struct pci_endpoint_test *test)
179{ 284{
180 u32 val; 285 u32 val;
181 286
287 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
288 IRQ_TYPE_LEGACY);
289 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 0);
182 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, 290 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
183 COMMAND_RAISE_LEGACY_IRQ); 291 COMMAND_RAISE_LEGACY_IRQ);
184 val = wait_for_completion_timeout(&test->irq_raised, 292 val = wait_for_completion_timeout(&test->irq_raised,
@@ -190,14 +298,18 @@ static bool pci_endpoint_test_legacy_irq(struct pci_endpoint_test *test)
190} 298}
191 299
192static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test, 300static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
193 u8 msi_num) 301 u16 msi_num, bool msix)
194{ 302{
195 u32 val; 303 u32 val;
196 struct pci_dev *pdev = test->pdev; 304 struct pci_dev *pdev = test->pdev;
197 305
306 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
307 msix == false ? IRQ_TYPE_MSI :
308 IRQ_TYPE_MSIX);
309 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, msi_num);
198 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, 310 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
199 msi_num << MSI_NUMBER_SHIFT | 311 msix == false ? COMMAND_RAISE_MSI_IRQ :
200 COMMAND_RAISE_MSI_IRQ); 312 COMMAND_RAISE_MSIX_IRQ);
201 val = wait_for_completion_timeout(&test->irq_raised, 313 val = wait_for_completion_timeout(&test->irq_raised,
202 msecs_to_jiffies(1000)); 314 msecs_to_jiffies(1000));
203 if (!val) 315 if (!val)
@@ -230,6 +342,11 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
230 if (size > SIZE_MAX - alignment) 342 if (size > SIZE_MAX - alignment)
231 goto err; 343 goto err;
232 344
345 if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
346 dev_err(dev, "Invalid IRQ type option\n");
347 goto err;
348 }
349
233 orig_src_addr = dma_alloc_coherent(dev, size + alignment, 350 orig_src_addr = dma_alloc_coherent(dev, size + alignment,
234 &orig_src_phys_addr, GFP_KERNEL); 351 &orig_src_phys_addr, GFP_KERNEL);
235 if (!orig_src_addr) { 352 if (!orig_src_addr) {
@@ -281,8 +398,10 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
281 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, 398 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE,
282 size); 399 size);
283 400
401 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
402 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
284 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, 403 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
285 1 << MSI_NUMBER_SHIFT | COMMAND_COPY); 404 COMMAND_COPY);
286 405
287 wait_for_completion(&test->irq_raised); 406 wait_for_completion(&test->irq_raised);
288 407
@@ -318,6 +437,11 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)
318 if (size > SIZE_MAX - alignment) 437 if (size > SIZE_MAX - alignment)
319 goto err; 438 goto err;
320 439
440 if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
441 dev_err(dev, "Invalid IRQ type option\n");
442 goto err;
443 }
444
321 orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr, 445 orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr,
322 GFP_KERNEL); 446 GFP_KERNEL);
323 if (!orig_addr) { 447 if (!orig_addr) {
@@ -348,8 +472,10 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)
348 472
349 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size); 473 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
350 474
475 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
476 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
351 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, 477 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
352 1 << MSI_NUMBER_SHIFT | COMMAND_READ); 478 COMMAND_READ);
353 479
354 wait_for_completion(&test->irq_raised); 480 wait_for_completion(&test->irq_raised);
355 481
@@ -379,6 +505,11 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size)
379 if (size > SIZE_MAX - alignment) 505 if (size > SIZE_MAX - alignment)
380 goto err; 506 goto err;
381 507
508 if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
509 dev_err(dev, "Invalid IRQ type option\n");
510 goto err;
511 }
512
382 orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr, 513 orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr,
383 GFP_KERNEL); 514 GFP_KERNEL);
384 if (!orig_addr) { 515 if (!orig_addr) {
@@ -403,8 +534,10 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size)
403 534
404 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size); 535 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
405 536
537 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
538 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
406 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, 539 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
407 1 << MSI_NUMBER_SHIFT | COMMAND_WRITE); 540 COMMAND_WRITE);
408 541
409 wait_for_completion(&test->irq_raised); 542 wait_for_completion(&test->irq_raised);
410 543
@@ -417,6 +550,38 @@ err:
417 return ret; 550 return ret;
418} 551}
419 552
553static bool pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
554 int req_irq_type)
555{
556 struct pci_dev *pdev = test->pdev;
557 struct device *dev = &pdev->dev;
558
559 if (req_irq_type < IRQ_TYPE_LEGACY || req_irq_type > IRQ_TYPE_MSIX) {
560 dev_err(dev, "Invalid IRQ type option\n");
561 return false;
562 }
563
564 if (irq_type == req_irq_type)
565 return true;
566
567 pci_endpoint_test_release_irq(test);
568 pci_endpoint_test_free_irq_vectors(test);
569
570 if (!pci_endpoint_test_alloc_irq_vectors(test, req_irq_type))
571 goto err;
572
573 if (!pci_endpoint_test_request_irq(test))
574 goto err;
575
576 irq_type = req_irq_type;
577 return true;
578
579err:
580 pci_endpoint_test_free_irq_vectors(test);
581 irq_type = IRQ_TYPE_UNDEFINED;
582 return false;
583}
584
420static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd, 585static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
421 unsigned long arg) 586 unsigned long arg)
422{ 587{
@@ -436,7 +601,8 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
436 ret = pci_endpoint_test_legacy_irq(test); 601 ret = pci_endpoint_test_legacy_irq(test);
437 break; 602 break;
438 case PCITEST_MSI: 603 case PCITEST_MSI:
439 ret = pci_endpoint_test_msi_irq(test, arg); 604 case PCITEST_MSIX:
605 ret = pci_endpoint_test_msi_irq(test, arg, cmd == PCITEST_MSIX);
440 break; 606 break;
441 case PCITEST_WRITE: 607 case PCITEST_WRITE:
442 ret = pci_endpoint_test_write(test, arg); 608 ret = pci_endpoint_test_write(test, arg);
@@ -447,6 +613,12 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
447 case PCITEST_COPY: 613 case PCITEST_COPY:
448 ret = pci_endpoint_test_copy(test, arg); 614 ret = pci_endpoint_test_copy(test, arg);
449 break; 615 break;
616 case PCITEST_SET_IRQTYPE:
617 ret = pci_endpoint_test_set_irq(test, arg);
618 break;
619 case PCITEST_GET_IRQTYPE:
620 ret = irq_type;
621 break;
450 } 622 }
451 623
452ret: 624ret:
@@ -462,9 +634,7 @@ static const struct file_operations pci_endpoint_test_fops = {
462static int pci_endpoint_test_probe(struct pci_dev *pdev, 634static int pci_endpoint_test_probe(struct pci_dev *pdev,
463 const struct pci_device_id *ent) 635 const struct pci_device_id *ent)
464{ 636{
465 int i;
466 int err; 637 int err;
467 int irq = 0;
468 int id; 638 int id;
469 char name[20]; 639 char name[20];
470 enum pci_barno bar; 640 enum pci_barno bar;
@@ -486,11 +656,14 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
486 test->alignment = 0; 656 test->alignment = 0;
487 test->pdev = pdev; 657 test->pdev = pdev;
488 658
659 if (no_msi)
660 irq_type = IRQ_TYPE_LEGACY;
661
489 data = (struct pci_endpoint_test_data *)ent->driver_data; 662 data = (struct pci_endpoint_test_data *)ent->driver_data;
490 if (data) { 663 if (data) {
491 test_reg_bar = data->test_reg_bar; 664 test_reg_bar = data->test_reg_bar;
492 test->alignment = data->alignment; 665 test->alignment = data->alignment;
493 no_msi = data->no_msi; 666 irq_type = data->irq_type;
494 } 667 }
495 668
496 init_completion(&test->irq_raised); 669 init_completion(&test->irq_raised);
@@ -510,28 +683,11 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
510 683
511 pci_set_master(pdev); 684 pci_set_master(pdev);
512 685
513 if (!no_msi) { 686 if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type))
514 irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI); 687 goto err_disable_irq;
515 if (irq < 0)
516 dev_err(dev, "Failed to get MSI interrupts\n");
517 test->num_irqs = irq;
518 }
519
520 err = devm_request_irq(dev, pdev->irq, pci_endpoint_test_irqhandler,
521 IRQF_SHARED, DRV_MODULE_NAME, test);
522 if (err) {
523 dev_err(dev, "Failed to request IRQ %d\n", pdev->irq);
524 goto err_disable_msi;
525 }
526 688
527 for (i = 1; i < irq; i++) { 689 if (!pci_endpoint_test_request_irq(test))
528 err = devm_request_irq(dev, pci_irq_vector(pdev, i), 690 goto err_disable_irq;
529 pci_endpoint_test_irqhandler,
530 IRQF_SHARED, DRV_MODULE_NAME, test);
531 if (err)
532 dev_err(dev, "failed to request IRQ %d for MSI %d\n",
533 pci_irq_vector(pdev, i), i + 1);
534 }
535 691
536 for (bar = BAR_0; bar <= BAR_5; bar++) { 692 for (bar = BAR_0; bar <= BAR_5; bar++) {
537 if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) { 693 if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
@@ -590,12 +746,10 @@ err_iounmap:
590 if (test->bar[bar]) 746 if (test->bar[bar])
591 pci_iounmap(pdev, test->bar[bar]); 747 pci_iounmap(pdev, test->bar[bar]);
592 } 748 }
749 pci_endpoint_test_release_irq(test);
593 750
594 for (i = 0; i < irq; i++) 751err_disable_irq:
595 devm_free_irq(&pdev->dev, pci_irq_vector(pdev, i), test); 752 pci_endpoint_test_free_irq_vectors(test);
596
597err_disable_msi:
598 pci_disable_msi(pdev);
599 pci_release_regions(pdev); 753 pci_release_regions(pdev);
600 754
601err_disable_pdev: 755err_disable_pdev:
@@ -607,7 +761,6 @@ err_disable_pdev:
607static void pci_endpoint_test_remove(struct pci_dev *pdev) 761static void pci_endpoint_test_remove(struct pci_dev *pdev)
608{ 762{
609 int id; 763 int id;
610 int i;
611 enum pci_barno bar; 764 enum pci_barno bar;
612 struct pci_endpoint_test *test = pci_get_drvdata(pdev); 765 struct pci_endpoint_test *test = pci_get_drvdata(pdev);
613 struct miscdevice *misc_device = &test->miscdev; 766 struct miscdevice *misc_device = &test->miscdev;
@@ -624,9 +777,10 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev)
624 if (test->bar[bar]) 777 if (test->bar[bar])
625 pci_iounmap(pdev, test->bar[bar]); 778 pci_iounmap(pdev, test->bar[bar]);
626 } 779 }
627 for (i = 0; i < test->num_irqs; i++) 780
628 devm_free_irq(&pdev->dev, pci_irq_vector(pdev, i), test); 781 pci_endpoint_test_release_irq(test);
629 pci_disable_msi(pdev); 782 pci_endpoint_test_free_irq_vectors(test);
783
630 pci_release_regions(pdev); 784 pci_release_regions(pdev);
631 pci_disable_device(pdev); 785 pci_disable_device(pdev);
632} 786}
diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
index 345aab56ce8b..ce9224a36f62 100644
--- a/drivers/pci/controller/dwc/pci-dra7xx.c
+++ b/drivers/pci/controller/dwc/pci-dra7xx.c
@@ -370,7 +370,7 @@ static void dra7xx_pcie_raise_msi_irq(struct dra7xx_pcie *dra7xx,
370} 370}
371 371
372static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, 372static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
373 enum pci_epc_irq_type type, u8 interrupt_num) 373 enum pci_epc_irq_type type, u16 interrupt_num)
374{ 374{
375 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 375 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
376 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); 376 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
index 4cc1e5df8c79..cee5f2f590e2 100644
--- a/drivers/pci/controller/dwc/pci-exynos.c
+++ b/drivers/pci/controller/dwc/pci-exynos.c
@@ -421,7 +421,6 @@ static int __init exynos_add_pcie_port(struct exynos_pcie *ep,
421 } 421 }
422 } 422 }
423 423
424 pp->root_bus_nr = -1;
425 pp->ops = &exynos_pcie_host_ops; 424 pp->ops = &exynos_pcie_host_ops;
426 425
427 ret = dw_pcie_host_init(pp); 426 ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 80f604602783..4a9a673b4777 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -667,7 +667,6 @@ static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
667 } 667 }
668 } 668 }
669 669
670 pp->root_bus_nr = -1;
671 pp->ops = &imx6_pcie_host_ops; 670 pp->ops = &imx6_pcie_host_ops;
672 671
673 ret = dw_pcie_host_init(pp); 672 ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
index 3722a5f31e5e..e88bd221fffe 100644
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -347,7 +347,6 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,
347 } 347 }
348 } 348 }
349 349
350 pp->root_bus_nr = -1;
351 pp->ops = &keystone_pcie_host_ops; 350 pp->ops = &keystone_pcie_host_ops;
352 ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np); 351 ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
353 if (ret) { 352 if (ret) {
diff --git a/drivers/pci/controller/dwc/pcie-armada8k.c b/drivers/pci/controller/dwc/pcie-armada8k.c
index 072fd7ecc29f..0c389a30ef5d 100644
--- a/drivers/pci/controller/dwc/pcie-armada8k.c
+++ b/drivers/pci/controller/dwc/pcie-armada8k.c
@@ -172,7 +172,6 @@ static int armada8k_add_pcie_port(struct armada8k_pcie *pcie,
172 struct device *dev = &pdev->dev; 172 struct device *dev = &pdev->dev;
173 int ret; 173 int ret;
174 174
175 pp->root_bus_nr = -1;
176 pp->ops = &armada8k_pcie_host_ops; 175 pp->ops = &armada8k_pcie_host_ops;
177 176
178 pp->irq = platform_get_irq(pdev, 0); 177 pp->irq = platform_get_irq(pdev, 0);
diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c
index 321b56cfd5d0..dba83abfe764 100644
--- a/drivers/pci/controller/dwc/pcie-artpec6.c
+++ b/drivers/pci/controller/dwc/pcie-artpec6.c
@@ -399,7 +399,6 @@ static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie,
399 } 399 }
400 } 400 }
401 401
402 pp->root_bus_nr = -1;
403 pp->ops = &artpec6_pcie_host_ops; 402 pp->ops = &artpec6_pcie_host_ops;
404 403
405 ret = dw_pcie_host_init(pp); 404 ret = dw_pcie_host_init(pp);
@@ -428,7 +427,7 @@ static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
428} 427}
429 428
430static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, 429static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
431 enum pci_epc_irq_type type, u8 interrupt_num) 430 enum pci_epc_irq_type type, u16 interrupt_num)
432{ 431{
433 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 432 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
434 433
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 8650416f6f9e..1e7b02221eac 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -40,6 +40,39 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
40 __dw_pcie_ep_reset_bar(pci, bar, 0); 40 __dw_pcie_ep_reset_bar(pci, bar, 0);
41} 41}
42 42
43static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie *pci, u8 cap_ptr,
44 u8 cap)
45{
46 u8 cap_id, next_cap_ptr;
47 u16 reg;
48
49 reg = dw_pcie_readw_dbi(pci, cap_ptr);
50 next_cap_ptr = (reg & 0xff00) >> 8;
51 cap_id = (reg & 0x00ff);
52
53 if (!next_cap_ptr || cap_id > PCI_CAP_ID_MAX)
54 return 0;
55
56 if (cap_id == cap)
57 return cap_ptr;
58
59 return __dw_pcie_ep_find_next_cap(pci, next_cap_ptr, cap);
60}
61
62static u8 dw_pcie_ep_find_capability(struct dw_pcie *pci, u8 cap)
63{
64 u8 next_cap_ptr;
65 u16 reg;
66
67 reg = dw_pcie_readw_dbi(pci, PCI_CAPABILITY_LIST);
68 next_cap_ptr = (reg & 0x00ff);
69
70 if (!next_cap_ptr)
71 return 0;
72
73 return __dw_pcie_ep_find_next_cap(pci, next_cap_ptr, cap);
74}
75
43static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no, 76static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
44 struct pci_epf_header *hdr) 77 struct pci_epf_header *hdr)
45{ 78{
@@ -213,36 +246,84 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
213 246
214static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no) 247static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
215{ 248{
216 int val;
217 struct dw_pcie_ep *ep = epc_get_drvdata(epc); 249 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
218 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 250 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
251 u32 val, reg;
252
253 if (!ep->msi_cap)
254 return -EINVAL;
255
256 reg = ep->msi_cap + PCI_MSI_FLAGS;
257 val = dw_pcie_readw_dbi(pci, reg);
258 if (!(val & PCI_MSI_FLAGS_ENABLE))
259 return -EINVAL;
260
261 val = (val & PCI_MSI_FLAGS_QSIZE) >> 4;
262
263 return val;
264}
265
266static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
267{
268 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
269 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
270 u32 val, reg;
271
272 if (!ep->msi_cap)
273 return -EINVAL;
274
275 reg = ep->msi_cap + PCI_MSI_FLAGS;
276 val = dw_pcie_readw_dbi(pci, reg);
277 val &= ~PCI_MSI_FLAGS_QMASK;
278 val |= (interrupts << 1) & PCI_MSI_FLAGS_QMASK;
279 dw_pcie_dbi_ro_wr_en(pci);
280 dw_pcie_writew_dbi(pci, reg, val);
281 dw_pcie_dbi_ro_wr_dis(pci);
282
283 return 0;
284}
285
286static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
287{
288 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
289 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
290 u32 val, reg;
219 291
220 val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL); 292 if (!ep->msix_cap)
221 if (!(val & MSI_CAP_MSI_EN_MASK))
222 return -EINVAL; 293 return -EINVAL;
223 294
224 val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT; 295 reg = ep->msix_cap + PCI_MSIX_FLAGS;
296 val = dw_pcie_readw_dbi(pci, reg);
297 if (!(val & PCI_MSIX_FLAGS_ENABLE))
298 return -EINVAL;
299
300 val &= PCI_MSIX_FLAGS_QSIZE;
301
225 return val; 302 return val;
226} 303}
227 304
228static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 encode_int) 305static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts)
229{ 306{
230 int val;
231 struct dw_pcie_ep *ep = epc_get_drvdata(epc); 307 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
232 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 308 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
309 u32 val, reg;
310
311 if (!ep->msix_cap)
312 return -EINVAL;
233 313
234 val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL); 314 reg = ep->msix_cap + PCI_MSIX_FLAGS;
235 val &= ~MSI_CAP_MMC_MASK; 315 val = dw_pcie_readw_dbi(pci, reg);
236 val |= (encode_int << MSI_CAP_MMC_SHIFT) & MSI_CAP_MMC_MASK; 316 val &= ~PCI_MSIX_FLAGS_QSIZE;
317 val |= interrupts;
237 dw_pcie_dbi_ro_wr_en(pci); 318 dw_pcie_dbi_ro_wr_en(pci);
238 dw_pcie_writew_dbi(pci, MSI_MESSAGE_CONTROL, val); 319 dw_pcie_writew_dbi(pci, reg, val);
239 dw_pcie_dbi_ro_wr_dis(pci); 320 dw_pcie_dbi_ro_wr_dis(pci);
240 321
241 return 0; 322 return 0;
242} 323}
243 324
244static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no, 325static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no,
245 enum pci_epc_irq_type type, u8 interrupt_num) 326 enum pci_epc_irq_type type, u16 interrupt_num)
246{ 327{
247 struct dw_pcie_ep *ep = epc_get_drvdata(epc); 328 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
248 329
@@ -282,32 +363,52 @@ static const struct pci_epc_ops epc_ops = {
282 .unmap_addr = dw_pcie_ep_unmap_addr, 363 .unmap_addr = dw_pcie_ep_unmap_addr,
283 .set_msi = dw_pcie_ep_set_msi, 364 .set_msi = dw_pcie_ep_set_msi,
284 .get_msi = dw_pcie_ep_get_msi, 365 .get_msi = dw_pcie_ep_get_msi,
366 .set_msix = dw_pcie_ep_set_msix,
367 .get_msix = dw_pcie_ep_get_msix,
285 .raise_irq = dw_pcie_ep_raise_irq, 368 .raise_irq = dw_pcie_ep_raise_irq,
286 .start = dw_pcie_ep_start, 369 .start = dw_pcie_ep_start,
287 .stop = dw_pcie_ep_stop, 370 .stop = dw_pcie_ep_stop,
288}; 371};
289 372
373int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no)
374{
375 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
376 struct device *dev = pci->dev;
377
378 dev_err(dev, "EP cannot trigger legacy IRQs\n");
379
380 return -EINVAL;
381}
382
290int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, 383int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
291 u8 interrupt_num) 384 u8 interrupt_num)
292{ 385{
293 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 386 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
294 struct pci_epc *epc = ep->epc; 387 struct pci_epc *epc = ep->epc;
295 u16 msg_ctrl, msg_data; 388 u16 msg_ctrl, msg_data;
296 u32 msg_addr_lower, msg_addr_upper; 389 u32 msg_addr_lower, msg_addr_upper, reg;
297 u64 msg_addr; 390 u64 msg_addr;
298 bool has_upper; 391 bool has_upper;
299 int ret; 392 int ret;
300 393
394 if (!ep->msi_cap)
395 return -EINVAL;
396
301 /* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */ 397 /* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */
302 msg_ctrl = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL); 398 reg = ep->msi_cap + PCI_MSI_FLAGS;
399 msg_ctrl = dw_pcie_readw_dbi(pci, reg);
303 has_upper = !!(msg_ctrl & PCI_MSI_FLAGS_64BIT); 400 has_upper = !!(msg_ctrl & PCI_MSI_FLAGS_64BIT);
304 msg_addr_lower = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_L32); 401 reg = ep->msi_cap + PCI_MSI_ADDRESS_LO;
402 msg_addr_lower = dw_pcie_readl_dbi(pci, reg);
305 if (has_upper) { 403 if (has_upper) {
306 msg_addr_upper = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_U32); 404 reg = ep->msi_cap + PCI_MSI_ADDRESS_HI;
307 msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_64); 405 msg_addr_upper = dw_pcie_readl_dbi(pci, reg);
406 reg = ep->msi_cap + PCI_MSI_DATA_64;
407 msg_data = dw_pcie_readw_dbi(pci, reg);
308 } else { 408 } else {
309 msg_addr_upper = 0; 409 msg_addr_upper = 0;
310 msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_32); 410 reg = ep->msi_cap + PCI_MSI_DATA_32;
411 msg_data = dw_pcie_readw_dbi(pci, reg);
311 } 412 }
312 msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower; 413 msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower;
313 ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr, 414 ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
@@ -322,6 +423,64 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
322 return 0; 423 return 0;
323} 424}
324 425
426int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
427 u16 interrupt_num)
428{
429 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
430 struct pci_epc *epc = ep->epc;
431 u16 tbl_offset, bir;
432 u32 bar_addr_upper, bar_addr_lower;
433 u32 msg_addr_upper, msg_addr_lower;
434 u32 reg, msg_data, vec_ctrl;
435 u64 tbl_addr, msg_addr, reg_u64;
436 void __iomem *msix_tbl;
437 int ret;
438
439 reg = ep->msix_cap + PCI_MSIX_TABLE;
440 tbl_offset = dw_pcie_readl_dbi(pci, reg);
441 bir = (tbl_offset & PCI_MSIX_TABLE_BIR);
442 tbl_offset &= PCI_MSIX_TABLE_OFFSET;
443 tbl_offset >>= 3;
444
445 reg = PCI_BASE_ADDRESS_0 + (4 * bir);
446 bar_addr_upper = 0;
447 bar_addr_lower = dw_pcie_readl_dbi(pci, reg);
448 reg_u64 = (bar_addr_lower & PCI_BASE_ADDRESS_MEM_TYPE_MASK);
449 if (reg_u64 == PCI_BASE_ADDRESS_MEM_TYPE_64)
450 bar_addr_upper = dw_pcie_readl_dbi(pci, reg + 4);
451
452 tbl_addr = ((u64) bar_addr_upper) << 32 | bar_addr_lower;
453 tbl_addr += (tbl_offset + ((interrupt_num - 1) * PCI_MSIX_ENTRY_SIZE));
454 tbl_addr &= PCI_BASE_ADDRESS_MEM_MASK;
455
456 msix_tbl = ioremap_nocache(ep->phys_base + tbl_addr,
457 PCI_MSIX_ENTRY_SIZE);
458 if (!msix_tbl)
459 return -EINVAL;
460
461 msg_addr_lower = readl(msix_tbl + PCI_MSIX_ENTRY_LOWER_ADDR);
462 msg_addr_upper = readl(msix_tbl + PCI_MSIX_ENTRY_UPPER_ADDR);
463 msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower;
464 msg_data = readl(msix_tbl + PCI_MSIX_ENTRY_DATA);
465 vec_ctrl = readl(msix_tbl + PCI_MSIX_ENTRY_VECTOR_CTRL);
466
467 iounmap(msix_tbl);
468
469 if (vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT)
470 return -EPERM;
471
472 ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
473 epc->mem->page_size);
474 if (ret)
475 return ret;
476
477 writel(msg_data, ep->msi_mem);
478
479 dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys);
480
481 return 0;
482}
483
325void dw_pcie_ep_exit(struct dw_pcie_ep *ep) 484void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
326{ 485{
327 struct pci_epc *epc = ep->epc; 486 struct pci_epc *epc = ep->epc;
@@ -386,15 +545,18 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
386 return -ENOMEM; 545 return -ENOMEM;
387 ep->outbound_addr = addr; 546 ep->outbound_addr = addr;
388 547
389 if (ep->ops->ep_init)
390 ep->ops->ep_init(ep);
391
392 epc = devm_pci_epc_create(dev, &epc_ops); 548 epc = devm_pci_epc_create(dev, &epc_ops);
393 if (IS_ERR(epc)) { 549 if (IS_ERR(epc)) {
394 dev_err(dev, "Failed to create epc device\n"); 550 dev_err(dev, "Failed to create epc device\n");
395 return PTR_ERR(epc); 551 return PTR_ERR(epc);
396 } 552 }
397 553
554 ep->epc = epc;
555 epc_set_drvdata(epc, ep);
556
557 if (ep->ops->ep_init)
558 ep->ops->ep_init(ep);
559
398 ret = of_property_read_u8(np, "max-functions", &epc->max_functions); 560 ret = of_property_read_u8(np, "max-functions", &epc->max_functions);
399 if (ret < 0) 561 if (ret < 0)
400 epc->max_functions = 1; 562 epc->max_functions = 1;
@@ -409,15 +571,13 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
409 ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys, 571 ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
410 epc->mem->page_size); 572 epc->mem->page_size);
411 if (!ep->msi_mem) { 573 if (!ep->msi_mem) {
412 dev_err(dev, "Failed to reserve memory for MSI\n"); 574 dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n");
413 return -ENOMEM; 575 return -ENOMEM;
414 } 576 }
577 ep->msi_cap = dw_pcie_ep_find_capability(pci, PCI_CAP_ID_MSI);
415 578
416 epc->features = EPC_FEATURE_NO_LINKUP_NOTIFIER; 579 ep->msix_cap = dw_pcie_ep_find_capability(pci, PCI_CAP_ID_MSIX);
417 EPC_FEATURE_SET_BAR(epc->features, BAR_0);
418 580
419 ep->epc = epc;
420 epc_set_drvdata(epc, ep);
421 dw_pcie_setup(pci); 581 dw_pcie_setup(pci);
422 582
423 return 0; 583 return 0;
diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
index 5937fed4c938..c12bf794d69c 100644
--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
+++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
@@ -70,24 +70,29 @@ static const struct dw_pcie_ops dw_pcie_ops = {
70static void dw_plat_pcie_ep_init(struct dw_pcie_ep *ep) 70static void dw_plat_pcie_ep_init(struct dw_pcie_ep *ep)
71{ 71{
72 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 72 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
73 struct pci_epc *epc = ep->epc;
73 enum pci_barno bar; 74 enum pci_barno bar;
74 75
75 for (bar = BAR_0; bar <= BAR_5; bar++) 76 for (bar = BAR_0; bar <= BAR_5; bar++)
76 dw_pcie_ep_reset_bar(pci, bar); 77 dw_pcie_ep_reset_bar(pci, bar);
78
79 epc->features |= EPC_FEATURE_NO_LINKUP_NOTIFIER;
80 epc->features |= EPC_FEATURE_MSIX_AVAILABLE;
77} 81}
78 82
79static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, 83static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
80 enum pci_epc_irq_type type, 84 enum pci_epc_irq_type type,
81 u8 interrupt_num) 85 u16 interrupt_num)
82{ 86{
83 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 87 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
84 88
85 switch (type) { 89 switch (type) {
86 case PCI_EPC_IRQ_LEGACY: 90 case PCI_EPC_IRQ_LEGACY:
87 dev_err(pci->dev, "EP cannot trigger legacy IRQs\n"); 91 return dw_pcie_ep_raise_legacy_irq(ep, func_no);
88 return -EINVAL;
89 case PCI_EPC_IRQ_MSI: 92 case PCI_EPC_IRQ_MSI:
90 return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); 93 return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
94 case PCI_EPC_IRQ_MSIX:
95 return dw_pcie_ep_raise_msix_irq(ep, func_no, interrupt_num);
91 default: 96 default:
92 dev_err(pci->dev, "UNKNOWN IRQ type\n"); 97 dev_err(pci->dev, "UNKNOWN IRQ type\n");
93 } 98 }
@@ -118,7 +123,6 @@ static int dw_plat_add_pcie_port(struct dw_plat_pcie *dw_plat_pcie,
118 return pp->msi_irq; 123 return pp->msi_irq;
119 } 124 }
120 125
121 pp->root_bus_nr = -1;
122 pp->ops = &dw_plat_pcie_host_ops; 126 pp->ops = &dw_plat_pcie_host_ops;
123 127
124 ret = dw_pcie_host_init(pp); 128 ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index bee4e2535a61..96126fd8403c 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -96,17 +96,6 @@
96#define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) \ 96#define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) \
97 ((0x3 << 20) | ((region) << 9) | (0x1 << 8)) 97 ((0x3 << 20) | ((region) << 9) | (0x1 << 8))
98 98
99#define MSI_MESSAGE_CONTROL 0x52
100#define MSI_CAP_MMC_SHIFT 1
101#define MSI_CAP_MMC_MASK (7 << MSI_CAP_MMC_SHIFT)
102#define MSI_CAP_MME_SHIFT 4
103#define MSI_CAP_MSI_EN_MASK 0x1
104#define MSI_CAP_MME_MASK (7 << MSI_CAP_MME_SHIFT)
105#define MSI_MESSAGE_ADDR_L32 0x54
106#define MSI_MESSAGE_ADDR_U32 0x58
107#define MSI_MESSAGE_DATA_32 0x58
108#define MSI_MESSAGE_DATA_64 0x5C
109
110#define MAX_MSI_IRQS 256 99#define MAX_MSI_IRQS 256
111#define MAX_MSI_IRQS_PER_CTRL 32 100#define MAX_MSI_IRQS_PER_CTRL 32
112#define MAX_MSI_CTRLS (MAX_MSI_IRQS / MAX_MSI_IRQS_PER_CTRL) 101#define MAX_MSI_CTRLS (MAX_MSI_IRQS / MAX_MSI_IRQS_PER_CTRL)
@@ -191,7 +180,7 @@ enum dw_pcie_as_type {
191struct dw_pcie_ep_ops { 180struct dw_pcie_ep_ops {
192 void (*ep_init)(struct dw_pcie_ep *ep); 181 void (*ep_init)(struct dw_pcie_ep *ep);
193 int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no, 182 int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no,
194 enum pci_epc_irq_type type, u8 interrupt_num); 183 enum pci_epc_irq_type type, u16 interrupt_num);
195}; 184};
196 185
197struct dw_pcie_ep { 186struct dw_pcie_ep {
@@ -208,6 +197,8 @@ struct dw_pcie_ep {
208 u32 num_ob_windows; 197 u32 num_ob_windows;
209 void __iomem *msi_mem; 198 void __iomem *msi_mem;
210 phys_addr_t msi_mem_phys; 199 phys_addr_t msi_mem_phys;
200 u8 msi_cap; /* MSI capability offset */
201 u8 msix_cap; /* MSI-X capability offset */
211}; 202};
212 203
213struct dw_pcie_ops { 204struct dw_pcie_ops {
@@ -357,8 +348,11 @@ static inline int dw_pcie_allocate_domains(struct pcie_port *pp)
357void dw_pcie_ep_linkup(struct dw_pcie_ep *ep); 348void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);
358int dw_pcie_ep_init(struct dw_pcie_ep *ep); 349int dw_pcie_ep_init(struct dw_pcie_ep *ep);
359void dw_pcie_ep_exit(struct dw_pcie_ep *ep); 350void dw_pcie_ep_exit(struct dw_pcie_ep *ep);
351int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no);
360int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, 352int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
361 u8 interrupt_num); 353 u8 interrupt_num);
354int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
355 u16 interrupt_num);
362void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar); 356void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar);
363#else 357#else
364static inline void dw_pcie_ep_linkup(struct dw_pcie_ep *ep) 358static inline void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
@@ -374,12 +368,23 @@ static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
374{ 368{
375} 369}
376 370
371static inline int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no)
372{
373 return 0;
374}
375
377static inline int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, 376static inline int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
378 u8 interrupt_num) 377 u8 interrupt_num)
379{ 378{
380 return 0; 379 return 0;
381} 380}
382 381
382static inline int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
383 u16 interrupt_num)
384{
385 return 0;
386}
387
383static inline void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) 388static inline void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
384{ 389{
385} 390}
diff --git a/drivers/pci/controller/dwc/pcie-histb.c b/drivers/pci/controller/dwc/pcie-histb.c
index 3611d6ce9a92..7b32e619b959 100644
--- a/drivers/pci/controller/dwc/pcie-histb.c
+++ b/drivers/pci/controller/dwc/pcie-histb.c
@@ -420,7 +420,6 @@ static int histb_pcie_probe(struct platform_device *pdev)
420 phy_init(hipcie->phy); 420 phy_init(hipcie->phy);
421 } 421 }
422 422
423 pp->root_bus_nr = -1;
424 pp->ops = &histb_pcie_host_ops; 423 pp->ops = &histb_pcie_host_ops;
425 424
426 platform_set_drvdata(pdev, hipcie); 425 platform_set_drvdata(pdev, hipcie);
diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c
index d2970a009eb5..5352e0c3be82 100644
--- a/drivers/pci/controller/dwc/pcie-kirin.c
+++ b/drivers/pci/controller/dwc/pcie-kirin.c
@@ -430,6 +430,9 @@ static int kirin_pcie_host_init(struct pcie_port *pp)
430{ 430{
431 kirin_pcie_establish_link(pp); 431 kirin_pcie_establish_link(pp);
432 432
433 if (IS_ENABLED(CONFIG_PCI_MSI))
434 dw_pcie_msi_init(pp);
435
433 return 0; 436 return 0;
434} 437}
435 438
@@ -445,9 +448,34 @@ static const struct dw_pcie_host_ops kirin_pcie_host_ops = {
445 .host_init = kirin_pcie_host_init, 448 .host_init = kirin_pcie_host_init,
446}; 449};
447 450
451static int kirin_pcie_add_msi(struct dw_pcie *pci,
452 struct platform_device *pdev)
453{
454 int irq;
455
456 if (IS_ENABLED(CONFIG_PCI_MSI)) {
457 irq = platform_get_irq(pdev, 0);
458 if (irq < 0) {
459 dev_err(&pdev->dev,
460 "failed to get MSI IRQ (%d)\n", irq);
461 return irq;
462 }
463
464 pci->pp.msi_irq = irq;
465 }
466
467 return 0;
468}
469
448static int __init kirin_add_pcie_port(struct dw_pcie *pci, 470static int __init kirin_add_pcie_port(struct dw_pcie *pci,
449 struct platform_device *pdev) 471 struct platform_device *pdev)
450{ 472{
473 int ret;
474
475 ret = kirin_pcie_add_msi(pci, pdev);
476 if (ret)
477 return ret;
478
451 pci->pp.ops = &kirin_pcie_host_ops; 479 pci->pp.ops = &kirin_pcie_host_ops;
452 480
453 return dw_pcie_host_init(&pci->pp); 481 return dw_pcie_host_init(&pci->pp);
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index a1d0198081a6..4352c1cb926d 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1251,7 +1251,6 @@ static int qcom_pcie_probe(struct platform_device *pdev)
1251 if (ret) 1251 if (ret)
1252 return ret; 1252 return ret;
1253 1253
1254 pp->root_bus_nr = -1;
1255 pp->ops = &qcom_pcie_dw_ops; 1254 pp->ops = &qcom_pcie_dw_ops;
1256 1255
1257 if (IS_ENABLED(CONFIG_PCI_MSI)) { 1256 if (IS_ENABLED(CONFIG_PCI_MSI)) {
diff --git a/drivers/pci/controller/dwc/pcie-spear13xx.c b/drivers/pci/controller/dwc/pcie-spear13xx.c
index ecb58f7b7566..7d0cdfd8138b 100644
--- a/drivers/pci/controller/dwc/pcie-spear13xx.c
+++ b/drivers/pci/controller/dwc/pcie-spear13xx.c
@@ -210,7 +210,6 @@ static int spear13xx_add_pcie_port(struct spear13xx_pcie *spear13xx_pcie,
210 return ret; 210 return ret;
211 } 211 }
212 212
213 pp->root_bus_nr = -1;
214 pp->ops = &spear13xx_pcie_host_ops; 213 pp->ops = &spear13xx_pcie_host_ops;
215 214
216 ret = dw_pcie_host_init(pp); 215 ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/controller/pcie-cadence-ep.c b/drivers/pci/controller/pcie-cadence-ep.c
index 04fe76c3d59d..9e87dd7f9ac3 100644
--- a/drivers/pci/controller/pcie-cadence-ep.c
+++ b/drivers/pci/controller/pcie-cadence-ep.c
@@ -362,7 +362,8 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn,
362} 362}
363 363
364static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, 364static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
365 enum pci_epc_irq_type type, u8 interrupt_num) 365 enum pci_epc_irq_type type,
366 u16 interrupt_num)
366{ 367{
367 struct cdns_pcie_ep *ep = epc_get_drvdata(epc); 368 struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
368 369
diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
index 6beba8ed7b84..b8163c56a142 100644
--- a/drivers/pci/controller/pcie-rockchip-ep.c
+++ b/drivers/pci/controller/pcie-rockchip-ep.c
@@ -472,7 +472,7 @@ static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn,
472 472
473static int rockchip_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, 473static int rockchip_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
474 enum pci_epc_irq_type type, 474 enum pci_epc_irq_type type,
475 u8 interrupt_num) 475 u16 interrupt_num)
476{ 476{
477 struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); 477 struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
478 478
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 63ed706445b9..3e86fa3c7da3 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -18,13 +18,16 @@
18#include <linux/pci-epf.h> 18#include <linux/pci-epf.h>
19#include <linux/pci_regs.h> 19#include <linux/pci_regs.h>
20 20
21#define IRQ_TYPE_LEGACY 0
22#define IRQ_TYPE_MSI 1
23#define IRQ_TYPE_MSIX 2
24
21#define COMMAND_RAISE_LEGACY_IRQ BIT(0) 25#define COMMAND_RAISE_LEGACY_IRQ BIT(0)
22#define COMMAND_RAISE_MSI_IRQ BIT(1) 26#define COMMAND_RAISE_MSI_IRQ BIT(1)
23#define MSI_NUMBER_SHIFT 2 27#define COMMAND_RAISE_MSIX_IRQ BIT(2)
24#define MSI_NUMBER_MASK (0x3f << MSI_NUMBER_SHIFT) 28#define COMMAND_READ BIT(3)
25#define COMMAND_READ BIT(8) 29#define COMMAND_WRITE BIT(4)
26#define COMMAND_WRITE BIT(9) 30#define COMMAND_COPY BIT(5)
27#define COMMAND_COPY BIT(10)
28 31
29#define STATUS_READ_SUCCESS BIT(0) 32#define STATUS_READ_SUCCESS BIT(0)
30#define STATUS_READ_FAIL BIT(1) 33#define STATUS_READ_FAIL BIT(1)
@@ -45,6 +48,7 @@ struct pci_epf_test {
45 struct pci_epf *epf; 48 struct pci_epf *epf;
46 enum pci_barno test_reg_bar; 49 enum pci_barno test_reg_bar;
47 bool linkup_notifier; 50 bool linkup_notifier;
51 bool msix_available;
48 struct delayed_work cmd_handler; 52 struct delayed_work cmd_handler;
49}; 53};
50 54
@@ -56,6 +60,8 @@ struct pci_epf_test_reg {
56 u64 dst_addr; 60 u64 dst_addr;
57 u32 size; 61 u32 size;
58 u32 checksum; 62 u32 checksum;
63 u32 irq_type;
64 u32 irq_number;
59} __packed; 65} __packed;
60 66
61static struct pci_epf_header test_header = { 67static struct pci_epf_header test_header = {
@@ -244,31 +250,42 @@ err:
244 return ret; 250 return ret;
245} 251}
246 252
247static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test, u8 irq) 253static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test, u8 irq_type,
254 u16 irq)
248{ 255{
249 u8 msi_count;
250 struct pci_epf *epf = epf_test->epf; 256 struct pci_epf *epf = epf_test->epf;
257 struct device *dev = &epf->dev;
251 struct pci_epc *epc = epf->epc; 258 struct pci_epc *epc = epf->epc;
252 enum pci_barno test_reg_bar = epf_test->test_reg_bar; 259 enum pci_barno test_reg_bar = epf_test->test_reg_bar;
253 struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar]; 260 struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
254 261
255 reg->status |= STATUS_IRQ_RAISED; 262 reg->status |= STATUS_IRQ_RAISED;
256 msi_count = pci_epc_get_msi(epc, epf->func_no); 263
257 if (irq > msi_count || msi_count <= 0) 264 switch (irq_type) {
265 case IRQ_TYPE_LEGACY:
258 pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0); 266 pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0);
259 else 267 break;
268 case IRQ_TYPE_MSI:
260 pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq); 269 pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq);
270 break;
271 case IRQ_TYPE_MSIX:
272 pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSIX, irq);
273 break;
274 default:
275 dev_err(dev, "Failed to raise IRQ, unknown type\n");
276 break;
277 }
261} 278}
262 279
263static void pci_epf_test_cmd_handler(struct work_struct *work) 280static void pci_epf_test_cmd_handler(struct work_struct *work)
264{ 281{
265 int ret; 282 int ret;
266 u8 irq; 283 int count;
267 u8 msi_count;
268 u32 command; 284 u32 command;
269 struct pci_epf_test *epf_test = container_of(work, struct pci_epf_test, 285 struct pci_epf_test *epf_test = container_of(work, struct pci_epf_test,
270 cmd_handler.work); 286 cmd_handler.work);
271 struct pci_epf *epf = epf_test->epf; 287 struct pci_epf *epf = epf_test->epf;
288 struct device *dev = &epf->dev;
272 struct pci_epc *epc = epf->epc; 289 struct pci_epc *epc = epf->epc;
273 enum pci_barno test_reg_bar = epf_test->test_reg_bar; 290 enum pci_barno test_reg_bar = epf_test->test_reg_bar;
274 struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar]; 291 struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
@@ -280,7 +297,10 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
280 reg->command = 0; 297 reg->command = 0;
281 reg->status = 0; 298 reg->status = 0;
282 299
283 irq = (command & MSI_NUMBER_MASK) >> MSI_NUMBER_SHIFT; 300 if (reg->irq_type > IRQ_TYPE_MSIX) {
301 dev_err(dev, "Failed to detect IRQ type\n");
302 goto reset_handler;
303 }
284 304
285 if (command & COMMAND_RAISE_LEGACY_IRQ) { 305 if (command & COMMAND_RAISE_LEGACY_IRQ) {
286 reg->status = STATUS_IRQ_RAISED; 306 reg->status = STATUS_IRQ_RAISED;
@@ -294,7 +314,8 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
294 reg->status |= STATUS_WRITE_FAIL; 314 reg->status |= STATUS_WRITE_FAIL;
295 else 315 else
296 reg->status |= STATUS_WRITE_SUCCESS; 316 reg->status |= STATUS_WRITE_SUCCESS;
297 pci_epf_test_raise_irq(epf_test, irq); 317 pci_epf_test_raise_irq(epf_test, reg->irq_type,
318 reg->irq_number);
298 goto reset_handler; 319 goto reset_handler;
299 } 320 }
300 321
@@ -304,7 +325,8 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
304 reg->status |= STATUS_READ_SUCCESS; 325 reg->status |= STATUS_READ_SUCCESS;
305 else 326 else
306 reg->status |= STATUS_READ_FAIL; 327 reg->status |= STATUS_READ_FAIL;
307 pci_epf_test_raise_irq(epf_test, irq); 328 pci_epf_test_raise_irq(epf_test, reg->irq_type,
329 reg->irq_number);
308 goto reset_handler; 330 goto reset_handler;
309 } 331 }
310 332
@@ -314,16 +336,28 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
314 reg->status |= STATUS_COPY_SUCCESS; 336 reg->status |= STATUS_COPY_SUCCESS;
315 else 337 else
316 reg->status |= STATUS_COPY_FAIL; 338 reg->status |= STATUS_COPY_FAIL;
317 pci_epf_test_raise_irq(epf_test, irq); 339 pci_epf_test_raise_irq(epf_test, reg->irq_type,
340 reg->irq_number);
318 goto reset_handler; 341 goto reset_handler;
319 } 342 }
320 343
321 if (command & COMMAND_RAISE_MSI_IRQ) { 344 if (command & COMMAND_RAISE_MSI_IRQ) {
322 msi_count = pci_epc_get_msi(epc, epf->func_no); 345 count = pci_epc_get_msi(epc, epf->func_no);
323 if (irq > msi_count || msi_count <= 0) 346 if (reg->irq_number > count || count <= 0)
324 goto reset_handler; 347 goto reset_handler;
325 reg->status = STATUS_IRQ_RAISED; 348 reg->status = STATUS_IRQ_RAISED;
326 pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq); 349 pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI,
350 reg->irq_number);
351 goto reset_handler;
352 }
353
354 if (command & COMMAND_RAISE_MSIX_IRQ) {
355 count = pci_epc_get_msix(epc, epf->func_no);
356 if (reg->irq_number > count || count <= 0)
357 goto reset_handler;
358 reg->status = STATUS_IRQ_RAISED;
359 pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSIX,
360 reg->irq_number);
327 goto reset_handler; 361 goto reset_handler;
328 } 362 }
329 363
@@ -440,6 +474,8 @@ static int pci_epf_test_bind(struct pci_epf *epf)
440 else 474 else
441 epf_test->linkup_notifier = true; 475 epf_test->linkup_notifier = true;
442 476
477 epf_test->msix_available = epc->features & EPC_FEATURE_MSIX_AVAILABLE;
478
443 epf_test->test_reg_bar = EPC_FEATURE_GET_BAR(epc->features); 479 epf_test->test_reg_bar = EPC_FEATURE_GET_BAR(epc->features);
444 480
445 ret = pci_epc_write_header(epc, epf->func_no, header); 481 ret = pci_epc_write_header(epc, epf->func_no, header);
@@ -457,8 +493,18 @@ static int pci_epf_test_bind(struct pci_epf *epf)
457 return ret; 493 return ret;
458 494
459 ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts); 495 ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts);
460 if (ret) 496 if (ret) {
497 dev_err(dev, "MSI configuration failed\n");
461 return ret; 498 return ret;
499 }
500
501 if (epf_test->msix_available) {
502 ret = pci_epc_set_msix(epc, epf->func_no, epf->msix_interrupts);
503 if (ret) {
504 dev_err(dev, "MSI-X configuration failed\n");
505 return ret;
506 }
507 }
462 508
463 if (!epf_test->linkup_notifier) 509 if (!epf_test->linkup_notifier)
464 queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work); 510 queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work);
diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c
index 018ea3433cb5..d1288a0bd530 100644
--- a/drivers/pci/endpoint/pci-ep-cfs.c
+++ b/drivers/pci/endpoint/pci-ep-cfs.c
@@ -286,6 +286,28 @@ static ssize_t pci_epf_msi_interrupts_show(struct config_item *item,
286 to_pci_epf_group(item)->epf->msi_interrupts); 286 to_pci_epf_group(item)->epf->msi_interrupts);
287} 287}
288 288
289static ssize_t pci_epf_msix_interrupts_store(struct config_item *item,
290 const char *page, size_t len)
291{
292 u16 val;
293 int ret;
294
295 ret = kstrtou16(page, 0, &val);
296 if (ret)
297 return ret;
298
299 to_pci_epf_group(item)->epf->msix_interrupts = val;
300
301 return len;
302}
303
304static ssize_t pci_epf_msix_interrupts_show(struct config_item *item,
305 char *page)
306{
307 return sprintf(page, "%d\n",
308 to_pci_epf_group(item)->epf->msix_interrupts);
309}
310
289PCI_EPF_HEADER_R(vendorid) 311PCI_EPF_HEADER_R(vendorid)
290PCI_EPF_HEADER_W_u16(vendorid) 312PCI_EPF_HEADER_W_u16(vendorid)
291 313
@@ -327,6 +349,7 @@ CONFIGFS_ATTR(pci_epf_, subsys_vendor_id);
327CONFIGFS_ATTR(pci_epf_, subsys_id); 349CONFIGFS_ATTR(pci_epf_, subsys_id);
328CONFIGFS_ATTR(pci_epf_, interrupt_pin); 350CONFIGFS_ATTR(pci_epf_, interrupt_pin);
329CONFIGFS_ATTR(pci_epf_, msi_interrupts); 351CONFIGFS_ATTR(pci_epf_, msi_interrupts);
352CONFIGFS_ATTR(pci_epf_, msix_interrupts);
330 353
331static struct configfs_attribute *pci_epf_attrs[] = { 354static struct configfs_attribute *pci_epf_attrs[] = {
332 &pci_epf_attr_vendorid, 355 &pci_epf_attr_vendorid,
@@ -340,6 +363,7 @@ static struct configfs_attribute *pci_epf_attrs[] = {
340 &pci_epf_attr_subsys_id, 363 &pci_epf_attr_subsys_id,
341 &pci_epf_attr_interrupt_pin, 364 &pci_epf_attr_interrupt_pin,
342 &pci_epf_attr_msi_interrupts, 365 &pci_epf_attr_msi_interrupts,
366 &pci_epf_attr_msix_interrupts,
343 NULL, 367 NULL,
344}; 368};
345 369
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index b0ee42739c3c..094dcc3203b8 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -131,13 +131,13 @@ EXPORT_SYMBOL_GPL(pci_epc_start);
131 * pci_epc_raise_irq() - interrupt the host system 131 * pci_epc_raise_irq() - interrupt the host system
132 * @epc: the EPC device which has to interrupt the host 132 * @epc: the EPC device which has to interrupt the host
133 * @func_no: the endpoint function number in the EPC device 133 * @func_no: the endpoint function number in the EPC device
134 * @type: specify the type of interrupt; legacy or MSI 134 * @type: specify the type of interrupt; legacy, MSI or MSI-X
135 * @interrupt_num: the MSI interrupt number 135 * @interrupt_num: the MSI or MSI-X interrupt number
136 * 136 *
137 * Invoke to raise an MSI or legacy interrupt 137 * Invoke to raise an legacy, MSI or MSI-X interrupt
138 */ 138 */
139int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, 139int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
140 enum pci_epc_irq_type type, u8 interrupt_num) 140 enum pci_epc_irq_type type, u16 interrupt_num)
141{ 141{
142 int ret; 142 int ret;
143 unsigned long flags; 143 unsigned long flags;
@@ -201,7 +201,8 @@ int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
201 u8 encode_int; 201 u8 encode_int;
202 unsigned long flags; 202 unsigned long flags;
203 203
204 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions) 204 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions ||
205 interrupts > 32)
205 return -EINVAL; 206 return -EINVAL;
206 207
207 if (!epc->ops->set_msi) 208 if (!epc->ops->set_msi)
@@ -218,6 +219,63 @@ int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
218EXPORT_SYMBOL_GPL(pci_epc_set_msi); 219EXPORT_SYMBOL_GPL(pci_epc_set_msi);
219 220
220/** 221/**
222 * pci_epc_get_msix() - get the number of MSI-X interrupt numbers allocated
223 * @epc: the EPC device to which MSI-X interrupts was requested
224 * @func_no: the endpoint function number in the EPC device
225 *
226 * Invoke to get the number of MSI-X interrupts allocated by the RC
227 */
228int pci_epc_get_msix(struct pci_epc *epc, u8 func_no)
229{
230 int interrupt;
231 unsigned long flags;
232
233 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
234 return 0;
235
236 if (!epc->ops->get_msix)
237 return 0;
238
239 spin_lock_irqsave(&epc->lock, flags);
240 interrupt = epc->ops->get_msix(epc, func_no);
241 spin_unlock_irqrestore(&epc->lock, flags);
242
243 if (interrupt < 0)
244 return 0;
245
246 return interrupt + 1;
247}
248EXPORT_SYMBOL_GPL(pci_epc_get_msix);
249
250/**
251 * pci_epc_set_msix() - set the number of MSI-X interrupt numbers required
252 * @epc: the EPC device on which MSI-X has to be configured
253 * @func_no: the endpoint function number in the EPC device
254 * @interrupts: number of MSI-X interrupts required by the EPF
255 *
256 * Invoke to set the required number of MSI-X interrupts.
257 */
258int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts)
259{
260 int ret;
261 unsigned long flags;
262
263 if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions ||
264 interrupts < 1 || interrupts > 2048)
265 return -EINVAL;
266
267 if (!epc->ops->set_msix)
268 return 0;
269
270 spin_lock_irqsave(&epc->lock, flags);
271 ret = epc->ops->set_msix(epc, func_no, interrupts - 1);
272 spin_unlock_irqrestore(&epc->lock, flags);
273
274 return ret;
275}
276EXPORT_SYMBOL_GPL(pci_epc_set_msix);
277
278/**
221 * pci_epc_unmap_addr() - unmap CPU address from PCI address 279 * pci_epc_unmap_addr() - unmap CPU address from PCI address
222 * @epc: the EPC device on which address is allocated 280 * @epc: the EPC device on which address is allocated
223 * @func_no: the endpoint function number in the EPC device 281 * @func_no: the endpoint function number in the EPC device
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 243eaa5a66ff..37dab8116901 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -17,6 +17,7 @@ enum pci_epc_irq_type {
17 PCI_EPC_IRQ_UNKNOWN, 17 PCI_EPC_IRQ_UNKNOWN,
18 PCI_EPC_IRQ_LEGACY, 18 PCI_EPC_IRQ_LEGACY,
19 PCI_EPC_IRQ_MSI, 19 PCI_EPC_IRQ_MSI,
20 PCI_EPC_IRQ_MSIX,
20}; 21};
21 22
22/** 23/**
@@ -30,7 +31,11 @@ enum pci_epc_irq_type {
30 * capability register 31 * capability register
31 * @get_msi: ops to get the number of MSI interrupts allocated by the RC from 32 * @get_msi: ops to get the number of MSI interrupts allocated by the RC from
32 * the MSI capability register 33 * the MSI capability register
33 * @raise_irq: ops to raise a legacy or MSI interrupt 34 * @set_msix: ops to set the requested number of MSI-X interrupts in the
35 * MSI-X capability register
36 * @get_msix: ops to get the number of MSI-X interrupts allocated by the RC
37 * from the MSI-X capability register
38 * @raise_irq: ops to raise a legacy, MSI or MSI-X interrupt
34 * @start: ops to start the PCI link 39 * @start: ops to start the PCI link
35 * @stop: ops to stop the PCI link 40 * @stop: ops to stop the PCI link
36 * @owner: the module owner containing the ops 41 * @owner: the module owner containing the ops
@@ -48,8 +53,10 @@ struct pci_epc_ops {
48 phys_addr_t addr); 53 phys_addr_t addr);
49 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);
50 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);
57 int (*get_msix)(struct pci_epc *epc, u8 func_no);
51 int (*raise_irq)(struct pci_epc *epc, u8 func_no, 58 int (*raise_irq)(struct pci_epc *epc, u8 func_no,
52 enum pci_epc_irq_type type, u8 interrupt_num); 59 enum pci_epc_irq_type type, u16 interrupt_num);
53 int (*start)(struct pci_epc *epc); 60 int (*start)(struct pci_epc *epc);
54 void (*stop)(struct pci_epc *epc); 61 void (*stop)(struct pci_epc *epc);
55 struct module *owner; 62 struct module *owner;
@@ -95,6 +102,7 @@ struct pci_epc {
95 102
96#define EPC_FEATURE_NO_LINKUP_NOTIFIER BIT(0) 103#define EPC_FEATURE_NO_LINKUP_NOTIFIER BIT(0)
97#define EPC_FEATURE_BAR_MASK (BIT(1) | BIT(2) | BIT(3)) 104#define EPC_FEATURE_BAR_MASK (BIT(1) | BIT(2) | BIT(3))
105#define EPC_FEATURE_MSIX_AVAILABLE BIT(4)
98#define EPC_FEATURE_SET_BAR(features, bar) \ 106#define EPC_FEATURE_SET_BAR(features, bar) \
99 (features |= (EPC_FEATURE_BAR_MASK & (bar << 1))) 107 (features |= (EPC_FEATURE_BAR_MASK & (bar << 1)))
100#define EPC_FEATURE_GET_BAR(features) \ 108#define EPC_FEATURE_GET_BAR(features) \
@@ -144,8 +152,10 @@ void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,
144 phys_addr_t phys_addr); 152 phys_addr_t phys_addr);
145int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts); 153int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts);
146int pci_epc_get_msi(struct pci_epc *epc, u8 func_no); 154int pci_epc_get_msi(struct pci_epc *epc, u8 func_no);
155int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts);
156int pci_epc_get_msix(struct pci_epc *epc, u8 func_no);
147int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, 157int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
148 enum pci_epc_irq_type type, u8 interrupt_num); 158 enum pci_epc_irq_type type, u16 interrupt_num);
149int pci_epc_start(struct pci_epc *epc); 159int pci_epc_start(struct pci_epc *epc);
150void pci_epc_stop(struct pci_epc *epc); 160void pci_epc_stop(struct pci_epc *epc);
151struct pci_epc *pci_epc_get(const char *epc_name); 161struct pci_epc *pci_epc_get(const char *epc_name);
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 4e7764935fa8..ec02f58758c8 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -119,6 +119,7 @@ struct pci_epf {
119 struct pci_epf_header *header; 119 struct pci_epf_header *header;
120 struct pci_epf_bar bar[6]; 120 struct pci_epf_bar bar[6];
121 u8 msi_interrupts; 121 u8 msi_interrupts;
122 u16 msix_interrupts;
122 u8 func_no; 123 u8 func_no;
123 124
124 struct pci_epc *epc; 125 struct pci_epc *epc;
diff --git a/include/uapi/linux/pcitest.h b/include/uapi/linux/pcitest.h
index 953cf036cb26..cbf422e56696 100644
--- a/include/uapi/linux/pcitest.h
+++ b/include/uapi/linux/pcitest.h
@@ -16,5 +16,8 @@
16#define PCITEST_WRITE _IOW('P', 0x4, unsigned long) 16#define PCITEST_WRITE _IOW('P', 0x4, unsigned long)
17#define PCITEST_READ _IOW('P', 0x5, unsigned long) 17#define PCITEST_READ _IOW('P', 0x5, unsigned long)
18#define PCITEST_COPY _IOW('P', 0x6, unsigned long) 18#define PCITEST_COPY _IOW('P', 0x6, unsigned long)
19#define PCITEST_MSIX _IOW('P', 0x7, int)
20#define PCITEST_SET_IRQTYPE _IOW('P', 0x8, int)
21#define PCITEST_GET_IRQTYPE _IO('P', 0x9)
19 22
20#endif /* __UAPI_LINUX_PCITEST_H */ 23#endif /* __UAPI_LINUX_PCITEST_H */
diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c
index 9074b477bff0..af146bb03b4d 100644
--- a/tools/pci/pcitest.c
+++ b/tools/pci/pcitest.c
@@ -31,12 +31,17 @@
31#define BILLION 1E9 31#define BILLION 1E9
32 32
33static char *result[] = { "NOT OKAY", "OKAY" }; 33static char *result[] = { "NOT OKAY", "OKAY" };
34static char *irq[] = { "LEGACY", "MSI", "MSI-X" };
34 35
35struct pci_test { 36struct pci_test {
36 char *device; 37 char *device;
37 char barnum; 38 char barnum;
38 bool legacyirq; 39 bool legacyirq;
39 unsigned int msinum; 40 unsigned int msinum;
41 unsigned int msixnum;
42 int irqtype;
43 bool set_irqtype;
44 bool get_irqtype;
40 bool read; 45 bool read;
41 bool write; 46 bool write;
42 bool copy; 47 bool copy;
@@ -65,6 +70,24 @@ static int run_test(struct pci_test *test)
65 fprintf(stdout, "%s\n", result[ret]); 70 fprintf(stdout, "%s\n", result[ret]);
66 } 71 }
67 72
73 if (test->set_irqtype) {
74 ret = ioctl(fd, PCITEST_SET_IRQTYPE, test->irqtype);
75 fprintf(stdout, "SET IRQ TYPE TO %s:\t\t", irq[test->irqtype]);
76 if (ret < 0)
77 fprintf(stdout, "FAILED\n");
78 else
79 fprintf(stdout, "%s\n", result[ret]);
80 }
81
82 if (test->get_irqtype) {
83 ret = ioctl(fd, PCITEST_GET_IRQTYPE);
84 fprintf(stdout, "GET IRQ TYPE:\t\t");
85 if (ret < 0)
86 fprintf(stdout, "FAILED\n");
87 else
88 fprintf(stdout, "%s\n", irq[ret]);
89 }
90
68 if (test->legacyirq) { 91 if (test->legacyirq) {
69 ret = ioctl(fd, PCITEST_LEGACY_IRQ, 0); 92 ret = ioctl(fd, PCITEST_LEGACY_IRQ, 0);
70 fprintf(stdout, "LEGACY IRQ:\t"); 93 fprintf(stdout, "LEGACY IRQ:\t");
@@ -83,6 +106,15 @@ static int run_test(struct pci_test *test)
83 fprintf(stdout, "%s\n", result[ret]); 106 fprintf(stdout, "%s\n", result[ret]);
84 } 107 }
85 108
109 if (test->msixnum > 0 && test->msixnum <= 2048) {
110 ret = ioctl(fd, PCITEST_MSIX, test->msixnum);
111 fprintf(stdout, "MSI-X%d:\t\t", test->msixnum);
112 if (ret < 0)
113 fprintf(stdout, "TEST FAILED\n");
114 else
115 fprintf(stdout, "%s\n", result[ret]);
116 }
117
86 if (test->write) { 118 if (test->write) {
87 ret = ioctl(fd, PCITEST_WRITE, test->size); 119 ret = ioctl(fd, PCITEST_WRITE, test->size);
88 fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size); 120 fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size);
@@ -133,7 +165,7 @@ int main(int argc, char **argv)
133 /* set default endpoint device */ 165 /* set default endpoint device */
134 test->device = "/dev/pci-endpoint-test.0"; 166 test->device = "/dev/pci-endpoint-test.0";
135 167
136 while ((c = getopt(argc, argv, "D:b:m:lrwcs:")) != EOF) 168 while ((c = getopt(argc, argv, "D:b:m:x:i:Ilrwcs:")) != EOF)
137 switch (c) { 169 switch (c) {
138 case 'D': 170 case 'D':
139 test->device = optarg; 171 test->device = optarg;
@@ -151,6 +183,20 @@ int main(int argc, char **argv)
151 if (test->msinum < 1 || test->msinum > 32) 183 if (test->msinum < 1 || test->msinum > 32)
152 goto usage; 184 goto usage;
153 continue; 185 continue;
186 case 'x':
187 test->msixnum = atoi(optarg);
188 if (test->msixnum < 1 || test->msixnum > 2048)
189 goto usage;
190 continue;
191 case 'i':
192 test->irqtype = atoi(optarg);
193 if (test->irqtype < 0 || test->irqtype > 2)
194 goto usage;
195 test->set_irqtype = true;
196 continue;
197 case 'I':
198 test->get_irqtype = true;
199 continue;
154 case 'r': 200 case 'r':
155 test->read = true; 201 test->read = true;
156 continue; 202 continue;
@@ -173,6 +219,9 @@ usage:
173 "\t-D <dev> PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n" 219 "\t-D <dev> PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n"
174 "\t-b <bar num> BAR test (bar number between 0..5)\n" 220 "\t-b <bar num> BAR test (bar number between 0..5)\n"
175 "\t-m <msi num> MSI test (msi number between 1..32)\n" 221 "\t-m <msi num> MSI test (msi number between 1..32)\n"
222 "\t-x <msix num> \tMSI-X test (msix number between 1..2048)\n"
223 "\t-i <irq type> \tSet IRQ type (0 - Legacy, 1 - MSI, 2 - MSI-X)\n"
224 "\t-I Get current IRQ type configured\n"
176 "\t-l Legacy IRQ test\n" 225 "\t-l Legacy IRQ test\n"
177 "\t-r Read buffer test\n" 226 "\t-r Read buffer test\n"
178 "\t-w Write buffer test\n" 227 "\t-w Write buffer test\n"
diff --git a/tools/pci/pcitest.sh b/tools/pci/pcitest.sh
index 77e8c85ef744..75ed48ff2990 100644
--- a/tools/pci/pcitest.sh
+++ b/tools/pci/pcitest.sh
@@ -16,7 +16,10 @@ echo
16echo "Interrupt tests" 16echo "Interrupt tests"
17echo 17echo
18 18
19pcitest -i 0
19pcitest -l 20pcitest -l
21
22pcitest -i 1
20msi=1 23msi=1
21 24
22while [ $msi -lt 33 ] 25while [ $msi -lt 33 ]
@@ -26,9 +29,21 @@ do
26done 29done
27echo 30echo
28 31
32pcitest -i 2
33msix=1
34
35while [ $msix -lt 2049 ]
36do
37 pcitest -x $msix
38 msix=`expr $msix + 1`
39done
40echo
41
29echo "Read Tests" 42echo "Read Tests"
30echo 43echo
31 44
45pcitest -i 1
46
32pcitest -r -s 1 47pcitest -r -s 1
33pcitest -r -s 1024 48pcitest -r -s 1024
34pcitest -r -s 1025 49pcitest -r -s 1025