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