From: Dmitry Torokhov IRDA: smsc-ircc2 - avoid closing device and releasing DMA/interrupt when suspending - they may not be available any more at resume time. Signed-off-by: Dmitry Torokhov Cc: Jean Tourrilhes Signed-off-by: Andrew Morton --- drivers/net/irda/smsc-ircc2.c | 35 +++++++++++++++++++++++++++++------ 1 files changed, 29 insertions(+), 6 deletions(-) diff -puN drivers/net/irda/smsc-ircc2.c~smsc-ircc2-pm-cleanup-do-not-close-device-when-suspending drivers/net/irda/smsc-ircc2.c --- 25/drivers/net/irda/smsc-ircc2.c~smsc-ircc2-pm-cleanup-do-not-close-device-when-suspending 2005-06-24 23:45:21.000000000 -0700 +++ 25-akpm/drivers/net/irda/smsc-ircc2.c 2005-06-24 23:45:21.000000000 -0700 @@ -1579,6 +1579,11 @@ static int smsc_ircc_net_open(struct net self = (struct smsc_ircc_cb *) dev->priv; IRDA_ASSERT(self != NULL, return 0;); + if (self->io.suspended) { + IRDA_DEBUG(0, "%s(), device is suspended\n", __FUNCTION__); + return -EAGAIN; + } + if (request_irq(self->io.irq, smsc_ircc_interrupt, 0, dev->name, (void *) dev)) { IRDA_DEBUG(0, "%s(), unable to allocate irq=%d\n", @@ -1654,11 +1659,17 @@ static int smsc_ircc_suspend(struct devi { struct smsc_ircc_cb *self = dev_get_drvdata(dev); - IRDA_MESSAGE("%s, Suspending\n", driver_name); - if (level == SUSPEND_DISABLE && !self->io.suspended) { - smsc_ircc_net_close(self->netdev); + IRDA_DEBUG("%s, Suspending\n", driver_name); + + rtnl_lock(); + if (netif_running(self->netdev)) { + netif_device_detach(self->netdev); + disable_irq(self->io.irq); + disable_dma(self->io.dma); + } self->io.suspended = 1; + rtnl_unlock(); } return 0; @@ -1667,13 +1678,25 @@ static int smsc_ircc_suspend(struct devi static int smsc_ircc_resume(struct device *dev, u32 level) { struct smsc_ircc_cb *self = dev_get_drvdata(dev); + unsigned long flags; if (level == RESUME_ENABLE && self->io.suspended) { + IRDA_DEBUG("%s, Waking up\n", driver_name); - smsc_ircc_net_open(self->netdev); + rtnl_lock(); + if (netif_running(self->netdev)) { + spin_lock_irqsave(&self->lock, flags); + self->io.speed = 0; + smsc_ircc_change_speed(self, + SMSC_IRCC2_C_IRDA_FALLBACK_SPEED); + spin_unlock_irqrestore(&self->lock, flags); + + enable_dma(self->io.dma); + enable_irq(self->io.irq); + netif_device_attach(self->netdev); + } self->io.suspended = 0; - - IRDA_MESSAGE("%s, Waking up\n", driver_name); + rtnl_unlock(); } return 0; } _