// SPDX-License-Identifier: GPL-2.0
/*
 * Glue code for the ISP1760 driver and bus
 * Currently there is support for
 * - OpenFirmware
 * - PCI
 * - PDEV (generic platform device centralized driver model)
 *
 * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de>
 * Copyright 2021 Linaro, Rui Miguel Silva <rui.silva@linaro.org>
 *
 */

#include <linux/usb.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/usb/hcd.h>
#include <linux/usb/otg.h>

#include "isp1760-core.h"
#include "isp1760-regs.h"

#ifdef CONFIG_USB_PCI
#include <linux/pci.h>
#endif

#ifdef CONFIG_USB_PCI
static int isp1761_pci_init(struct pci_dev *dev)
{
	resource_size_t mem_start;
	resource_size_t mem_length;
	u8 __iomem *iobase;
	u8 latency, limit;
	int retry_count;
	u32 reg_data;

	/* Grab the PLX PCI shared memory of the ISP 1761 we need  */
	mem_start = pci_resource_start(dev, 3);
	mem_length = pci_resource_len(dev, 3);
	if (mem_length < 0xffff) {
		printk(KERN_ERR "memory length for this resource is wrong\n");
		return -ENOMEM;
	}

	if (!request_mem_region(mem_start, mem_length, "ISP-PCI")) {
		printk(KERN_ERR "host controller already in use\n");
		return -EBUSY;
	}

	/* map available memory */
	iobase = ioremap(mem_start, mem_length);
	if (!iobase) {
		printk(KERN_ERR "Error ioremap failed\n");
		release_mem_region(mem_start, mem_length);
		return -ENOMEM;
	}

	/* bad pci latencies can contribute to overruns */
	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency);
	if (latency) {
		pci_read_config_byte(dev, PCI_MAX_LAT, &limit);
		if (limit && limit < latency)
			pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit);
	}

	/* Try to check whether we can access Scratch Register of
	 * Host Controller or not. The initial PCI access is retried until
	 * local init for the PCI bridge is completed
	 */
	retry_count = 20;
	reg_data = 0;
	while ((reg_data != 0xFACE) && retry_count) {
		/*by default host is in 16bit mode, so
		 * io operations at this stage must be 16 bit
		 * */
		writel(0xface, iobase + ISP176x_HC_SCRATCH);
		udelay(100);
		reg_data = readl(iobase + ISP176x_HC_SCRATCH) & 0x0000ffff;
		retry_count--;
	}

	iounmap(iobase);
	release_mem_region(mem_start, mem_length);

	/* Host Controller presence is detected by writing to scratch register
	 * and reading back and checking the contents are same or not
	 */
	if (reg_data != 0xFACE) {
		dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data);
		return -ENOMEM;
	}

	/* Grab the PLX PCI mem maped port start address we need  */
	mem_start = pci_resource_start(dev, 0);
	mem_length = pci_resource_len(dev, 0);

	if (!request_mem_region(mem_start, mem_length, "ISP1761 IO MEM")) {
		printk(KERN_ERR "request region #1\n");
		return -EBUSY;
	}

	iobase = ioremap(mem_start, mem_length);
	if (!iobase) {
		printk(KERN_ERR "ioremap #1\n");
		release_mem_region(mem_start, mem_length);
		return -ENOMEM;
	}

	/* configure PLX PCI chip to pass interrupts */
#define PLX_INT_CSR_REG 0x68
	reg_data = readl(iobase + PLX_INT_CSR_REG);
	reg_data |= 0x900;
	writel(reg_data, iobase + PLX_INT_CSR_REG);

	/* done with PLX IO access */
	iounmap(iobase);
	release_mem_region(mem_start, mem_length);

	return 0;
}

static int isp1761_pci_probe(struct pci_dev *dev,
		const struct pci_device_id *id)
{
	unsigned int devflags = 0;
	int ret;

	if (!dev->irq)
		return -ENODEV;

	if (pci_enable_device(dev) < 0)
		return -ENODEV;

	ret = isp1761_pci_init(dev);
	if (ret < 0)
		goto error;

	pci_set_master(dev);

	ret = isp1760_register(&dev->resource[3], dev->irq, 0, &dev->dev,
			       devflags);
	if (ret < 0)
		goto error;

	return 0;

error:
	pci_disable_device(dev);
	return ret;
}

static void isp1761_pci_remove(struct pci_dev *dev)
{
	isp1760_unregister(&dev->dev);

	pci_disable_device(dev);
}

