brintos

brintos / linux-shallow public Read only

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