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-rc3 166 lines 4.1 kB view raw
1/* 2 * Copyright 2008 Cavium Networks 3 * 4 * This file is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License, Version 2, as 6 * published by the Free Software Foundation. 7 */ 8 9#include <linux/platform_device.h> 10#include <linux/atomic.h> 11#include <mach/cns3xxx.h> 12#include <mach/pm.h> 13 14static int __devinit 15cns3xxx_ohci_start(struct usb_hcd *hcd) 16{ 17 struct ohci_hcd *ohci = hcd_to_ohci(hcd); 18 int ret; 19 20 /* 21 * EHCI and OHCI share the same clock and power, 22 * resetting twice would cause the 1st controller been reset. 23 * Therefore only do power up at the first up device, and 24 * power down at the last down device. 25 * 26 * Set USB AHB INCR length to 16 27 */ 28 if (atomic_inc_return(&usb_pwr_ref) == 1) { 29 cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB); 30 cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); 31 cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST); 32 __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)), 33 MISC_CHIP_CONFIG_REG); 34 } 35 36 ret = ohci_init(ohci); 37 if (ret < 0) 38 return ret; 39 40 ohci->num_ports = 1; 41 42 ret = ohci_run(ohci); 43 if (ret < 0) { 44 dev_err(hcd->self.controller, "can't start %s\n", 45 hcd->self.bus_name); 46 ohci_stop(hcd); 47 return ret; 48 } 49 return 0; 50} 51 52static const struct hc_driver cns3xxx_ohci_hc_driver = { 53 .description = hcd_name, 54 .product_desc = "CNS3XXX OHCI Host controller", 55 .hcd_priv_size = sizeof(struct ohci_hcd), 56 .irq = ohci_irq, 57 .flags = HCD_USB11 | HCD_MEMORY, 58 .start = cns3xxx_ohci_start, 59 .stop = ohci_stop, 60 .shutdown = ohci_shutdown, 61 .urb_enqueue = ohci_urb_enqueue, 62 .urb_dequeue = ohci_urb_dequeue, 63 .endpoint_disable = ohci_endpoint_disable, 64 .get_frame_number = ohci_get_frame, 65 .hub_status_data = ohci_hub_status_data, 66 .hub_control = ohci_hub_control, 67#ifdef CONFIG_PM 68 .bus_suspend = ohci_bus_suspend, 69 .bus_resume = ohci_bus_resume, 70#endif 71 .start_port_reset = ohci_start_port_reset, 72}; 73 74static int cns3xxx_ohci_probe(struct platform_device *pdev) 75{ 76 struct device *dev = &pdev->dev; 77 struct usb_hcd *hcd; 78 const struct hc_driver *driver = &cns3xxx_ohci_hc_driver; 79 struct resource *res; 80 int irq; 81 int retval; 82 83 if (usb_disabled()) 84 return -ENODEV; 85 86 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 87 if (!res) { 88 dev_err(dev, "Found HC with no IRQ.\n"); 89 return -ENODEV; 90 } 91 irq = res->start; 92 93 hcd = usb_create_hcd(driver, dev, dev_name(dev)); 94 if (!hcd) 95 return -ENOMEM; 96 97 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 98 if (!res) { 99 dev_err(dev, "Found HC with no register addr.\n"); 100 retval = -ENODEV; 101 goto err1; 102 } 103 hcd->rsrc_start = res->start; 104 hcd->rsrc_len = resource_size(res); 105 106 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, 107 driver->description)) { 108 dev_dbg(dev, "controller already in use\n"); 109 retval = -EBUSY; 110 goto err1; 111 } 112 113 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); 114 if (!hcd->regs) { 115 dev_dbg(dev, "error mapping memory\n"); 116 retval = -EFAULT; 117 goto err2; 118 } 119 120 ohci_hcd_init(hcd_to_ohci(hcd)); 121 122 retval = usb_add_hcd(hcd, irq, IRQF_SHARED); 123 if (retval == 0) 124 return retval; 125 126 iounmap(hcd->regs); 127err2: 128 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 129err1: 130 usb_put_hcd(hcd); 131 return retval; 132} 133 134static int cns3xxx_ohci_remove(struct platform_device *pdev) 135{ 136 struct usb_hcd *hcd = platform_get_drvdata(pdev); 137 138 usb_remove_hcd(hcd); 139 iounmap(hcd->regs); 140 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 141 142 /* 143 * EHCI and OHCI share the same clock and power, 144 * resetting twice would cause the 1st controller been reset. 145 * Therefore only do power up at the first up device, and 146 * power down at the last down device. 147 */ 148 if (atomic_dec_return(&usb_pwr_ref) == 0) 149 cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); 150 151 usb_put_hcd(hcd); 152 153 platform_set_drvdata(pdev, NULL); 154 155 return 0; 156} 157 158MODULE_ALIAS("platform:cns3xxx-ohci"); 159 160static struct platform_driver ohci_hcd_cns3xxx_driver = { 161 .probe = cns3xxx_ohci_probe, 162 .remove = cns3xxx_ohci_remove, 163 .driver = { 164 .name = "cns3xxx-ohci", 165 }, 166};