aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/irda
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/irda')
-rw-r--r--drivers/net/irda/smsc-ircc2.c98
1 files changed, 75 insertions, 23 deletions
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>");
79MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver"); 79MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver");
80MODULE_LICENSE("GPL"); 80MODULE_LICENSE("GPL");
81 81
82static int smsc_nopnp;
83module_param_named(nopnp, smsc_nopnp, bool, 0);
84MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings");
85
82#define DMA_INVAL 255 86#define DMA_INVAL 255
83static int ircc_dma = DMA_INVAL; 87static int ircc_dma = DMA_INVAL;
84module_param(ircc_dma, int, 0); 88module_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 */
367static const struct pnp_device_id smsc_ircc_pnp_table[] = { 370static 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};
372MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); 375MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table);
373#endif 376
377static int pnp_driver_registered;
378
379static 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
400static 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
415static 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