// SPDX-License-Identifier: GPL-2.0
/*
 * snps_udc_plat.c - Synopsys UDC Platform Driver
 *
 * Copyright (C) 2016 Broadcom
 */

#include <linux/extcon.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/phy/phy.h>
#include <linux/module.h>
#include <linux/dmapool.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
#include "amd5536udc.h"

/* description */
#define UDC_MOD_DESCRIPTION     "Synopsys UDC platform driver"

static void start_udc(struct udc *udc)
{
	if (udc->driver) {
		dev_info(udc->dev, "Connecting...\n");
		udc_enable_dev_setup_interrupts(udc);
		udc_basic_init(udc);
		udc->connected = 1;
	}
}

static void stop_udc(struct udc *udc)
{
	int tmp;
	u32 reg;

	spin_lock(&udc->lock);

	/* Flush the receieve fifo */
	reg = readl(&udc->regs->ctl);
	reg |= AMD_BIT(UDC_DEVCTL_SRX_FLUSH);
	writel(reg, &udc->regs->ctl);

	reg = readl(&udc->regs->ctl);
	reg &= ~(AMD_BIT(UDC_DEVCTL_SRX_FLUSH));
	writel(reg, &udc->regs->ctl);
	dev_dbg(udc->dev, "ep rx queue flushed\n");

	/* Mask interrupts. Required more so when the
	 * UDC is connected to a DRD phy.
	 */
	udc_mask_unused_interrupts(udc);

	/* Disconnect gadget driver */
	if (udc->driver) {
		spin_unlock(&udc->lock);
		udc->driver->disconnect(&udc->gadget);
		spin_lock(&udc->lock);

		/* empty queues */
		for (tmp = 0; tmp < UDC_EP_NUM; tmp++)
			empty_req_queue(&udc->ep[tmp]);
	}
	udc->connected = 0;

	spin_unlock(&udc->lock);
	dev_info(udc->dev, "Device disconnected\n");
}

static void udc_drd_work(struct work_struct *work)
{
	struct udc *udc;

	udc = container_of(to_delayed_work(work),
			   struct udc, drd_work);

	if (udc->conn_type) {
		dev_dbg(udc->dev, "idle -> device\n");
		start_udc(udc);
	} else {
		dev_dbg(udc->dev, "device -> idle\n");
		stop_udc(udc);
	}
}

static int usbd_connect_notify(struct notifier_block *self,
			       unsigned long event, void *ptr)
{
	struct udc *udc = container_of(self, struct udc, nb);

	dev_dbg(udc->dev, "%s: event: %lu\n", __func__, event);

	udc->conn_type = event;

	schedule_delayed_work(&udc->drd_work, 0);

	return NOTIFY_OK;
}

static int udc_plat_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct resource *res;
	struct udc *udc;
	int ret;

	udc = devm_kzalloc(dev, sizeof(*udc), GFP_KERNEL);
	if (!udc)
		return -ENOMEM;

	spin_lock_init(&udc->lock);
	udc->dev = dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	udc->virt_addr = devm_ioremap_resource(dev, res);
	if (IS_ERR(udc->virt_addr))
		return PTR_ERR(udc->virt_addr);

	/* udc csr registers base */
	udc->csr = udc->virt_addr + UDC_CSR_ADDR;

	/* dev registers base */
	udc->regs = udc->virt_addr + UDC_DEVCFG_ADDR;

	/* ep registers base */
	udc->ep_regs = udc->virt_addr + UDC_EPREGS_ADDR;

	/* fifo's base */
	udc->rxfifo = (u32 __iomem *)(udc->virt_addr + UDC_RXFIFO_ADDR);
	udc->txfifo = (u32 __iomem *)(udc->virt_addr + UDC_TXFIFO_ADDR);

	udc->phys_addr = (unsigned long)res->start;

	udc->irq = irq_of_parse_and_map(dev->of_node, 0);
	if (udc->irq <= 0) {
		dev_err(dev, "Can't parse and map interrupt\n");
		return -EINVAL;
	}

	udc->udc_phy = devm_of_phy_get_by_index(dev, dev->of_node, 0);
	if (IS_ERR(udc->udc_phy)) {
		dev_err(dev, "Failed to obtain phy from device tree\n");
		return PTR_ERR(udc->udc_phy);
	}

	ret = phy_init(udc->udc_phy);
	if (ret) {
		dev_err(dev, "UDC phy init failed");
		return ret;
	}

	ret = phy_power_on(udc->udc_phy);
	if (ret) {
		dev_err(dev, "UDC phy power on failed");
		phy_exit(udc->udc_phy);
		return ret;
	}

	/* Register for extcon if supported */
	if (of_get_property(dev->of_node, "extcon", NULL)) {
		udc->edev = extcon_get_edev_by_phandle(dev, 0);
		if (IS_ERR(udc->edev)) {
			if (PTR_ERR(udc->edev) == -EPROBE_DEFER)
				return -EPROBE_DEFER;
			dev_err(dev, "Invalid or missing extcon\n");
			ret = PTR_ERR(udc->edev);
			goto exit_phy;
		}

		udc->nb.notifier_call = usbd_connect_notify;
		ret = extcon_register_notifier(udc->edev, EXTCON_USB,
					       &udc->nb);
		if (ret < 0) {
			dev_err(dev, "Can't register extcon device\n");
			goto exit_phy;
		}

		ret = extcon_get_state(udc->edev, EXTCON_USB);
		if (ret < 0) {
			dev_err(dev, "Can't get cable state\n");
			goto exit_extcon;
		} else if (ret) {
			udc->conn_type = ret;
		}
		INIT_DELAYED_WORK(&udc->drd_work, udc_drd_work);
	}

	/* init dma pools */
	if (use_dma) {
		ret = init_dma_pools(udc);
		if (ret != 0)
			goto exit_extcon;
	}

	ret = devm_request_irq(dev, udc->irq, udc_irq, IRQF_SHARED,
			       "snps-udc", udc);
	if (ret < 0) {
		dev_err(dev, "Request irq %d failed for UDC\n", udc->irq);
		goto exit_dma;
	}

	platform_set_drvdata(pdev, udc);
	udc->chiprev = UDC_BCM_REV;

	if (udc_probe(udc)) {
		ret = -ENODEV;
		goto exit_dma;
	}
	dev_info(dev, "Synopsys UDC platform driver probe successful\n");

	return 0;

