// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/* Copyright 2019 NXP */

#include <linux/module.h>
#include <linux/of.h>
#include <linux/fsl/ptp_qoriq.h>

#include "enetc.h"

int enetc_phc_index = -1;
EXPORT_SYMBOL_GPL(enetc_phc_index);

static struct ptp_clock_info enetc_ptp_caps = {
	.owner		= THIS_MODULE,
	.name		= "ENETC PTP clock",
	.max_adj	= 512000,
	.n_alarm	= 0,
	.n_ext_ts	= 2,
	.n_per_out	= 0,
	.n_pins		= 0,
	.pps		= 1,
	.adjfine	= ptp_qoriq_adjfine,
	.adjtime	= ptp_qoriq_adjtime,
	.gettime64	= ptp_qoriq_gettime,
	.settime64	= ptp_qoriq_settime,
	.enable		= ptp_qoriq_enable,
};

static int enetc_ptp_probe(struct pci_dev *pdev,
			   const struct pci_device_id *ent)
{
	struct ptp_qoriq *ptp_qoriq;
	void __iomem *base;
	int err, len, n;

	if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) {
		dev_info(&pdev->dev, "device is disabled, skipping\n");
		return -ENODEV;
	}

	err = pci_enable_device_mem(pdev);
	if (err)
		return dev_err_probe(&pdev->dev, err, "device enable failed\n");

	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
	if (err) {
		dev_err(&pdev->dev, "DMA configuration failed: 0x%x\n", err);
		goto err_dma;
	}

	err = pci_request_mem_regions(pdev, KBUILD_MODNAME);
	if (err) {
		dev_err(&pdev->dev, "pci_request_regions failed err=%d\n", err);
		goto err_pci_mem_reg;
	}

	pci_set_master(pdev);

	ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL);
	if (!ptp_qoriq) {
		err = -ENOMEM;
		goto err_alloc_ptp;
	}

	len = pci_resource_len(pdev, ENETC_BAR_REGS);

	base = ioremap(pci_resource_start(pdev, ENETC_BAR_REGS), len);
	if (!base) {
		err = -ENXIO;
		dev_err(&pdev->dev, "ioremap() failed\n");
		goto err_ioremap;
	}

	/* Allocate 1 interrupt */
	n = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
	if (n != 1) {
		err = -EPERM;
		goto err_irq_vectors;
	}

	ptp_qoriq->irq = pci_irq_vector(pdev, 0);

	err = request_irq(ptp_qoriq->irq, ptp_qoriq_isr, 0, DRIVER, ptp_qoriq);
	if (err) {
		dev_err(&pdev->dev, "request_irq() failed!\n");
		goto err_irq;
	}

	ptp_qoriq->dev = &pdev->dev;

	err = ptp_qoriq_init(ptp_qoriq, base, &enetc_ptp_caps);
	if (err)
		goto err_no_clock;

	enetc_phc_index = ptp_qoriq->phc_index;
	pci_set_drvdata(pdev, ptp_qoriq);

	return 0;

err_no_clock:
	free_irq(ptp_qoriq->irq, ptp_qoriq);
err_irq:
	pci_free_irq_vectors(pdev);
err_irq_vectors:
	iounmap(base);
err_ioremap:
	kfree(ptp_qoriq);
err_alloc_ptp:
	pci_release_mem_regions(pdev);
err_pci_mem_reg:
err_dma:
	pci_disable_device(pdev);

	return err;
}

static void enetc_ptp_remove(struct pci_dev *pdev)
{
	struct ptp_qoriq *ptp_qoriq = pci_get_drvdata(pdev);

	enetc_phc_index = -1;
	ptp_qoriq_free(ptp_qoriq);
	pci_free_irq_vectors(pdev);
	kfree(ptp_qoriq);

	pci_release_mem_regions(pdev);
	pci_disable_device(pdev);
}

static const struct pci_device_id enetc_ptp_id_table[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PTP) },
	{ 0, } /* End of table. */
};
MODULE_DEVICE_TABLE(pci, enetc_ptp_id_table);

static struct pci_driver enetc_ptp_driver = {
	.name = KBUILD_MODNAME,
	.id_table = enetc_ptp_id_table,
	.probe = enetc_ptp_probe,
	.remove = enetc_ptp_remove,
};
module_pci_driver(enetc_ptp_driver);

MODULE_DESCRIPTION("ENETC PTP clock driver");
MODULE_LICENSE("Dual BSD/GPL");
