]> err.no Git - linux-2.6/blobdiff - drivers/net/irda/smsc-ircc2.c
Merge by Hand
[linux-2.6] / drivers / net / irda / smsc-ircc2.c
index a5090ddb0d0f5225d5a44a65da84ea234e45c6bc..a1d207f2fa68e0c26f54267539ab169dfd40bff0 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/serial_reg.h>
 #include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -73,7 +74,6 @@ MODULE_AUTHOR("Daniele Peri <peri@csai.unipa.it>");
 MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver");
 MODULE_LICENSE("GPL");
 
-
 static int ircc_dma = 255;
 module_param(ircc_dma, int, 0);
 MODULE_PARM_DESC(ircc_dma, "DMA channel");
@@ -105,17 +105,6 @@ struct smsc_transceiver {
        void (*set_for_speed)(int fir_base, u32 speed);
        int  (*probe)(int fir_base);
 };
-typedef struct smsc_transceiver smsc_transceiver_t;
-
-#if 0
-struct smc_chip {
-       char *name;
-       u16 flags;
-       u8 devid;
-       u8 rev;
-};
-typedef struct smc_chip smc_chip_t;
-#endif
 
 struct smsc_chip {
        char *name;
@@ -126,13 +115,11 @@ struct smsc_chip {
        u8 devid;
        u8 rev;
 };
-typedef struct smsc_chip smsc_chip_t;
 
 struct smsc_chip_address {
        unsigned int cfg_base;
        unsigned int type;
 };
-typedef struct smsc_chip_address smsc_chip_address_t;
 
 /* Private data for each instance */
 struct smsc_ircc_cb {
@@ -157,17 +144,20 @@ struct smsc_ircc_cb {
        int tx_len;                /* Number of frames in tx_buff */
 
        int transceiver;
-       struct pm_dev *pmdev;
+       struct platform_device *pldev;
 };
 
 /* Constants */
 
-static const char *driver_name = "smsc-ircc2";
+#define SMSC_IRCC2_DRIVER_NAME                 "smsc-ircc2"
+
 #define SMSC_IRCC2_C_IRDA_FALLBACK_SPEED       9600
 #define SMSC_IRCC2_C_DEFAULT_TRANSCEIVER       1
 #define SMSC_IRCC2_C_NET_TIMEOUT               0
 #define SMSC_IRCC2_C_SIR_STOP                  0
 
+static const char *driver_name = SMSC_IRCC2_DRIVER_NAME;
+
 /* Prototypes */
 
 static int smsc_ircc_open(unsigned int firbase, unsigned int sirbase, u8 dma, u8 irq);
@@ -176,15 +166,15 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self, unsigned int fir_base,
 static void smsc_ircc_setup_qos(struct smsc_ircc_cb *self);
 static void smsc_ircc_init_chip(struct smsc_ircc_cb *self);
 static int __exit smsc_ircc_close(struct smsc_ircc_cb *self);
-static int  smsc_ircc_dma_receive(struct smsc_ircc_cb *self, int iobase);
-static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self, int iobase);
+static int  smsc_ircc_dma_receive(struct smsc_ircc_cb *self);
+static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self);
 static void smsc_ircc_sir_receive(struct smsc_ircc_cb *self);
 static int  smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev);
 static int  smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev);
-static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int iobase, int bofs);
-static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self, int iobase);
-static void smsc_ircc_change_speed(void *priv, u32 speed);
-static void smsc_ircc_set_sir_speed(void *priv, u32 speed);
+static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int bofs);
+static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self);
+static void smsc_ircc_change_speed(struct smsc_ircc_cb *self, u32 speed);
+static void smsc_ircc_set_sir_speed(struct smsc_ircc_cb *self, u32 speed);
 static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static irqreturn_t smsc_ircc_interrupt_sir(struct net_device *dev);
 static void smsc_ircc_sir_start(struct smsc_ircc_cb *self);
@@ -200,7 +190,6 @@ static int  smsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cm
 static void smsc_ircc_timeout(struct net_device *dev);
 #endif
 static struct net_device_stats *smsc_ircc_net_get_stats(struct net_device *dev);