exit_dma:
	if (use_dma)
		free_dma_pools(udc);
exit_extcon:
	if (udc->edev)
		extcon_unregister_notifier(udc->edev, EXTCON_USB, &udc->nb);
exit_phy:
	if (udc->udc_phy) {
		phy_power_off(udc->udc_phy);
		phy_exit(udc->udc_phy);
	}
	return ret;
}

static int udc_plat_remove(struct platform_device *pdev)
{
	struct udc *dev;

	dev = platform_get_drvdata(pdev);

	usb_del_gadget_udc(&dev->gadget);
	/* gadget driver must not be registered */
	if (WARN_ON(dev->driver))
		return 0;

	/* dma pool cleanup */
	free_dma_pools(dev);

	udc_remove(dev);

	platform_set_drvdata(pdev, NULL);

	phy_power_off(dev->udc_phy);
	phy_exit(dev->udc_phy);
	extcon_unregister_notifier(dev->edev, EXTCON_USB, &dev->nb);

	dev_info(&pdev->dev, "Synopsys UDC platform driver removed\n");

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int udc_plat_suspend(struct device *dev)
{
	struct udc *udc;

	udc = dev_get_drvdata(dev);
	stop_udc(udc);

	if (extcon_get_state(udc->edev, EXTCON_USB) > 0) {
		dev_dbg(udc->dev, "device -> idle\n");
		stop_udc(udc);
	}
	phy_power_off(udc->udc_phy);
	phy_exit(udc->udc_phy);

	return 0;
}

static int udc_plat_resume(struct device *dev)
{
	struct udc *udc;
	int ret;

	udc = dev_get_drvdata(dev);

	ret = phy_init(udc->udc_phy);
	if (ret) {
		dev_err(udc->dev, "UDC phy init failure");
		return ret;
	}

	ret = phy_power_on(udc->udc_phy);
	if (ret) {
		dev_err(udc->dev, "UDC phy power on failure");
		phy_exit(udc->udc_phy);
		return ret;
	}

	if (extcon_get_state(udc->edev, EXTCON_USB) > 0) {
		dev_dbg(udc->dev, "idle -> device\n");
		start_udc(udc);
	}

	return 0;
}
static const struct dev_pm_ops udc_plat_pm_ops = {
	.suspend	= udc_plat_suspend,
	.resume		= udc_plat_resume,
};
#endif

#if defined(CONFIG_OF)
static const struct of_device_id of_udc_match[] = {
	{ .compatible = "brcm,ns2-udc", },
	{ .compatible = "brcm,cygnus-udc", },
	{ .compatible = "brcm,iproc-udc", },
	{ }
};
MODULE_DEVICE_TABLE(of, of_udc_match);
#endif

static struct platform_driver udc_plat_driver = {
	.probe		= udc_plat_probe,
	.remove		= udc_plat_remove,
	.driver		= {
		.name	= "snps-udc-plat",
		.of_match_table = of_match_ptr(of_udc_match),
#ifdef CONFIG_PM_SLEEP
		.pm	= &udc_plat_pm_ops,
#endif
	},
};
module_platform_driver(udc_plat_driver);

MODULE_DESCRIPTION(UDC_MOD_DESCRIPTION);
MODULE_AUTHOR("Broadcom");
MODULE_LICENSE("GPL v2");
