// SPDX-License-Identifier: GPL-2.0+
/*
 * aspeed-vhub -- Driver for Aspeed SoC "vHub" USB gadget
 *
 * core.c - Top level support
 *
 * Copyright 2017 IBM Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
#include <linux/prefetch.h>
#include <linux/clk.h>
#include <linux/usb/gadget.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/regmap.h>
#include <linux/dma-mapping.h>

#include "vhub.h"

void ast_vhub_done(struct ast_vhub_ep *ep, struct ast_vhub_req *req,
		   int status)
{
	bool internal = req->internal;

	EPVDBG(ep, "completing request @%p, status %d\n", req, status);

	list_del_init(&req->queue);

	if (req->req.status == -EINPROGRESS)
		req->req.status = status;

	if (req->req.dma) {
		if (!WARN_ON(!ep->dev))
			usb_gadget_unmap_request(&ep->dev->gadget,
						 &req->req, ep->epn.is_in);
		req->req.dma = 0;
	}

	/*
	 * If this isn't an internal EP0 request, call the core
	 * to call the gadget completion.
	 */
	if (!internal) {
		spin_unlock(&ep->vhub->lock);
		usb_gadget_giveback_request(&ep->ep, &req->req);
		spin_lock(&ep->vhub->lock);
	}
}

void ast_vhub_nuke(struct ast_vhub_ep *ep, int status)
{
	struct ast_vhub_req *req;
	int count = 0;

	/* Beware, lock will be dropped & req-acquired by done() */
	while (!list_empty(&ep->queue)) {
		req = list_first_entry(&ep->queue, struct ast_vhub_req, queue);
		ast_vhub_done(ep, req, status);
		count++;
	}
	if (count)
		EPDBG(ep, "Nuked %d request(s)\n", count);
}

struct usb_request *ast_vhub_alloc_request(struct usb_ep *u_ep,
					   gfp_t gfp_flags)
{
	struct ast_vhub_req *req;

	req = kzalloc(sizeof(*req), gfp_flags);
	if (!req)
		return NULL;
	return &req->req;
}

void ast_vhub_free_request(struct usb_ep *u_ep, struct usb_request *u_req)
{
	struct ast_vhub_req *req = to_ast_req(u_req);

	kfree(req);
}