-static int  smsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data);
 static int smsc_ircc_is_receiving(struct smsc_ircc_cb *self);
 static void smsc_ircc_probe_transceiver(struct smsc_ircc_cb *self);
 static void smsc_ircc_set_transceiver_for_speed(struct smsc_ircc_cb *self, u32 speed);
@@ -208,9 +197,9 @@ static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self);
 
 /* Probing */
 static int __init smsc_ircc_look_for_chips(void);
-static const smsc_chip_t * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const smsc_chip_t *chip, char *type);
-static int __init smsc_superio_flat(const smsc_chip_t *chips, unsigned short cfg_base, char *type);
-static int __init smsc_superio_paged(const smsc_chip_t *chips, unsigned short cfg_base, char *type);
+static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type);
+static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned short cfg_base, char *type);
+static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type);
 static int __init smsc_superio_fdc(unsigned short cfg_base);
 static int __init smsc_superio_lpc(unsigned short cfg_base);
 
@@ -225,14 +214,19 @@ static int  smsc_ircc_probe_transceiver_smsc_ircc_atc(int fir_base);
 
 /* Power Management */
 
-static void smsc_ircc_suspend(struct smsc_ircc_cb *self);
-static void smsc_ircc_wakeup(struct smsc_ircc_cb *self);
-static int smsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data);
+static int smsc_ircc_suspend(struct device *dev, pm_message_t state);
+static int smsc_ircc_resume(struct device *dev);
 
+static struct device_driver smsc_ircc_driver = {
+       .name           = SMSC_IRCC2_DRIVER_NAME,
+       .bus            = &platform_bus_type,
+       .suspend        = smsc_ircc_suspend,
+       .resume         = smsc_ircc_resume,
+};
 
 /* Transceivers for SMSC-ircc */
 
-static smsc_transceiver_t smsc_transceivers[] =
+static struct smsc_transceiver smsc_transceivers[] =
 {
        { "Toshiba Satellite 1800 (GP data pin select)", smsc_ircc_set_transceiver_toshiba_sat1800, smsc_ircc_probe_transceiver_toshiba_sat1800 },
        { "Fast pin select", smsc_ircc_set_transceiver_smsc_ircc_fast_pin_select, smsc_ircc_probe_transceiver_smsc_ircc_fast_pin_select },
@@ -250,7 +244,7 @@ static smsc_transceiver_t smsc_transceivers[] =
 #define        FIR     4       /* SuperIO Chip has fast IRDA */
 #define        SERx4   8       /* SuperIO Chip supports 115,2 KBaud * 4=460,8 KBaud */
 
-static smsc_chip_t __initdata fdc_chips_flat[] =
+static struct smsc_chip __initdata fdc_chips_flat[] =
 {
        /* Base address 0x3f0 or 0x370 */
        { "37C44",      KEY55_1|NoIRDA,         0x00, 0x00 }, /* This chip cannot be detected */
@@ -264,7 +258,7 @@ static smsc_chip_t __initdata fdc_chips_flat[] =
        { NULL }
 };
 
-static smsc_chip_t __initdata fdc_chips_paged[] =
+static struct smsc_chip __initdata fdc_chips_paged[] =
 {
        /* Base address 0x3f0 or 0x370 */
        { "37B72X",     KEY55_1|SIR|SERx4,      0x4c, 0x00 },
@@ -283,7 +277,7 @@ static smsc_chip_t __initdata fdc_chips_paged[] =
        { NULL }
 };
 
-static smsc_chip_t __initdata lpc_chips_flat[] =
+static struct smsc_chip __initdata lpc_chips_flat[] =
 {
        /* Base address 0x2E or 0x4E */
        { "47N227",     KEY55_1|FIR|SERx4,      0x5a, 0x00 },
@@ -291,7 +285,7 @@ static smsc_chip_t __initdata lpc_chips_flat[] =
        { NULL }
 };
 
-static smsc_chip_t __initdata lpc_chips_paged[] =
+static struct smsc_chip __initdata lpc_chips_paged[] =
 {
        /* Base address 0x2E or 0x4E */
        { "47B27X",     KEY55_1|SIR|SERx4,      0x51, 0x00 },
@@ -310,7 +304,7 @@ static smsc_chip_t __initdata lpc_chips_paged[] =
 #define SMSCSIO_TYPE_FLAT      4
 #define SMSCSIO_TYPE_PAGED     8
 
-static smsc_chip_address_t __initdata possible_addresses[] =
+static struct smsc_chip_address __initdata possible_addresses[] =
 {
        { 0x3f0, SMSCSIO_TYPE_FDC|SMSCSIO_TYPE_FLAT|SMSCSIO_TYPE_PAGED },
        { 0x370, SMSCSIO_TYPE_FDC|SMSCSIO_TYPE_FLAT|SMSCSIO_TYPE_PAGED },
@@ -348,34 +342,43 @@ static inline void register_bank(int iobase, int bank)
  */
 static int __init smsc_ircc_init(void)
 {
-       int ret = -ENODEV;
+       int ret;
 
        IRDA_DEBUG(1, "%s\n", __FUNCTION__);
 
+       ret = driver_register(&smsc_ircc_driver);
+       if (ret) {
+               IRDA_ERROR("%s, Can't register driver!\n", driver_name);
+               return ret;
+       }
+
        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) == 0)
-                       return 0;
-
-               return -ENODEV;
-       }
+               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;
+               }
 
