Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
0002 /* Copyright 2019 NXP */
0003 
0004 #include <linux/module.h>
0005 #include <linux/of.h>
0006 #include <linux/fsl/ptp_qoriq.h>
0007 
0008 #include "enetc.h"
0009 
0010 int enetc_phc_index = -1;
0011 EXPORT_SYMBOL(enetc_phc_index);
0012 
0013 static struct ptp_clock_info enetc_ptp_caps = {
0014     .owner      = THIS_MODULE,
0015     .name       = "ENETC PTP clock",
0016     .max_adj    = 512000,
0017     .n_alarm    = 0,
0018     .n_ext_ts   = 2,
0019     .n_per_out  = 0,
0020     .n_pins     = 0,
0021     .pps        = 1,
0022     .adjfine    = ptp_qoriq_adjfine,
0023     .adjtime    = ptp_qoriq_adjtime,
0024     .gettime64  = ptp_qoriq_gettime,
0025     .settime64  = ptp_qoriq_settime,
0026     .enable     = ptp_qoriq_enable,
0027 };
0028 
0029 static int enetc_ptp_probe(struct pci_dev *pdev,
0030                const struct pci_device_id *ent)
0031 {
0032     struct ptp_qoriq *ptp_qoriq;
0033     void __iomem *base;
0034     int err, len, n;
0035 
0036     if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) {
0037         dev_info(&pdev->dev, "device is disabled, skipping\n");
0038         return -ENODEV;
0039     }
0040 
0041     err = pci_enable_device_mem(pdev);
0042     if (err)
0043         return dev_err_probe(&pdev->dev, err, "device enable failed\n");
0044 
0045     err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
0046     if (err) {
0047         dev_err(&pdev->dev, "DMA configuration failed: 0x%x\n", err);
0048         goto err_dma;
0049     }
0050 
0051     err = pci_request_mem_regions(pdev, KBUILD_MODNAME);
0052     if (err) {
0053         dev_err(&pdev->dev, "pci_request_regions failed err=%d\n", err);
0054         goto err_pci_mem_reg;
0055     }
0056 
0057     pci_set_master(pdev);
0058 
0059     ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL);
0060     if (!ptp_qoriq) {
0061         err = -ENOMEM;
0062         goto err_alloc_ptp;
0063     }
0064 
0065     len = pci_resource_len(pdev, ENETC_BAR_REGS);
0066 
0067     base = ioremap(pci_resource_start(pdev, ENETC_BAR_REGS), len);
0068     if (!base) {
0069         err = -ENXIO;
0070         dev_err(&pdev->dev, "ioremap() failed\n");
0071         goto err_ioremap;
0072     }
0073 
0074     /* Allocate 1 interrupt */
0075     n = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
0076     if (n != 1) {
0077         err = -EPERM;
0078         goto err_irq_vectors;
0079     }
0080 
0081     ptp_qoriq->irq = pci_irq_vector(pdev, 0);
0082 
0083     err = request_irq(ptp_qoriq->irq, ptp_qoriq_isr, 0, DRIVER, ptp_qoriq);
0084     if (err) {
0085         dev_err(&pdev->dev, "request_irq() failed!\n");
0086         goto err_irq;
0087     }
0088 
0089     ptp_qoriq->dev = &pdev->dev;
0090 
0091     err = ptp_qoriq_init(ptp_qoriq, base, &enetc_ptp_caps);
0092     if (err)
0093         goto err_no_clock;
0094 
0095     enetc_phc_index = ptp_qoriq->phc_index;
0096     pci_set_drvdata(pdev, ptp_qoriq);
0097 
0098     return 0;
0099 
0100 err_no_clock:
0101     free_irq(ptp_qoriq->irq, ptp_qoriq);
0102 err_irq:
0103     pci_free_irq_vectors(pdev);
0104 err_irq_vectors:
0105     iounmap(base);
0106 err_ioremap:
0107     kfree(ptp_qoriq);
0108 err_alloc_ptp:
0109     pci_release_mem_regions(pdev);
0110 err_pci_mem_reg:
0111 err_dma:
0112     pci_disable_device(pdev);
0113 
0114     return err;
0115 }
0116 
0117 static void enetc_ptp_remove(struct pci_dev *pdev)
0118 {
0119     struct ptp_qoriq *ptp_qoriq = pci_get_drvdata(pdev);
0120 
0121     enetc_phc_index = -1;
0122     ptp_qoriq_free(ptp_qoriq);
0123     pci_free_irq_vectors(pdev);
0124     kfree(ptp_qoriq);
0125 
0126     pci_release_mem_regions(pdev);
0127     pci_disable_device(pdev);
0128 }
0129 
0130 static const struct pci_device_id enetc_ptp_id_table[] = {
0131     { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PTP) },
0132     { 0, } /* End of table. */
0133 };
0134 MODULE_DEVICE_TABLE(pci, enetc_ptp_id_table);
0135 
0136 static struct pci_driver enetc_ptp_driver = {
0137     .name = KBUILD_MODNAME,
0138     .id_table = enetc_ptp_id_table,
0139     .probe = enetc_ptp_probe,
0140     .remove = enetc_ptp_remove,
0141 };
0142 module_pci_driver(enetc_ptp_driver);
0143 
0144 MODULE_DESCRIPTION("ENETC PTP clock driver");
0145 MODULE_LICENSE("Dual BSD/GPL");