+#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)
{
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"))
info->irq_flags = IRQF_SHARED;
info->handler = mf614_irq_handler;
+ info->irqcontrol = mf614_irqcontrol;
+
if(uio_register_device(&dev->dev, info))
goto out_unmap;
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 = {