-       /* 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))
+               if (smsc_ircc_look_for_chips() > 0)
                        ret = 0;
        }
 
-       if (smsc_ircc_look_for_chips() > 0)
-               ret = 0;
+       if (ret)
+               driver_unregister(&smsc_ircc_driver);
 
        return ret;
 }
@@ -425,7 +428,7 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u
        dev->do_ioctl        = smsc_ircc_net_ioctl;
        dev->get_stats       = smsc_ircc_net_get_stats;
 
-       self = dev->priv;
+       self = netdev_priv(dev);
        self->netdev = dev;
 
        /* Make ifconfig display some details */
@@ -433,7 +436,7 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u
        dev->irq = self->io.irq = irq;
 
        /* Need to store self somewhere */
-       dev_self[dev_count++] = self;
+       dev_self[dev_count] = self;
        spin_lock_init(&self->lock);
 
        self->rx_buff.truesize = SMSC_IRCC2_RX_BUFF_TRUESIZE;
@@ -482,14 +485,22 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u
                goto err_out4;
        }
 
-       self->pmdev = pm_register(PM_SYS_DEV, PM_SYS_IRDA, smsc_ircc_pmproc);
-       if (self->pmdev)
-               self->pmdev->data = self;
+       self->pldev = platform_device_register_simple(SMSC_IRCC2_DRIVER_NAME,
+                                                     dev_count, NULL, 0);
+       if (IS_ERR(self->pldev)) {
+               err = PTR_ERR(self->pldev);
+               goto err_out5;
+       }
+       dev_set_drvdata(&self->pldev->dev, self);
 
        IRDA_MESSAGE("IrDA: Registered device %s\n", dev->name);
+       dev_count++;
 
        return 0;
 
+ err_out5:
+       unregister_netdev(self->netdev);
+
  err_out4:
        dma_free_coherent(NULL, self->tx_buff.truesize,
                          self->tx_buff.head, self->tx_buff_dma);
@@ -498,7 +509,7 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u
                          self->rx_buff.head, self->rx_buff_dma);
  err_out2:
        free_netdev(self->netdev);
-       dev_self[--dev_count] = NULL;
+       dev_self[dev_count] = NULL;
  err_out1:
        release_region(fir_base, SMSC_IRCC2_FIR_CHIP_IO_EXTENT);
        release_region(sir_base, SMSC_IRCC2_SIR_CHIP_IO_EXTENT);