static irqreturn_t ast_vhub_irq(int irq, void *data)
{
	struct ast_vhub *vhub = data;
	irqreturn_t iret = IRQ_NONE;
	u32 istat;

	/* Stale interrupt while tearing down */
	if (!vhub->ep0_bufs)
		return IRQ_NONE;

	spin_lock(&vhub->lock);

	/* Read and ACK interrupts */
	istat = readl(vhub->regs + AST_VHUB_ISR);
	if (!istat)
		goto bail;
	writel(istat, vhub->regs + AST_VHUB_ISR);
	iret = IRQ_HANDLED;

	UDCVDBG(vhub, "irq status=%08x, ep_acks=%08x ep_nacks=%08x\n",
	       istat,
	       readl(vhub->regs + AST_VHUB_EP_ACK_ISR),
	       readl(vhub->regs + AST_VHUB_EP_NACK_ISR));

	/* Handle generic EPs first */
	if (istat & VHUB_IRQ_EP_POOL_ACK_STALL) {
		u32 i, ep_acks = readl(vhub->regs + AST_VHUB_EP_ACK_ISR);
		writel(ep_acks, vhub->regs + AST_VHUB_EP_ACK_ISR);

		for (i = 0; ep_acks && i < AST_VHUB_NUM_GEN_EPs; i++) {
			u32 mask = VHUB_EP_IRQ(i);
			if (ep_acks & mask) {
				ast_vhub_epn_ack_irq(&vhub->epns[i]);
				ep_acks &= ~mask;
			}
		}
	}

	/* Handle device interrupts */
	if (istat & (VHUB_IRQ_DEVICE1 |
		     VHUB_IRQ_DEVICE2 |
		     VHUB_IRQ_DEVICE3 |
		     VHUB_IRQ_DEVICE4 |
		     VHUB_IRQ_DEVICE5)) {
		if (istat & VHUB_IRQ_DEVICE1)
			ast_vhub_dev_irq(&vhub->ports[0].dev);
		if (istat & VHUB_IRQ_DEVICE2)
			ast_vhub_dev_irq(&vhub->ports[1].dev);
		if (istat & VHUB_IRQ_DEVICE3)
			ast_vhub_dev_irq(&vhub->ports[2].dev);
		if (istat & VHUB_IRQ_DEVICE4)
			ast_vhub_dev_irq(&vhub->ports[3].dev);
		if (istat & VHUB_IRQ_DEVICE5)
			ast_vhub_dev_irq(&vhub->ports[4].dev);
	}

	/* Handle top-level vHub EP0 interrupts */
	if (istat & (VHUB_IRQ_HUB_EP0_OUT_ACK_STALL |
		     VHUB_IRQ_HUB_EP0_IN_ACK_STALL |
		     VHUB_IRQ_HUB_EP0_SETUP)) {
		if (istat & VHUB_IRQ_HUB_EP0_IN_ACK_STALL)
			ast_vhub_ep0_handle_ack(&vhub->ep0, true);
		if (istat & VHUB_IRQ_HUB_EP0_OUT_ACK_STALL)
			ast_vhub_ep0_handle_ack(&vhub->ep0, false);
		if (istat & VHUB_IRQ_HUB_EP0_SETUP)
			ast_vhub_ep0_handle_setup(&vhub->ep0);
	}

	/* Various top level bus events */
	if (istat & (VHUB_IRQ_BUS_RESUME |
		     VHUB_IRQ_BUS_SUSPEND |
		     VHUB_IRQ_BUS_RESET)) {
		if (istat & VHUB_IRQ_BUS_RESUME)
			ast_vhub_hub_resume(vhub);
		if (istat & VHUB_IRQ_BUS_SUSPEND)
			ast_vhub_hub_suspend(vhub);
		if (istat & VHUB_IRQ_BUS_RESET)
			ast_vhub_hub_reset(vhub);
	}

 bail:
	spin_unlock(&vhub->lock);
	return iret;
}

