// SPDX-License-Identifier: GPL-2.0
/*
 * Cadence PCI Glue driver.
 *
 * Copyright (C) 2019 Cadence.
 *
 * Author: Pawel Laszczak <pawell@cadence.com>
 *
 */

#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/pci.h>

#include "core.h"
#include "gadget-export.h"

#define PCI_BAR_HOST		0
#define PCI_BAR_OTG		0
#define PCI_BAR_DEV		2

#define PCI_DEV_FN_HOST_DEVICE	0
#define PCI_DEV_FN_OTG		1

#define PCI_DRIVER_NAME		"cdns-pci-usbssp"
#define PLAT_DRIVER_NAME	"cdns-usbssp"

#define PCI_DEVICE_ID_CDNS_USB3		0x0100
#define PCI_DEVICE_ID_CDNS_UDC		0x0200

#define PCI_CLASS_SERIAL_USB_CDNS_USB3	(PCI_CLASS_SERIAL_USB << 8 | 0x80)
#define PCI_CLASS_SERIAL_USB_CDNS_UDC	PCI_CLASS_SERIAL_USB_DEVICE

static struct pci_dev *cdnsp_get_second_fun(struct pci_dev *pdev)
{
	/*
	 * Gets the second function.
	 * Platform has two function. The fist keeps resources for
	 * Host/Device while the secon keeps resources for DRD/OTG.
	 */
	if (pdev->device == PCI_DEVICE_ID_CDNS_UDC)
		return pci_get_device(pdev->vendor, PCI_DEVICE_ID_CDNS_USB3, NULL);
	if (pdev->device == PCI_DEVICE_ID_CDNS_USB3)
		return pci_get_device(pdev->vendor, PCI_DEVICE_ID_CDNS_UDC, NULL);

	return NULL;
}

static int cdnsp_pci_probe(struct pci_dev *pdev,
			   const struct pci_device_id *id)
{
	struct device *dev = &pdev->dev;
	struct pci_dev *func;
	struct resource *res;
	struct cdns *cdnsp;
	int ret;

	/*
	 * For GADGET/HOST PCI (devfn) function number is 0,
	 * for OTG PCI (devfn) function number is 1.
	 */
	if (!id || (pdev->devfn != PCI_DEV_FN_HOST_DEVICE &&
		    pdev->devfn != PCI_DEV_FN_OTG))
		return -EINVAL;

	func = cdnsp_get_second_fun(pdev);
	if (!func)
		return -EINVAL;

	if (func->class == PCI_CLASS_SERIAL_USB_XHCI ||
	    pdev->class == PCI_CLASS_SERIAL_USB_XHCI) {
		ret = -EINVAL;
		goto put_pci;
	}

	ret = pcim_enable_device(pdev);
	if (ret) {
		dev_err(&pdev->dev, "Enabling PCI device has failed %d\n", ret);
		goto put_pci;
	}

	pci_set_master(pdev);
	if (pci_is_enabled(func)) {
		cdnsp = pci_get_drvdata(func);
	} else {
		cdnsp = kzalloc(sizeof(*cdnsp), GFP_KERNEL);
		if (!cdnsp) {
			ret = -ENOMEM;
			goto disable_pci;
		}
	}

	/* For GADGET device function number is 0. */
	if (pdev->devfn == 0) {
		resource_size_t rsrc_start, rsrc_len;

		/* Function 0: host(BAR_0) + device(BAR_1).*/
		dev_dbg(dev, "Initialize resources\n");
		rsrc_start = pci_resource_start(pdev, PCI_BAR_DEV);
		rsrc_len = pci_resource_len(pdev, PCI_BAR_DEV);
		res = devm_request_mem_region(dev, rsrc_start, rsrc_len, "dev");
		if (!res) {
			dev_dbg(dev, "controller already in use\n");
			ret = -EBUSY;
			goto free_cdnsp;
		}

		cdnsp->dev_regs = devm_ioremap(dev, rsrc_start, rsrc_len);
		if (!cdnsp->dev_regs) {
			dev_dbg(dev, "error mapping memory\n");
			ret = -EFAULT;
			goto free_cdnsp;
		}

		cdnsp->dev_irq = pdev->irq;
		dev_dbg(dev, "USBSS-DEV physical base addr: %pa\n",
			&rsrc_start);

		res = &cdnsp->xhci_res[0];
		res->start = pci_resource_start(pdev, PCI_BAR_HOST);
		res->end = pci_resource_end(pdev, PCI_BAR_HOST);
		res->name = "xhci";
		res->flags = IORESOURCE_MEM;
		dev_dbg(dev, "USBSS-XHCI physical base addr: %pa\n",
			&res->start);

		/* Interrupt for XHCI, */
		res = &cdnsp->xhci_res[1];
		res->start = pdev->irq;
		res->name = "host";
		res->flags = IORESOURCE_IRQ;
	} else {
		res = &cdnsp->otg_res;
		res->start = pci_resource_start(pdev, PCI_BAR_OTG);
		res->end =   pci_resource_end(pdev, PCI_BAR_OTG);
		res->name = "otg";
		res->flags = IORESOURCE_MEM;
		dev_dbg(dev, "CDNSP-DRD physical base addr: %pa\n",
			&res->start);

		/* Interrupt for OTG/DRD. */
		cdnsp->otg_irq = pdev->irq;
	}

	if (pci_is_enabled(func)) {
		cdnsp->dev = dev;
		cdnsp->gadget_init = cdnsp_gadget_init;

		ret = cdns_init(cdnsp);
		if (ret)
			goto free_cdnsp;
	}

	pci_set_drvdata(pdev, cdnsp);

	device_wakeup_enable(&pdev->dev);
	if (pci_dev_run_wake(pdev))
		pm_runtime_put_noidle(&pdev->dev);

	return 0;

free_cdnsp:
	if (!pci_is_enabled(func))
		kfree(cdnsp);

disable_pci:
	pci_disable_device(pdev);

put_pci:
	pci_dev_put(func);

	return ret;
}