@@ -628,21 +639,14 @@ static void smsc_ircc_setup_qos(struct smsc_ircc_cb *self)
  */
 static void smsc_ircc_init_chip(struct smsc_ircc_cb *self)
 {
-       int iobase, ir_mode, ctrl, fast;
-
-       IRDA_ASSERT(self != NULL, return;);
-
-       iobase = self->io.fir_base;
-       ir_mode = IRCC_CFGA_IRDA_SIR_A;
-       ctrl = 0;
-       fast = 0;
+       int iobase = self->io.fir_base;
 
        register_bank(iobase, 0);
        outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
        outb(0x00, iobase + IRCC_MASTER);
 
        register_bank(iobase, 1);
-       outb(((inb(iobase + IRCC_SCE_CFGA) & 0x87) | ir_mode),
+       outb(((inb(iobase + IRCC_SCE_CFGA) & 0x87) | IRCC_CFGA_IRDA_SIR_A),
             iobase + IRCC_SCE_CFGA);
 
 #ifdef smsc_669 /* Uses pin 88/89 for Rx/Tx */
@@ -656,10 +660,10 @@ static void smsc_ircc_init_chip(struct smsc_ircc_cb *self)
        outb(SMSC_IRCC2_FIFO_THRESHOLD, iobase + IRCC_FIFO_THRESHOLD);
 
        register_bank(iobase, 4);
-       outb((inb(iobase + IRCC_CONTROL) & 0x30) | ctrl, iobase + IRCC_CONTROL);
+       outb((inb(iobase + IRCC_CONTROL) & 0x30), iobase + IRCC_CONTROL);
 
        register_bank(iobase, 0);
-       outb(fast, iobase + IRCC_LCR_A);
+       outb(0, iobase + IRCC_LCR_A);
 
        smsc_ircc_set_sir_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
 
@@ -682,7 +686,7 @@ static int smsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd
 
        IRDA_ASSERT(dev != NULL, return -1;);
 
-       self = dev->priv;
+       self = netdev_priv(dev);
 
        IRDA_ASSERT(self != NULL, return -1;);
 
@@ -729,7 +733,7 @@ static int smsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd
 
 static struct net_device_stats *smsc_ircc_net_get_stats(struct net_device *dev)
 {
-       struct smsc_ircc_cb *self = (struct smsc_ircc_cb *) dev->priv;
+       struct smsc_ircc_cb *self = netdev_priv(dev);
 
        return &self->stats;
 }
@@ -744,11 +748,9 @@ static struct net_device_stats *smsc_ircc_net_get_stats(struct net_device *dev)
 
 static void smsc_ircc_timeout(struct net_device *dev)
 {
-       struct smsc_ircc_cb *self;
+       struct smsc_ircc_cb *self = netdev_priv(dev);
        unsigned long flags;
 
-       self = (struct smsc_ircc_cb *) dev->priv;
-
        IRDA_WARNING("%s: transmit timed out, changing speed to: %d\n",
                     dev->name, self->io.speed);
        spin_lock_irqsave(&self->lock, flags);
@@ -771,18 +773,15 @@ int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev)
 {
        struct smsc_ircc_cb *self;
        unsigned long flags;
-       int iobase;
        s32 speed;
 
        IRDA_DEBUG(1, "%s\n", __FUNCTION__);
 
        IRDA_ASSERT(dev != NULL, return 0;);
 
-       self = (struct smsc_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
        IRDA_ASSERT(self != NULL, return 0;);
 
-       iobase = self->io.sir_base;
-
        netif_stop_queue(dev);
 
        /* Make sure test of self->io.speed & speed change are atomic */
@@ -821,7 +820,7 @@ int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev)
        self->stats.tx_bytes += self->tx_buff.len;
 
        /* Turn on transmit finished interrupt. Will fire immediately!  */
-       outb(UART_IER_THRI, iobase + UART_IER);
+       outb(UART_IER_THRI, self->io.sir_base + UART_IER);
 
        spin_unlock_irqrestore(&self->lock, flags);
 
@@ -960,18 +959,15 @@ static void smsc_ircc_fir_stop(struct smsc_ircc_cb *self)
  * This function *must* be called with spinlock held, because it may
  * be called from the irq handler. - Jean II
  */
-static void smsc_ircc_change_speed(void *priv, u32 speed)
+static void smsc_ircc_change_speed(struct smsc_ircc_cb *self, u32 speed)
 {
-       struct smsc_ircc_cb *self = (struct smsc_ircc_cb *) priv;
        struct net_device *dev;
-       int iobase;
        int last_speed_was_sir;
 
        IRDA_DEBUG(0, "%s() changing speed to: %d\n", __FUNCTION__, speed);
 
        IRDA_ASSERT(self != NULL, return;);
        dev = self->netdev;
-       iobase = self->io.fir_base;
 
        last_speed_was_sir = self->io.speed <= SMSC_IRCC2_MAX_SIR_SPEED;
 
@@ -1014,10 +1010,10 @@ static void smsc_ircc_change_speed(void *priv, u32 speed)
                self->tx_buff.len = 10;
                self->tx_buff.data = self->tx_buff.head;
 
-               smsc_ircc_dma_xmit(self, iobase, 4000);
+               smsc_ircc_dma_xmit(self, 4000);
                #endif
                /* Be ready for incoming frames */
-               smsc_ircc_dma_receive(self, iobase);
+               smsc_ircc_dma_receive(self);
        }
 
        netif_wake_queue(dev);
@@ -1029,9 +1025,8 @@ static void smsc_ircc_change_speed(void *priv, u32 speed)
  *    Set speed of IrDA port to specified baudrate
  *
  */
-void smsc_ircc_set_sir_speed(void *priv, __u32 speed)
+void smsc_ircc_set_sir_speed(struct smsc_ircc_cb *self, __u32 speed)
 {
-       struct smsc_ircc_cb *self = (struct smsc_ircc_cb *) priv;
        int iobase;
        int fcr;    /* FIFO control reg */
        int lcr;    /* Line control reg */
@@ -1087,15 +1082,12 @@ static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev)
        struct smsc_ircc_cb *self;
        unsigned long flags;
        s32 speed;
-       int iobase;
        int mtt;
 
        IRDA_ASSERT(dev != NULL, return 0;);
-       self = (struct smsc_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
        IRDA_ASSERT(self != NULL, return 0;);
 
-       iobase = self->io.fir_base;
-
        netif_stop_queue(dev);
 
        /* Make sure test of self->io.speed & speed change are atomic */
@@ -1135,10 +1127,10 @@ static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev)
                if (bofs > 4095)
                        bofs = 4095;
 
-               smsc_ircc_dma_xmit(self, iobase, bofs);
+               smsc_ircc_dma_xmit(self, bofs);
        } else {
                /* Transmit frame */
-               smsc_ircc_dma_xmit(self, iobase, 0);
+               smsc_ircc_dma_xmit(self, 0);
        }
 
        spin_unlock_irqrestore(&self->lock, flags);
@@ -1148,13 +1140,14 @@ static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev)
 }
 
 /*
- * Function smsc_ircc_dma_xmit (self, iobase)
+ * Function smsc_ircc_dma_xmit (self, bofs)
  *
  *    Transmit data using DMA
  *
  */
