#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>
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");
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;
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 {
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);
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);
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);
/* 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);
/* 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 },
#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 */
{ 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 },
{ 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 },
{ 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 },
#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 },
*/
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;
}
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 */
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;
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);
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);
*/
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 */
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);
IRDA_ASSERT(dev != NULL, return -1;);
- self = dev->priv;
+ self = netdev_priv(dev);
IRDA_ASSERT(self != NULL, return -1;);
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;
}
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);
{
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 */
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);
* 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;
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);
* 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 */
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 */
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);
}
/*
- * 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__);
* 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);
* 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);
}
/*
- * 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);
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 */
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) {
*/
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;
}
#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)
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)) {
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 */
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);
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;
}
*/
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__,
if (dev_self[i])
smsc_ircc_close(dev_self[i]);
}
+
+ driver_unregister(&smsc_ircc_driver);
}
/*
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;
* 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;
* 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;
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;