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 v2.6.28-rc5 330 lines 7.6 kB view raw
1/* 2 * Glue code for the ISP1760 driver and bus 3 * Currently there is support for 4 * - OpenFirmware 5 * - PCI 6 * 7 * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de> 8 * 9 */ 10 11#include <linux/usb.h> 12#include <linux/io.h> 13 14#include "../core/hcd.h" 15#include "isp1760-hcd.h" 16 17#ifdef CONFIG_PPC_OF 18#include <linux/of.h> 19#include <linux/of_platform.h> 20#endif 21 22#ifdef CONFIG_PCI 23#include <linux/pci.h> 24#endif 25 26#ifdef CONFIG_PPC_OF 27static int of_isp1760_probe(struct of_device *dev, 28 const struct of_device_id *match) 29{ 30 struct usb_hcd *hcd; 31 struct device_node *dp = dev->node; 32 struct resource *res; 33 struct resource memory; 34 struct of_irq oirq; 35 int virq; 36 u64 res_len; 37 int ret; 38 const unsigned int *prop; 39 unsigned int devflags = 0; 40 41 ret = of_address_to_resource(dp, 0, &memory); 42 if (ret) 43 return -ENXIO; 44 45 res = request_mem_region(memory.start, memory.end - memory.start + 1, 46 dev_name(&dev->dev)); 47 if (!res) 48 return -EBUSY; 49 50 res_len = memory.end - memory.start + 1; 51 52 if (of_irq_map_one(dp, 0, &oirq)) { 53 ret = -ENODEV; 54 goto release_reg; 55 } 56 57 virq = irq_create_of_mapping(oirq.controller, oirq.specifier, 58 oirq.size); 59 60 if (of_device_is_compatible(dp, "nxp,usb-isp1761")) 61 devflags |= ISP1760_FLAG_ISP1761; 62 63 if (of_get_property(dp, "port1-disable", NULL) != NULL) 64 devflags |= ISP1760_FLAG_PORT1_DIS; 65 66 /* Some systems wire up only 16 of the 32 data lines */ 67 prop = of_get_property(dp, "bus-width", NULL); 68 if (prop && *prop == 16) 69 devflags |= ISP1760_FLAG_BUS_WIDTH_16; 70 71 if (of_get_property(dp, "port1-otg", NULL) != NULL) 72 devflags |= ISP1760_FLAG_OTG_EN; 73 74 if (of_get_property(dp, "analog-oc", NULL) != NULL) 75 devflags |= ISP1760_FLAG_ANALOG_OC; 76 77 if (of_get_property(dp, "dack-polarity", NULL) != NULL) 78 devflags |= ISP1760_FLAG_DACK_POL_HIGH; 79 80 if (of_get_property(dp, "dreq-polarity", NULL) != NULL) 81 devflags |= ISP1760_FLAG_DREQ_POL_HIGH; 82 83 hcd = isp1760_register(memory.start, res_len, virq, 84 IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev), 85 devflags); 86 if (IS_ERR(hcd)) { 87 ret = PTR_ERR(hcd); 88 goto release_reg; 89 } 90 91 dev_set_drvdata(&dev->dev, hcd); 92 return ret; 93 94release_reg: 95 release_mem_region(memory.start, memory.end - memory.start + 1); 96 return ret; 97} 98 99static int of_isp1760_remove(struct of_device *dev) 100{ 101 struct usb_hcd *hcd = dev_get_drvdata(&dev->dev); 102 103 dev_set_drvdata(&dev->dev, NULL); 104 105 usb_remove_hcd(hcd); 106 iounmap(hcd->regs); 107 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 108 usb_put_hcd(hcd); 109 return 0; 110} 111 112static struct of_device_id of_isp1760_match[] = { 113 { 114 .compatible = "nxp,usb-isp1760", 115 }, 116 { 117 .compatible = "nxp,usb-isp1761", 118 }, 119 { }, 120}; 121MODULE_DEVICE_TABLE(of, of_isp1760_match); 122 123static struct of_platform_driver isp1760_of_driver = { 124 .name = "nxp-isp1760", 125 .match_table = of_isp1760_match, 126 .probe = of_isp1760_probe, 127 .remove = of_isp1760_remove, 128}; 129#endif 130 131#ifdef CONFIG_PCI 132static u32 nxp_pci_io_base; 133static u32 iolength; 134static u32 pci_mem_phy0; 135static u32 length; 136static u8 __iomem *chip_addr; 137static u8 __iomem *iobase; 138 139static int __devinit isp1761_pci_probe(struct pci_dev *dev, 140 const struct pci_device_id *id) 141{ 142 u8 latency, limit; 143 __u32 reg_data; 144 int retry_count; 145 int length; 146 int status = 1; 147 struct usb_hcd *hcd; 148 unsigned int devflags = 0; 149 150 if (usb_disabled()) 151 return -ENODEV; 152 153 if (pci_enable_device(dev) < 0) 154 return -ENODEV; 155 156 if (!dev->irq) 157 return -ENODEV; 158 159 /* Grab the PLX PCI mem maped port start address we need */ 160 nxp_pci_io_base = pci_resource_start(dev, 0); 161 iolength = pci_resource_len(dev, 0); 162 163 if (!request_mem_region(nxp_pci_io_base, iolength, "ISP1761 IO MEM")) { 164 printk(KERN_ERR "request region #1\n"); 165 return -EBUSY; 166 } 167 168 iobase = ioremap_nocache(nxp_pci_io_base, iolength); 169 if (!iobase) { 170 printk(KERN_ERR "ioremap #1\n"); 171 release_mem_region(nxp_pci_io_base, iolength); 172 return -ENOMEM; 173 } 174 /* Grab the PLX PCI shared memory of the ISP 1761 we need */ 175 pci_mem_phy0 = pci_resource_start(dev, 3); 176 length = pci_resource_len(dev, 3); 177 178 if (length < 0xffff) { 179 printk(KERN_ERR "memory length for this resource is less than " 180 "required\n"); 181 release_mem_region(nxp_pci_io_base, iolength); 182 iounmap(iobase); 183 return -ENOMEM; 184 } 185 186 if (!request_mem_region(pci_mem_phy0, length, "ISP-PCI")) { 187 printk(KERN_ERR "host controller already in use\n"); 188 release_mem_region(nxp_pci_io_base, iolength); 189 iounmap(iobase); 190 return -EBUSY; 191 } 192 193 /* bad pci latencies can contribute to overruns */ 194 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency); 195 if (latency) { 196 pci_read_config_byte(dev, PCI_MAX_LAT, &limit); 197 if (limit && limit < latency) 198 pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit); 199 } 200 201 /* Try to check whether we can access Scratch Register of 202 * Host Controller or not. The initial PCI access is retried until 203 * local init for the PCI bridge is completed 204 */ 205 retry_count = 20; 206 reg_data = 0; 207 while ((reg_data != 0xFACE) && retry_count) { 208 /*by default host is in 16bit mode, so 209 * io operations at this stage must be 16 bit 210 * */ 211 writel(0xface, chip_addr + HC_SCRATCH_REG); 212 udelay(100); 213 reg_data = readl(chip_addr + HC_SCRATCH_REG); 214 retry_count--; 215 } 216 217 /* Host Controller presence is detected by writing to scratch register 218 * and reading back and checking the contents are same or not 219 */ 220 if (reg_data != 0xFACE) { 221 dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data); 222 goto clean; 223 } 224 225 pci_set_master(dev); 226 227 status = readl(iobase + 0x68); 228 status |= 0x900; 229 writel(status, iobase + 0x68); 230 231 dev->dev.dma_mask = NULL; 232 hcd = isp1760_register(pci_mem_phy0, length, dev->irq, 233 IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev), 234 devflags); 235 if (!IS_ERR(hcd)) { 236 pci_set_drvdata(dev, hcd); 237 return 0; 238 } 239clean: 240 status = -ENODEV; 241 iounmap(iobase); 242 release_mem_region(pci_mem_phy0, length); 243 release_mem_region(nxp_pci_io_base, iolength); 244 return status; 245} 246static void isp1761_pci_remove(struct pci_dev *dev) 247{ 248 struct usb_hcd *hcd; 249 250 hcd = pci_get_drvdata(dev); 251 252 usb_remove_hcd(hcd); 253 iounmap(hcd->regs); 254 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 255 usb_put_hcd(hcd); 256 257 pci_disable_device(dev); 258 259 iounmap(iobase); 260 iounmap(chip_addr); 261 262 release_mem_region(nxp_pci_io_base, iolength); 263 release_mem_region(pci_mem_phy0, length); 264} 265 266static void isp1761_pci_shutdown(struct pci_dev *dev) 267{ 268 printk(KERN_ERR "ips1761_pci_shutdown\n"); 269} 270 271static const struct pci_device_id isp1760_plx [] = { { 272 /* handle any USB 2.0 EHCI controller */ 273 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_OTHER << 8) | (0x06 << 16)), ~0), 274 .driver_data = 0, 275}, 276{ /* end: all zeroes */ } 277}; 278MODULE_DEVICE_TABLE(pci, isp1760_plx); 279 280static struct pci_driver isp1761_pci_driver = { 281 .name = "isp1760", 282 .id_table = isp1760_plx, 283 .probe = isp1761_pci_probe, 284 .remove = isp1761_pci_remove, 285 .shutdown = isp1761_pci_shutdown, 286}; 287#endif 288 289static int __init isp1760_init(void) 290{ 291 int ret; 292 293 init_kmem_once(); 294 295#ifdef CONFIG_PPC_OF 296 ret = of_register_platform_driver(&isp1760_of_driver); 297 if (ret) { 298 deinit_kmem_cache(); 299 return ret; 300 } 301#endif 302#ifdef CONFIG_PCI 303 ret = pci_register_driver(&isp1761_pci_driver); 304 if (ret) 305 goto unreg_of; 306#endif 307 return ret; 308 309#ifdef CONFIG_PCI 310unreg_of: 311#endif 312#ifdef CONFIG_PPC_OF 313 of_unregister_platform_driver(&isp1760_of_driver); 314#endif 315 deinit_kmem_cache(); 316 return ret; 317} 318module_init(isp1760_init); 319 320static void __exit isp1760_exit(void) 321{ 322#ifdef CONFIG_PPC_OF 323 of_unregister_platform_driver(&isp1760_of_driver); 324#endif 325#ifdef CONFIG_PCI 326 pci_unregister_driver(&isp1761_pci_driver); 327#endif 328 deinit_kmem_cache(); 329} 330module_exit(isp1760_exit);