aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/irda/smsc-ircc2.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor_core@ameritech.net>2005-10-30 18:00:14 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-30 20:37:17 -0500
commite812cb5226af32aec91bcbaa8365bd7f921b6ebb (patch)
treeadb7ccb2a766f92dcb354dd20834ce3c023c04b9 /drivers/net/irda/smsc-ircc2.c
parent17fd47ab4d33e764216b87006d8118fa050b4c92 (diff)
[PATCH] smsc-ircc2: PM cleanup - do not close device when suspending
smsc-ircc2 - avoid closing network device when suspending; just release interrupt and disable DMA ourselves. Also make sure to reset chip when resuming. Signed-off-by: Dmitry Torokhov <dtor@mail.ru> Cc: Jean Tourrilhes <jt@bougret.hpl.hp.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/net/irda/smsc-ircc2.c')
-rw-r--r--drivers/net/irda/smsc-ircc2.c129
1 files changed, 85 insertions, 44 deletions
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index bbac720cca63..140b7cdb1f7e 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -638,21 +638,14 @@ static void smsc_ircc_setup_qos(struct smsc_ircc_cb *self)
638 */ 638 */
639static void smsc_ircc_init_chip(struct smsc_ircc_cb *self) 639static void smsc_ircc_init_chip(struct smsc_ircc_cb *self)
640{ 640{
641 int iobase, ir_mode, ctrl, fast; 641 int iobase = self->io.fir_base;
642
643 IRDA_ASSERT(self != NULL, return;);
644
645 iobase = self->io.fir_base;
646 ir_mode = IRCC_CFGA_IRDA_SIR_A;
647 ctrl = 0;
648 fast = 0;
649 642
650 register_bank(iobase, 0); 643 register_bank(iobase, 0);
651 outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER); 644 outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
652 outb(0x00, iobase + IRCC_MASTER); 645 outb(0x00, iobase + IRCC_MASTER);
653 646
654 register_bank(iobase, 1); 647 register_bank(iobase, 1);
655 outb(((inb(iobase + IRCC_SCE_CFGA) & 0x87) | ir_mode), 648 outb(((inb(iobase + IRCC_SCE_CFGA) & 0x87) | IRCC_CFGA_IRDA_SIR_A),
656 iobase + IRCC_SCE_CFGA); 649 iobase + IRCC_SCE_CFGA);
657 650
658#ifdef smsc_669 /* Uses pin 88/89 for Rx/Tx */ 651#ifdef smsc_669 /* Uses pin 88/89 for Rx/Tx */
@@ -666,10 +659,10 @@ static void smsc_ircc_init_chip(struct smsc_ircc_cb *self)
666 outb(SMSC_IRCC2_FIFO_THRESHOLD, iobase + IRCC_FIFO_THRESHOLD); 659 outb(SMSC_IRCC2_FIFO_THRESHOLD, iobase + IRCC_FIFO_THRESHOLD);
667 660
668 register_bank(iobase, 4); 661 register_bank(iobase, 4);
669 outb((inb(iobase + IRCC_CONTROL) & 0x30) | ctrl, iobase + IRCC_CONTROL); 662 outb((inb(iobase + IRCC_CONTROL) & 0x30), iobase + IRCC_CONTROL);
670 663
671 register_bank(iobase, 0); 664 register_bank(iobase, 0);
672 outb(fast, iobase + IRCC_LCR_A); 665 outb(0, iobase + IRCC_LCR_A);
673 666
674 smsc_ircc_set_sir_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED); 667 smsc_ircc_set_sir_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
675 668
@@ -1556,6 +1549,46 @@ static int ircc_is_receiving(struct smsc_ircc_cb *self)
1556} 1549}
1557#endif /* unused */ 1550#endif /* unused */
1558 1551
1552static int smsc_ircc_request_irq(struct smsc_ircc_cb *self)
1553{
1554 int error;
1555
1556 error = request_irq(self->io.irq, smsc_ircc_interrupt, 0,
1557 self->netdev->name, self->netdev);
1558 if (error)
1559 IRDA_DEBUG(0, "%s(), unable to allocate irq=%d, err=%d\n",
1560 __FUNCTION__, self->io.irq, error);
1561
1562 return error;
1563}
1564
1565static void smsc_ircc_start_interrupts(struct smsc_ircc_cb *self)
1566{
1567 unsigned long flags;
1568
1569 spin_lock_irqsave(&self->lock, flags);
1570
1571 self->io.speed = 0;
1572 smsc_ircc_change_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
1573
1574 spin_unlock_irqrestore(&self->lock, flags);
1575}
1576
1577static void smsc_ircc_stop_interrupts(struct smsc_ircc_cb *self)
1578{
1579 int iobase = self->io.fir_base;
1580 unsigned long flags;
1581
1582 spin_lock_irqsave(&self->lock, flags);
1583
1584 register_bank(iobase, 0);
1585 outb(0, iobase + IRCC_IER);
1586 outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
1587 outb(0x00, iobase + IRCC_MASTER);
1588
1589 spin_unlock_irqrestore(&self->lock, flags);
1590}
1591
1559 1592
1560/* 1593/*
1561 * Function smsc_ircc_net_open (dev) 1594 * Function smsc_ircc_net_open (dev)
@@ -1567,7 +1600,6 @@ static int smsc_ircc_net_open(struct net_device *dev)
1567{ 1600{
1568 struct smsc_ircc_cb *self; 1601 struct smsc_ircc_cb *self;
1569 char hwname[16]; 1602 char hwname[16];
1570 unsigned long flags;
1571 1603
1572 IRDA_DEBUG(1, "%s\n", __FUNCTION__); 1604 IRDA_DEBUG(1, "%s\n", __FUNCTION__);
1573 1605
@@ -1575,6 +1607,11 @@ static int smsc_ircc_net_open(struct net_device *dev)
1575 self = netdev_priv(dev); 1607 self = netdev_priv(dev);
1576 IRDA_ASSERT(self != NULL, return 0;); 1608 IRDA_ASSERT(self != NULL, return 0;);
1577 1609
1610 if (self->io.suspended) {
1611 IRDA_DEBUG(0, "%s(), device is suspended\n", __FUNCTION__);
1612 return -EAGAIN;
1613 }
1614
1578 if (request_irq(self->io.irq, smsc_ircc_interrupt, 0, dev->name, 1615 if (request_irq(self->io.irq, smsc_ircc_interrupt, 0, dev->name,
1579 (void *) dev)) { 1616 (void *) dev)) {
1580 IRDA_DEBUG(0, "%s(), unable to allocate irq=%d\n", 1617 IRDA_DEBUG(0, "%s(), unable to allocate irq=%d\n",
@@ -1582,11 +1619,7 @@ static int smsc_ircc_net_open(struct net_device *dev)
1582 return -EAGAIN; 1619 return -EAGAIN;
1583 } 1620 }
1584 1621
1585 spin_lock_irqsave(&self->lock, flags); 1622 smsc_ircc_start_interrupts(self);
1586 /*smsc_ircc_sir_start(self);*/
1587 self->io.speed = 0;
1588 smsc_ircc_change_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
1589 spin_unlock_irqrestore(&self->lock, flags);
1590 1623
1591 /* Give self a hardware name */ 1624 /* Give self a hardware name */
1592 /* It would be cool to offer the chip revision here - Jean II */ 1625 /* It would be cool to offer the chip revision here - Jean II */
@@ -1639,7 +1672,12 @@ static int smsc_ircc_net_close(struct net_device *dev)
1639 irlap_close(self->irlap); 1672 irlap_close(self->irlap);
1640 self->irlap = NULL; 1673 self->irlap = NULL;
1641 1674
1642 free_irq(self->io.irq, dev); 1675 smsc_ircc_stop_interrupts(self);
1676
1677 /* if we are called from smsc_ircc_resume we don't have IRQ reserved */
1678 if (!self->io.suspended)
1679 free_irq(self->io.irq, dev);
1680
1643 disable_dma(self->io.dma); 1681 disable_dma(self->io.dma);
1644 free_dma(self->io.dma); 1682 free_dma(self->io.dma);
1645 1683
@@ -1650,11 +1688,18 @@ static int smsc_ircc_suspend(struct device *dev, pm_message_t state)
1650{ 1688{
1651 struct smsc_ircc_cb *self = dev_get_drvdata(dev); 1689 struct smsc_ircc_cb *self = dev_get_drvdata(dev);
1652 1690
1653 IRDA_MESSAGE("%s, Suspending\n", driver_name);
1654
1655 if (!self->io.suspended) { 1691 if (!self->io.suspended) {
1656 smsc_ircc_net_close(self->netdev); 1692 IRDA_DEBUG(1, "%s, Suspending\n", driver_name);
1693
1694 rtnl_lock();
1695 if (netif_running(self->netdev)) {
1696 netif_device_detach(self->netdev);
1697 smsc_ircc_stop_interrupts(self);
1698 free_irq(self->io.irq, self->netdev);
1699 disable_dma(self->io.dma);
1700 }
1657 self->io.suspended = 1; 1701 self->io.suspended = 1;
1702 rtnl_unlock();
1658 } 1703 }
1659 1704
1660 return 0; 1705 return 0;
@@ -1665,11 +1710,25 @@ static int smsc_ircc_resume(struct device *dev)
1665 struct smsc_ircc_cb *self = dev_get_drvdata(dev); 1710 struct smsc_ircc_cb *self = dev_get_drvdata(dev);
1666 1711
1667 if (self->io.suspended) { 1712 if (self->io.suspended) {
1668 1713 IRDA_DEBUG(1, "%s, Waking up\n", driver_name);
1669 smsc_ircc_net_open(self->netdev); 1714
1715 rtnl_lock();
1716 smsc_ircc_init_chip(self);
1717 if (netif_running(self->netdev)) {
1718 if (smsc_ircc_request_irq(self)) {
1719 /*
1720 * Don't fail resume process, just kill this
1721 * network interface
1722 */
1723 unregister_netdevice(self->netdev);
1724 } else {
1725 enable_dma(self->io.dma);
1726 smsc_ircc_start_interrupts(self);
1727 netif_device_attach(self->netdev);
1728 }
1729 }
1670 self->io.suspended = 0; 1730 self->io.suspended = 0;
1671 1731 rtnl_unlock();
1672 IRDA_MESSAGE("%s, Waking up\n", driver_name);
1673 } 1732 }
1674 return 0; 1733 return 0;
1675} 1734}
@@ -1682,9 +1741,6 @@ static int smsc_ircc_resume(struct device *dev)
1682 */ 1741 */
1683static int __exit smsc_ircc_close(struct smsc_ircc_cb *self) 1742static int __exit smsc_ircc_close(struct smsc_ircc_cb *self)
1684{ 1743{
1685 int iobase;
1686 unsigned long flags;
1687
1688 IRDA_DEBUG(1, "%s\n", __FUNCTION__); 1744 IRDA_DEBUG(1, "%s\n", __FUNCTION__);
1689 1745
1690 IRDA_ASSERT(self != NULL, return -1;); 1746 IRDA_ASSERT(self != NULL, return -1;);
@@ -1694,22 +1750,7 @@ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self)
1694 /* Remove netdevice */ 1750 /* Remove netdevice */
1695 unregister_netdev(self->netdev); 1751 unregister_netdev(self->netdev);
1696 1752
1697 /* Make sure the irq handler is not exectuting */ 1753 smsc_ircc_stop_interrupts(self);
1698 spin_lock_irqsave(&self->lock, flags);
1699
1700 /* Stop interrupts */
1701 iobase = self->io.fir_base;
1702 register_bank(iobase, 0);
1703 outb(0, iobase + IRCC_IER);
1704 outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
1705 outb(0x00, iobase + IRCC_MASTER);
1706#if 0
1707 /* Reset to SIR mode */
1708 register_bank(iobase, 1);
1709 outb(IRCC_CFGA_IRDA_SIR_A|IRCC_CFGA_TX_POLARITY, iobase + IRCC_SCE_CFGA);
1710 outb(IRCC_CFGB_IR, iobase + IRCC_SCE_CFGB);
1711#endif
1712 spin_unlock_irqrestore(&self->lock, flags);
1713 1754
1714 /* Release the PORTS that this driver is using */ 1755 /* Release the PORTS that this driver is using */
1715 IRDA_DEBUG(0, "%s(), releasing 0x%03x\n", __FUNCTION__, 1756 IRDA_DEBUG(0, "%s(), releasing 0x%03x\n", __FUNCTION__,