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