74ba9207e1adf (Thomas Gleixner 2019-05-20 09:19:02 +0200 1) // SPDX-License-Identifier: GPL-2.0-or-later
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 2) /*
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 3) * UIO driver fo Humusoft MF624 DAQ card.
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 4) * Copyright (C) 2011 Rostislav Lisovy <lisovy@gmail.com>,
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 5) * Czech Technical University in Prague
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 6) */
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 7)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 8) #include <linux/init.h>
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 9) #include <linux/module.h>
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 10) #include <linux/device.h>
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 11) #include <linux/pci.h>
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 12) #include <linux/slab.h>
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 13) #include <linux/io.h>
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 14) #include <linux/kernel.h>
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 15) #include <linux/uio_driver.h>
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 16)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 17) #define PCI_VENDOR_ID_HUMUSOFT 0x186c
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 18) #define PCI_DEVICE_ID_MF624 0x0624
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 19) #define PCI_SUBVENDOR_ID_HUMUSOFT 0x186c
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 20) #define PCI_SUBDEVICE_DEVICE 0x0624
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 21)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 22) /* BAR0 Interrupt control/status register */
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 23) #define INTCSR 0x4C
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 24) #define INTCSR_ADINT_ENABLE (1 << 0)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 25) #define INTCSR_CTR4INT_ENABLE (1 << 3)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 26) #define INTCSR_PCIINT_ENABLE (1 << 6)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 27) #define INTCSR_ADINT_STATUS (1 << 2)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 28) #define INTCSR_CTR4INT_STATUS (1 << 5)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 29)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 30) enum mf624_interrupt_source {ADC, CTR4, ALL};
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 31)
497b46dbc660d (Fengguang Wu 2013-09-02 10:38:33 +0200 32) static void mf624_disable_interrupt(enum mf624_interrupt_source source,
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 33) struct uio_info *info)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 34) {
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 35) void __iomem *INTCSR_reg = info->mem[0].internal_addr + INTCSR;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 36)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 37) switch (source) {
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 38) case ADC:
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 39) iowrite32(ioread32(INTCSR_reg)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 40) & ~(INTCSR_ADINT_ENABLE | INTCSR_PCIINT_ENABLE),
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 41) INTCSR_reg);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 42) break;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 43)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 44) case CTR4:
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 45) iowrite32(ioread32(INTCSR_reg)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 46) & ~(INTCSR_CTR4INT_ENABLE | INTCSR_PCIINT_ENABLE),
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 47) INTCSR_reg);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 48) break;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 49)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 50) case ALL:
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 51) default:
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 52) iowrite32(ioread32(INTCSR_reg)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 53) & ~(INTCSR_ADINT_ENABLE | INTCSR_CTR4INT_ENABLE
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 54) | INTCSR_PCIINT_ENABLE),
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 55) INTCSR_reg);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 56) break;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 57) }
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 58) }
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 59)
497b46dbc660d (Fengguang Wu 2013-09-02 10:38:33 +0200 60) static void mf624_enable_interrupt(enum mf624_interrupt_source source,
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 61) struct uio_info *info)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 62) {
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 63) void __iomem *INTCSR_reg = info->mem[0].internal_addr + INTCSR;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 64)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 65) switch (source) {
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 66) case ADC:
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 67) iowrite32(ioread32(INTCSR_reg)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 68) | INTCSR_ADINT_ENABLE | INTCSR_PCIINT_ENABLE,
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 69) INTCSR_reg);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 70) break;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 71)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 72) case CTR4:
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 73) iowrite32(ioread32(INTCSR_reg)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 74) | INTCSR_CTR4INT_ENABLE | INTCSR_PCIINT_ENABLE,
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 75) INTCSR_reg);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 76) break;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 77)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 78) case ALL:
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 79) default:
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 80) iowrite32(ioread32(INTCSR_reg)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 81) | INTCSR_ADINT_ENABLE | INTCSR_CTR4INT_ENABLE
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 82) | INTCSR_PCIINT_ENABLE,
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 83) INTCSR_reg);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 84) break;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 85) }
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 86) }
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 87)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 88) static irqreturn_t mf624_irq_handler(int irq, struct uio_info *info)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 89) {
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 90) void __iomem *INTCSR_reg = info->mem[0].internal_addr + INTCSR;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 91)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 92) if ((ioread32(INTCSR_reg) & INTCSR_ADINT_ENABLE)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 93) && (ioread32(INTCSR_reg) & INTCSR_ADINT_STATUS)) {
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 94) mf624_disable_interrupt(ADC, info);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 95) return IRQ_HANDLED;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 96) }
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 97)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 98) if ((ioread32(INTCSR_reg) & INTCSR_CTR4INT_ENABLE)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 99) && (ioread32(INTCSR_reg) & INTCSR_CTR4INT_STATUS)) {
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 100) mf624_disable_interrupt(CTR4, info);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 101) return IRQ_HANDLED;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 102) }
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 103)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 104) return IRQ_NONE;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 105) }
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 106)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 107) static int mf624_irqcontrol(struct uio_info *info, s32 irq_on)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 108) {
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 109) if (irq_on == 0)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 110) mf624_disable_interrupt(ALL, info);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 111) else if (irq_on == 1)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 112) mf624_enable_interrupt(ALL, info);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 113)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 114) return 0;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 115) }
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 116)
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 117) static int mf624_setup_mem(struct pci_dev *dev, int bar, struct uio_mem *mem, const char *name)
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 118) {
270579d95f820 (Michal Sojka 2017-03-16 14:50:10 +0100 119) resource_size_t start = pci_resource_start(dev, bar);
270579d95f820 (Michal Sojka 2017-03-16 14:50:10 +0100 120) resource_size_t len = pci_resource_len(dev, bar);
270579d95f820 (Michal Sojka 2017-03-16 14:50:10 +0100 121)
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 122) mem->name = name;
270579d95f820 (Michal Sojka 2017-03-16 14:50:10 +0100 123) mem->addr = start & PAGE_MASK;
270579d95f820 (Michal Sojka 2017-03-16 14:50:10 +0100 124) mem->offs = start & ~PAGE_MASK;
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 125) if (!mem->addr)
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 126) return -ENODEV;
270579d95f820 (Michal Sojka 2017-03-16 14:50:10 +0100 127) mem->size = ((start & ~PAGE_MASK) + len + PAGE_SIZE - 1) & PAGE_MASK;
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 128) mem->memtype = UIO_MEM_PHYS;
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 129) mem->internal_addr = pci_ioremap_bar(dev, bar);
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 130) if (!mem->internal_addr)
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 131) return -ENODEV;
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 132) return 0;
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 133) }
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 134)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 135) static int mf624_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 136) {
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 137) struct uio_info *info;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 138)
6b76c98b96bd6 (Alexandru Ardelean 2020-11-20 10:42:06 +0200 139) info = devm_kzalloc(&dev->dev, sizeof(struct uio_info), GFP_KERNEL);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 140) if (!info)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 141) return -ENOMEM;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 142)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 143) if (pci_enable_device(dev))
6b76c98b96bd6 (Alexandru Ardelean 2020-11-20 10:42:06 +0200 144) return -ENODEV;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 145)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 146) if (pci_request_regions(dev, "mf624"))
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 147) goto out_disable;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 148)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 149) info->name = "mf624";
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 150) info->version = "0.0.1";
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 151)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 152) /* Note: Datasheet says device uses BAR0, BAR1, BAR2 -- do not trust it */
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 153)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 154) /* BAR0 */
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 155) if (mf624_setup_mem(dev, 0, &info->mem[0], "PCI chipset, interrupts, status "
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 156) "bits, special functions"))
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 157) goto out_release;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 158) /* BAR2 */
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 159) if (mf624_setup_mem(dev, 2, &info->mem[1], "ADC, DAC, DIO"))
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 160) goto out_unmap0;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 161)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 162) /* BAR4 */
a15d2ddba9ee9 (Michal Sojka 2017-03-16 14:50:09 +0100 163) if (mf624_setup_mem(dev, 4, &info->mem[2], "Counter/timer chip"))
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 164) goto out_unmap1;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 165)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 166) info->irq = dev->irq;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 167) info->irq_flags = IRQF_SHARED;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 168) info->handler = mf624_irq_handler;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 169)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 170) info->irqcontrol = mf624_irqcontrol;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 171)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 172) if (uio_register_device(&dev->dev, info))
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 173) goto out_unmap2;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 174)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 175) pci_set_drvdata(dev, info);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 176)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 177) return 0;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 178)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 179) out_unmap2:
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 180) iounmap(info->mem[2].internal_addr);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 181) out_unmap1:
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 182) iounmap(info->mem[1].internal_addr);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 183) out_unmap0:
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 184) iounmap(info->mem[0].internal_addr);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 185)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 186) out_release:
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 187) pci_release_regions(dev);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 188)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 189) out_disable:
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 190) pci_disable_device(dev);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 191)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 192) return -ENODEV;
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 193) }
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 194)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 195) static void mf624_pci_remove(struct pci_dev *dev)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 196) {
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 197) struct uio_info *info = pci_get_drvdata(dev);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 198)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 199) mf624_disable_interrupt(ALL, info);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 200)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 201) uio_unregister_device(info);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 202) pci_release_regions(dev);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 203) pci_disable_device(dev);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 204)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 205) iounmap(info->mem[0].internal_addr);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 206) iounmap(info->mem[1].internal_addr);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 207) iounmap(info->mem[2].internal_addr);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 208) }
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 209)
0f4054df0bf6b (Jingoo Han 2013-12-03 08:27:13 +0900 210) static const struct pci_device_id mf624_pci_id[] = {
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 211) { PCI_DEVICE(PCI_VENDOR_ID_HUMUSOFT, PCI_DEVICE_ID_MF624) },
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 212) { 0, }
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 213) };
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 214)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 215) static struct pci_driver mf624_pci_driver = {
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 216) .name = "mf624",
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 217) .id_table = mf624_pci_id,
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 218) .probe = mf624_pci_probe,
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 219) .remove = mf624_pci_remove,
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 220) };
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 221) MODULE_DEVICE_TABLE(pci, mf624_pci_id);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 222)
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 223) module_pci_driver(mf624_pci_driver);
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 224) MODULE_LICENSE("GPL v2");
06849faab58fc (Rostislav Lisovy 2013-08-30 14:58:02 +0200 225) MODULE_AUTHOR("Rostislav Lisovy <lisovy@gmail.com>");