File Index
Files and directories
Sign in
FILE

enetc_ptp.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/freescale/enetc/enetc_ptp.c 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
 10static 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
 26static 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
 96err_no_clock:
 97	free_irq(ptp_qoriq->irq, ptp_qoriq);
 98err_irq:
 99	pci_free_irq_vectors(pdev);
100err_irq_vectors:
101	iounmap(base);
102err_ioremap:
103	kfree(ptp_qoriq);
104err_alloc_ptp:
105	pci_release_mem_regions(pdev);
106err_pci_mem_reg:
107err_dma:
108	pci_disable_device(pdev);
109
110	return err;
111}
112
113static 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
125static 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};
129MODULE_DEVICE_TABLE(pci, enetc_ptp_id_table);
130
131static 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};
137module_pci_driver(enetc_ptp_driver);
138
139MODULE_DESCRIPTION("ENETC PTP clock driver");
140MODULE_LICENSE("Dual BSD/GPL");
~/ Read-only file preview.