diff options
Diffstat (limited to 'target/linux/mcs814x/files-3.3/drivers/usb')
| -rw-r--r-- | target/linux/mcs814x/files-3.3/drivers/usb/host/ehci-mcs814x.c | 165 | ||||
| -rw-r--r-- | target/linux/mcs814x/files-3.3/drivers/usb/host/ohci-mcs814x.c | 202 | 
2 files changed, 367 insertions, 0 deletions
| diff --git a/target/linux/mcs814x/files-3.3/drivers/usb/host/ehci-mcs814x.c b/target/linux/mcs814x/files-3.3/drivers/usb/host/ehci-mcs814x.c new file mode 100644 index 000000000..183155e37 --- /dev/null +++ b/target/linux/mcs814x/files-3.3/drivers/usb/host/ehci-mcs814x.c @@ -0,0 +1,165 @@ +/* + * MCS814X EHCI Host Controller Driver + * + * Based on "ehci-fsl.c" by Randy Vinson <rvinson@mvista.com> + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include <linux/platform_device.h> +#include <linux/of.h> + +#define MCS814X_EHCI_CAPS_OFFSET	0x68 + +static int mcs814x_ehci_init(struct usb_hcd *hcd) +{ +	struct ehci_hcd *ehci = hcd_to_ehci(hcd); +	int retval = 0; + +	ehci->caps = hcd->regs + MCS814X_EHCI_CAPS_OFFSET; +	ehci->regs = hcd->regs +		+ HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); +	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); +	ehci_reset(ehci); + +	retval = ehci_init(hcd); +	if (retval) { +		pr_err("ehci_init failed\n"); +		return retval; +	} + +	ehci_port_power(ehci, 0); + +	return retval; +} + +static const struct hc_driver mcs814x_ehci_hc_driver = { +	.description		= hcd_name, +	.product_desc		= "MCS814X EHCI Host Controller", +	.hcd_priv_size		= sizeof(struct ehci_hcd), +	.irq			= ehci_irq, +	.flags			= HCD_MEMORY | HCD_USB2, +	.reset			= mcs814x_ehci_init, +	.start			= ehci_run, +	.stop			= ehci_stop, +	.shutdown		= ehci_shutdown, +	.urb_enqueue		= ehci_urb_enqueue, +	.urb_dequeue		= ehci_urb_dequeue, +	.endpoint_disable	= ehci_endpoint_disable, +	.get_frame_number	= ehci_get_frame, +	.hub_status_data	= ehci_hub_status_data, +	.hub_control		= ehci_hub_control, +#if defined(CONFIG_PM) +	.bus_suspend		= ehci_bus_suspend, +	.bus_resume		= ehci_bus_resume, +#endif +	.relinquish_port	= ehci_relinquish_port, +	.port_handed_over	= ehci_port_handed_over, + +	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete, +}; + +static int mcs814x_ehci_probe(struct platform_device *pdev) +{ +	struct usb_hcd *hcd; +	const struct hc_driver *driver = &mcs814x_ehci_hc_driver; +	struct resource *res; +	int irq; +	int retval; + +	if (usb_disabled()) +		return -ENODEV; + +	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); +	if (!res) { +		dev_err(&pdev->dev, +			"Found HC with no IRQ. Check %s setup!\n", +			dev_name(&pdev->dev)); +		return -ENODEV; +	} +	irq = res->start; + +	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); +	pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; + +	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); +	if (!hcd) { +		retval = -ENOMEM; +		goto fail_create_hcd; +	} + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	if (!res) { +		dev_err(&pdev->dev, +			"Found HC with no register addr. Check %s setup!\n", +			dev_name(&pdev->dev)); +		retval = -ENODEV; +		goto fail_request_resource; +	} +	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(&pdev->dev, "controller already in use\n"); +		retval = -EBUSY; +		goto fail_request_resource; +	} + +	hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); +	if (hcd->regs == NULL) { +		dev_dbg(&pdev->dev, "error mapping memory\n"); +		retval = -EFAULT; +		goto fail_ioremap; +	} + +	retval = usb_add_hcd(hcd, irq, IRQF_SHARED); +	if (retval) +		goto fail_add_hcd; + +	dev_info(&pdev->dev, "added MCS814X EHCI driver\n"); + +	return retval; + +fail_add_hcd: +	iounmap(hcd->regs); +fail_ioremap: +	release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +fail_request_resource: +	usb_put_hcd(hcd); +fail_create_hcd: +	dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval); +	return retval; +} + +static int mcs814x_ehci_remove(struct platform_device *pdev) +{ +	struct usb_hcd *hcd = platform_get_drvdata(pdev); + +	usb_remove_hcd(hcd); +	iounmap(hcd->regs); +	release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +	usb_put_hcd(hcd); + +	return 0; +} + +MODULE_ALIAS("platform:mcs814x-ehci"); + +static const struct of_device_id mcs814x_ehci_id[] = { +	{ .compatible = "moschip,mcs814x-ehci" }, +	{ .compatible = "usb-ehci" }, +	{ /* sentinel */ }, +}; + +static struct platform_driver mcs814x_ehci_driver = { +	.probe = mcs814x_ehci_probe, +	.remove = mcs814x_ehci_remove, +	.driver = { +		.name = "mcs814x-ehci", +		.of_match_table = mcs814x_ehci_id, +	}, +}; diff --git a/target/linux/mcs814x/files-3.3/drivers/usb/host/ohci-mcs814x.c b/target/linux/mcs814x/files-3.3/drivers/usb/host/ohci-mcs814x.c new file mode 100644 index 000000000..59ec7740d --- /dev/null +++ b/target/linux/mcs814x/files-3.3/drivers/usb/host/ohci-mcs814x.c @@ -0,0 +1,202 @@ +/* + * OHCI HCD (Host Controller Driver) for USB. + * + * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> + * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> + * (C) Copyright 2002 Hewlett-Packard Company + * + * Bus Glue for Moschip MCS814x. + * + * Written by Christopher Hoover <ch@hpl.hp.com> + * Based on fragments of previous driver by Russell King et al. + * + * Modified for LH7A404 from ohci-sa1111.c + *  by Durgesh Pattamatta <pattamattad@sharpsec.com> + * + * Modified for pxa27x from ohci-lh7a404.c + *  by Nick Bane <nick@cecomputing.co.uk> 26-8-2004 + * + * Modified for mcs814x from ohci-mcs814x.c + *  by Lennert Buytenhek <buytenh@wantstofly.org> 28-2-2006 + *  Based on an earlier driver by Ray Lehtiniemi + * + * This file is licenced under the GPL. + */ + +#include <linux/device.h> +#include <linux/signal.h> +#include <linux/platform_device.h> +#include <linux/of.h> + +static int usb_hcd_mcs814x_probe(const struct hc_driver *driver, +			 struct platform_device *pdev) +{ +	int retval; +	struct usb_hcd *hcd; + +	if (pdev->resource[1].flags != IORESOURCE_IRQ) { +		pr_debug("resource[1] is not IORESOURCE_IRQ"); +		return -ENOMEM; +	} + +	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); +	pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; + +	hcd = usb_create_hcd(driver, &pdev->dev, "mcs814x"); +	if (hcd == NULL) +		return -ENOMEM; + +	hcd->rsrc_start = pdev->resource[0].start; +	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; +	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { +		usb_put_hcd(hcd); +		retval = -EBUSY; +		goto err1; +	} + +	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); +	if (hcd->regs == NULL) { +		pr_debug("ioremap failed"); +		retval = -ENOMEM; +		goto err2; +	} + +	ohci_hcd_init(hcd_to_ohci(hcd)); + +	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED); +	if (retval == 0) +		return retval; + +	iounmap(hcd->regs); +err2: +	release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +err1: +	usb_put_hcd(hcd); + +	return retval; +} + +static void usb_hcd_mcs814x_remove(struct usb_hcd *hcd, +			struct platform_device *pdev) +{ +	usb_remove_hcd(hcd); +	iounmap(hcd->regs); +	release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +	usb_put_hcd(hcd); +} + +static int __devinit ohci_mcs814x_start(struct usb_hcd *hcd) +{ +	struct ohci_hcd *ohci = hcd_to_ohci(hcd); +	int ret; + +	ret = ohci_init(ohci); +	if (ret < 0) +		return ret; + +	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_mcs814x_hc_driver = { +	.description		= hcd_name, +	.product_desc		= "MCS814X OHCI", +	.hcd_priv_size		= sizeof(struct ohci_hcd), +	.irq			= ohci_irq, +	.flags			= HCD_USB11 | HCD_MEMORY, +	.start			= ohci_mcs814x_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, +}; + +extern int usb_disabled(void); + +static int ohci_hcd_mcs814x_drv_probe(struct platform_device *pdev) +{ +	int ret; + +	ret = -ENODEV; +	if (!usb_disabled()) +		ret = usb_hcd_mcs814x_probe(&ohci_mcs814x_hc_driver, pdev); + +	return ret; +} + +static int ohci_hcd_mcs814x_drv_remove(struct platform_device *pdev) +{ +	struct usb_hcd *hcd = platform_get_drvdata(pdev); + +	usb_hcd_mcs814x_remove(hcd, pdev); + +	return 0; +} + +#ifdef CONFIG_PM +static int ohci_hcd_mcs814x_drv_suspend(struct platform_device *pdev, pm_message_t state) +{ +	struct usb_hcd *hcd = platform_get_drvdata(pdev); +	struct ohci_hcd *ohci = hcd_to_ohci(hcd); + +	if (time_before(jiffies, ohci->next_statechange)) +		msleep(5); +	ohci->next_statechange = jiffies; + +	hcd->state = HC_STATE_SUSPENDED; + +	return 0; +} + +static int ohci_hcd_mcs814x_drv_resume(struct platform_device *pdev) +{ +	struct usb_hcd *hcd = platform_get_drvdata(pdev); +	struct ohci_hcd *ohci = hcd_to_ohci(hcd); +	int status; + +	if (time_before(jiffies, ohci->next_statechange)) +		msleep(5); +	ohci->next_statechange = jiffies; + +	ohci_finish_controller_resume(hcd); +	return 0; +} +#endif + +static const struct of_device_id mcs814x_ohci_id[] = { +	{ .compatible = "moschip,mcs814x-ohci" }, +	{ .compatible = "ohci-le" }, +	{ /* sentinel */ }, +}; + +static struct platform_driver ohci_hcd_mcs814x_driver = { +	.probe		= ohci_hcd_mcs814x_drv_probe, +	.remove		= ohci_hcd_mcs814x_drv_remove, +	.shutdown	= usb_hcd_platform_shutdown, +#ifdef CONFIG_PM +	.suspend	= ohci_hcd_mcs814x_drv_suspend, +	.resume		= ohci_hcd_mcs814x_drv_resume, +#endif +	.driver		= { +		.name	= "mcs814x-ohci", +		.owner	= THIS_MODULE, +		.of_match_table = mcs814x_ohci_id, +	}, +}; + +MODULE_ALIAS("platform:mcs814x-ohci"); | 
