/*
 * Copyright 2012 Tilera Corporation. All Rights Reserved.
 *
 *   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, version 2.
 *
 *   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, GOOD TITLE or
 *   NON INFRINGEMENT.  See the GNU General Public License for
 *   more details.
 */

/*
 * Tilera TILE-Gx USB EHCI host controller driver.
 */

#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/usb/tilegx.h>
#include <linux/usb.h>

#include <asm/homecache.h>

#include <gxio/iorpc_usb_host.h>
#include <gxio/usb_host.h>

static void tilegx_start_ehc(void)
{
}

static void tilegx_stop_ehc(void)
{
}

static int tilegx_ehci_setup(struct usb_hcd *hcd)
{
	int ret = ehci_init(hcd);

	/*
	 * Some drivers do:
	 *
	 *   struct ehci_hcd *ehci = hcd_to_ehci(hcd);
	 *   ehci->need_io_watchdog = 0;
	 *
	 * here, but since this is a new driver we're going to leave the
	 * watchdog enabled.  Later we may try to turn it off and see
	 * whether we run into any problems.
	 */

	return ret;
}

static const struct hc_driver ehci_tilegx_hc_driver = {
	.description		= hcd_name,
	.product_desc		= "Tile-Gx EHCI",
	.hcd_priv_size		= sizeof(struct ehci_hcd),

	/*
	 * Generic hardware linkage.
	 */
	.irq			= ehci_irq,
	.flags			= HCD_MEMORY | HCD_USB2 | HCD_BH,

	/*
	 * Basic lifecycle operations.
	 */
	.reset			= tilegx_ehci_setup,
	.start			= ehci_run,
	.stop			= ehci_stop,
	.shutdown		= ehci_shutdown,

	/*
	 * Managing I/O requests and associated device resources.
	 */
	.urb_enqueue		= ehci_urb_enqueue,
	.urb_dequeue		= ehci_urb_dequeue,
	.endpoint_disable	= ehci_endpoint_disable,
	.endpoint_reset		= ehci_endpoint_reset,

	/*
	 * Scheduling support.
	 */
	.get_frame_number	= ehci_get_frame,

	/*
	 * Root hub support.
	 */
	.hub_status_data	= ehci_hub_status_data,
	.hub_control		= ehci_hub_control,
	.bus_suspend		= ehci_bus_suspend,
	.bus_resume		= ehci_bus_resume,
	.relinquish_port	= ehci_relinquish_port,
	.port_handed_over	= ehci_port_handed_over,

	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
};

static int ehci_hcd_tilegx_drv_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	struct ehci_hcd *ehci;
	struct tilegx_usb_platform_data *pdata = dev_get_platdata(&pdev->dev);
	pte_t pte = { 0 };
	int my_cpu = smp_processor_id();
	int ret;

	if (usb_disabled())
		return -ENODEV;

	/*
	 * Try to initialize our GXIO context; if we can't, the device
	 * doesn't exist.
	 */
	if (gxio_usb_host_init(&pdata->usb_ctx, pdata->dev_index, 1) != 0)
		return -ENXIO;

	hcd = usb_create_hcd(&ehci_tilegx_hc_driver, &pdev->dev,
			     dev_name(&pdev->dev));
	if (!hcd) {
          ret = -ENOMEM;
          goto err_hcd;
        }

	/*
	 * We don't use rsrc_start to map in our registers, but seems like
	 * we ought to set it to something, so we use the register VA.
	 */
	hcd->rsrc_start =
		(ulong) gxio_usb_host_get_reg_start(&pdata->usb_ctx);
	hcd->rsrc_len = gxio_usb_host_get_reg_len(&pdata->usb_ctx);
	hcd->regs = gxio_usb_host_get_reg_start(&pdata->usb_ctx);

	tilegx_start_ehc();

	ehci = hcd_to_ehci(hcd);
	ehci->caps = hcd->regs;
	ehci->regs =
		hcd->regs + HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase));
	/* cache this readonly data; minimize chip reads */
	ehci->hcs_params = readl(&ehci->caps->hcs_params);

	/* Create our IRQs and register them. */
	pdata->irq = create_irq();
	if (pdata->irq < 0) {
		ret = -ENXIO;
		goto err_no_irq;
	}

	tile_irq_activate(pdata->irq, TILE_IRQ_PERCPU);

	/* Configure interrupts. */
	ret = gxio_usb_host_cfg_interrupt(&pdata->usb_ctx,
					  cpu_x(my_cpu), cpu_y(my_cpu),
					  KERNEL_PL, pdata->irq);
	if (ret) {
		ret = -ENXIO;
		goto err_have_irq;
	}

	/* Register all of our memory. */
	pte = pte_set_home(pte, PAGE_HOME_HASH);
	ret = gxio_usb_host_register_client_memory(&pdata->usb_ctx, pte, 0);
	if (ret) {
		ret = -ENXIO;
		goto err_have_irq;
	}

	ret = usb_add_hcd(hcd, pdata->irq, IRQF_SHARED);
	if (ret == 0) {
		platform_set_drvdata(pdev, hcd);
		device_wakeup_enable(hcd->self.controller);
		return ret;
	}

err_have_irq:
	destroy_irq(pdata->irq);
err_no_irq:
	tilegx_stop_ehc();
	usb_put_hcd(hcd);
err_hcd:
	gxio_usb_host_destroy(&pdata->usb_ctx);
	return ret;
}

static int ehci_hcd_tilegx_drv_remove(struct platform_device *pdev)
{
	struct usb_hcd *hcd = platform_get_drvdata(pdev);
	struct tilegx_usb_platform_data *pdata = dev_get_platdata(&pdev->dev);

	usb_remove_hcd(hcd);
	usb_put_hcd(hcd);
	tilegx_stop_ehc();
	gxio_usb_host_destroy(&pdata->usb_ctx);
	destroy_irq(pdata->irq);

	return 0;
}

static void ehci_hcd_tilegx_drv_shutdown(struct platform_device *pdev)
{
	usb_hcd_platform_shutdown(pdev);
	ehci_hcd_tilegx_drv_remove(pdev);
}

static struct platform_driver ehci_hcd_tilegx_driver = {
	.probe		= ehci_hcd_tilegx_drv_probe,
	.remove		= ehci_hcd_tilegx_drv_remove,
	.shutdown	= ehci_hcd_tilegx_drv_shutdown,
	.driver = {
		.name	= "tilegx-ehci",
		.owner	= THIS_MODULE,
	}
};

MODULE_ALIAS("platform:tilegx-ehci");
