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.1-rc3 427 lines 10 kB view raw
1/* 2 * Glue code for the ISP1760 driver and bus 3 * Currently there is support for 4 * - OpenFirmware 5 * - PCI 6 * - PDEV (generic platform device centralized driver model) 7 * 8 * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de> 9 * 10 */ 11 12#include <linux/usb.h> 13#include <linux/io.h> 14#include <linux/platform_device.h> 15#include <linux/usb/isp1760.h> 16#include <linux/usb/hcd.h> 17 18#include "isp1760-hcd.h" 19 20#ifdef CONFIG_PPC_OF 21#include <linux/of.h> 22#include <linux/of_platform.h> 23#endif 24 25#ifdef CONFIG_PCI 26#include <linux/pci.h> 27#endif 28 29#ifdef CONFIG_PPC_OF 30static int of_isp1760_probe(struct platform_device *dev) 31{ 32 struct usb_hcd *hcd; 33 struct device_node *dp = dev->dev.of_node; 34 struct resource *res; 35 struct resource memory; 36 struct of_irq oirq; 37 int virq; 38 resource_size_t res_len; 39 int ret; 40 const unsigned int *prop; 41 unsigned int devflags = 0; 42 43 ret = of_address_to_resource(dp, 0, &memory); 44 if (ret) 45 return -ENXIO; 46 47 res_len = resource_size(&memory); 48 49 res = request_mem_region(memory.start, res_len, dev_name(&dev->dev)); 50 if (!res) 51 return -EBUSY; 52 53 if (of_irq_map_one(dp, 0, &oirq)) { 54 ret = -ENODEV; 55 goto release_reg; 56 } 57 58 virq = irq_create_of_mapping(oirq.controller, oirq.specifier, 59 oirq.size); 60 61 if (of_device_is_compatible(dp, "nxp,usb-isp1761")) 62 devflags |= ISP1760_FLAG_ISP1761; 63 64 /* Some systems wire up only 16 of the 32 data lines */ 65 prop = of_get_property(dp, "bus-width", NULL); 66 if (prop && *prop == 16) 67 devflags |= ISP1760_FLAG_BUS_WIDTH_16; 68 69 if (of_get_property(dp, "port1-otg", NULL) != NULL) 70 devflags |= ISP1760_FLAG_OTG_EN; 71 72 if (of_get_property(dp, "analog-oc", NULL) != NULL) 73 devflags |= ISP1760_FLAG_ANALOG_OC; 74 75 if (of_get_property(dp, "dack-polarity", NULL) != NULL) 76 devflags |= ISP1760_FLAG_DACK_POL_HIGH; 77 78 if (of_get_property(dp, "dreq-polarity", NULL) != NULL) 79 devflags |= ISP1760_FLAG_DREQ_POL_HIGH; 80 81 hcd = isp1760_register(memory.start, res_len, virq, 82 IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev), 83 devflags); 84 if (IS_ERR(hcd)) { 85 ret = PTR_ERR(hcd); 86 goto release_reg; 87 } 88 89 dev_set_drvdata(&dev->dev, hcd); 90 return ret; 91 92release_reg: 93 release_mem_region(memory.start, res_len); 94 return ret; 95} 96 97static int of_isp1760_remove(struct platform_device *dev) 98{ 99 struct usb_hcd *hcd = dev_get_drvdata(&dev->dev); 100 101 dev_set_drvdata(&dev->dev, NULL); 102 103 usb_remove_hcd(hcd); 104 iounmap(hcd->regs); 105 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 106 usb_put_hcd(hcd); 107 return 0; 108} 109 110static const struct of_device_id of_isp1760_match[] = { 111 { 112 .compatible = "nxp,usb-isp1760", 113 }, 114 { 115 .compatible = "nxp,usb-isp1761", 116 }, 117 { }, 118}; 119MODULE_DEVICE_TABLE(of, of_isp1760_match); 120 121static struct platform_driver isp1760_of_driver = { 122 .driver = { 123 .name = "nxp-isp1760", 124 .owner = THIS_MODULE, 125 .of_match_table = of_isp1760_match, 126 }, 127 .probe = of_isp1760_probe, 128 .remove = of_isp1760_remove, 129}; 130#endif 131 132#ifdef CONFIG_PCI 133static int __devinit isp1761_pci_probe(struct pci_dev *dev, 134 const struct pci_device_id *id) 135{ 136 u8 latency, limit; 137 __u32 reg_data; 138 int retry_count; 139 struct usb_hcd *hcd; 140 unsigned int devflags = 0; 141 int ret_status = 0; 142 143 resource_size_t pci_mem_phy0; 144 resource_size_t memlength; 145 146 u8 __iomem *chip_addr; 147 u8 __iomem *iobase; 148 resource_size_t nxp_pci_io_base; 149 resource_size_t iolength; 150 151 if (usb_disabled()) 152 return -ENODEV; 153 154 if (pci_enable_device(dev) < 0) 155 return -ENODEV; 156 157 if (!dev->irq) 158 return -ENODEV; 159 160 /* Grab the PLX PCI mem maped port start address we need */ 161 nxp_pci_io_base = pci_resource_start(dev, 0); 162 iolength = pci_resource_len(dev, 0); 163 164 if (!request_mem_region(nxp_pci_io_base, iolength, "ISP1761 IO MEM")) { 165 printk(KERN_ERR "request region #1\n"); 166 return -EBUSY; 167 } 168 169 iobase = ioremap_nocache(nxp_pci_io_base, iolength); 170 if (!iobase) { 171 printk(KERN_ERR "ioremap #1\n"); 172 ret_status = -ENOMEM; 173 goto cleanup1; 174 } 175 /* Grab the PLX PCI shared memory of the ISP 1761 we need */ 176 pci_mem_phy0 = pci_resource_start(dev, 3); 177 memlength = pci_resource_len(dev, 3); 178 if (memlength < 0xffff) { 179 printk(KERN_ERR "memory length for this resource is wrong\n"); 180 ret_status = -ENOMEM; 181 goto cleanup2; 182 } 183 184 if (!request_mem_region(pci_mem_phy0, memlength, "ISP-PCI")) { 185 printk(KERN_ERR "host controller already in use\n"); 186 ret_status = -EBUSY; 187 goto cleanup2; 188 } 189 190 /* map available memory */ 191 chip_addr = ioremap_nocache(pci_mem_phy0,memlength); 192 if (!chip_addr) { 193 printk(KERN_ERR "Error ioremap failed\n"); 194 ret_status = -ENOMEM; 195 goto cleanup3; 196 } 197 198 /* bad pci latencies can contribute to overruns */ 199 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency); 200 if (latency) { 201 pci_read_config_byte(dev, PCI_MAX_LAT, &limit); 202 if (limit && limit < latency) 203 pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit); 204 } 205 206 /* Try to check whether we can access Scratch Register of 207 * Host Controller or not. The initial PCI access is retried until 208 * local init for the PCI bridge is completed 209 */ 210 retry_count = 20; 211 reg_data = 0; 212 while ((reg_data != 0xFACE) && retry_count) { 213 /*by default host is in 16bit mode, so 214 * io operations at this stage must be 16 bit 215 * */ 216 writel(0xface, chip_addr + HC_SCRATCH_REG); 217 udelay(100); 218 reg_data = readl(chip_addr + HC_SCRATCH_REG) & 0x0000ffff; 219 retry_count--; 220 } 221 222 iounmap(chip_addr); 223 224 /* Host Controller presence is detected by writing to scratch register 225 * and reading back and checking the contents are same or not 226 */ 227 if (reg_data != 0xFACE) { 228 dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data); 229 ret_status = -ENOMEM; 230 goto cleanup3; 231 } 232 233 pci_set_master(dev); 234 235 /* configure PLX PCI chip to pass interrupts */ 236#define PLX_INT_CSR_REG 0x68 237 reg_data = readl(iobase + PLX_INT_CSR_REG); 238 reg_data |= 0x900; 239 writel(reg_data, iobase + PLX_INT_CSR_REG); 240 241 dev->dev.dma_mask = NULL; 242 hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq, 243 IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev), 244 devflags); 245 if (IS_ERR(hcd)) { 246 ret_status = -ENODEV; 247 goto cleanup3; 248 } 249 250 /* done with PLX IO access */ 251 iounmap(iobase); 252 release_mem_region(nxp_pci_io_base, iolength); 253 254 pci_set_drvdata(dev, hcd); 255 return 0; 256 257cleanup3: 258 release_mem_region(pci_mem_phy0, memlength); 259cleanup2: 260 iounmap(iobase); 261cleanup1: 262 release_mem_region(nxp_pci_io_base, iolength); 263 return ret_status; 264} 265 266static void isp1761_pci_remove(struct pci_dev *dev) 267{ 268 struct usb_hcd *hcd; 269 270 hcd = pci_get_drvdata(dev); 271 272 usb_remove_hcd(hcd); 273 iounmap(hcd->regs); 274 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 275 usb_put_hcd(hcd); 276 277 pci_disable_device(dev); 278} 279 280static void isp1761_pci_shutdown(struct pci_dev *dev) 281{ 282 printk(KERN_ERR "ips1761_pci_shutdown\n"); 283} 284 285static const struct pci_device_id isp1760_plx [] = { 286 { 287 .class = PCI_CLASS_BRIDGE_OTHER << 8, 288 .class_mask = ~0, 289 .vendor = PCI_VENDOR_ID_PLX, 290 .device = 0x5406, 291 .subvendor = PCI_VENDOR_ID_PLX, 292 .subdevice = 0x9054, 293 }, 294 { } 295}; 296MODULE_DEVICE_TABLE(pci, isp1760_plx); 297 298static struct pci_driver isp1761_pci_driver = { 299 .name = "isp1760", 300 .id_table = isp1760_plx, 301 .probe = isp1761_pci_probe, 302 .remove = isp1761_pci_remove, 303 .shutdown = isp1761_pci_shutdown, 304}; 305#endif 306 307static int __devinit isp1760_plat_probe(struct platform_device *pdev) 308{ 309 int ret = 0; 310 struct usb_hcd *hcd; 311 struct resource *mem_res; 312 struct resource *irq_res; 313 resource_size_t mem_size; 314 struct isp1760_platform_data *priv = pdev->dev.platform_data; 315 unsigned int devflags = 0; 316 unsigned long irqflags = IRQF_SHARED | IRQF_DISABLED; 317 318 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 319 if (!mem_res) { 320 pr_warning("isp1760: Memory resource not available\n"); 321 ret = -ENODEV; 322 goto out; 323 } 324 mem_size = resource_size(mem_res); 325 if (!request_mem_region(mem_res->start, mem_size, "isp1760")) { 326 pr_warning("isp1760: Cannot reserve the memory resource\n"); 327 ret = -EBUSY; 328 goto out; 329 } 330 331 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 332 if (!irq_res) { 333 pr_warning("isp1760: IRQ resource not available\n"); 334 return -ENODEV; 335 } 336 irqflags |= irq_res->flags & IRQF_TRIGGER_MASK; 337 338 if (priv) { 339 if (priv->is_isp1761) 340 devflags |= ISP1760_FLAG_ISP1761; 341 if (priv->bus_width_16) 342 devflags |= ISP1760_FLAG_BUS_WIDTH_16; 343 if (priv->port1_otg) 344 devflags |= ISP1760_FLAG_OTG_EN; 345 if (priv->analog_oc) 346 devflags |= ISP1760_FLAG_ANALOG_OC; 347 if (priv->dack_polarity_high) 348 devflags |= ISP1760_FLAG_DACK_POL_HIGH; 349 if (priv->dreq_polarity_high) 350 devflags |= ISP1760_FLAG_DREQ_POL_HIGH; 351 } 352 353 hcd = isp1760_register(mem_res->start, mem_size, irq_res->start, 354 irqflags, &pdev->dev, dev_name(&pdev->dev), devflags); 355 if (IS_ERR(hcd)) { 356 pr_warning("isp1760: Failed to register the HCD device\n"); 357 ret = -ENODEV; 358 goto cleanup; 359 } 360 361 pr_info("ISP1760 USB device initialised\n"); 362 return ret; 363 364cleanup: 365 release_mem_region(mem_res->start, mem_size); 366out: 367 return ret; 368} 369 370static int __devexit isp1760_plat_remove(struct platform_device *pdev) 371{ 372 struct resource *mem_res; 373 resource_size_t mem_size; 374 375 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 376 mem_size = resource_size(mem_res); 377 release_mem_region(mem_res->start, mem_size); 378 379 return 0; 380} 381 382static struct platform_driver isp1760_plat_driver = { 383 .probe = isp1760_plat_probe, 384 .remove = __devexit_p(isp1760_plat_remove), 385 .driver = { 386 .name = "isp1760", 387 }, 388}; 389 390static int __init isp1760_init(void) 391{ 392 int ret, any_ret = -ENODEV; 393 394 init_kmem_once(); 395 396 ret = platform_driver_register(&isp1760_plat_driver); 397 if (!ret) 398 any_ret = 0; 399#ifdef CONFIG_PPC_OF 400 ret = platform_driver_register(&isp1760_of_driver); 401 if (!ret) 402 any_ret = 0; 403#endif 404#ifdef CONFIG_PCI 405 ret = pci_register_driver(&isp1761_pci_driver); 406 if (!ret) 407 any_ret = 0; 408#endif 409 410 if (any_ret) 411 deinit_kmem_cache(); 412 return any_ret; 413} 414module_init(isp1760_init); 415 416static void __exit isp1760_exit(void) 417{ 418 platform_driver_unregister(&isp1760_plat_driver); 419#ifdef CONFIG_PPC_OF 420 platform_driver_unregister(&isp1760_of_driver); 421#endif 422#ifdef CONFIG_PCI 423 pci_unregister_driver(&isp1761_pci_driver); 424#endif 425 deinit_kmem_cache(); 426} 427module_exit(isp1760_exit);