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