static void cdnsp_pci_remove(struct pci_dev *pdev)
{
	struct cdns *cdnsp;
	struct pci_dev *func;

	func = cdnsp_get_second_fun(pdev);
	cdnsp = (struct cdns *)pci_get_drvdata(pdev);

	if (pci_dev_run_wake(pdev))
		pm_runtime_get_noresume(&pdev->dev);

	if (pci_is_enabled(func)) {
		cdns_remove(cdnsp);
	} else {
		kfree(cdnsp);
	}

	pci_dev_put(func);
}

static int __maybe_unused cdnsp_pci_suspend(struct device *dev)
{
	struct cdns *cdns = dev_get_drvdata(dev);

	return cdns_suspend(cdns);
}

static int __maybe_unused cdnsp_pci_resume(struct device *dev)
{
	struct cdns *cdns = dev_get_drvdata(dev);
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&cdns->lock, flags);
	ret = cdns_resume(cdns);
	spin_unlock_irqrestore(&cdns->lock, flags);
	cdns_set_active(cdns, 1);

	return ret;
}

static const struct dev_pm_ops cdnsp_pci_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(cdnsp_pci_suspend, cdnsp_pci_resume)
};

static const struct pci_device_id cdnsp_pci_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_CDNS, PCI_DEVICE_ID_CDNS_UDC),
	  .class = PCI_CLASS_SERIAL_USB_CDNS_UDC },
	{ PCI_DEVICE(PCI_VENDOR_ID_CDNS, PCI_DEVICE_ID_CDNS_UDC),
	  .class = PCI_CLASS_SERIAL_USB_CDNS_USB3 },
	{ PCI_DEVICE(PCI_VENDOR_ID_CDNS, PCI_DEVICE_ID_CDNS_USB3),
	  .class = PCI_CLASS_SERIAL_USB_CDNS_USB3 },
	{ 0, }
};

static struct pci_driver cdnsp_pci_driver = {
	.name = "cdnsp-pci",
	.id_table = cdnsp_pci_ids,
	.probe = cdnsp_pci_probe,
	.remove = cdnsp_pci_remove,
	.driver = {
		.pm = &cdnsp_pci_pm_ops,
	}
};

module_pci_driver(cdnsp_pci_driver);
MODULE_DEVICE_TABLE(pci, cdnsp_pci_ids);

MODULE_ALIAS("pci:cdnsp");
MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Cadence CDNSP PCI driver");