-static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int iobase, int bofs)
+static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int bofs)
 {
+       int iobase = self->io.fir_base;
        u8 ctrl;
 
        IRDA_DEBUG(3, "%s\n", __FUNCTION__);
@@ -1207,17 +1200,19 @@ static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int iobase, int bofs)
  *    by the interrupt handler
  *
  */
-static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self, int iobase)
+static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self)
 {
+       int iobase = self->io.fir_base;
+
        IRDA_DEBUG(3, "%s\n", __FUNCTION__);
 #if 0
        /* Disable Tx */
        register_bank(iobase, 0);
        outb(0x00, iobase + IRCC_LCR_B);
 #endif
-       register_bank(self->io.fir_base, 1);
-       outb(inb(self->io.fir_base + IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE,
-            self->io.fir_base + IRCC_SCE_CFGB);
+       register_bank(iobase, 1);
+       outb(inb(iobase + IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE,
+            iobase + IRCC_SCE_CFGB);
 
        /* Check for underrun! */
        register_bank(iobase, 0);
@@ -1250,8 +1245,9 @@ static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self, int iobase)
  *    if it starts to receive a frame.
  *
  */
-static int smsc_ircc_dma_receive(struct smsc_ircc_cb *self, int iobase)
+static int smsc_ircc_dma_receive(struct smsc_ircc_cb *self)
 {
+       int iobase = self->io.fir_base;
 #if 0
        /* Turn off chip DMA */
        register_bank(iobase, 1);
@@ -1299,15 +1295,16 @@ static int smsc_ircc_dma_receive(struct smsc_ircc_cb *self, int iobase)
 }
 
 /*
- * Function smsc_ircc_dma_receive_complete(self, iobase)
+ * Function smsc_ircc_dma_receive_complete(self)
  *
  *    Finished with receiving frames
  *
  */
-static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self, int iobase)
+static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self)
 {
        struct sk_buff *skb;
        int len, msgcnt, lsr;
+       int iobase = self->io.fir_base;
 
        register_bank(iobase, 0);
 
@@ -1419,7 +1416,8 @@ static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id, struct pt_regs *re
                       driver_name, irq);
                goto irq_ret;
        }