void ast_vhub_init_hw(struct ast_vhub *vhub)
{
	u32 ctrl;

	UDCDBG(vhub,"(Re)Starting HW ...\n");

	/* Enable PHY */
	ctrl = VHUB_CTRL_PHY_CLK |
		VHUB_CTRL_PHY_RESET_DIS;

       /*
	* We do *NOT* set the VHUB_CTRL_CLK_STOP_SUSPEND bit
	* to stop the logic clock during suspend because
	* it causes the registers to become inaccessible and
	* we haven't yet figured out a good wayt to bring the
	* controller back into life to issue a wakeup.
	*/

	/*
	 * Set some ISO & split control bits according to Aspeed
	 * recommendation
	 *
	 * VHUB_CTRL_ISO_RSP_CTRL: When set tells the HW to respond
	 * with 0 bytes data packet to ISO IN endpoints when no data
	 * is available.
	 *
	 * VHUB_CTRL_SPLIT_IN: This makes a SOF complete a split IN
	 * transaction.
	 */
	ctrl |= VHUB_CTRL_ISO_RSP_CTRL | VHUB_CTRL_SPLIT_IN;
	writel(ctrl, vhub->regs + AST_VHUB_CTRL);
	udelay(1);

	/* Set descriptor ring size */
	if (AST_VHUB_DESCS_COUNT == 256) {
		ctrl |= VHUB_CTRL_LONG_DESC;
		writel(ctrl, vhub->regs + AST_VHUB_CTRL);
	} else {
		BUILD_BUG_ON(AST_VHUB_DESCS_COUNT != 32);
	}

	/* Reset all devices */
	writel(VHUB_SW_RESET_ALL, vhub->regs + AST_VHUB_SW_RESET);
	udelay(1);
	writel(0, vhub->regs + AST_VHUB_SW_RESET);

	/* Disable and cleanup EP ACK/NACK interrupts */
	writel(0, vhub->regs + AST_VHUB_EP_ACK_IER);
	writel(0, vhub->regs + AST_VHUB_EP_NACK_IER);
	writel(VHUB_EP_IRQ_ALL, vhub->regs + AST_VHUB_EP_ACK_ISR);
	writel(VHUB_EP_IRQ_ALL, vhub->regs + AST_VHUB_EP_NACK_ISR);

	/* Default settings for EP0, enable HW hub EP1 */
	writel(0, vhub->regs + AST_VHUB_EP0_CTRL);
	writel(VHUB_EP1_CTRL_RESET_TOGGLE |
	       VHUB_EP1_CTRL_ENABLE,
	       vhub->regs + AST_VHUB_EP1_CTRL);
	writel(0, vhub->regs + AST_VHUB_EP1_STS_CHG);

	/* Configure EP0 DMA buffer */
	writel(vhub->ep0.buf_dma, vhub->regs + AST_VHUB_EP0_DATA);

	/* Clear address */
	writel(0, vhub->regs + AST_VHUB_CONF);

	/* Pullup hub (activate on host) */
	if (vhub->force_usb1)
		ctrl |= VHUB_CTRL_FULL_SPEED_ONLY;

	ctrl |= VHUB_CTRL_UPSTREAM_CONNECT;
	writel(ctrl, vhub->regs + AST_VHUB_CTRL);

	/* Enable some interrupts */
	writel(VHUB_IRQ_HUB_EP0_IN_ACK_STALL |
	       VHUB_IRQ_HUB_EP0_OUT_ACK_STALL |
	       VHUB_IRQ_HUB_EP0_SETUP |
	       VHUB_IRQ_EP_POOL_ACK_STALL |
	       VHUB_IRQ_BUS_RESUME |
	       VHUB_IRQ_BUS_SUSPEND |
	       VHUB_IRQ_BUS_RESET,
	       vhub->regs + AST_VHUB_IER);
}

static int ast_vhub_remove(struct platform_device *pdev)
{
	struct ast_vhub *vhub = platform_get_drvdata(pdev);
	unsigned long flags;
	int i;

	if (!vhub || !vhub->regs)
		return 0;

	/* Remove devices */
	for (i = 0; i < AST_VHUB_NUM_PORTS; i++)
		ast_vhub_del_dev(&vhub->ports[i].dev);

	spin_lock_irqsave(&vhub->lock, flags);

	/* Mask & ack all interrupts  */
	writel(0, vhub->regs + AST_VHUB_IER);
	writel(VHUB_IRQ_ACK_ALL, vhub->regs + AST_VHUB_ISR);

	/* Pull device, leave PHY enabled */
	writel(VHUB_CTRL_PHY_CLK |
	       VHUB_CTRL_PHY_RESET_DIS,
	       vhub->regs + AST_VHUB_CTRL);

	if (vhub->clk)
		clk_disable_unprepare(vhub->clk);

	spin_unlock_irqrestore(&vhub->lock, flags);

	if (vhub->ep0_bufs)
		dma_free_coherent(&pdev->dev,
				  AST_VHUB_EP0_MAX_PACKET *
				  (AST_VHUB_NUM_PORTS + 1),
				  vhub->ep0_bufs,
				  vhub->ep0_bufs_dma);
	vhub->ep0_bufs = NULL;

	return 0;
}

