VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   33 Branches   55 Tags
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>");