-       self = (struct smsc_ircc_cb *) dev->priv;
+
+       self = netdev_priv(dev);
        IRDA_ASSERT(self != NULL, return IRQ_NONE;);
 
        /* Serialise the interrupt handler in various CPUs, stop Tx path */
@@ -1448,11 +1446,11 @@ static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id, struct pt_regs *re
 
        if (iir & IRCC_IIR_EOM) {
                if (self->io.direction == IO_RECV)
-                       smsc_ircc_dma_receive_complete(self, iobase);
+                       smsc_ircc_dma_receive_complete(self);
                else
-                       smsc_ircc_dma_xmit_complete(self, iobase);
+                       smsc_ircc_dma_xmit_complete(self);
 
-               smsc_ircc_dma_receive(self, iobase);
+               smsc_ircc_dma_receive(self);
        }
 
        if (iir & IRCC_IIR_ACTIVE_FRAME) {
@@ -1477,7 +1475,7 @@ static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id, struct pt_regs *re
  */
 static irqreturn_t smsc_ircc_interrupt_sir(struct net_device *dev)
 {
-       struct smsc_ircc_cb *self = dev->priv;
+       struct smsc_ircc_cb *self = netdev_priv(dev);
        int boguscount = 0;
        int iobase;
        int iir, lsr;
@@ -1552,6 +1550,46 @@ static int ircc_is_receiving(struct smsc_ircc_cb *self)
 }
 #endif /* unused */
 
+static int smsc_ircc_request_irq(struct smsc_ircc_cb *self)
+{
+       int error;
+
+       error = request_irq(self->io.irq, smsc_ircc_interrupt, 0,
+                           self->netdev->name, self->netdev);
+       if (error)
+               IRDA_DEBUG(0, "%s(), unable to allocate irq=%d, err=%d\n",
+                          __FUNCTION__, self->io.irq, error);
+
+       return error;
+}
+
+static void smsc_ircc_start_interrupts(struct smsc_ircc_cb *self)
+{
+       unsigned long flags;
+
+       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);
+}
+
+static void smsc_ircc_stop_interrupts(struct smsc_ircc_cb *self)
+{
+       int iobase = self->io.fir_base;
+       unsigned long flags;
+
+       spin_lock_irqsave(&self->lock, flags);
+
+       register_bank(iobase, 0);
+       outb(0, iobase + IRCC_IER);
+       outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
+       outb(0x00, iobase + IRCC_MASTER);
+
+       spin_unlock_irqrestore(&self->lock, flags);
+}
+
 
 /*
  * Function smsc_ircc_net_open (dev)
@@ -1562,17 +1600,18 @@ static int ircc_is_receiving(struct smsc_ircc_cb *self)
 static int smsc_ircc_net_open(struct net_device *dev)
 {
        struct smsc_ircc_cb *self;
-       int iobase;
        char hwname[16];
-       unsigned long flags;
 
        IRDA_DEBUG(1, "%s\n", __FUNCTION__);
 
        IRDA_ASSERT(dev != NULL, return -1;);
-       self = (struct smsc_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
        IRDA_ASSERT(self != NULL, return 0;);
 
-       iobase = self->io.fir_base;
+       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)) {
@@ -1581,11 +1620,7 @@ static int smsc_ircc_net_open(struct net_device *dev)
                return -EAGAIN;
        }
 
-       spin_lock_irqsave(&self->lock, flags);
-       /*smsc_ircc_sir_start(self);*/
-       self->io.speed = 0;
-       smsc_ircc_change_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
-       spin_unlock_irqrestore(&self->lock, flags);
+       smsc_ircc_start_interrupts(self);
 
        /* Give self a hardware name */
        /* It would be cool to offer the chip revision here - Jean II */
