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.17-rc7 154 lines 3.4 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/dma-mapping.h> 15#include <linux/io.h> 16#include <linux/kernel.h> 17#include <linux/module.h> 18#include <linux/of.h> 19#include <linux/platform_device.h> 20#include <linux/usb.h> 21#include <linux/usb/hcd.h> 22 23#include "ehci.h" 24 25/* enable phy0 and phy1 for w90p910 */ 26#define ENPHY (0x01<<8) 27#define PHY0_CTR (0xA4) 28#define PHY1_CTR (0xA8) 29 30#define DRIVER_DESC "EHCI w90x900 driver" 31 32static const char hcd_name[] = "ehci-w90x900 "; 33 34static struct hc_driver __read_mostly ehci_w90x900_hc_driver; 35 36static int usb_w90x900_probe(const struct hc_driver *driver, 37 struct platform_device *pdev) 38{ 39 struct usb_hcd *hcd; 40 struct ehci_hcd *ehci; 41 struct resource *res; 42 int retval = 0, irq; 43 unsigned long val; 44 45 46 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 47 if (!res) { 48 retval = -ENXIO; 49 goto err1; 50 } 51 52 hcd = usb_create_hcd(driver, &pdev->dev, "w90x900 EHCI"); 53 if (!hcd) { 54 retval = -ENOMEM; 55 goto err1; 56 } 57 58 hcd->rsrc_start = res->start; 59 hcd->rsrc_len = resource_size(res); 60 61 hcd->regs = devm_ioremap_resource(&pdev->dev, res); 62 if (IS_ERR(hcd->regs)) { 63 retval = PTR_ERR(hcd->regs); 64 goto err2; 65 } 66 67 ehci = hcd_to_ehci(hcd); 68 ehci->caps = hcd->regs; 69 ehci->regs = hcd->regs + 70 HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); 71 72 /* enable PHY 0,1,the regs only apply to w90p910 73 * 0xA4,0xA8 were offsets of PHY0 and PHY1 controller of 74 * w90p910 IC relative to ehci->regs. 75 */ 76 val = __raw_readl(ehci->regs+PHY0_CTR); 77 val |= ENPHY; 78 __raw_writel(val, ehci->regs+PHY0_CTR); 79 80 val = __raw_readl(ehci->regs+PHY1_CTR); 81 val |= ENPHY; 82 __raw_writel(val, ehci->regs+PHY1_CTR); 83 84 irq = platform_get_irq(pdev, 0); 85 if (irq < 0) 86 goto err2; 87 88 retval = usb_add_hcd(hcd, irq, IRQF_SHARED); 89 if (retval != 0) 90 goto err2; 91 92 device_wakeup_enable(hcd->self.controller); 93 return retval; 94err2: 95 usb_put_hcd(hcd); 96err1: 97 return retval; 98} 99 100static void usb_w90x900_remove(struct usb_hcd *hcd, 101 struct platform_device *pdev) 102{ 103 usb_remove_hcd(hcd); 104 usb_put_hcd(hcd); 105} 106 107static int ehci_w90x900_probe(struct platform_device *pdev) 108{ 109 if (usb_disabled()) 110 return -ENODEV; 111 112 return usb_w90x900_probe(&ehci_w90x900_hc_driver, pdev); 113} 114 115static int ehci_w90x900_remove(struct platform_device *pdev) 116{ 117 struct usb_hcd *hcd = platform_get_drvdata(pdev); 118 119 usb_w90x900_remove(hcd, pdev); 120 121 return 0; 122} 123 124static struct platform_driver ehci_hcd_w90x900_driver = { 125 .probe = ehci_w90x900_probe, 126 .remove = ehci_w90x900_remove, 127 .driver = { 128 .name = "w90x900-ehci", 129 .owner = THIS_MODULE, 130 }, 131}; 132 133static int __init ehci_w90X900_init(void) 134{ 135 if (usb_disabled()) 136 return -ENODEV; 137 138 pr_info("%s: " DRIVER_DESC "\n", hcd_name); 139 140 ehci_init_driver(&ehci_w90x900_hc_driver, NULL); 141 return platform_driver_register(&ehci_hcd_w90x900_driver); 142} 143module_init(ehci_w90X900_init); 144 145static void __exit ehci_w90X900_cleanup(void) 146{ 147 platform_driver_unregister(&ehci_hcd_w90x900_driver); 148} 149module_exit(ehci_w90X900_cleanup); 150 151MODULE_DESCRIPTION(DRIVER_DESC); 152MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); 153MODULE_ALIAS("platform:w90p910-ehci"); 154MODULE_LICENSE("GPL v2");