diff options
| -rw-r--r-- | Documentation/kernel-parameters.txt | 11 | ||||
| -rw-r--r-- | drivers/net/irda/smsc-ircc2.c | 98 |
2 files changed, 86 insertions, 23 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 38d7db3262c7..fa885174fd75 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -1578,6 +1578,17 @@ and is between 256 and 4096 characters. It is defined in the file | |||
| 1578 | smp-alt-once [IA-32,SMP] On a hotplug CPU system, only | 1578 | smp-alt-once [IA-32,SMP] On a hotplug CPU system, only |
| 1579 | attempt to substitute SMP alternatives once at boot. | 1579 | attempt to substitute SMP alternatives once at boot. |
| 1580 | 1580 | ||
| 1581 | smsc-ircc2.nopnp [HW] Don't use PNP to discover SMC devices | ||
| 1582 | smsc-ircc2.ircc_cfg= [HW] Device configuration I/O port | ||
| 1583 | smsc-ircc2.ircc_sir= [HW] SIR base I/O port | ||
| 1584 | smsc-ircc2.ircc_fir= [HW] FIR base I/O port | ||
| 1585 | smsc-ircc2.ircc_irq= [HW] IRQ line | ||
| 1586 | smsc-ircc2.ircc_dma= [HW] DMA channel | ||
| 1587 | smsc-ircc2.ircc_transceiver= [HW] Transceiver type: | ||
| 1588 | 0: Toshiba Satellite 1800 (GP data pin select) | ||
| 1589 | 1: Fast pin select (default) | ||
| 1590 | 2: ATC IRMode | ||
| 1591 | |||
| 1581 | snd-ad1816a= [HW,ALSA] | 1592 | snd-ad1816a= [HW,ALSA] |
| 1582 | 1593 | ||
| 1583 | snd-ad1848= [HW,ALSA] | 1594 | snd-ad1848= [HW,ALSA] |
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 1d249737f96f..9043bf4aa49e 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c | |||
| @@ -79,6 +79,10 @@ MODULE_AUTHOR("Daniele Peri <peri@csai.unipa.it>"); | |||
| 79 | MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver"); | 79 | MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver"); |
| 80 | MODULE_LICENSE("GPL"); | 80 | MODULE_LICENSE("GPL"); |
| 81 | 81 | ||
| 82 | static int smsc_nopnp; | ||
| 83 | module_param_named(nopnp, smsc_nopnp, bool, 0); | ||
| 84 | MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings"); | ||
| 85 | |||
| 82 | #define DMA_INVAL 255 | 86 | #define DMA_INVAL 255 |
| 83 | static int ircc_dma = DMA_INVAL; | 87 | static int ircc_dma = DMA_INVAL; |
| 84 | module_param(ircc_dma, int, 0); | 88 | module_param(ircc_dma, int, 0); |
| @@ -362,7 +366,6 @@ static inline void register_bank(int iobase, int bank) | |||
| 362 | iobase + IRCC_MASTER); | 366 | iobase + IRCC_MASTER); |
| 363 | } | 367 | } |
| 364 | 368 | ||
| 365 | #ifdef CONFIG_PNP | ||
| 366 | /* PNP hotplug support */ | 369 | /* PNP hotplug support */ |
| 367 | static const struct pnp_device_id smsc_ircc_pnp_table[] = { | 370 | static const struct pnp_device_id smsc_ircc_pnp_table[] = { |
| 368 | { .id = "SMCf010", .driver_data = 0 }, | 371 | { .id = "SMCf010", .driver_data = 0 }, |
| @@ -370,7 +373,35 @@ static const struct pnp_device_id smsc_ircc_pnp_table[] = { | |||
| 370 | { } | 373 | { } |
| 371 | }; | 374 | }; |
| 372 | MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); | 375 | MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); |
| 373 | #endif | 376 | |
| 377 | static int pnp_driver_registered; | ||
| 378 | |||
| 379 | static int __init smsc_ircc_pnp_probe(struct pnp_dev *dev, | ||
| 380 | const struct pnp_device_id *dev_id) | ||
| 381 | { | ||
| 382 | unsigned int firbase, sirbase; | ||
| 383 | u8 dma, irq; | ||
| 384 | |||
| 385 | if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && | ||
| 386 | pnp_dma_valid(dev, 0) && pnp_irq_valid(dev, 0))) | ||
| 387 | return -EINVAL; | ||
| 388 | |||
| 389 | sirbase = pnp_port_start(dev, 0); | ||
| 390 | firbase = pnp_port_start(dev, 1); | ||
| 391 | dma = pnp_dma(dev, 0); | ||
| 392 | irq = pnp_irq(dev, 0); | ||
| 393 | |||
| 394 | if (smsc_ircc_open(firbase, sirbase, dma, irq)) | ||
| 395 | return -ENODEV; | ||
| 396 | |||
| 397 | return 0; | ||
| 398 | } | ||
| 399 | |||
| 400 | static struct pnp_driver smsc_ircc_pnp_driver = { | ||
| 401 | .name = "smsc-ircc2", | ||
| 402 | .id_table = smsc_ircc_pnp_table, | ||
| 403 | .probe = smsc_ircc_pnp_probe, | ||
| 404 | }; | ||
| 374 | 405 | ||
| 375 | 406 | ||
| 376 | /******************************************************************************* | 407 | /******************************************************************************* |
| @@ -381,6 +412,35 @@ MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); | |||
| 381 | * | 412 | * |
| 382 | *******************************************************************************/ | 413 | *******************************************************************************/ |
| 383 | 414 | ||
| 415 | static int __init smsc_ircc_legacy_probe(void) | ||
| 416 | { | ||
| 417 | int ret = 0; | ||
| 418 | |||
| 419 | if (ircc_fir > 0 && ircc_sir > 0) { | ||
| 420 | IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir); | ||
| 421 | IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir); | ||
| 422 | |||
| 423 | if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq)) | ||
| 424 | ret = -ENODEV; | ||
| 425 | } else { | ||
| 426 | ret = -ENODEV; | ||
| 427 | |||
| 428 | /* try user provided configuration register base address */ | ||
| 429 | if (ircc_cfg > 0) { | ||
| 430 | IRDA_MESSAGE(" Overriding configuration address " | ||
| 431 | "0x%04x\n", ircc_cfg); | ||
| 432 | if (!smsc_superio_fdc(ircc_cfg)) | ||
| 433 | ret = 0; | ||
| 434 | if (!smsc_superio_lpc(ircc_cfg)) | ||
| 435 | ret = 0; | ||
| 436 | } | ||
| 437 | |||
| 438 | if (smsc_ircc_look_for_chips() > 0) | ||
| 439 | ret = 0; | ||
| 440 | } | ||
| 441 | return ret; | ||
| 442 | } | ||
| 443 | |||
| 384 | /* | 444 | /* |
| 385 | * Function smsc_ircc_init () | 445 | * Function smsc_ircc_init () |
| 386 | * | 446 | * |
| @@ -408,31 +468,20 @@ static int __init smsc_ircc_init(void) | |||
| 408 | 468 | ||
| 409 | dev_count = 0; | 469 | dev_count = 0; |
| 410 | 470 | ||
| 411 | if (ircc_fir > 0 && ircc_sir > 0) { | 471 | if (smsc_nopnp || !pnp_platform_devices || |
| 412 | IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir); | 472 | ircc_cfg || ircc_fir || ircc_sir || |
| 413 | IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir); | 473 | ircc_dma != DMA_INVAL || ircc_irq != IRQ_INVAL) { |
| 414 | 474 | ret = smsc_ircc_legacy_probe(); | |
| 415 | if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq)) | ||
| 416 | ret = -ENODEV; | ||
| 417 | } else { | 475 | } else { |
| 418 | ret = -ENODEV; | 476 | if (pnp_register_driver(&smsc_ircc_pnp_driver) == 0) |
| 419 | 477 | pnp_driver_registered = 1; | |
| 420 | /* try user provided configuration register base address */ | ||
| 421 | if (ircc_cfg > 0) { | ||
| 422 | IRDA_MESSAGE(" Overriding configuration address " | ||
| 423 | "0x%04x\n", ircc_cfg); | ||
| 424 | if (!smsc_superio_fdc(ircc_cfg)) | ||
| 425 | ret = 0; | ||
| 426 | if (!smsc_superio_lpc(ircc_cfg)) | ||
| 427 | ret = 0; | ||
| 428 | } | ||
| 429 | |||
| 430 | if (smsc_ircc_look_for_chips() > 0) | ||
| 431 | ret = 0; | ||
| 432 | } | 478 | } |
| 433 | 479 | ||
| 434 | if (ret) | 480 | if (ret) { |
| 481 | if (pnp_driver_registered) | ||
| 482 | pnp_unregister_driver(&smsc_ircc_pnp_driver); | ||
| 435 | platform_driver_unregister(&smsc_ircc_driver); | 483 | platform_driver_unregister(&smsc_ircc_driver); |
| 484 | } | ||
| 436 | 485 | ||
| 437 | return ret; | 486 | return ret; |
| 438 | } | 487 | } |
| @@ -1842,6 +1891,9 @@ static void __exit smsc_ircc_cleanup(void) | |||
| 1842 | smsc_ircc_close(dev_self[i]); | 1891 | smsc_ircc_close(dev_self[i]); |
| 1843 | } | 1892 | } |
| 1844 | 1893 | ||
| 1894 | if (pnp_driver_registered) | ||
| 1895 | pnp_unregister_driver(&smsc_ircc_pnp_driver); | ||
| 1896 | |||
| 1845 | platform_driver_unregister(&smsc_ircc_driver); | 1897 | platform_driver_unregister(&smsc_ircc_driver); |
| 1846 | } | 1898 | } |
| 1847 | 1899 | ||