@@ -1623,16 +1658,13 @@ static int smsc_ircc_net_open(struct net_device *dev)
 static int smsc_ircc_net_close(struct net_device *dev)
 {
        struct smsc_ircc_cb *self;
-       int iobase;
 
        IRDA_DEBUG(1, "%s\n", __FUNCTION__);
 
        IRDA_ASSERT(dev != NULL, return -1;);
-       self = (struct smsc_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
        IRDA_ASSERT(self != NULL, return 0;);
 
-       iobase = self->io.fir_base;
-
        /* Stop device */
        netif_stop_queue(dev);
 
@@ -1641,51 +1673,64 @@ static int smsc_ircc_net_close(struct net_device *dev)
                irlap_close(self->irlap);
        self->irlap = NULL;
 
-       free_irq(self->io.irq, dev);
+       smsc_ircc_stop_interrupts(self);
+
+       /* if we are called from smsc_ircc_resume we don't have IRQ reserved */
+       if (!self->io.suspended)
+               free_irq(self->io.irq, dev);
+
        disable_dma(self->io.dma);
        free_dma(self->io.dma);
 
        return 0;
 }
 
-
-static void smsc_ircc_suspend(struct smsc_ircc_cb *self)
+static int smsc_ircc_suspend(struct device *dev, pm_message_t state)
 {
-       IRDA_MESSAGE("%s, Suspending\n", driver_name);
+       struct smsc_ircc_cb *self = dev_get_drvdata(dev);
 
        if (!self->io.suspended) {
-               smsc_ircc_net_close(self->netdev);
+               IRDA_DEBUG(1, "%s, Suspending\n", driver_name);
+
+               rtnl_lock();
+               if (netif_running(self->netdev)) {
+                       netif_device_detach(self->netdev);
+                       smsc_ircc_stop_interrupts(self);
+                       free_irq(self->io.irq, self->netdev);
+                       disable_dma(self->io.dma);
+               }
                self->io.suspended = 1;
+               rtnl_unlock();
        }
-}
-
-static void smsc_ircc_wakeup(struct smsc_ircc_cb *self)
-{
-       if (!self->io.suspended)
-               return;
 
-       /* The code was doing a "cli()" here, but this can't be right.
-        * If you need protection, do it in net_open with a spinlock
-        * or give a good reason. - Jean II */
-
-       smsc_ircc_net_open(self->netdev);
-
-       IRDA_MESSAGE("%s, Waking up\n", driver_name);
+       return 0;
 }
 
-static int smsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data)
+static int smsc_ircc_resume(struct device *dev)
 {
-        struct smsc_ircc_cb *self = (struct smsc_ircc_cb*) dev->data;
-        if (self) {
-                switch (rqst) {
-                case PM_SUSPEND:
-                        smsc_ircc_suspend(self);
-                        break;
-                case PM_RESUME:
-                        smsc_ircc_wakeup(self);
-                        break;
-                }
-        }
+       struct smsc_ircc_cb *self = dev_get_drvdata(dev);
+
+       if (self->io.suspended) {
+               IRDA_DEBUG(1, "%s, Waking up\n", driver_name);
+
+               rtnl_lock();
+               smsc_ircc_init_chip(self);
+               if (netif_running(self->netdev)) {
+                       if (smsc_ircc_request_irq(self)) {
+                               /*
+                                * Don't fail resume process, just kill this
+                                * network interface
+                                */
+                               unregister_netdevice(self->netdev);
+                       } else {
+                               enable_dma(self->io.dma);
+                               smsc_ircc_start_interrupts(self);
+                               netif_device_attach(self->netdev);
+                       }
+               }
+               self->io.suspended = 0;
+               rtnl_unlock();
+       }
        return 0;
 }
 
