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.c140
1 files changed, 91 insertions, 49 deletions
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index dd89bda1f131..a1d207f2fa68 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -53,6 +53,7 @@
53#include <linux/rtnetlink.h> 53#include <linux/rtnetlink.h>
54#include <linux/serial_reg.h> 54#include <linux/serial_reg.h>
55#include <linux/dma-mapping.h> 55#include <linux/dma-mapping.h>
56#include <linux/platform_device.h>
56 57
57#include <asm/io.h> 58#include <asm/io.h>
58#include <asm/dma.h> 59#include <asm/dma.h>
@@ -213,8 +214,8 @@ static int smsc_ircc_probe_transceiver_smsc_ircc_atc(int fir_base);
213 214
214/* Power Management */ 215/* Power Management */
215 216
216static int smsc_ircc_suspend(struct device *dev, pm_message_t state, u32 level); 217static int smsc_ircc_suspend(struct device *dev, pm_message_t state);
217static int smsc_ircc_resume(struct device *dev, u32 level); 218static int smsc_ircc_resume(struct device *dev);
218 219
219static struct device_driver smsc_ircc_driver = { 220static struct device_driver smsc_ircc_driver = {
220 .name = SMSC_IRCC2_DRIVER_NAME, 221 .name = SMSC_IRCC2_DRIVER_NAME,
@@ -638,21 +639,14 @@ static void smsc_ircc_setup_qos(struct smsc_ircc_cb *self)
638 */ 639 */
639static void smsc_ircc_init_chip(struct smsc_ircc_cb *self) 640static void smsc_ircc_init_chip(struct smsc_ircc_cb *self)
640{ 641{
641 int iobase, ir_mode, ctrl, fast; 642 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 643
650 register_bank(iobase, 0); 644 register_bank(iobase, 0);
651 outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER); 645 outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
652 outb(0x00, iobase + IRCC_MASTER); 646 outb(0x00, iobase + IRCC_MASTER);
653 647
654 register_bank(iobase, 1); 648 register_bank(iobase, 1);
655 outb(((inb(iobase + IRCC_SCE_CFGA) & 0x87) | ir_mode), 649 outb(((inb(iobase + IRCC_SCE_CFGA) & 0x87) | IRCC_CFGA_IRDA_SIR_A),
656 iobase + IRCC_SCE_CFGA); 650 iobase + IRCC_SCE_CFGA);
657 651
658#ifdef smsc_669 /* Uses pin 88/89 for Rx/Tx */ 652#ifdef smsc_669 /* Uses pin 88/89 for Rx/Tx */
@@ -666,10 +660,10 @@ static void smsc_ircc_init_chip(struct smsc_ircc_cb *self)
666 outb(SMSC_IRCC2_FIFO_THRESHOLD, iobase + IRCC_FIFO_THRESHOLD); 660 outb(SMSC_IRCC2_FIFO_THRESHOLD, iobase + IRCC_FIFO_THRESHOLD);
667 661
668 register_bank(iobase, 4); 662 register_bank(iobase, 4);
669 outb((inb(iobase + IRCC_CONTROL) & 0x30) | ctrl, iobase + IRCC_CONTROL); 663 outb((inb(iobase + IRCC_CONTROL) & 0x30), iobase + IRCC_CONTROL);
670 664
671 register_bank(iobase, 0); 665 register_bank(iobase, 0);
672 outb(fast, iobase + IRCC_LCR_A); 666 outb(0, iobase + IRCC_LCR_A);
673 667
674 smsc_ircc_set_sir_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED); 668 smsc_ircc_set_sir_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
675 669
@@ -1556,6 +1550,46 @@ static int ircc_is_receiving(struct smsc_ircc_cb *self)
1556} 1550}
1557#endif /* unused */ 1551#endif /* unused */
1558 1552
1553static int smsc_ircc_request_irq(struct smsc_ircc_cb *self)
1554{
1555 int error;
1556
1557 error = request_irq(self->io.irq, smsc_ircc_interrupt, 0,
1558 self->netdev->name, self->netdev);
1559 if (error)
1560 IRDA_DEBUG(0, "%s(), unable to allocate irq=%d, err=%d\n",
1561 __FUNCTION__, self->io.irq, error);
1562
1563 return error;
1564}
1565
1566static void smsc_ircc_start_interrupts(struct smsc_ircc_cb *self)
1567{
1568 unsigned long flags;
1569
1570 spin_lock_irqsave(&self->lock, flags);
1571
1572 self->io.speed = 0;
1573 smsc_ircc_change_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
1574
1575 spin_unlock_irqrestore(&self->lock, flags);
1576}
1577
1578static void smsc_ircc_stop_interrupts(struct smsc_ircc_cb *self)
1579{
1580 int iobase = self->io.fir_base;
1581 unsigned long flags;
1582
1583 spin_lock_irqsave(&self->lock, flags);
1584
1585 register_bank(iobase, 0);
1586 outb(0, iobase + IRCC_IER);
1587 outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
1588 outb(0x00, iobase + IRCC_MASTER);
1589
1590 spin_unlock_irqrestore(&self->lock, flags);
1591}
1592
1559 1593
1560/* 1594/*
1561 * Function smsc_ircc_net_open (dev) 1595 * Function smsc_ircc_net_open (dev)
@@ -1567,7 +1601,6 @@ static int smsc_ircc_net_open(struct net_device *dev)
1567{ 1601{
1568 struct smsc_ircc_cb *self; 1602 struct smsc_ircc_cb *self;
1569 char hwname[16]; 1603 char hwname[16];
1570 unsigned long flags;
1571 1604
1572 IRDA_DEBUG(1, "%s\n", __FUNCTION__); 1605 IRDA_DEBUG(1, "%s\n", __FUNCTION__);
1573 1606
@@ -1575,6 +1608,11 @@ static int smsc_ircc_net_open(struct net_device *dev)
1575 self = netdev_priv(dev); 1608 self = netdev_priv(dev);
1576 IRDA_ASSERT(self != NULL, return 0;); 1609 IRDA_ASSERT(self != NULL, return 0;);
1577 1610
1611 if (self->io.suspended) {
1612 IRDA_DEBUG(0, "%s(), device is suspended\n", __FUNCTION__);
1613 return -EAGAIN;
1614 }
1615
1578 if (request_irq(self->io.irq, smsc_ircc_interrupt, 0, dev->name, 1616 if (request_irq(self->io.irq, smsc_ircc_interrupt, 0, dev->name,
1579 (void *) dev)) { 1617 (void *) dev)) {
1580 IRDA_DEBUG(0, "%s(), unable to allocate irq=%d\n", 1618 IRDA_DEBUG(0, "%s(), unable to allocate irq=%d\n",
@@ -1582,11 +1620,7 @@ static int smsc_ircc_net_open(struct net_device *dev)
1582 return -EAGAIN; 1620 return -EAGAIN;
1583 } 1621 }
1584 1622
1585 spin_lock_irqsave(&self->lock, flags); 1623 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 1624
1591 /* Give self a hardware name */ 1625 /* Give self a hardware name */
1592 /* It would be cool to offer the chip revision here - Jean II */ 1626 /* It would be cool to offer the chip revision here - Jean II */
@@ -1639,37 +1673,63 @@ static int smsc_ircc_net_close(struct net_device *dev)
1639 irlap_close(self->irlap); 1673 irlap_close(self->irlap);
1640 self->irlap = NULL; 1674 self->irlap = NULL;
1641 1675
1642 free_irq(self->io.irq, dev); 1676 smsc_ircc_stop_interrupts(self);
1677
1678 /* if we are called from smsc_ircc_resume we don't have IRQ reserved */
1679 if (!self->io.suspended)
1680 free_irq(self->io.irq, dev);
1681
1643 disable_dma(self->io.dma); 1682 disable_dma(self->io.dma);
1644 free_dma(self->io.dma); 1683 free_dma(self->io.dma);
1645 1684
1646 return 0; 1685 return 0;
1647} 1686}
1648 1687
1649static int smsc_ircc_suspend(struct device *dev, pm_message_t state, u32 level) 1688static int smsc_ircc_suspend(struct device *dev, pm_message_t state)
1650{ 1689{
1651 struct smsc_ircc_cb *self = dev_get_drvdata(dev); 1690 struct smsc_ircc_cb *self = dev_get_drvdata(dev);
1652 1691
1653 IRDA_MESSAGE("%s, Suspending\n", driver_name); 1692 if (!self->io.suspended) {
1693 IRDA_DEBUG(1, "%s, Suspending\n", driver_name);
1654 1694
1655 if (level == SUSPEND_DISABLE && !self->io.suspended) { 1695 rtnl_lock();
1656 smsc_ircc_net_close(self->netdev); 1696 if (netif_running(self->netdev)) {
1697 netif_device_detach(self->netdev);
1698 smsc_ircc_stop_interrupts(self);
1699 free_irq(self->io.irq, self->netdev);
1700 disable_dma(self->io.dma);
1701 }
1657 self->io.suspended = 1; 1702 self->io.suspended = 1;
1703 rtnl_unlock();
1658 } 1704 }
1659 1705
1660 return 0; 1706 return 0;
1661} 1707}
1662 1708
1663static int smsc_ircc_resume(struct device *dev, u32 level) 1709static int smsc_ircc_resume(struct device *dev)
1664{ 1710{
1665 struct smsc_ircc_cb *self = dev_get_drvdata(dev); 1711 struct smsc_ircc_cb *self = dev_get_drvdata(dev);
1666 1712
1667 if (level == RESUME_ENABLE && self->io.suspended) { 1713 if (self->io.suspended) {
1668 1714 IRDA_DEBUG(1, "%s, Waking up\n", driver_name);
1669 smsc_ircc_net_open(self->netdev); 1715
1716 rtnl_lock();
1717 smsc_ircc_init_chip(self);
1718 if (netif_running(self->netdev)) {
1719 if (smsc_ircc_request_irq(self)) {
1720 /*
1721 * Don't fail resume process, just kill this
1722 * network interface
1723 */
1724 unregister_netdevice(self->netdev);
1725 } else {
1726 enable_dma(self->io.dma);
1727 smsc_ircc_start_interrupts(self);
1728 netif_device_attach(self->netdev);
1729 }
1730 }
1670 self->io.suspended = 0; 1731 self->io.suspended = 0;
1671 1732 rtnl_unlock();
1672 IRDA_MESSAGE("%s, Waking up\n", driver_name);
1673 } 1733 }
1674 return 0; 1734 return 0;
1675} 1735}
@@ -1682,9 +1742,6 @@ static int smsc_ircc_resume(struct device *dev, u32 level)
1682 */ 1742 */
1683static int __exit smsc_ircc_close(struct smsc_ircc_cb *self) 1743static int __exit smsc_ircc_close(struct smsc_ircc_cb *self)
1684{ 1744{
1685 int iobase;
1686 unsigned long flags;
1687
1688 IRDA_DEBUG(1, "%s\n", __FUNCTION__); 1745 IRDA_DEBUG(1, "%s\n", __FUNCTION__);
1689 1746
1690 IRDA_ASSERT(self != NULL, return -1;); 1747 IRDA_ASSERT(self != NULL, return -1;);
@@ -1694,22 +1751,7 @@ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self)
1694 /* Remove netdevice */ 1751 /* Remove netdevice */
1695 unregister_netdev(self->netdev); 1752 unregister_netdev(self->netdev);
1696 1753
1697 /* Make sure the irq handler is not exectuting */ 1754 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 1755
1714 /* Release the PORTS that this driver is using */ 1756 /* Release the PORTS that this driver is using */
1715 IRDA_DEBUG(0, "%s(), releasing 0x%03x\n", __FUNCTION__, 1757 IRDA_DEBUG(0, "%s(), releasing 0x%03x\n", __FUNCTION__,