]> rtime.felk.cvut.cz Git - mf6xx.git/commitdiff
Added pci_remove() section + irqcontrol(); Module seems to be able to load, unload...
authorRostislav Lisovy <lisovy@gmail.com>
Thu, 16 Dec 2010 16:54:03 +0000 (17:54 +0100)
committerRostislav Lisovy <lisovy@gmail.com>
Thu, 16 Dec 2010 16:54:03 +0000 (17:54 +0100)
mf614.c

diff --git a/mf614.c b/mf614.c
index 3b522a62c919e92223782b76e0162a0fbb480a76..35d5b78c10f326395bb4fd1c6b9890ed127478b5 100644 (file)
--- a/mf614.c
+++ b/mf614.c
@@ -1,6 +1,12 @@
+#include <linux/init.h>
 #include <linux/module.h>
+#include <linux/device.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
+
+
 #include <linux/uio_driver.h>
+#include <linux/io.h>
 
 #define PCI_VENDOR_ID_HUMUSOFT         0x186c
 #define PCI_DEVICE_ID_MF614            0x0614
 #define STATUS_CC                      (u32) (1 << 2)
 
 
-static irqreturn_t mf614_irq_handler(int irq, struct uio_info *dev_info)
+static irqreturn_t mf614_irq_handler(int irq, struct uio_info *info)
 {
-       void __iomem *status_reg = dev_info->priv + STATUS_OFFSET;
+       void __iomem *status_reg = info->priv + STATUS_OFFSET;
 
        if ((ioread16(status_reg) & STATUS_T5INTE) 
                && (ioread16(status_reg) & STATUS_T5))
        {
-               iowrite16(ioread16(status_reg) & ~STATUS_T5, status_reg);
+               iowrite16(ioread16(status_reg) & ~STATUS_T5INTE, status_reg);
                return IRQ_HANDLED;
        }
 
        if ((ioread16(status_reg) & STATUS_CCINTE) 
                && (ioread16(status_reg) & STATUS_CC))
        {
-               iowrite16(ioread16(status_reg) & ~STATUS_CC, status_reg);
+               iowrite16(ioread16(status_reg) & ~STATUS_CCINTE, status_reg);
                return IRQ_HANDLED;
        }
 
        return IRQ_NONE;
 }
 
+static int mf614_irqcontrol(struct uio_info *info, s32 irq_on)
+{
+       void __iomem *status_reg = info->priv + STATUS_OFFSET;
+
+       if (irq_on == 0) { /* Disable interrupts */
+               iowrite16(ioread16(status_reg) & ~STATUS_T5INTE, status_reg);
+               iowrite16(ioread16(status_reg) & ~STATUS_CCINTE, status_reg);
+       } 
+       else if (irq_on == 1) {
+               iowrite16(ioread16(status_reg) | STATUS_T5INTE, status_reg);
+               iowrite16(ioread16(status_reg) | STATUS_CCINTE, status_reg);
+       }
+
+       return 0;
+}
+
 static int __devinit mf614_pci_probe(struct pci_dev *dev,
                                      const struct pci_device_id *id)
 {
@@ -44,7 +66,7 @@ static int __devinit mf614_pci_probe(struct pci_dev *dev,
        if (!info)
                return -ENOMEM;
        
-       if (pci_enable_device(dev)) //FIXME what is return value??
+       if (pci_enable_device(dev))
                goto out_free;
 
        if (pci_request_regions(dev, "mf614"))
@@ -82,6 +104,8 @@ static int __devinit mf614_pci_probe(struct pci_dev *dev,
        info->irq_flags = IRQF_SHARED;
        info->handler = mf614_irq_handler;
 
+       info->irqcontrol = mf614_irqcontrol;
+
        if(uio_register_device(&dev->dev, info))
                goto out_unmap;
 
@@ -102,7 +126,20 @@ out_free:
 
 static void mf614_pci_remove(struct pci_dev *dev)
 {
-
+       struct uio_info *info = pci_get_drvdata(dev);
+       void __iomem *status_reg = info->priv + STATUS_OFFSET;
+       
+       /* Disable interrupts */
+       iowrite16(ioread16(status_reg) & ~STATUS_T5INTE, status_reg);   
+       iowrite16(ioread16(status_reg) & ~STATUS_CCINTE, status_reg);   
+       
+       uio_unregister_device(info);
+       pci_release_regions(dev);
+       pci_disable_device(dev);
+       pci_set_drvdata(dev, NULL);
+       iounmap(info->priv);
+       
+       kfree(info);
 }
 
 static struct pci_device_id mf614_pci_id[] __devinitdata = {