diff options
Diffstat (limited to 'drivers/usb/host/isp1760-if.c')
| -rw-r--r-- | drivers/usb/host/isp1760-if.c | 95 |
1 files changed, 79 insertions, 16 deletions
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 4cf7ca428b33..3fa3a1702796 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | #include <linux/usb.h> | 11 | #include <linux/usb.h> |
| 12 | #include <linux/io.h> | 12 | #include <linux/io.h> |
| 13 | #include <linux/platform_device.h> | ||
| 13 | 14 | ||
| 14 | #include "../core/hcd.h" | 15 | #include "../core/hcd.h" |
| 15 | #include "isp1760-hcd.h" | 16 | #include "isp1760-hcd.h" |
| @@ -300,39 +301,101 @@ static struct pci_driver isp1761_pci_driver = { | |||
| 300 | }; | 301 | }; |
| 301 | #endif | 302 | #endif |
| 302 | 303 | ||
| 304 | static int __devinit isp1760_plat_probe(struct platform_device *pdev) | ||
| 305 | { | ||
| 306 | int ret = 0; | ||
| 307 | struct usb_hcd *hcd; | ||
| 308 | struct resource *mem_res; | ||
| 309 | struct resource *irq_res; | ||
| 310 | resource_size_t mem_size; | ||
| 311 | unsigned long irqflags = IRQF_SHARED | IRQF_DISABLED; | ||
| 312 | |||
| 313 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 314 | if (!mem_res) { | ||
| 315 | pr_warning("isp1760: Memory resource not available\n"); | ||
| 316 | ret = -ENODEV; | ||
| 317 | goto out; | ||
| 318 | } | ||
| 319 | mem_size = resource_size(mem_res); | ||
| 320 | if (!request_mem_region(mem_res->start, mem_size, "isp1760")) { | ||
| 321 | pr_warning("isp1760: Cannot reserve the memory resource\n"); | ||
| 322 | ret = -EBUSY; | ||
| 323 | goto out; | ||
| 324 | } | ||
| 325 | |||
| 326 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
| 327 | if (!irq_res) { | ||
| 328 | pr_warning("isp1760: IRQ resource not available\n"); | ||
| 329 | return -ENODEV; | ||
| 330 | } | ||
| 331 | irqflags |= irq_res->flags & IRQF_TRIGGER_MASK; | ||
| 332 | |||
| 333 | hcd = isp1760_register(mem_res->start, mem_size, irq_res->start, | ||
| 334 | irqflags, &pdev->dev, dev_name(&pdev->dev), 0); | ||
| 335 | if (IS_ERR(hcd)) { | ||
| 336 | pr_warning("isp1760: Failed to register the HCD device\n"); | ||
| 337 | ret = -ENODEV; | ||
| 338 | goto cleanup; | ||
| 339 | } | ||
| 340 | |||
| 341 | pr_info("ISP1760 USB device initialised\n"); | ||
| 342 | return ret; | ||
| 343 | |||
| 344 | cleanup: | ||
| 345 | release_mem_region(mem_res->start, mem_size); | ||
| 346 | out: | ||
| 347 | return ret; | ||
| 348 | } | ||
| 349 | |||
| 350 | static int __devexit isp1760_plat_remove(struct platform_device *pdev) | ||
| 351 | { | ||
| 352 | struct resource *mem_res; | ||
| 353 | resource_size_t mem_size; | ||
| 354 | |||
| 355 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 356 | mem_size = resource_size(mem_res); | ||
| 357 | release_mem_region(mem_res->start, mem_size); | ||
| 358 | |||
| 359 | return 0; | ||
| 360 | } | ||
| 361 | |||
| 362 | static struct platform_driver isp1760_plat_driver = { | ||
| 363 | .probe = isp1760_plat_probe, | ||
| 364 | .remove = isp1760_plat_remove, | ||
| 365 | .driver = { | ||
| 366 | .name = "isp1760", | ||
| 367 | }, | ||
| 368 | }; | ||
| 369 | |||
| 303 | static int __init isp1760_init(void) | 370 | static int __init isp1760_init(void) |
| 304 | { | 371 | { |
| 305 | int ret; | 372 | int ret, any_ret = -ENODEV; |
| 306 | 373 | ||
| 307 | init_kmem_once(); | 374 | init_kmem_once(); |
| 308 | 375 | ||
| 376 | ret = platform_driver_register(&isp1760_plat_driver); | ||
| 377 | if (!ret) | ||
| 378 | any_ret = 0; | ||
| 309 | #ifdef CONFIG_PPC_OF | 379 | #ifdef CONFIG_PPC_OF |
| 310 | ret = of_register_platform_driver(&isp1760_of_driver); | 380 | ret = of_register_platform_driver(&isp1760_of_driver); |
| 311 | if (ret) { | 381 | if (!ret) |
| 312 | deinit_kmem_cache(); | 382 | any_ret = 0; |
| 313 | return ret; | ||
| 314 | } | ||
| 315 | #endif | 383 | #endif |
| 316 | #ifdef CONFIG_PCI | 384 | #ifdef CONFIG_PCI |
| 317 | ret = pci_register_driver(&isp1761_pci_driver); | 385 | ret = pci_register_driver(&isp1761_pci_driver); |
| 318 | if (ret) | 386 | if (!ret) |
| 319 | goto unreg_of; | 387 | any_ret = 0; |
| 320 | #endif | 388 | #endif |
| 321 | return ret; | ||
| 322 | 389 | ||
| 323 | #ifdef CONFIG_PCI | 390 | if (any_ret) |
| 324 | unreg_of: | 391 | deinit_kmem_cache(); |
| 325 | #endif | 392 | return any_ret; |
| 326 | #ifdef CONFIG_PPC_OF | ||
| 327 | of_unregister_platform_driver(&isp1760_of_driver); | ||
| 328 | #endif | ||
| 329 | deinit_kmem_cache(); | ||
| 330 | return ret; | ||
| 331 | } | 393 | } |
| 332 | module_init(isp1760_init); | 394 | module_init(isp1760_init); |
| 333 | 395 | ||
| 334 | static void __exit isp1760_exit(void) | 396 | static void __exit isp1760_exit(void) |
| 335 | { | 397 | { |
| 398 | platform_driver_unregister(&isp1760_plat_driver); | ||
| 336 | #ifdef CONFIG_PPC_OF | 399 | #ifdef CONFIG_PPC_OF |
| 337 | of_unregister_platform_driver(&isp1760_of_driver); | 400 | of_unregister_platform_driver(&isp1760_of_driver); |
| 338 | #endif | 401 | #endif |
