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 | ||