aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/irda/smsc-ircc2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/irda/smsc-ircc2.c')
-rw-r--r--drivers/net/irda/smsc-ircc2.c112
1 files changed, 83 insertions, 29 deletions
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 198bf3bfa70f..9043bf4aa49e 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -79,11 +79,17 @@ 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 ircc_dma = 255; 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
86#define DMA_INVAL 255
87static int ircc_dma = DMA_INVAL;
83module_param(ircc_dma, int, 0); 88module_param(ircc_dma, int, 0);
84MODULE_PARM_DESC(ircc_dma, "DMA channel"); 89MODULE_PARM_DESC(ircc_dma, "DMA channel");
85 90
86static int ircc_irq = 255; 91#define IRQ_INVAL 255
92static int ircc_irq = IRQ_INVAL;
87module_param(ircc_irq, int, 0); 93module_param(ircc_irq, int, 0);
88MODULE_PARM_DESC(ircc_irq, "IRQ line"); 94MODULE_PARM_DESC(ircc_irq, "IRQ line");
89 95
@@ -360,7 +366,6 @@ static inline void register_bank(int iobase, int bank)
360 iobase + IRCC_MASTER); 366 iobase + IRCC_MASTER);
361} 367}
362 368
363#ifdef CONFIG_PNP
364/* PNP hotplug support */ 369/* PNP hotplug support */
365static const struct pnp_device_id smsc_ircc_pnp_table[] = { 370static const struct pnp_device_id smsc_ircc_pnp_table[] = {
366 { .id = "SMCf010", .driver_data = 0 }, 371 { .id = "SMCf010", .driver_data = 0 },
@@ -368,7 +373,35 @@ static const struct pnp_device_id smsc_ircc_pnp_table[] = {
368 { } 373 { }
369}; 374};
370MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); 375MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table);
371#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};
372 405
373 406
374/******************************************************************************* 407/*******************************************************************************
@@ -379,6 +412,35 @@ MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table);
379 * 412 *
380 *******************************************************************************/ 413 *******************************************************************************/
381 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
382/* 444/*
383 * Function smsc_ircc_init () 445 * Function smsc_ircc_init ()
384 * 446 *
@@ -406,31 +468,20 @@ static int __init smsc_ircc_init(void)
406 468
407 dev_count = 0; 469 dev_count = 0;
408 470
409 if (ircc_fir > 0 && ircc_sir > 0) { 471 if (smsc_nopnp || !pnp_platform_devices ||
410 IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir); 472 ircc_cfg || ircc_fir || ircc_sir ||
411 IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir); 473 ircc_dma != DMA_INVAL || ircc_irq != IRQ_INVAL) {
412 474 ret = smsc_ircc_legacy_probe();
413 if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq))
414 ret = -ENODEV;
415 } else { 475 } else {
416 ret = -ENODEV; 476 if (pnp_register_driver(&smsc_ircc_pnp_driver) == 0)
417 477 pnp_driver_registered = 1;
418 /* try user provided configuration register base address */
419 if (ircc_cfg > 0) {
420 IRDA_MESSAGE(" Overriding configuration address "
421 "0x%04x\n", ircc_cfg);
422 if (!smsc_superio_fdc(ircc_cfg))
423 ret = 0;
424 if (!smsc_superio_lpc(ircc_cfg))
425 ret = 0;
426 }
427
428 if (smsc_ircc_look_for_chips() > 0)
429 ret = 0;
430 } 478 }
431 479
432 if (ret) 480 if (ret) {
481 if (pnp_driver_registered)
482 pnp_unregister_driver(&smsc_ircc_pnp_driver);
433 platform_driver_unregister(&smsc_ircc_driver); 483 platform_driver_unregister(&smsc_ircc_driver);
484 }
434 485
435 return ret; 486 return ret;
436} 487}
@@ -646,7 +697,7 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self,
646 self->io.fifo_size = SMSC_IRCC2_FIFO_SIZE; 697 self->io.fifo_size = SMSC_IRCC2_FIFO_SIZE;
647 self->io.speed = SMSC_IRCC2_C_IRDA_FALLBACK_SPEED; 698 self->io.speed = SMSC_IRCC2_C_IRDA_FALLBACK_SPEED;
648 699
649 if (irq < 255) { 700 if (irq != IRQ_INVAL) {
650 if (irq != chip_irq) 701 if (irq != chip_irq)
651 IRDA_MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n", 702 IRDA_MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n",
652 driver_name, chip_irq, irq); 703 driver_name, chip_irq, irq);
@@ -654,7 +705,7 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self,
654 } else 705 } else
655 self->io.irq = chip_irq; 706 self->io.irq = chip_irq;
656 707
657 if (dma < 255) { 708 if (dma != DMA_INVAL) {
658 if (dma != chip_dma) 709 if (dma != chip_dma)
659 IRDA_MESSAGE("%s, Overriding DMA - chip says %d, using %d\n", 710 IRDA_MESSAGE("%s, Overriding DMA - chip says %d, using %d\n",
660 driver_name, chip_dma, dma); 711 driver_name, chip_dma, dma);
@@ -1840,6 +1891,9 @@ static void __exit smsc_ircc_cleanup(void)
1840 smsc_ircc_close(dev_self[i]); 1891 smsc_ircc_close(dev_self[i]);
1841 } 1892 }
1842 1893
1894 if (pnp_driver_registered)
1895 pnp_unregister_driver(&smsc_ircc_pnp_driver);
1896
1843 platform_driver_unregister(&smsc_ircc_driver); 1897 platform_driver_unregister(&smsc_ircc_driver);
1844} 1898}
1845 1899
@@ -2836,9 +2890,9 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
2836 tmpconf.fir_io = ircc_fir; 2890 tmpconf.fir_io = ircc_fir;
2837 if (ircc_sir != 0) 2891 if (ircc_sir != 0)
2838 tmpconf.sir_io = ircc_sir; 2892 tmpconf.sir_io = ircc_sir;
2839 if (ircc_dma != 0xff) 2893 if (ircc_dma != DMA_INVAL)
2840 tmpconf.fir_dma = ircc_dma; 2894 tmpconf.fir_dma = ircc_dma;
2841 if (ircc_irq != 0xff) 2895 if (ircc_irq != IRQ_INVAL)
2842 tmpconf.fir_irq = ircc_irq; 2896 tmpconf.fir_irq = ircc_irq;
2843 2897
2844 IRDA_MESSAGE("Detected unconfigured %s SMSC IrDA chip, pre-configuring device.\n", conf->name); 2898 IRDA_MESSAGE("Detected unconfigured %s SMSC IrDA chip, pre-configuring device.\n", conf->name);