// 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 CDNS_VENDOR_ID		0x17cd
#define CDNS_DEVICE_ID		0x0100
#define CDNS_DRD_IF		(PCI_CLASS_SERIAL_USB << 8 | 0x80)

static struct pci_dev *cdnsp_get_second_fun(struct pci_dev *pdev)
{
	struct pci_dev *func;

	/*
	 * Gets the second function.
	 * It's little tricky, but this platform has two function.
	 * The fist keeps resources for Host/Device while the second
	 * keeps resources for DRD/OTG.
	 */
	func = pci_get_device(pdev->vendor, pdev->device, NULL);
	if (!func)
		return NULL;

	if (func->devfn == pdev->devfn) {
		func = pci_get_device(pdev->vendor, pdev->device, func);
		if (!func)
			return NULL;
	}

	return func;
}

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)) {
		kfree(cdnsp);
		goto pci_put;
	}

	cdns_remove(cdnsp);

pci_put:
	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, 1);
	spin_unlock_irqrestore(&cdns->lock, flags);

	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_VENDOR_ID_CDNS, CDNS_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,
	  PCI_CLASS_SERIAL_USB_DEVICE, PCI_ANY_ID },
	{ PCI_VENDOR_ID_CDNS, CDNS_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,
	  CDNS_DRD_IF, PCI_ANY_ID },
	{ 0, }
};

static struct pci_driver cdnsp_pci_driver = {
	.name = "cdnsp-pci",
	.id_table = &cdnsp_pci_ids[0],
	.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");
