1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2 /* Copyright 2019 NXP */
3
4 #include <linux/module.h>
5 #include <linux/of.h>
6 #include <linux/fsl/ptp_qoriq.h>
7
8 #include "enetc.h"
9
10 static struct ptp_clock_info enetc_ptp_caps = {
11 .owner = THIS_MODULE,
12 .name = "ENETC PTP clock",
13 .max_adj = 512000,
14 .n_alarm = 0,
15 .n_ext_ts = 2,
16 .n_per_out = 0,
17 .n_pins = 0,
18 .pps = 1,
19 .adjfine = ptp_qoriq_adjfine,
20 .adjtime = ptp_qoriq_adjtime,
21 .gettime64 = ptp_qoriq_gettime,
22 .settime64 = ptp_qoriq_settime,
23 .enable = ptp_qoriq_enable,
24 };
25
enetc_ptp_probe(struct pci_dev * pdev,const struct pci_device_id * ent)26 static int enetc_ptp_probe(struct pci_dev *pdev,
27 const struct pci_device_id *ent)
28 {
29 struct ptp_qoriq *ptp_qoriq;
30 void __iomem *base;
31 int err, len, n;
32
33 if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) {
34 dev_info(&pdev->dev, "device is disabled, skipping\n");
35 return -ENODEV;
36 }
37
38 err = pci_enable_device_mem(pdev);
39 if (err)
40 return dev_err_probe(&pdev->dev, err, "device enable failed\n");
41
42 err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
43 if (err) {
44 dev_err(&pdev->dev, "DMA configuration failed: 0x%x\n", err);
45 goto err_dma;
46 }
47
48 err = pci_request_mem_regions(pdev, KBUILD_MODNAME);
49 if (err) {
50 dev_err(&pdev->dev, "pci_request_regions failed err=%d\n", err);
51 goto err_pci_mem_reg;
52 }
53
54 pci_set_master(pdev);
55
56 ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL);
57 if (!ptp_qoriq) {
58 err = -ENOMEM;
59 goto err_alloc_ptp;
60 }
61
62 len = pci_resource_len(pdev, ENETC_BAR_REGS);
63
64 base = ioremap(pci_resource_start(pdev, ENETC_BAR_REGS), len);
65 if (!base) {
66 err = -ENXIO;
67 dev_err(&pdev->dev, "ioremap() failed\n");
68 goto err_ioremap;
69 }
70
71 /* Allocate 1 interrupt */
72 n = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
73 if (n != 1) {
74 err = -EPERM;
75 goto err_irq_vectors;
76 }
77
78 ptp_qoriq->irq = pci_irq_vector(pdev, 0);
79
80 err = request_irq(ptp_qoriq->irq, ptp_qoriq_isr, 0, DRIVER, ptp_qoriq);
81 if (err) {
82 dev_err(&pdev->dev, "request_irq() failed!\n");
83 goto err_irq;
84 }
85
86 ptp_qoriq->dev = &pdev->dev;
87
88 err = ptp_qoriq_init(ptp_qoriq, base, &enetc_ptp_caps);
89 if (err)
90 goto err_no_clock;
91
92 pci_set_drvdata(pdev, ptp_qoriq);
93
94 return 0;
95
96 err_no_clock:
97 free_irq(ptp_qoriq->irq, ptp_qoriq);
98 err_irq:
99 pci_free_irq_vectors(pdev);
100 err_irq_vectors:
101 iounmap(base);
102 err_ioremap:
103 kfree(ptp_qoriq);
104 err_alloc_ptp:
105 pci_release_mem_regions(pdev);
106 err_pci_mem_reg:
107 err_dma:
108 pci_disable_device(pdev);
109
110 return err;
111 }
112
enetc_ptp_remove(struct pci_dev * pdev)113 static void enetc_ptp_remove(struct pci_dev *pdev)
114 {
115 struct ptp_qoriq *ptp_qoriq = pci_get_drvdata(pdev);
116
117 ptp_qoriq_free(ptp_qoriq);
118 pci_free_irq_vectors(pdev);
119 kfree(ptp_qoriq);
120
121 pci_release_mem_regions(pdev);
122 pci_disable_device(pdev);
123 }
124
125 static const struct pci_device_id enetc_ptp_id_table[] = {
126 { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PTP) },
127 { 0, } /* End of table. */
128 };
129 MODULE_DEVICE_TABLE(pci, enetc_ptp_id_table);
130
131 static struct pci_driver enetc_ptp_driver = {
132 .name = KBUILD_MODNAME,
133 .id_table = enetc_ptp_id_table,
134 .probe = enetc_ptp_probe,
135 .remove = enetc_ptp_remove,
136 };
137 module_pci_driver(enetc_ptp_driver);
138
139 MODULE_DESCRIPTION("ENETC PTP clock driver");
140 MODULE_LICENSE("Dual BSD/GPL");
141