-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
USB: Add nuvoton Ehci driver for w90p910 platform
Add ehci support for w90p910 platform. Signed-off-by: Wan ZongShun <mcuos.com@gmail.com> Cc: David Brownell <david-b@pacbell.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
- Loading branch information
Wan ZongShun
authored and
Greg Kroah-Hartman
committed
Sep 23, 2009
1 parent
b95cd7e
commit 586dfc8
Showing
4 changed files
with
194 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/* | ||
* linux/driver/usb/host/ehci-w90x900.c | ||
* | ||
* Copyright (c) 2008 Nuvoton technology corporation. | ||
* | ||
* Wan ZongShun <mcuos.com@gmail.com> | ||
* | ||
* 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 of the License. | ||
* | ||
*/ | ||
|
||
#include <linux/platform_device.h> | ||
|
||
/*ebable phy0 and phy1 for w90p910*/ | ||
#define ENPHY (0x01<<8) | ||
#define PHY0_CTR (0xA4) | ||
#define PHY1_CTR (0xA8) | ||
|
||
static int __devinit usb_w90x900_probe(const struct hc_driver *driver, | ||
struct platform_device *pdev) | ||
{ | ||
struct usb_hcd *hcd; | ||
struct ehci_hcd *ehci; | ||
struct resource *res; | ||
int retval = 0, irq; | ||
unsigned long val; | ||
|
||
|
||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
if (!res) { | ||
retval = -ENXIO; | ||
goto err1; | ||
} | ||
|
||
hcd = usb_create_hcd(driver, &pdev->dev, "w90x900 EHCI"); | ||
if (!hcd) { | ||
retval = -ENOMEM; | ||
goto err1; | ||
} | ||
|
||
hcd->rsrc_start = res->start; | ||
hcd->rsrc_len = res->end - res->start + 1; | ||
|
||
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
retval = -EBUSY; | ||
goto err2; | ||
} | ||
|
||
hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
if (hcd->regs == NULL) { | ||
retval = -EFAULT; | ||
goto err3; | ||
} | ||
|
||
ehci = hcd_to_ehci(hcd); | ||
ehci->caps = hcd->regs; | ||
ehci->regs = hcd->regs + | ||
HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
|
||
/* enable PHY 0,1,the regs only apply to w90p910 | ||
* 0xA4,0xA8 were offsets of PHY0 and PHY1 controller of | ||
* w90p910 IC relative to ehci->regs. | ||
*/ | ||
val = __raw_readl(ehci->regs+PHY0_CTR); | ||
val |= ENPHY; | ||
__raw_writel(val, ehci->regs+PHY0_CTR); | ||
|
||
val = __raw_readl(ehci->regs+PHY1_CTR); | ||
val |= ENPHY; | ||
__raw_writel(val, ehci->regs+PHY1_CTR); | ||
|
||
ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
ehci->sbrn = 0x20; | ||
|
||
irq = platform_get_irq(pdev, 0); | ||
if (irq < 0) | ||
goto err4; | ||
|
||
retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | ||
if (retval != 0) | ||
goto err4; | ||
|
||
ehci_writel(ehci, 1, &ehci->regs->configured_flag); | ||
|
||
return retval; | ||
err4: | ||
iounmap(hcd->regs); | ||
err3: | ||
release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
err2: | ||
usb_put_hcd(hcd); | ||
err1: | ||
return retval; | ||
} | ||
|
||
static | ||
void usb_w90x900_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 const struct hc_driver ehci_w90x900_hc_driver = { | ||
.description = hcd_name, | ||
.product_desc = "Nuvoton w90x900 EHCI Host Controller", | ||
.hcd_priv_size = sizeof(struct ehci_hcd), | ||
|
||
/* | ||
* generic hardware linkage | ||
*/ | ||
.irq = ehci_irq, | ||
.flags = HCD_USB2|HCD_MEMORY, | ||
|
||
/* | ||
* basic lifecycle operations | ||
*/ | ||
.reset = ehci_init, | ||
.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, | ||
|
||
/* | ||
* scheduling support | ||
*/ | ||
.get_frame_number = ehci_get_frame, | ||
|
||
/* | ||
* root hub support | ||
*/ | ||
.hub_status_data = ehci_hub_status_data, | ||
.hub_control = ehci_hub_control, | ||
#ifdef 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, | ||
}; | ||
|
||
static int __devinit ehci_w90x900_probe(struct platform_device *pdev) | ||
{ | ||
if (usb_disabled()) | ||
return -ENODEV; | ||
|
||
return usb_w90x900_probe(&ehci_w90x900_hc_driver, pdev); | ||
} | ||
|
||
static int __devexit ehci_w90x900_remove(struct platform_device *pdev) | ||
{ | ||
struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
|
||
usb_w90x900_remove(hcd, pdev); | ||
|
||
return 0; | ||
} | ||
|
||
static struct platform_driver ehci_hcd_w90x900_driver = { | ||
.probe = ehci_w90x900_probe, | ||
.remove = __devexit_p(ehci_w90x900_remove), | ||
.driver = { | ||
.name = "w90x900-ehci", | ||
.owner = THIS_MODULE, | ||
}, | ||
}; | ||
|
||
MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); | ||
MODULE_DESCRIPTION("w90p910 usb ehci driver!"); | ||
MODULE_LICENSE("GPL"); | ||
MODULE_ALIAS("platform:w90p910-ehci"); |