xref: /linux/drivers/net/ethernet/freescale/enetc/enetc_ptp.c (revision 2b64b2ed277ff23e785fbdb65098ee7e1252d64f)
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 
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 		dev_err(&pdev->dev, "device enable failed\n");
41 		return err;
42 	}
43 
44 	/* set up for high or low dma */
45 	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
46 	if (err) {
47 		err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
48 		if (err) {
49 			dev_err(&pdev->dev,
50 				"DMA configuration failed: 0x%x\n", err);
51 			goto err_dma;
52 		}
53 	}
54 
55 	err = pci_request_mem_regions(pdev, KBUILD_MODNAME);
56 	if (err) {
57 		dev_err(&pdev->dev, "pci_request_regions failed err=%d\n", err);
58 		goto err_pci_mem_reg;
59 	}
60 
61 	pci_set_master(pdev);
62 
63 	ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL);
64 	if (!ptp_qoriq) {
65 		err = -ENOMEM;
66 		goto err_alloc_ptp;
67 	}
68 
69 	len = pci_resource_len(pdev, ENETC_BAR_REGS);
70 
71 	base = ioremap(pci_resource_start(pdev, ENETC_BAR_REGS), len);
72 	if (!base) {
73 		err = -ENXIO;
74 		dev_err(&pdev->dev, "ioremap() failed\n");
75 		goto err_ioremap;
76 	}
77 
78 	/* Allocate 1 interrupt */
79 	n = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
80 	if (n != 1) {
81 		err = -EPERM;
82 		goto err_irq;
83 	}
84 
85 	ptp_qoriq->irq = pci_irq_vector(pdev, 0);
86 
87 	err = request_irq(ptp_qoriq->irq, ptp_qoriq_isr, 0, DRIVER, ptp_qoriq);
88 	if (err) {
89 		dev_err(&pdev->dev, "request_irq() failed!\n");
90 		goto err_irq;
91 	}
92 
93 	ptp_qoriq->dev = &pdev->dev;
94 
95 	err = ptp_qoriq_init(ptp_qoriq, base, &enetc_ptp_caps);
96 	if (err)
97 		goto err_no_clock;
98 
99 	pci_set_drvdata(pdev, ptp_qoriq);
100 
101 	return 0;
102 
103 err_no_clock:
104 	free_irq(ptp_qoriq->irq, ptp_qoriq);
105 err_irq:
106 	iounmap(base);
107 err_ioremap:
108 	kfree(ptp_qoriq);
109 err_alloc_ptp:
110 	pci_release_mem_regions(pdev);
111 err_pci_mem_reg:
112 err_dma:
113 	pci_disable_device(pdev);
114 
115 	return err;
116 }
117 
118 static void enetc_ptp_remove(struct pci_dev *pdev)
119 {
120 	struct ptp_qoriq *ptp_qoriq = pci_get_drvdata(pdev);
121 
122 	ptp_qoriq_free(ptp_qoriq);
123 	kfree(ptp_qoriq);
124 
125 	pci_release_mem_regions(pdev);
126 	pci_disable_device(pdev);
127 }
128 
129 static const struct pci_device_id enetc_ptp_id_table[] = {
130 	{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PTP) },
131 	{ 0, } /* End of table. */
132 };
133 MODULE_DEVICE_TABLE(pci, enetc_ptp_id_table);
134 
135 static struct pci_driver enetc_ptp_driver = {
136 	.name = KBUILD_MODNAME,
137 	.id_table = enetc_ptp_id_table,
138 	.probe = enetc_ptp_probe,
139 	.remove = enetc_ptp_remove,
140 };
141 module_pci_driver(enetc_ptp_driver);
142 
143 MODULE_DESCRIPTION("ENETC PTP clock driver");
144 MODULE_LICENSE("Dual BSD/GPL");
145