// SPDX-License-Identifier: GPL-2.0+
/*
 * c67x00-drv.c: Cypress C67X00 USB Common infrastructure
 *
 * Copyright (C) 2006-2008 Barco N.V.
 *    Derived from the Cypress cy7c67200/300 ezusb linux driver and
 *    based on multiple host controller drivers inside the linux kernel.
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301  USA.
 */

/*
 * This file implements the common infrastructure for using the c67x00.
 * It is both the link between the platform configuration and subdrivers and
 * the link between the common hardware parts and the subdrivers (e.g.
 * interrupt handling).
 *
 * The c67x00 has 2 SIE's (serial interface engine) which can be configured
 * to be host, device or OTG (with some limitations, E.G. only SIE1 can be OTG).
 *
 * Depending on the platform configuration, the SIE's are created and
 * the corresponding subdriver is initialized (c67x00_probe_sie).
 */

#include <linux/device.h>
#include <linux/io.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/c67x00.h>

#include "c67x00.h"
#include "c67x00-hcd.h"

static void c67x00_probe_sie(struct c67x00_sie *sie,
			     struct c67x00_device *dev, int sie_num)
{
	spin_lock_init(&sie->lock);
	sie->dev = dev;
	sie->sie_num = sie_num;
	sie->mode = c67x00_sie_config(dev->pdata->sie_config, sie_num);

	switch (sie->mode) {
	case C67X00_SIE_HOST:
		c67x00_hcd_probe(sie);
		break;

	case C67X00_SIE_UNUSED:
		dev_info(sie_dev(sie),
			 "Not using SIE %d as requested\n", sie->sie_num);
		break;

	default:
		dev_err(sie_dev(sie),
			"Unsupported configuration: 0x%x for SIE %d\n",
			sie->mode, sie->sie_num);
		break;
	}
}

static void c67x00_remove_sie(struct c67x00_sie *sie)
{
	switch (sie->mode) {
	case C67X00_SIE_HOST:
		c67x00_hcd_remove(sie);
		break;

	default:
		break;
	}
}

static irqreturn_t c67x00_irq(int irq, void *__dev)
{
	struct c67x00_device *c67x00 = __dev;
	struct c67x00_sie *sie;
	u16 msg, int_status;
	int i, count = 8;

	int_status = c67x00_ll_hpi_status(c67x00);
	if (!int_status)
		return IRQ_NONE;

	while (int_status != 0 && (count-- >= 0)) {
		c67x00_ll_irq(c67x00, int_status);
		for (i = 0; i < C67X00_SIES; i++) {
			sie = &c67x00->sie[i];
			msg = 0;
			if (int_status & SIEMSG_FLG(i))
				msg = c67x00_ll_fetch_siemsg(c67x00, i);
			if (sie->irq)
				sie->irq(sie, int_status, msg);
		}
		int_status = c67x00_ll_hpi_status(c67x00);
	}

	if (int_status)
		dev_warn(&c67x00->pdev->dev, "Not all interrupts handled! "
			 "status = 0x%04x\n", int_status);

	return IRQ_HANDLED;
}

/* ------------------------------------------------------------------------- */

static int c67x00_drv_probe(struct platform_device *pdev)
{
	struct c67x00_device *c67x00;
	struct c67x00_platform_data *pdata;
	struct resource *res, *res2;
	int ret, i;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;

	res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res2)
		return -ENODEV;

	pdata = dev_get_platdata(&pdev->dev);
	if (!pdata)
		return -ENODEV;

	c67x00 = kzalloc(sizeof(*c67x00), GFP_KERNEL);
	if (!c67x00)
		return -ENOMEM;

	if (!request_mem_region(res->start, resource_size(res),
				pdev->name)) {
		dev_err(&pdev->dev, "Memory region busy\n");
		ret = -EBUSY;
		goto request_mem_failed;
	}
	c67x00->hpi.base = ioremap(res->start, resource_size(res));
	if (!c67x00->hpi.base) {
		dev_err(&pdev->dev, "Unable to map HPI registers\n");
		ret = -EIO;
		goto map_failed;
	}

	spin_lock_init(&c67x00->hpi.lock);
	c67x00->hpi.regstep = pdata->hpi_regstep;
	c67x00->pdata = dev_get_platdata(&pdev->dev);
	c67x00->pdev = pdev;

	c67x00_ll_init(c67x00);
	c67x00_ll_hpi_reg_init(c67x00);

	ret = request_irq(res2->start, c67x00_irq, 0, pdev->name, c67x00);
	if (ret) {
		dev_err(&pdev->dev, "Cannot claim IRQ\n");
		goto request_irq_failed;
	}

	ret = c67x00_ll_reset(c67x00);
	if (ret) {
		dev_err(&pdev->dev, "Device reset failed\n");
		goto reset_failed;
	}

	for (i = 0; i < C67X00_SIES; i++)
		c67x00_probe_sie(&c67x00->sie[i], c67x00, i);

	platform_set_drvdata(pdev, c67x00);

	return 0;

 reset_failed:
	free_irq(res2->start, c67x00);
 request_irq_failed:
	iounmap(c67x00->hpi.base);
 map_failed:
	release_mem_region(res->start, resource_size(res));
 request_mem_failed:
	kfree(c67x00);

	return ret;
}

static int c67x00_drv_remove(struct platform_device *pdev)
{
	struct c67x00_device *c67x00 = platform_get_drvdata(pdev);
	struct resource *res;
	int i;

	for (i = 0; i < C67X00_SIES; i++)
		c67x00_remove_sie(&c67x00->sie[i]);

	c67x00_ll_release(c67x00);

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (res)
		free_irq(res->start, c67x00);

	iounmap(c67x00->hpi.base);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res)
		release_mem_region(res->start, resource_size(res));

	kfree(c67x00);

	return 0;
}

static struct platform_driver c67x00_driver = {
	.probe	= c67x00_drv_probe,
	.remove	= c67x00_drv_remove,
	.driver	= {
		.name = "c67x00",
	},
};

module_platform_driver(c67x00_driver);

MODULE_AUTHOR("Peter Korsgaard, Jan Veldeman, Grant Likely");
MODULE_DESCRIPTION("Cypress C67X00 USB Controller Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:c67x00");