static int ast_vhub_probe(struct platform_device *pdev)
{
	enum usb_device_speed max_speed;
	struct ast_vhub *vhub;
	struct resource *res;
	int i, rc = 0;

	vhub = devm_kzalloc(&pdev->dev, sizeof(*vhub), GFP_KERNEL);
	if (!vhub)
		return -ENOMEM;

	spin_lock_init(&vhub->lock);
	vhub->pdev = pdev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	vhub->regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(vhub->regs)) {
		dev_err(&pdev->dev, "Failed to map resources\n");
		return PTR_ERR(vhub->regs);
	}
	UDCDBG(vhub, "vHub@%pR mapped @%p\n", res, vhub->regs);

	platform_set_drvdata(pdev, vhub);

	vhub->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(vhub->clk)) {
		rc = PTR_ERR(vhub->clk);
		goto err;
	}
	rc = clk_prepare_enable(vhub->clk);
	if (rc) {
		dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n", rc);
		goto err;
	}

	/* Check if we need to limit the HW to USB1 */
	max_speed = usb_get_maximum_speed(&pdev->dev);
	if (max_speed != USB_SPEED_UNKNOWN && max_speed < USB_SPEED_HIGH)
		vhub->force_usb1 = true;

	/* Mask & ack all interrupts before installing the handler */
	writel(0, vhub->regs + AST_VHUB_IER);
	writel(VHUB_IRQ_ACK_ALL, vhub->regs + AST_VHUB_ISR);

	/* Find interrupt and install handler */
	vhub->irq = platform_get_irq(pdev, 0);
	if (vhub->irq < 0) {
		rc = vhub->irq;
		goto err;
	}
	rc = devm_request_irq(&pdev->dev, vhub->irq, ast_vhub_irq, 0,
			      KBUILD_MODNAME, vhub);
	if (rc) {
		dev_err(&pdev->dev, "Failed to request interrupt\n");
		goto err;
	}

	/*
	 * Allocate DMA buffers for all EP0s in one chunk,
	 * one per port and one for the vHub itself
	 */
	vhub->ep0_bufs = dma_alloc_coherent(&pdev->dev,
					    AST_VHUB_EP0_MAX_PACKET *
					    (AST_VHUB_NUM_PORTS + 1),
					    &vhub->ep0_bufs_dma, GFP_KERNEL);
	if (!vhub->ep0_bufs) {
		dev_err(&pdev->dev, "Failed to allocate EP0 DMA buffers\n");
		rc = -ENOMEM;
		goto err;
	}
	UDCVDBG(vhub, "EP0 DMA buffers @%p (DMA 0x%08x)\n",
		vhub->ep0_bufs, (u32)vhub->ep0_bufs_dma);

	/* Init vHub EP0 */
	ast_vhub_init_ep0(vhub, &vhub->ep0, NULL);

	/* Init devices */
	for (i = 0; i < AST_VHUB_NUM_PORTS && rc == 0; i++)
		rc = ast_vhub_init_dev(vhub, i);
	if (rc)
		goto err;

	/* Init hub emulation */
	ast_vhub_init_hub(vhub);

	/* Initialize HW */
	ast_vhub_init_hw(vhub);

	dev_info(&pdev->dev, "Initialized virtual hub in USB%d mode\n",
		 vhub->force_usb1 ? 1 : 2);

	return 0;
 err:
	ast_vhub_remove(pdev);
	return rc;
}

static const struct of_device_id ast_vhub_dt_ids[] = {
	{
		.compatible = "aspeed,ast2400-usb-vhub",
	},
	{
		.compatible = "aspeed,ast2500-usb-vhub",
	},
	{ }
};
MODULE_DEVICE_TABLE(of, ast_vhub_dt_ids);

static struct platform_driver ast_vhub_driver = {
	.probe		= ast_vhub_probe,
	.remove		= ast_vhub_remove,
	.driver		= {
		.name	= KBUILD_MODNAME,
		.of_match_table	= ast_vhub_dt_ids,
	},
};
module_platform_driver(ast_vhub_driver);

MODULE_DESCRIPTION("Aspeed vHub udc driver");
MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
MODULE_LICENSE("GPL");
