From: Bjorn Helgaas Claim devices using PNP, unless the user explicitly specified device addresses. This can be disabled with the "smsc-ircc2.nopnp" option. This removes the need for probing legacy addresses and helps untangle IR devices from serial8250 devices. Sometimes the SMC device is at a legacy COM port address but does not use the legacy COM IRQ. In this case, claiming the device using PNP rather than 8250 legacy probe means we can automatically use the correct IRQ rather than forcing the user to use "setserial" to set the IRQ manually. If the PNP claim doesn't work, make sure you don't have a setserial init script, e.g., /etc/init.d/setserial, configured to poke in legacy COM port resources for the IRDA device. That causes the serial driver to claim resources needed by this driver. Based on this patch by Ville Syrjälä: http://www.hpl.hp.com/personal/Jean_Tourrilhes/IrDA/ir260_smsc_pnp.diff Signed-off-by: Bjorn Helgaas Cc: Keith Owens Cc: Len Brown Cc: Adam Belay Cc: Matthieu CASTET Cc: Jean Tourrilhes Cc: Matthew Garrett Cc: Ville Syrjala Cc: Russell King Acked-by: Samuel Ortiz Signed-off-by: Andrew Morton --- Documentation/kernel-parameters.txt | 11 ++ drivers/net/irda/smsc-ircc2.c | 98 +++++++++++++++++++------- 2 files changed, 86 insertions(+), 23 deletions(-) diff -puN Documentation/kernel-parameters.txt~smsc-ircc2-add-pnp-support Documentation/kernel-parameters.txt --- a/Documentation/kernel-parameters.txt~smsc-ircc2-add-pnp-support +++ a/Documentation/kernel-parameters.txt @@ -1584,6 +1584,17 @@ and is between 256 and 4096 characters. smp-alt-once [X86-32,SMP] On a hotplug CPU system, only attempt to substitute SMP alternatives once at boot. + smsc-ircc2.nopnp [HW] Don't use PNP to discover SMC devices + smsc-ircc2.ircc_cfg= [HW] Device configuration I/O port + smsc-ircc2.ircc_sir= [HW] SIR base I/O port + smsc-ircc2.ircc_fir= [HW] FIR base I/O port + smsc-ircc2.ircc_irq= [HW] IRQ line + smsc-ircc2.ircc_dma= [HW] DMA channel + smsc-ircc2.ircc_transceiver= [HW] Transceiver type: + 0: Toshiba Satellite 1800 (GP data pin select) + 1: Fast pin select (default) + 2: ATC IRMode + snd-ad1816a= [HW,ALSA] snd-ad1848= [HW,ALSA] diff -puN drivers/net/irda/smsc-ircc2.c~smsc-ircc2-add-pnp-support drivers/net/irda/smsc-ircc2.c --- a/drivers/net/irda/smsc-ircc2.c~smsc-ircc2-add-pnp-support +++ a/drivers/net/irda/smsc-ircc2.c @@ -79,6 +79,10 @@ MODULE_AUTHOR("Daniele Peri 0 && ircc_sir > 0) { + IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir); + IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir); + + if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq)) + ret = -ENODEV; + } else { + ret = -ENODEV; + + /* try user provided configuration register base address */ + if (ircc_cfg > 0) { + IRDA_MESSAGE(" Overriding configuration address " + "0x%04x\n", ircc_cfg); + if (!smsc_superio_fdc(ircc_cfg)) + ret = 0; + if (!smsc_superio_lpc(ircc_cfg)) + ret = 0; + } + + if (smsc_ircc_look_for_chips() > 0) + ret = 0; + } + return ret; +} + /* * Function smsc_ircc_init () * @@ -408,31 +468,20 @@ static int __init smsc_ircc_init(void) dev_count = 0; - if (ircc_fir > 0 && ircc_sir > 0) { - IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir); - IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir); - - if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq)) - ret = -ENODEV; + if (smsc_nopnp || !pnp_platform_devices || + ircc_cfg || ircc_fir || ircc_sir || + ircc_dma != DMA_INVAL || ircc_irq != IRQ_INVAL) { + ret = smsc_ircc_legacy_probe(); } else { - ret = -ENODEV; - - /* try user provided configuration register base address */ - if (ircc_cfg > 0) { - IRDA_MESSAGE(" Overriding configuration address " - "0x%04x\n", ircc_cfg); - if (!smsc_superio_fdc(ircc_cfg)) - ret = 0; - if (!smsc_superio_lpc(ircc_cfg)) - ret = 0; - } - - if (smsc_ircc_look_for_chips() > 0) - ret = 0; + if (pnp_register_driver(&smsc_ircc_pnp_driver) == 0) + pnp_driver_registered = 1; } - if (ret) + if (ret) { + if (pnp_driver_registered) + pnp_unregister_driver(&smsc_ircc_pnp_driver); platform_driver_unregister(&smsc_ircc_driver); + } return ret; } @@ -1842,6 +1891,9 @@ static void __exit smsc_ircc_cleanup(voi smsc_ircc_close(dev_self[i]); } + if (pnp_driver_registered) + pnp_unregister_driver(&smsc_ircc_pnp_driver); + platform_driver_unregister(&smsc_ircc_driver); } _