diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/irda/smsc-ircc2.c | 121 |
1 files changed, 65 insertions, 56 deletions
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index ee5ab94..0f651ee 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -73,7 +73,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"); @@ -144,17 +143,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); @@ -187,7 +189,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); @@ -212,10 +213,15 @@ 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, u32 level); +static int smsc_ircc_resume(struct device *dev, u32 level); +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 */ @@ -335,34 +341,42 @@ 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; + if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq)) + ret = -ENODEV; + } else { - return -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; } @@ -420,7 +434,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; @@ -469,14 +483,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); @@ -485,7 +507,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); @@ -1626,44 +1648,31 @@ static int smsc_ircc_net_close(struct net_device *dev) return 0; } - -static void smsc_ircc_suspend(struct smsc_ircc_cb *self) +static int smsc_ircc_suspend(struct device *dev, pm_message_t state, u32 level) { + struct smsc_ircc_cb *self = dev_get_drvdata(dev); + IRDA_MESSAGE("%s, Suspending\n", driver_name); - if (!self->io.suspended) { + if (level == SUSPEND_DISABLE && !self->io.suspended) { smsc_ircc_net_close(self->netdev); self->io.suspended = 1; } + + return 0; } -static void smsc_ircc_wakeup(struct smsc_ircc_cb *self) +static int smsc_ircc_resume(struct device *dev, u32 level) { - if (!self->io.suspended) - return; + struct smsc_ircc_cb *self = dev_get_drvdata(dev); - /* 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 */ + if (level == RESUME_ENABLE && self->io.suspended) { - smsc_ircc_net_open(self->netdev); + smsc_ircc_net_open(self->netdev); + self->io.suspended = 0; - IRDA_MESSAGE("%s, Waking up\n", driver_name); -} - -static int smsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data) -{ - 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; - } - } + IRDA_MESSAGE("%s, Waking up\n", driver_name); + } return 0; } @@ -1682,10 +1691,7 @@ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self) 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); @@ -1694,6 +1700,7 @@ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self) spin_lock_irqsave(&self->lock, flags); /* Stop interrupts */ + iobase = self->io.fir_base; register_bank(iobase, 0); outb(0, iobase + IRCC_IER); outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER); @@ -1740,6 +1747,8 @@ static void __exit smsc_ircc_cleanup(void) if (dev_self[i]) smsc_ircc_close(dev_self[i]); } + + driver_unregister(&smsc_ircc_driver); } /* |