Hi!

For some reason, the IrDA port on my laptop (Sony Vaio Z600NE) stopped
working after a suspend/resume cycle on 2.4. It works fine with
2.2.19pre6, even though I can't see any significant differences in the
driver versions (but maybe it just has to do with the change_speed
changes, that seems possible).

I found that I don't get RX interrupts anymore after resume, TX interrupts
work fine.

I tracked it down to the fact that I need to insert the following fragment
into nsc_ircc_wakeup to make it work after resume.

        /* Set FIFO threshold to TX17, RX16, reset and enable FIFO's */
        switch_bank(iobase, BANK0);
        outb(FCR_RXTH|FCR_TXTH|FCR_TXSR|FCR_RXSR|FCR_FIFO_EN, iobase+FCR);

        outb(0x03, iobase+LCR);         /* 8 bit word length */
        outb(MCR_SIR, iobase+MCR);      /* Start at SIR-mode, also clears
LSR*/

        /* Set FIFO size to 32 */
        switch_bank(iobase, BANK2);
        outb(EXCR2_RFSIZ|EXCR2_TFSIZ, iobase+EXCR2);

However, I think a general solution, i.e. calling nsc_ircc_setup again
after resume is probably the easiest. The following patch fixes the
problem I've seen here, and it fixes another little buglet (free_irq
called with wrong parameter).

--Kai

--- linux-2.4.0-test13-pre4/drivers/net/irda/nsc-ircc.c Tue Nov 28 03:07:31 2000
+++ linux-2.4.0.work/drivers/net/irda/nsc-ircc.c        Fri Jan  5 17:27:16 2001
@@ -251,9 +251,14 @@

        IRDA_DEBUG(2, __FUNCTION__ "()\n");

+       MESSAGE("%s, Found chip at base=0x%03x\n", driver_name,
+               info->cfg_base);
+
        if ((nsc_ircc_setup(info)) == -1)
                return -1;

+       MESSAGE("%s, driver loaded (Dag Brattli)\n", driver_name);
+
        /* Allocate new instance of the driver */
        self = kmalloc(sizeof(struct nsc_ircc_cb), GFP_KERNEL);
        if (self == NULL) {
@@ -699,8 +704,6 @@
                ERROR("%s, Wrong chip version %02x\n", driver_name, version);
                return -1;
        }
-       MESSAGE("%s, Found chip at base=0x%03x\n", driver_name,
-               info->cfg_base);

        /* Switch to advanced mode */
        switch_bank(iobase, BANK2);
@@ -729,8 +732,6 @@
        outb(0x0d, iobase+2); /* Set SIR pulse width to 1.6us */
        outb(0x2a, iobase+4); /* Set beginning frag, and preamble length */

-       MESSAGE("%s, driver loaded (Dag Brattli)\n", driver_name);
-
        /* Enable receive interrupts */
        switch_bank(iobase, BANK0);
        outb(IER_RXHDL_IE, iobase+IER);
@@ -1854,7 +1855,7 @@
        if (request_dma(self->io.dma, dev->name)) {
                WARNING("%s, unable to allocate dma=%d\n", driver_name,
                        self->io.dma);
-               free_irq(self->io.irq, self);
+               free_irq(self->io.irq, dev);
                return -EAGAIN;
        }

@@ -2001,18 +2002,10 @@

 static void nsc_ircc_wakeup(struct nsc_ircc_cb *self)
 {
-       int iobase;
-
        if (!self->io.suspended)
                return;

-       iobase = self->io.fir_base;
-
-       /* Switch to advanced mode */
-       switch_bank(iobase, BANK2);
-       outb(ECR1_EXT_SL, iobase+ECR1);
-       switch_bank(iobase, BANK0);
-
+       nsc_ircc_setup(&self->io);
        nsc_ircc_net_open(self->netdev);

        MESSAGE("%s, Waking up\n", driver_name);

_______________________________________________
Linux-IrDA mailing list  -  [EMAIL PROTECTED]
http://www.pasta.cs.UiT.No/mailman/listinfo/linux-irda

Reply via email to