Merge branch 'for-linus' into for-next
[linux-2.6-microblaze.git] / drivers / misc / pci_endpoint_test.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /**
3  * Host side test driver to test endpoint functionality
4  *
5  * Copyright (C) 2017 Texas Instruments
6  * Author: Kishon Vijay Abraham I <kishon@ti.com>
7  */
8
9 #include <linux/crc32.h>
10 #include <linux/delay.h>
11 #include <linux/fs.h>
12 #include <linux/io.h>
13 #include <linux/interrupt.h>
14 #include <linux/irq.h>
15 #include <linux/miscdevice.h>
16 #include <linux/module.h>
17 #include <linux/mutex.h>
18 #include <linux/random.h>
19 #include <linux/slab.h>
20 #include <linux/pci.h>
21 #include <linux/pci_ids.h>
22
23 #include <linux/pci_regs.h>
24
25 #include <uapi/linux/pcitest.h>
26
27 #define DRV_MODULE_NAME                         "pci-endpoint-test"
28
29 #define IRQ_TYPE_UNDEFINED                      -1
30 #define IRQ_TYPE_LEGACY                         0
31 #define IRQ_TYPE_MSI                            1
32 #define IRQ_TYPE_MSIX                           2
33
34 #define PCI_ENDPOINT_TEST_MAGIC                 0x0
35
36 #define PCI_ENDPOINT_TEST_COMMAND               0x4
37 #define COMMAND_RAISE_LEGACY_IRQ                BIT(0)
38 #define COMMAND_RAISE_MSI_IRQ                   BIT(1)
39 #define COMMAND_RAISE_MSIX_IRQ                  BIT(2)
40 #define COMMAND_READ                            BIT(3)
41 #define COMMAND_WRITE                           BIT(4)
42 #define COMMAND_COPY                            BIT(5)
43
44 #define PCI_ENDPOINT_TEST_STATUS                0x8
45 #define STATUS_READ_SUCCESS                     BIT(0)
46 #define STATUS_READ_FAIL                        BIT(1)
47 #define STATUS_WRITE_SUCCESS                    BIT(2)
48 #define STATUS_WRITE_FAIL                       BIT(3)
49 #define STATUS_COPY_SUCCESS                     BIT(4)
50 #define STATUS_COPY_FAIL                        BIT(5)
51 #define STATUS_IRQ_RAISED                       BIT(6)
52 #define STATUS_SRC_ADDR_INVALID                 BIT(7)
53 #define STATUS_DST_ADDR_INVALID                 BIT(8)
54
55 #define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR        0x0c
56 #define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR        0x10
57
58 #define PCI_ENDPOINT_TEST_LOWER_DST_ADDR        0x14
59 #define PCI_ENDPOINT_TEST_UPPER_DST_ADDR        0x18
60
61 #define PCI_ENDPOINT_TEST_SIZE                  0x1c
62 #define PCI_ENDPOINT_TEST_CHECKSUM              0x20
63
64 #define PCI_ENDPOINT_TEST_IRQ_TYPE              0x24
65 #define PCI_ENDPOINT_TEST_IRQ_NUMBER            0x28
66
67 #define PCI_DEVICE_ID_TI_AM654                  0xb00c
68
69 #define is_am654_pci_dev(pdev)          \
70                 ((pdev)->device == PCI_DEVICE_ID_TI_AM654)
71
72 static DEFINE_IDA(pci_endpoint_test_ida);
73
74 #define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
75                                             miscdev)
76
77 static bool no_msi;
78 module_param(no_msi, bool, 0444);
79 MODULE_PARM_DESC(no_msi, "Disable MSI interrupt in pci_endpoint_test");
80
81 static int irq_type = IRQ_TYPE_MSI;
82 module_param(irq_type, int, 0444);
83 MODULE_PARM_DESC(irq_type, "IRQ mode selection in pci_endpoint_test (0 - Legacy, 1 - MSI, 2 - MSI-X)");
84
85 enum pci_barno {
86         BAR_0,
87         BAR_1,
88         BAR_2,
89         BAR_3,
90         BAR_4,
91         BAR_5,
92 };
93
94 struct pci_endpoint_test {
95         struct pci_dev  *pdev;
96         void __iomem    *base;
97         void __iomem    *bar[PCI_STD_NUM_BARS];
98         struct completion irq_raised;
99         int             last_irq;
100         int             num_irqs;
101         /* mutex to protect the ioctls */
102         struct mutex    mutex;
103         struct miscdevice miscdev;
104         enum pci_barno test_reg_bar;
105         size_t alignment;
106 };
107
108 struct pci_endpoint_test_data {
109         enum pci_barno test_reg_bar;
110         size_t alignment;
111         int irq_type;
112 };
113
114 static inline u32 pci_endpoint_test_readl(struct pci_endpoint_test *test,
115                                           u32 offset)
116 {
117         return readl(test->base + offset);
118 }
119
120 static inline void pci_endpoint_test_writel(struct pci_endpoint_test *test,
121                                             u32 offset, u32 value)
122 {
123         writel(value, test->base + offset);
124 }
125
126 static inline u32 pci_endpoint_test_bar_readl(struct pci_endpoint_test *test,
127                                               int bar, int offset)
128 {
129         return readl(test->bar[bar] + offset);
130 }
131
132 static inline void pci_endpoint_test_bar_writel(struct pci_endpoint_test *test,
133                                                 int bar, u32 offset, u32 value)
134 {
135         writel(value, test->bar[bar] + offset);
136 }
137
138 static irqreturn_t pci_endpoint_test_irqhandler(int irq, void *dev_id)
139 {
140         struct pci_endpoint_test *test = dev_id;
141         u32 reg;
142
143         reg = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
144         if (reg & STATUS_IRQ_RAISED) {
145                 test->last_irq = irq;
146                 complete(&test->irq_raised);
147                 reg &= ~STATUS_IRQ_RAISED;
148         }
149         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_STATUS,
150                                  reg);
151
152         return IRQ_HANDLED;
153 }
154
155 static void pci_endpoint_test_free_irq_vectors(struct pci_endpoint_test *test)
156 {
157         struct pci_dev *pdev = test->pdev;
158
159         pci_free_irq_vectors(pdev);
160 }
161
162 static bool pci_endpoint_test_alloc_irq_vectors(struct pci_endpoint_test *test,
163                                                 int type)
164 {
165         int irq = -1;
166         struct pci_dev *pdev = test->pdev;
167         struct device *dev = &pdev->dev;
168         bool res = true;
169
170         switch (type) {
171         case IRQ_TYPE_LEGACY:
172                 irq = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY);
173                 if (irq < 0)
174                         dev_err(dev, "Failed to get Legacy interrupt\n");
175                 break;
176         case IRQ_TYPE_MSI:
177                 irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI);
178                 if (irq < 0)
179                         dev_err(dev, "Failed to get MSI interrupts\n");
180                 break;
181         case IRQ_TYPE_MSIX:
182                 irq = pci_alloc_irq_vectors(pdev, 1, 2048, PCI_IRQ_MSIX);
183                 if (irq < 0)
184                         dev_err(dev, "Failed to get MSI-X interrupts\n");
185                 break;
186         default:
187                 dev_err(dev, "Invalid IRQ type selected\n");
188         }
189
190         if (irq < 0) {
191                 irq = 0;
192                 res = false;
193         }
194         test->num_irqs = irq;
195
196         return res;
197 }
198
199 static void pci_endpoint_test_release_irq(struct pci_endpoint_test *test)
200 {
201         int i;
202         struct pci_dev *pdev = test->pdev;
203         struct device *dev = &pdev->dev;
204
205         for (i = 0; i < test->num_irqs; i++)
206                 devm_free_irq(dev, pci_irq_vector(pdev, i), test);
207
208         test->num_irqs = 0;
209 }
210
211 static bool pci_endpoint_test_request_irq(struct pci_endpoint_test *test)
212 {
213         int i;
214         int err;
215         struct pci_dev *pdev = test->pdev;
216         struct device *dev = &pdev->dev;
217
218         for (i = 0; i < test->num_irqs; i++) {
219                 err = devm_request_irq(dev, pci_irq_vector(pdev, i),
220                                        pci_endpoint_test_irqhandler,
221                                        IRQF_SHARED, DRV_MODULE_NAME, test);
222                 if (err)
223                         goto fail;
224         }
225
226         return true;
227
228 fail:
229         switch (irq_type) {
230         case IRQ_TYPE_LEGACY:
231                 dev_err(dev, "Failed to request IRQ %d for Legacy\n",
232                         pci_irq_vector(pdev, i));
233                 break;
234         case IRQ_TYPE_MSI:
235                 dev_err(dev, "Failed to request IRQ %d for MSI %d\n",
236                         pci_irq_vector(pdev, i),
237                         i + 1);
238                 break;
239         case IRQ_TYPE_MSIX:
240                 dev_err(dev, "Failed to request IRQ %d for MSI-X %d\n",
241                         pci_irq_vector(pdev, i),
242                         i + 1);
243                 break;
244         }
245
246         return false;
247 }
248
249 static bool pci_endpoint_test_bar(struct pci_endpoint_test *test,
250                                   enum pci_barno barno)
251 {
252         int j;
253         u32 val;
254         int size;
255         struct pci_dev *pdev = test->pdev;
256
257         if (!test->bar[barno])
258                 return false;
259
260         size = pci_resource_len(pdev, barno);
261
262         if (barno == test->test_reg_bar)
263                 size = 0x4;
264
265         for (j = 0; j < size; j += 4)
266                 pci_endpoint_test_bar_writel(test, barno, j, 0xA0A0A0A0);
267
268         for (j = 0; j < size; j += 4) {
269                 val = pci_endpoint_test_bar_readl(test, barno, j);
270                 if (val != 0xA0A0A0A0)
271                         return false;
272         }
273
274         return true;
275 }
276
277 static bool pci_endpoint_test_legacy_irq(struct pci_endpoint_test *test)
278 {
279         u32 val;
280
281         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
282                                  IRQ_TYPE_LEGACY);
283         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 0);
284         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
285                                  COMMAND_RAISE_LEGACY_IRQ);
286         val = wait_for_completion_timeout(&test->irq_raised,
287                                           msecs_to_jiffies(1000));
288         if (!val)
289                 return false;
290
291         return true;
292 }
293
294 static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
295                                        u16 msi_num, bool msix)
296 {
297         u32 val;
298         struct pci_dev *pdev = test->pdev;
299
300         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
301                                  msix == false ? IRQ_TYPE_MSI :
302                                  IRQ_TYPE_MSIX);
303         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, msi_num);
304         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
305                                  msix == false ? COMMAND_RAISE_MSI_IRQ :
306                                  COMMAND_RAISE_MSIX_IRQ);
307         val = wait_for_completion_timeout(&test->irq_raised,
308                                           msecs_to_jiffies(1000));
309         if (!val)
310                 return false;
311
312         if (pci_irq_vector(pdev, msi_num - 1) == test->last_irq)
313                 return true;
314
315         return false;
316 }
317
318 static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
319 {
320         bool ret = false;
321         void *src_addr;
322         void *dst_addr;
323         dma_addr_t src_phys_addr;
324         dma_addr_t dst_phys_addr;
325         struct pci_dev *pdev = test->pdev;
326         struct device *dev = &pdev->dev;
327         void *orig_src_addr;
328         dma_addr_t orig_src_phys_addr;
329         void *orig_dst_addr;
330         dma_addr_t orig_dst_phys_addr;
331         size_t offset;
332         size_t alignment = test->alignment;
333         u32 src_crc32;
334         u32 dst_crc32;
335
336         if (size > SIZE_MAX - alignment)
337                 goto err;
338
339         if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
340                 dev_err(dev, "Invalid IRQ type option\n");
341                 goto err;
342         }
343
344         orig_src_addr = dma_alloc_coherent(dev, size + alignment,
345                                            &orig_src_phys_addr, GFP_KERNEL);
346         if (!orig_src_addr) {
347                 dev_err(dev, "Failed to allocate source buffer\n");
348                 ret = false;
349                 goto err;
350         }
351
352         if (alignment && !IS_ALIGNED(orig_src_phys_addr, alignment)) {
353                 src_phys_addr = PTR_ALIGN(orig_src_phys_addr, alignment);
354                 offset = src_phys_addr - orig_src_phys_addr;
355                 src_addr = orig_src_addr + offset;
356         } else {
357                 src_phys_addr = orig_src_phys_addr;
358                 src_addr = orig_src_addr;
359         }
360
361         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_SRC_ADDR,
362                                  lower_32_bits(src_phys_addr));
363
364         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_SRC_ADDR,
365                                  upper_32_bits(src_phys_addr));
366
367         get_random_bytes(src_addr, size);
368         src_crc32 = crc32_le(~0, src_addr, size);
369
370         orig_dst_addr = dma_alloc_coherent(dev, size + alignment,
371                                            &orig_dst_phys_addr, GFP_KERNEL);
372         if (!orig_dst_addr) {
373                 dev_err(dev, "Failed to allocate destination address\n");
374                 ret = false;
375                 goto err_orig_src_addr;
376         }
377
378         if (alignment && !IS_ALIGNED(orig_dst_phys_addr, alignment)) {
379                 dst_phys_addr = PTR_ALIGN(orig_dst_phys_addr, alignment);
380                 offset = dst_phys_addr - orig_dst_phys_addr;
381                 dst_addr = orig_dst_addr + offset;
382         } else {
383                 dst_phys_addr = orig_dst_phys_addr;
384                 dst_addr = orig_dst_addr;
385         }
386
387         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR,
388                                  lower_32_bits(dst_phys_addr));
389         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_DST_ADDR,
390                                  upper_32_bits(dst_phys_addr));
391
392         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE,
393                                  size);
394
395         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
396         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
397         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
398                                  COMMAND_COPY);
399
400         wait_for_completion(&test->irq_raised);
401
402         dst_crc32 = crc32_le(~0, dst_addr, size);
403         if (dst_crc32 == src_crc32)
404                 ret = true;
405
406         dma_free_coherent(dev, size + alignment, orig_dst_addr,
407                           orig_dst_phys_addr);
408
409 err_orig_src_addr:
410         dma_free_coherent(dev, size + alignment, orig_src_addr,
411                           orig_src_phys_addr);
412
413 err:
414         return ret;
415 }
416
417 static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)
418 {
419         bool ret = false;
420         u32 reg;
421         void *addr;
422         dma_addr_t phys_addr;
423         struct pci_dev *pdev = test->pdev;
424         struct device *dev = &pdev->dev;
425         void *orig_addr;
426         dma_addr_t orig_phys_addr;
427         size_t offset;
428         size_t alignment = test->alignment;
429         u32 crc32;
430
431         if (size > SIZE_MAX - alignment)
432                 goto err;
433
434         if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
435                 dev_err(dev, "Invalid IRQ type option\n");
436                 goto err;
437         }
438
439         orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr,
440                                        GFP_KERNEL);
441         if (!orig_addr) {
442                 dev_err(dev, "Failed to allocate address\n");
443                 ret = false;
444                 goto err;
445         }
446
447         if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) {
448                 phys_addr =  PTR_ALIGN(orig_phys_addr, alignment);
449                 offset = phys_addr - orig_phys_addr;
450                 addr = orig_addr + offset;
451         } else {
452                 phys_addr = orig_phys_addr;
453                 addr = orig_addr;
454         }
455
456         get_random_bytes(addr, size);
457
458         crc32 = crc32_le(~0, addr, size);
459         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_CHECKSUM,
460                                  crc32);
461
462         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_SRC_ADDR,
463                                  lower_32_bits(phys_addr));
464         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_SRC_ADDR,
465                                  upper_32_bits(phys_addr));
466
467         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
468
469         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
470         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
471         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
472                                  COMMAND_READ);
473
474         wait_for_completion(&test->irq_raised);
475
476         reg = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
477         if (reg & STATUS_READ_SUCCESS)
478                 ret = true;
479
480         dma_free_coherent(dev, size + alignment, orig_addr, orig_phys_addr);
481
482 err:
483         return ret;
484 }
485
486 static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size)
487 {
488         bool ret = false;
489         void *addr;
490         dma_addr_t phys_addr;
491         struct pci_dev *pdev = test->pdev;
492         struct device *dev = &pdev->dev;
493         void *orig_addr;
494         dma_addr_t orig_phys_addr;
495         size_t offset;
496         size_t alignment = test->alignment;
497         u32 crc32;
498
499         if (size > SIZE_MAX - alignment)
500                 goto err;
501
502         if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
503                 dev_err(dev, "Invalid IRQ type option\n");
504                 goto err;
505         }
506
507         orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr,
508                                        GFP_KERNEL);
509         if (!orig_addr) {
510                 dev_err(dev, "Failed to allocate destination address\n");
511                 ret = false;
512                 goto err;
513         }
514
515         if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) {
516                 phys_addr = PTR_ALIGN(orig_phys_addr, alignment);
517                 offset = phys_addr - orig_phys_addr;
518                 addr = orig_addr + offset;
519         } else {
520                 phys_addr = orig_phys_addr;
521                 addr = orig_addr;
522         }
523
524         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR,
525                                  lower_32_bits(phys_addr));
526         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_DST_ADDR,
527                                  upper_32_bits(phys_addr));
528
529         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
530
531         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
532         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
533         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
534                                  COMMAND_WRITE);
535
536         wait_for_completion(&test->irq_raised);
537
538         crc32 = crc32_le(~0, addr, size);
539         if (crc32 == pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CHECKSUM))
540                 ret = true;
541
542         dma_free_coherent(dev, size + alignment, orig_addr, orig_phys_addr);
543 err:
544         return ret;
545 }
546
547 static bool pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
548                                       int req_irq_type)
549 {
550         struct pci_dev *pdev = test->pdev;
551         struct device *dev = &pdev->dev;
552
553         if (req_irq_type < IRQ_TYPE_LEGACY || req_irq_type > IRQ_TYPE_MSIX) {
554                 dev_err(dev, "Invalid IRQ type option\n");
555                 return false;
556         }
557
558         if (irq_type == req_irq_type)
559                 return true;
560
561         pci_endpoint_test_release_irq(test);
562         pci_endpoint_test_free_irq_vectors(test);
563
564         if (!pci_endpoint_test_alloc_irq_vectors(test, req_irq_type))
565                 goto err;
566
567         if (!pci_endpoint_test_request_irq(test))
568                 goto err;
569
570         irq_type = req_irq_type;
571         return true;
572
573 err:
574         pci_endpoint_test_free_irq_vectors(test);
575         irq_type = IRQ_TYPE_UNDEFINED;
576         return false;
577 }
578
579 static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
580                                     unsigned long arg)
581 {
582         int ret = -EINVAL;
583         enum pci_barno bar;
584         struct pci_endpoint_test *test = to_endpoint_test(file->private_data);
585         struct pci_dev *pdev = test->pdev;
586
587         mutex_lock(&test->mutex);
588         switch (cmd) {
589         case PCITEST_BAR:
590                 bar = arg;
591                 if (bar < 0 || bar > 5)
592                         goto ret;
593                 if (is_am654_pci_dev(pdev) && bar == BAR_0)
594                         goto ret;
595                 ret = pci_endpoint_test_bar(test, bar);
596                 break;
597         case PCITEST_LEGACY_IRQ:
598                 ret = pci_endpoint_test_legacy_irq(test);
599                 break;
600         case PCITEST_MSI:
601         case PCITEST_MSIX:
602                 ret = pci_endpoint_test_msi_irq(test, arg, cmd == PCITEST_MSIX);
603                 break;
604         case PCITEST_WRITE:
605                 ret = pci_endpoint_test_write(test, arg);
606                 break;
607         case PCITEST_READ:
608                 ret = pci_endpoint_test_read(test, arg);
609                 break;
610         case PCITEST_COPY:
611                 ret = pci_endpoint_test_copy(test, arg);
612                 break;
613         case PCITEST_SET_IRQTYPE:
614                 ret = pci_endpoint_test_set_irq(test, arg);
615                 break;
616         case PCITEST_GET_IRQTYPE:
617                 ret = irq_type;
618                 break;
619         }
620
621 ret:
622         mutex_unlock(&test->mutex);
623         return ret;
624 }
625
626 static const struct file_operations pci_endpoint_test_fops = {
627         .owner = THIS_MODULE,
628         .unlocked_ioctl = pci_endpoint_test_ioctl,
629 };
630
631 static int pci_endpoint_test_probe(struct pci_dev *pdev,
632                                    const struct pci_device_id *ent)
633 {
634         int err;
635         int id;
636         char name[20];
637         enum pci_barno bar;
638         void __iomem *base;
639         struct device *dev = &pdev->dev;
640         struct pci_endpoint_test *test;
641         struct pci_endpoint_test_data *data;
642         enum pci_barno test_reg_bar = BAR_0;
643         struct miscdevice *misc_device;
644
645         if (pci_is_bridge(pdev))
646                 return -ENODEV;
647
648         test = devm_kzalloc(dev, sizeof(*test), GFP_KERNEL);
649         if (!test)
650                 return -ENOMEM;
651
652         test->test_reg_bar = 0;
653         test->alignment = 0;
654         test->pdev = pdev;
655
656         if (no_msi)
657                 irq_type = IRQ_TYPE_LEGACY;
658
659         data = (struct pci_endpoint_test_data *)ent->driver_data;
660         if (data) {
661                 test_reg_bar = data->test_reg_bar;
662                 test->test_reg_bar = test_reg_bar;
663                 test->alignment = data->alignment;
664                 irq_type = data->irq_type;
665         }
666
667         init_completion(&test->irq_raised);
668         mutex_init(&test->mutex);
669
670         err = pci_enable_device(pdev);
671         if (err) {
672                 dev_err(dev, "Cannot enable PCI device\n");
673                 return err;
674         }
675
676         err = pci_request_regions(pdev, DRV_MODULE_NAME);
677         if (err) {
678                 dev_err(dev, "Cannot obtain PCI resources\n");
679                 goto err_disable_pdev;
680         }
681
682         pci_set_master(pdev);
683
684         if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type))
685                 goto err_disable_irq;
686
687         if (!pci_endpoint_test_request_irq(test))
688                 goto err_disable_irq;
689
690         for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
691                 if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
692                         base = pci_ioremap_bar(pdev, bar);
693                         if (!base) {
694                                 dev_err(dev, "Failed to read BAR%d\n", bar);
695                                 WARN_ON(bar == test_reg_bar);
696                         }
697                         test->bar[bar] = base;
698                 }
699         }
700
701         test->base = test->bar[test_reg_bar];
702         if (!test->base) {
703                 err = -ENOMEM;
704                 dev_err(dev, "Cannot perform PCI test without BAR%d\n",
705                         test_reg_bar);
706                 goto err_iounmap;
707         }
708
709         pci_set_drvdata(pdev, test);
710
711         id = ida_simple_get(&pci_endpoint_test_ida, 0, 0, GFP_KERNEL);
712         if (id < 0) {
713                 err = id;
714                 dev_err(dev, "Unable to get id\n");
715                 goto err_iounmap;
716         }
717
718         snprintf(name, sizeof(name), DRV_MODULE_NAME ".%d", id);
719         misc_device = &test->miscdev;
720         misc_device->minor = MISC_DYNAMIC_MINOR;
721         misc_device->name = kstrdup(name, GFP_KERNEL);
722         if (!misc_device->name) {
723                 err = -ENOMEM;
724                 goto err_ida_remove;
725         }
726         misc_device->fops = &pci_endpoint_test_fops,
727
728         err = misc_register(misc_device);
729         if (err) {
730                 dev_err(dev, "Failed to register device\n");
731                 goto err_kfree_name;
732         }
733
734         return 0;
735
736 err_kfree_name:
737         kfree(misc_device->name);
738
739 err_ida_remove:
740         ida_simple_remove(&pci_endpoint_test_ida, id);
741
742 err_iounmap:
743         for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
744                 if (test->bar[bar])
745                         pci_iounmap(pdev, test->bar[bar]);
746         }
747         pci_endpoint_test_release_irq(test);
748
749 err_disable_irq:
750         pci_endpoint_test_free_irq_vectors(test);
751         pci_release_regions(pdev);
752
753 err_disable_pdev:
754         pci_disable_device(pdev);
755
756         return err;
757 }
758
759 static void pci_endpoint_test_remove(struct pci_dev *pdev)
760 {
761         int id;
762         enum pci_barno bar;
763         struct pci_endpoint_test *test = pci_get_drvdata(pdev);
764         struct miscdevice *misc_device = &test->miscdev;
765
766         if (sscanf(misc_device->name, DRV_MODULE_NAME ".%d", &id) != 1)
767                 return;
768         if (id < 0)
769                 return;
770
771         misc_deregister(&test->miscdev);
772         kfree(misc_device->name);
773         ida_simple_remove(&pci_endpoint_test_ida, id);
774         for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
775                 if (test->bar[bar])
776                         pci_iounmap(pdev, test->bar[bar]);
777         }
778
779         pci_endpoint_test_release_irq(test);
780         pci_endpoint_test_free_irq_vectors(test);
781
782         pci_release_regions(pdev);
783         pci_disable_device(pdev);
784 }
785
786 static const struct pci_endpoint_test_data am654_data = {
787         .test_reg_bar = BAR_2,
788         .alignment = SZ_64K,
789         .irq_type = IRQ_TYPE_MSI,
790 };
791
792 static const struct pci_device_id pci_endpoint_test_tbl[] = {
793         { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) },
794         { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) },
795         { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x81c0) },
796         { PCI_DEVICE_DATA(SYNOPSYS, EDDA, NULL) },
797         { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654),
798           .driver_data = (kernel_ulong_t)&am654_data
799         },
800         { }
801 };
802 MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);
803
804 static struct pci_driver pci_endpoint_test_driver = {
805         .name           = DRV_MODULE_NAME,
806         .id_table       = pci_endpoint_test_tbl,
807         .probe          = pci_endpoint_test_probe,
808         .remove         = pci_endpoint_test_remove,
809 };
810 module_pci_driver(pci_endpoint_test_driver);
811
812 MODULE_DESCRIPTION("PCI ENDPOINT TEST HOST DRIVER");
813 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
814 MODULE_LICENSE("GPL v2");