Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.7 179 lines 4.0 kB view raw
1/* 2 * linux/driver/usb/host/ehci-w90x900.c 3 * 4 * Copyright (c) 2008 Nuvoton technology corporation. 5 * 6 * Wan ZongShun <mcuos.com@gmail.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation;version 2 of the License. 11 * 12 */ 13 14#include <linux/platform_device.h> 15 16/*ebable phy0 and phy1 for w90p910*/ 17#define ENPHY (0x01<<8) 18#define PHY0_CTR (0xA4) 19#define PHY1_CTR (0xA8) 20 21static int __devinit usb_w90x900_probe(const struct hc_driver *driver, 22 struct platform_device *pdev) 23{ 24 struct usb_hcd *hcd; 25 struct ehci_hcd *ehci; 26 struct resource *res; 27 int retval = 0, irq; 28 unsigned long val; 29 30 31 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 32 if (!res) { 33 retval = -ENXIO; 34 goto err1; 35 } 36 37 hcd = usb_create_hcd(driver, &pdev->dev, "w90x900 EHCI"); 38 if (!hcd) { 39 retval = -ENOMEM; 40 goto err1; 41 } 42 43 hcd->rsrc_start = res->start; 44 hcd->rsrc_len = resource_size(res); 45 46 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { 47 retval = -EBUSY; 48 goto err2; 49 } 50 51 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); 52 if (hcd->regs == NULL) { 53 retval = -EFAULT; 54 goto err3; 55 } 56 57 ehci = hcd_to_ehci(hcd); 58 ehci->caps = hcd->regs; 59 ehci->regs = hcd->regs + 60 HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); 61 62 /* enable PHY 0,1,the regs only apply to w90p910 63 * 0xA4,0xA8 were offsets of PHY0 and PHY1 controller of 64 * w90p910 IC relative to ehci->regs. 65 */ 66 val = __raw_readl(ehci->regs+PHY0_CTR); 67 val |= ENPHY; 68 __raw_writel(val, ehci->regs+PHY0_CTR); 69 70 val = __raw_readl(ehci->regs+PHY1_CTR); 71 val |= ENPHY; 72 __raw_writel(val, ehci->regs+PHY1_CTR); 73 74 irq = platform_get_irq(pdev, 0); 75 if (irq < 0) 76 goto err4; 77 78 retval = usb_add_hcd(hcd, irq, IRQF_SHARED); 79 if (retval != 0) 80 goto err4; 81 82 return retval; 83err4: 84 iounmap(hcd->regs); 85err3: 86 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 87err2: 88 usb_put_hcd(hcd); 89err1: 90 return retval; 91} 92 93static 94void usb_w90x900_remove(struct usb_hcd *hcd, struct platform_device *pdev) 95{ 96 usb_remove_hcd(hcd); 97 iounmap(hcd->regs); 98 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 99 usb_put_hcd(hcd); 100} 101 102static const struct hc_driver ehci_w90x900_hc_driver = { 103 .description = hcd_name, 104 .product_desc = "Nuvoton w90x900 EHCI Host Controller", 105 .hcd_priv_size = sizeof(struct ehci_hcd), 106 107 /* 108 * generic hardware linkage 109 */ 110 .irq = ehci_irq, 111 .flags = HCD_USB2|HCD_MEMORY, 112 113 /* 114 * basic lifecycle operations 115 */ 116 .reset = ehci_setup, 117 .start = ehci_run, 118 119 .stop = ehci_stop, 120 .shutdown = ehci_shutdown, 121 122 /* 123 * managing i/o requests and associated device resources 124 */ 125 .urb_enqueue = ehci_urb_enqueue, 126 .urb_dequeue = ehci_urb_dequeue, 127 .endpoint_disable = ehci_endpoint_disable, 128 .endpoint_reset = ehci_endpoint_reset, 129 130 /* 131 * scheduling support 132 */ 133 .get_frame_number = ehci_get_frame, 134 135 /* 136 * root hub support 137 */ 138 .hub_status_data = ehci_hub_status_data, 139 .hub_control = ehci_hub_control, 140#ifdef CONFIG_PM 141 .bus_suspend = ehci_bus_suspend, 142 .bus_resume = ehci_bus_resume, 143#endif 144 .relinquish_port = ehci_relinquish_port, 145 .port_handed_over = ehci_port_handed_over, 146 147 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, 148}; 149 150static int __devinit ehci_w90x900_probe(struct platform_device *pdev) 151{ 152 if (usb_disabled()) 153 return -ENODEV; 154 155 return usb_w90x900_probe(&ehci_w90x900_hc_driver, pdev); 156} 157 158static int __devexit ehci_w90x900_remove(struct platform_device *pdev) 159{ 160 struct usb_hcd *hcd = platform_get_drvdata(pdev); 161 162 usb_w90x900_remove(hcd, pdev); 163 164 return 0; 165} 166 167static struct platform_driver ehci_hcd_w90x900_driver = { 168 .probe = ehci_w90x900_probe, 169 .remove = __devexit_p(ehci_w90x900_remove), 170 .driver = { 171 .name = "w90x900-ehci", 172 .owner = THIS_MODULE, 173 }, 174}; 175 176MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); 177MODULE_DESCRIPTION("w90p910 usb ehci driver!"); 178MODULE_LICENSE("GPL"); 179MODULE_ALIAS("platform:w90p910-ehci");