@@ -1697,36 +1742,16 @@ static int smsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data)
  */
 static int __exit smsc_ircc_close(struct smsc_ircc_cb *self)
 {
-       int iobase;
-       unsigned long flags;
-
        IRDA_DEBUG(1, "%s\n", __FUNCTION__);
 
        IRDA_ASSERT(self != NULL, return -1;);
 
-       iobase = self->io.fir_base;
-
-       if (self->pmdev)
-               pm_unregister(self->pmdev);
+       platform_device_unregister(self->pldev);
 
        /* Remove netdevice */
        unregister_netdev(self->netdev);
 
-       /* Make sure the irq handler is not exectuting */
-       spin_lock_irqsave(&self->lock, flags);
-
-       /* Stop interrupts */
-       register_bank(iobase, 0);
-       outb(0, iobase + IRCC_IER);
-       outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
-       outb(0x00, iobase + IRCC_MASTER);
-#if 0
-       /* Reset to SIR mode */
-       register_bank(iobase, 1);
-        outb(IRCC_CFGA_IRDA_SIR_A|IRCC_CFGA_TX_POLARITY, iobase + IRCC_SCE_CFGA);
-        outb(IRCC_CFGB_IR, iobase + IRCC_SCE_CFGB);
-#endif
-       spin_unlock_irqrestore(&self->lock, flags);
+       smsc_ircc_stop_interrupts(self);
 
        /* Release the PORTS that this driver is using */
        IRDA_DEBUG(0, "%s(), releasing 0x%03x\n",  __FUNCTION__,
@@ -1762,6 +1787,8 @@ static void __exit smsc_ircc_cleanup(void)
                if (dev_self[i])
                        smsc_ircc_close(dev_self[i]);
        }
+
+       driver_unregister(&smsc_ircc_driver);
 }
 
 /*
@@ -2010,7 +2037,7 @@ static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self)
 
 static int __init smsc_ircc_look_for_chips(void)
 {
-       smsc_chip_address_t *address;
+       struct smsc_chip_address *address;
        char *type;
        unsigned int cfg_base, found;
 
@@ -2053,7 +2080,7 @@ static int __init smsc_ircc_look_for_chips(void)
  *    Try to get configuration of a smc SuperIO chip with flat register model
  *
  */
-static int __init smsc_superio_flat(const smsc_chip_t *chips, unsigned short cfgbase, char *type)
+static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned short cfgbase, char *type)
 {
        unsigned short firbase, sirbase;
        u8 mode, dma, irq;
@@ -2104,7 +2131,7 @@ static int __init smsc_superio_flat(const smsc_chip_t *chips, unsigned short cfg
  *    Try  to get configuration of a smc SuperIO chip with paged register model
  *
  */
-static int __init smsc_superio_paged(const smsc_chip_t *chips, unsigned short cfg_base, char *type)
+static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type)
 {
        unsigned short fir_io, sir_io;
        int ret = -ENODEV;
@@ -2149,7 +2176,7 @@ static int __init smsc_access(unsigned short cfg_base, unsigned char reg)
        return inb(cfg_base) != reg ? -1 : 0;
 }
 
-static const smsc_chip_t * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const smsc_chip_t *chip, char *type)
+static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type)
 {
        u8 devid, xdevid, rev;