|
@@ -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);
|
|
|
}
|
|
|
|
|
|
/*
|