/*
 * OHCI HCD for Netlogic XLS processors.
 *
 * (C) Copyright 2011 Netlogic Microsystems Inc.
 *
 *  Based on ohci-au1xxx.c, and other Linux OHCI drivers.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive for
 * more details.
 */

#include <linux/platform_device.h>
#include <linux/signal.h>

static int ohci_xls_probe_internal(const struct hc_driver *driver,
			struct platform_device *dev)
{
	struct resource *res;
	struct usb_hcd *hcd;
	int retval, irq;

	/* Get our IRQ from an earlier registered Platform Resource */
	irq = platform_get_irq(dev, 0);
	if (irq < 0) {
		dev_err(&dev->dev, "Found HC with no IRQ\n");
		return -ENODEV;
	}

	/* Get our Memory Handle */
	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&dev->dev, "MMIO Handle incorrect!\n");
		return -ENODEV;
	}

	hcd = usb_create_hcd(driver, &dev->dev, "XLS");
	if (!hcd) {
		retval = -ENOMEM;
		goto err1;
	}
	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
			driver->description)) {
		dev_dbg(&dev->dev, "Controller already in use\n");
		retval = -EBUSY;
		goto err2;
	}

	hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
	if (hcd->regs == NULL) {
		dev_dbg(&dev->dev, "error mapping memory\n");
		retval = -EFAULT;
		goto err3;
	}

	retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (retval != 0)
		goto err4;
	return retval;

err4:
	iounmap(hcd->regs);
err3:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err2:
	usb_put_hcd(hcd);
err1:
	dev_err(&dev->dev, "init fail, %d\n", retval);
	return retval;
}

static int ohci_xls_reset(struct usb_hcd *hcd)
{
	struct ohci_hcd *ohci = hcd_to_ohci(hcd);

	ohci_hcd_init(ohci);
	return ohci_init(ohci);
}

static int __devinit ohci_xls_start(struct usb_hcd *hcd)
{
	struct ohci_hcd *ohci;
	int ret;

	ohci = hcd_to_ohci(hcd);
	ret = ohci_run(ohci);
	if (ret < 0) {
		err("can't start %s", hcd->self.bus_name);
		ohci_stop(hcd);
		return ret;
	}
	return 0;
}

static struct hc_driver ohci_xls_hc_driver = {
	.description	= hcd_name,
	.product_desc	= "XLS OHCI Host Controller",
	.hcd_priv_size	= sizeof(struct ohci_hcd),
	.irq		= ohci_irq,
	.flags		= HCD_MEMORY | HCD_USB11,
	.reset		= ohci_xls_reset,
	.start		= ohci_xls_start,
	.stop		= ohci_stop,
	.shutdown	= ohci_shutdown,
	.urb_enqueue	= ohci_urb_enqueue,
	.urb_dequeue	= ohci_urb_dequeue,
	.endpoint_disable = ohci_endpoint_disable,
	.get_frame_number = ohci_get_frame,
	.hub_status_data = ohci_hub_status_data,
	.hub_control	= ohci_hub_control,
#ifdef CONFIG_PM
	.bus_suspend	= ohci_bus_suspend,
	.bus_resume	= ohci_bus_resume,
#endif
	.start_port_reset = ohci_start_port_reset,
};

static int ohci_xls_probe(struct platform_device *dev)
{
	int ret;

	pr_debug("In ohci_xls_probe");
	if (usb_disabled())
		return -ENODEV;
	ret = ohci_xls_probe_internal(&ohci_xls_hc_driver, dev);
	return ret;
}

static int ohci_xls_remove(struct platform_device *dev)
{
	struct usb_hcd *hcd = platform_get_drvdata(dev);

	usb_remove_hcd(hcd);
	iounmap(hcd->regs);
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
	usb_put_hcd(hcd);
	return 0;
}

static struct platform_driver ohci_xls_driver = {
	.probe		= ohci_xls_probe,
	.remove		= ohci_xls_remove,
	.shutdown	= usb_hcd_platform_shutdown,
	.driver		= {
		.name	= "ohci-xls-0",
		.owner	= THIS_MODULE,
	},
};