static void isp1761_pci_shutdown(struct pci_dev *dev)
{
	printk(KERN_ERR "ips1761_pci_shutdown\n");
}

static const struct pci_device_id isp1760_plx[] = {
	{
		.class          = PCI_CLASS_BRIDGE_OTHER << 8,
		.class_mask     = ~0,
		.vendor		= PCI_VENDOR_ID_PLX,
		.device		= 0x5406,
		.subvendor	= PCI_VENDOR_ID_PLX,
		.subdevice	= 0x9054,
	},
	{ }
};
MODULE_DEVICE_TABLE(pci, isp1760_plx);

static struct pci_driver isp1761_pci_driver = {
	.name =         "isp1760",
	.id_table =     isp1760_plx,
	.probe =        isp1761_pci_probe,
	.remove =       isp1761_pci_remove,
	.shutdown =     isp1761_pci_shutdown,
};
#endif

static int isp1760_plat_probe(struct platform_device *pdev)
{
	unsigned long irqflags;
	unsigned int devflags = 0;
	struct resource *mem_res;
	struct resource *irq_res;
	int ret;

	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!irq_res) {
		pr_warn("isp1760: IRQ resource not available\n");
		return -ENODEV;
	}
	irqflags = irq_res->flags & IRQF_TRIGGER_MASK;

	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
		struct device_node *dp = pdev->dev.of_node;
		u32 bus_width = 0;

		if (of_device_is_compatible(dp, "nxp,usb-isp1761"))
			devflags |= ISP1760_FLAG_ISP1761;

		if (of_device_is_compatible(dp, "nxp,usb-isp1763"))
			devflags |= ISP1760_FLAG_ISP1763;

		/*
		 * Some systems wire up only 8 of 16 data lines or
		 * 16 of the 32 data lines
		 */
		of_property_read_u32(dp, "bus-width", &bus_width);
		if (bus_width == 16)
			devflags |= ISP1760_FLAG_BUS_WIDTH_16;
		else if (bus_width == 8)
			devflags |= ISP1760_FLAG_BUS_WIDTH_8;

		if (usb_get_dr_mode(&pdev->dev) == USB_DR_MODE_PERIPHERAL)
			devflags |= ISP1760_FLAG_PERIPHERAL_EN;

		if (of_property_read_bool(dp, "analog-oc"))
			devflags |= ISP1760_FLAG_ANALOG_OC;

		if (of_property_read_bool(dp, "dack-polarity"))
			devflags |= ISP1760_FLAG_DACK_POL_HIGH;

		if (of_property_read_bool(dp, "dreq-polarity"))
			devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
	} else {
		pr_err("isp1760: no platform data\n");
		return -ENXIO;
	}

	ret = isp1760_register(mem_res, irq_res->start, irqflags, &pdev->dev,
			       devflags);
	if (ret < 0)
		return ret;

	pr_info("ISP1760 USB device initialised\n");
	return 0;
}

static int isp1760_plat_remove(struct platform_device *pdev)
{
	isp1760_unregister(&pdev->dev);

	return 0;
}

#ifdef CONFIG_OF
static const struct of_device_id isp1760_of_match[] = {
	{ .compatible = "nxp,usb-isp1760", },
	{ .compatible = "nxp,usb-isp1761", },
	{ .compatible = "nxp,usb-isp1763", },
	{ },
};
MODULE_DEVICE_TABLE(of, isp1760_of_match);
#endif

static struct platform_driver isp1760_plat_driver = {
	.probe	= isp1760_plat_probe,
	.remove	= isp1760_plat_remove,
	.driver	= {
		.name	= "isp1760",
		.of_match_table = of_match_ptr(isp1760_of_match),
	},
};

static int __init isp1760_init(void)
{
	int ret, any_ret = -ENODEV;

	isp1760_init_kmem_once();

	ret = platform_driver_register(&isp1760_plat_driver);
	if (!ret)
		any_ret = 0;
#ifdef CONFIG_USB_PCI
	ret = pci_register_driver(&isp1761_pci_driver);
	if (!ret)
		any_ret = 0;
#endif

	if (any_ret)
		isp1760_deinit_kmem_cache();
	return any_ret;
}
module_init(isp1760_init);

static void __exit isp1760_exit(void)
{
	platform_driver_unregister(&isp1760_plat_driver);
#ifdef CONFIG_USB_PCI
	pci_unregister_driver(&isp1761_pci_driver);
#endif
	isp1760_deinit_kmem_cache();
}
module_exit(isp1760_exit);
