devices/ccat/module.c
branchstable-1.5
changeset 2639 3bedfc5ecd74
parent 2638 5995331a55fe
child 2640 b11e1014edfe
equal deleted inserted replaced
2632:08aa7305b9ba 2639:3bedfc5ecd74
     1 /**
     1 /**
     2     Network Driver for Beckhoff CCAT communication controller
     2     Network Driver for Beckhoff CCAT communication controller
     3     Copyright (C) 2014  Beckhoff Automation GmbH
     3     Copyright (C) 2014-2015  Beckhoff Automation GmbH
     4     Author: Patrick Bruenn <p.bruenn@beckhoff.com>
     4     Author: Patrick Bruenn <p.bruenn@beckhoff.com>
     5 
     5 
     6     This program is free software; you can redistribute it and/or modify
     6     This program is free software; you can redistribute it and/or modify
     7     it under the terms of the GNU General Public License as published by
     7     it under the terms of the GNU General Public License as published by
     8     the Free Software Foundation; either version 2 of the License, or
     8     the Free Software Foundation; either version 2 of the License, or
    16     You should have received a copy of the GNU General Public License along
    16     You should have received a copy of the GNU General Public License along
    17     with this program; if not, write to the Free Software Foundation, Inc.,
    17     with this program; if not, write to the Free Software Foundation, Inc.,
    18     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    18     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    19 */
    19 */
    20 
    20 
    21 #include <asm/dma.h>
       
    22 #include <linux/etherdevice.h>
    21 #include <linux/etherdevice.h>
    23 #include <linux/module.h>
    22 #include <linux/module.h>
    24 #include <linux/netdevice.h>
    23 #include <linux/netdevice.h>
       
    24 #include <linux/platform_device.h>
    25 #include <linux/version.h>
    25 #include <linux/version.h>
    26 #include "module.h"
    26 #include "module.h"
    27 #include "netdev.h"
       
    28 #include "update.h"
       
    29 
    27 
    30 MODULE_DESCRIPTION(DRV_DESCRIPTION);
    28 MODULE_DESCRIPTION(DRV_DESCRIPTION);
    31 MODULE_AUTHOR("Patrick Bruenn <p.bruenn@beckhoff.com>");
    29 MODULE_AUTHOR("Patrick Bruenn <p.bruenn@beckhoff.com>");
    32 MODULE_LICENSE("GPL");
    30 MODULE_LICENSE("GPL");
    33 MODULE_VERSION(DRV_VERSION);
    31 MODULE_VERSION(DRV_VERSION);
    34 
    32 
    35 static void ccat_bar_free(struct ccat_bar *bar)
    33 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,12,27))
    36 {
    34 /*
    37 	if (bar->ioaddr) {
    35  * Set both the DMA mask and the coherent DMA mask to the same thing.
    38 		const struct ccat_bar tmp = *bar;
    36  * Note that we don't check the return value from dma_set_coherent_mask()
    39 		memset(bar, 0, sizeof(*bar));
    37  * as the DMA API guarantees that the coherent DMA mask can be set to
    40 		iounmap(tmp.ioaddr);
    38  * the same or smaller than the streaming DMA mask.
    41 		release_mem_region(tmp.start, tmp.len);
    39  */
    42 	} else {
    40 static inline int dma_set_mask_and_coherent(struct device *dev, u64 mask)
    43 		pr_warn("%s(): %p was already done.\n", __FUNCTION__, bar);
    41 {
    44 	}
    42 	int rc = dma_set_mask(dev, mask);
    45 }
    43 	if (rc == 0)
       
    44 		dma_set_coherent_mask(dev, mask);
       
    45 	return rc;
       
    46 }
       
    47 #endif
    46 
    48 
    47 /**
    49 /**
    48  * ccat_bar_init() - Initialize a CCAT pci bar
    50  * configure the drivers capabilities here
    49  * @bar object which should be initialized
       
    50  * @index 0 and 2 are valid for CCAT, meaning pci bar0 or pci bar2
       
    51  * @pdev the pci device as which the CCAT was recognized before
       
    52  *
       
    53  * Reading PCI config space; request and map memory region.
       
    54  */
    51  */
    55 static int ccat_bar_init(struct ccat_bar *bar, size_t index,
    52 static const struct ccat_driver *const drivers[] = {
    56 			 struct pci_dev *pdev)
    53 #ifdef CONFIG_PCI
    57 {
    54 	&eth_dma_driver,	/* load Ethernet MAC/EtherCAT Master driver with DMA support from netdev.c */
    58 	struct resource *res;
    55 #endif
    59 
    56 	&eth_eim_driver,	/* load Ethernet MAC/EtherCAT Master driver without DMA support from */
    60 	bar->start = pci_resource_start(pdev, index);
    57 	&gpio_driver,		/* load GPIO driver from gpio.c */
    61 	bar->end = pci_resource_end(pdev, index);
    58 	&sram_driver,		/* load SRAM driver from sram.c */
    62 	bar->len = pci_resource_len(pdev, index);
    59 	&update_driver,		/* load Update driver from update.c */
    63 	bar->flags = pci_resource_flags(pdev, index);
    60 };
    64 	if (!(IORESOURCE_MEM & bar->flags)) {
    61 
    65 		pr_info("bar%llu is no mem_region -> abort.\n", (u64) index);
    62 static int __init ccat_class_init(struct ccat_class *base)
    66 		return -EIO;
    63 {
    67 	}
    64 	if (1 == atomic_inc_return(&base->instances)) {
    68 
    65 		if (alloc_chrdev_region
    69 	res = request_mem_region(bar->start, bar->len, KBUILD_MODNAME);
    66 		    (&base->dev, 0, base->count, KBUILD_MODNAME)) {
    70 	if (!res) {
    67 			pr_warn("alloc_chrdev_region() for '%s' failed\n",
    71 		pr_info("allocate mem_region failed.\n");
    68 				base->name);
    72 		return -EIO;
    69 			return -1;
    73 	}
    70 		}
    74 	pr_debug("bar%llu at [%lx,%lx] len=%lu res: %p.\n", (u64) index,
    71 
    75 		 bar->start, bar->end, bar->len, res);
    72 		base->class = class_create(THIS_MODULE, base->name);
    76 
    73 		if (!base->class) {
    77 	bar->ioaddr = ioremap(bar->start, bar->len);
    74 			pr_warn("Create device class '%s' failed\n",
    78 	if (!bar->ioaddr) {
    75 				base->name);
    79 		pr_info("bar%llu ioremap failed.\n", (u64) index);
    76 			unregister_chrdev_region(base->dev, base->count);
    80 		release_mem_region(bar->start, bar->len);
    77 			return -1;
    81 		return -EIO;
    78 		}
    82 	}
    79 	}
    83 	pr_debug("bar%llu I/O mem mapped to %p.\n", (u64) index, bar->ioaddr);
    80 	return 0;
    84 	return 0;
    81 }
    85 }
    82 
    86 
    83 static void ccat_class_exit(struct ccat_class *base)
    87 void ccat_dma_free(struct ccat_dma *const dma)
    84 {
    88 {
    85 	if (!atomic_dec_return(&base->instances)) {
    89 	const struct ccat_dma tmp = *dma;
    86 		class_destroy(base->class);
    90 
    87 		unregister_chrdev_region(base->dev, base->count);
    91 	free_dma(dma->channel);
    88 	}
    92 	memset(dma, 0, sizeof(*dma));
    89 }
    93 	dma_free_coherent(tmp.dev, tmp.size, tmp.virt, tmp.phys);
    90 
    94 }
    91 static void free_ccat_cdev(struct ccat_cdev *ccdev)
    95 
    92 {
    96 /**
    93 	ccat_class_exit(ccdev->class);
    97  * ccat_dma_init() - Initialize CCAT and host memory for DMA transfer
    94 	ccdev->dev = 0;
    98  * @dma object for management data which will be initialized
    95 }
    99  * @channel number of the DMA channel
    96 
   100  * @ioaddr of the pci bar2 configspace used to calculate the address of the pci dma configuration
    97 static struct ccat_cdev *alloc_ccat_cdev(struct ccat_class *base)
   101  * @dev which should be configured for DMA
    98 {
   102  */
    99 	int i = 0;
   103 int ccat_dma_init(struct ccat_dma *const dma, size_t channel,
   100 
   104 		  void __iomem * const ioaddr, struct device *const dev)
   101 	ccat_class_init(base);
   105 {
   102 	for (i = 0; i < base->count; ++i) {
   106 	void *frame;
   103 		if (base->devices[i].dev == 0) {
   107 	u64 addr;
   104 			base->devices[i].dev = MKDEV(MAJOR(base->dev), i);
   108 	u32 translateAddr;
   105 			return &base->devices[i];
   109 	u32 memTranslate;
   106 		}
   110 	u32 memSize;
   107 	}
   111 	u32 data = 0xffffffff;
   108 	pr_warn("exceeding max. number of '%s' devices (%d)\n",
   112 	u32 offset = (sizeof(u64) * channel) + 0x1000;
   109 		base->class->name, base->count);
   113 
   110 	atomic_dec_return(&base->instances);
   114 	dma->channel = channel;
   111 	return NULL;
   115 	dma->dev = dev;
   112 }
   116 
   113 
   117 	/* calculate size and alignments */
   114 static int ccat_cdev_init(struct cdev *cdev, dev_t dev, struct class *class,
   118 	iowrite32(data, ioaddr + offset);
   115 			  struct file_operations *fops)
   119 	wmb();
   116 {
   120 	data = ioread32(ioaddr + offset);
   117 	if (!device_create
   121 	memTranslate = data & 0xfffffffc;
   118 	    (class, NULL, dev, NULL, "%s%d", class->name, MINOR(dev))) {
   122 	memSize = (~memTranslate) + 1;
   119 		pr_warn("device_create() failed\n");
   123 	dma->size = 2 * memSize - PAGE_SIZE;
       
   124 	dma->virt = dma_zalloc_coherent(dev, dma->size, &dma->phys, GFP_KERNEL);
       
   125 	if (!dma->virt || !dma->phys) {
       
   126 		pr_info("init DMA%llu memory failed.\n", (u64) channel);
       
   127 		return -1;
   120 		return -1;
   128 	}
   121 	}
   129 
   122 
   130 	if (request_dma(channel, KBUILD_MODNAME)) {
   123 	cdev_init(cdev, fops);
   131 		pr_info("request dma channel %llu failed\n", (u64) channel);
   124 	cdev->owner = fops->owner;
   132 		ccat_dma_free(dma);
   125 	if (cdev_add(cdev, dev, 1)) {
       
   126 		pr_warn("add update device failed\n");
       
   127 		device_destroy(class, dev);
   133 		return -1;
   128 		return -1;
   134 	}
   129 	}
   135 
   130 
   136 	translateAddr = (dma->phys + memSize - PAGE_SIZE) & memTranslate;
   131 	pr_info("registered %s%d.\n", class->name, MINOR(dev));
   137 	addr = translateAddr;
   132 	return 0;
   138 	memcpy_toio(ioaddr + offset, &addr, sizeof(addr));
   133 }
   139 	frame = dma->virt + translateAddr - dma->phys;
   134 
   140 	pr_debug
   135 int ccat_cdev_open(struct inode *const i, struct file *const f)
   141 	    ("DMA%llu mem initialized\n virt:         0x%p\n phys:         0x%llx\n translated:   0x%llx\n pci addr:     0x%08x%x\n memTranslate: 0x%x\n size:         %llu bytes.\n",
   136 {
   142 	     (u64) channel, dma->virt, (u64) (dma->phys), addr,
   137 	struct ccat_cdev *ccdev =
   143 	     ioread32(ioaddr + offset + 4), ioread32(ioaddr + offset),
   138 	    container_of(i->i_cdev, struct ccat_cdev, cdev);
   144 	     memTranslate, (u64) dma->size);
   139 	struct cdev_buffer *buf;
   145 	return 0;
   140 
       
   141 	if (!atomic_dec_and_test(&ccdev->in_use)) {
       
   142 		atomic_inc(&ccdev->in_use);
       
   143 		return -EBUSY;
       
   144 	}
       
   145 
       
   146 	buf = kzalloc(sizeof(*buf) + ccdev->iosize, GFP_KERNEL);
       
   147 	if (!buf) {
       
   148 		atomic_inc(&ccdev->in_use);
       
   149 		return -ENOMEM;
       
   150 	}
       
   151 
       
   152 	buf->ccdev = ccdev;
       
   153 	f->private_data = buf;
       
   154 	return 0;
       
   155 }
       
   156 
       
   157 int ccat_cdev_probe(struct ccat_function *func, struct ccat_class *cdev_class,
       
   158 		    size_t iosize)
       
   159 {
       
   160 	struct ccat_cdev *const ccdev = alloc_ccat_cdev(cdev_class);
       
   161 	if (!ccdev) {
       
   162 		return -ENOMEM;
       
   163 	}
       
   164 
       
   165 	ccdev->ioaddr = func->ccat->bar_0 + func->info.addr;
       
   166 	ccdev->iosize = iosize;
       
   167 	atomic_set(&ccdev->in_use, 1);
       
   168 
       
   169 	if (ccat_cdev_init
       
   170 	    (&ccdev->cdev, ccdev->dev, cdev_class->class, &cdev_class->fops)) {
       
   171 		pr_warn("ccat_cdev_probe() failed\n");
       
   172 		free_ccat_cdev(ccdev);
       
   173 		return -1;
       
   174 	}
       
   175 	ccdev->class = cdev_class;
       
   176 	func->private_data = ccdev;
       
   177 	return 0;
       
   178 }
       
   179 
       
   180 int ccat_cdev_release(struct inode *const i, struct file *const f)
       
   181 {
       
   182 	const struct cdev_buffer *const buf = f->private_data;
       
   183 	struct ccat_cdev *const ccdev = buf->ccdev;
       
   184 
       
   185 	kfree(f->private_data);
       
   186 	atomic_inc(&ccdev->in_use);
       
   187 	return 0;
       
   188 }
       
   189 
       
   190 void ccat_cdev_remove(struct ccat_function *func)
       
   191 {
       
   192 	struct ccat_cdev *const ccdev = func->private_data;
       
   193 
       
   194 	cdev_del(&ccdev->cdev);
       
   195 	device_destroy(ccdev->class->class, ccdev->dev);
       
   196 	free_ccat_cdev(ccdev);
       
   197 }
       
   198 
       
   199 static const struct ccat_driver *ccat_function_connect(struct ccat_function
       
   200 						       *const func)
       
   201 {
       
   202 	int i;
       
   203 
       
   204 	for (i = 0; i < ARRAY_SIZE(drivers); ++i) {
       
   205 		if (func->info.type == drivers[i]->type) {
       
   206 			return drivers[i]->probe(func) ? NULL : drivers[i];
       
   207 		}
       
   208 	}
       
   209 	return NULL;
   146 }
   210 }
   147 
   211 
   148 /**
   212 /**
   149  * Initialize all available CCAT functions.
   213  * Initialize all available CCAT functions.
   150  *
   214  *
   151  * Return: count of failed functions
   215  * Return: count of failed functions
   152  */
   216  */
   153 static int ccat_functions_init(struct ccat_device *const ccatdev)
   217 static int ccat_functions_init(struct ccat_device *const ccatdev)
   154 {
   218 {
   155 	static const size_t block_size = sizeof(struct ccat_info_block);
   219 	static const size_t block_size = sizeof(struct ccat_info_block);
   156 	void __iomem *addr = ccatdev->bar[0].ioaddr; /** first block is the CCAT information block entry */
   220 	struct ccat_function *next = kzalloc(sizeof(*next), GFP_KERNEL);
       
   221 	void __iomem *addr = ccatdev->bar_0; /** first block is the CCAT information block entry */
   157 	const u8 num_func = ioread8(addr + 4); /** number of CCAT function blocks is at offset 0x4 */
   222 	const u8 num_func = ioread8(addr + 4); /** number of CCAT function blocks is at offset 0x4 */
   158 	const void __iomem *end = addr + (block_size * num_func);
   223 	const void __iomem *end = addr + (block_size * num_func);
   159 	int status = 0;	/** count init function failures */
   224 
   160 
   225 	INIT_LIST_HEAD(&ccatdev->functions);
   161 	while (addr < end) {
   226 	for (; addr < end && next; addr += block_size) {
   162 		const u8 type = ioread16(addr);
   227 		memcpy_fromio(&next->info, addr, sizeof(next->info));
   163 		switch (type) {
   228 		if (CCATINFO_NOTUSED != next->info.type) {
   164 		case CCATINFO_NOTUSED:
   229 			next->ccat = ccatdev;
   165 			break;
   230 			next->drv = ccat_function_connect(next);
   166 		case CCATINFO_EPCS_PROM:
   231 			if (next->drv) {
   167 			pr_info("Found: CCAT update(EPCS_PROM) -> init()\n");
   232 				list_add(&next->list, &ccatdev->functions);
   168 			ccatdev->update = ccat_update_init(ccatdev, addr);
   233 				next = kzalloc(sizeof(*next), GFP_KERNEL);
   169 			status += (NULL == ccatdev->update);
   234 			}
   170 			break;
   235 		}
   171 		case CCATINFO_ETHERCAT_MASTER_DMA:
   236 	}
   172 			pr_info("Found: ETHERCAT_MASTER_DMA -> init()\n");
   237 	kfree(next);
   173 			ccatdev->ethdev = ccat_eth_init(ccatdev, addr);
   238 	return list_empty(&ccatdev->functions);
   174 			status += (NULL == ccatdev->ethdev);
       
   175 			break;
       
   176 		default:
       
   177 			pr_info("Found: 0x%04x not supported\n", type);
       
   178 			break;
       
   179 		}
       
   180 		addr += block_size;
       
   181 	}
       
   182 	return status;
       
   183 }
   239 }
   184 
   240 
   185 /**
   241 /**
   186  * Destroy all previously initialized CCAT functions
   242  * Destroy all previously initialized CCAT functions
   187  */
   243  */
   188 static void ccat_functions_remove(struct ccat_device *const ccatdev)
   244 static void ccat_functions_remove(struct ccat_device *const dev)
   189 {
   245 {
   190 	if (!ccatdev->ethdev) {
   246 	struct ccat_function *func;
   191 		pr_warn("%s(): 'ethdev' was not initialized.\n", __FUNCTION__);
   247 	struct ccat_function *tmp;
   192 	} else {
   248 	list_for_each_entry_safe(func, tmp, &dev->functions, list) {
   193 		struct ccat_eth_priv *const ethdev = ccatdev->ethdev;
   249 		if (func->drv) {
   194 		ccatdev->ethdev = NULL;
   250 			func->drv->remove(func);
   195 		ccat_eth_remove(ethdev);
   251 			func->drv = NULL;
   196 	}
   252 		}
   197 	if (!ccatdev->update) {
   253 		list_del(&func->list);
   198 		pr_warn("%s(): 'update' was not initialized.\n", __FUNCTION__);
   254 		kfree(func);
   199 	} else {
   255 	}
   200 		struct ccat_update *const update = ccatdev->update;
   256 }
   201 		ccatdev->update = NULL;
   257 
   202 		ccat_update_remove(update);
   258 #ifdef CONFIG_PCI
   203 	}
   259 static int ccat_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
   204 }
   260 {
   205 
   261 	struct ccat_device *ccatdev;
   206 static int ccat_probe(struct pci_dev *pdev, const struct pci_device_id *id)
   262 	u8 rev;
   207 {
       
   208 	int status;
   263 	int status;
   209 	u8 revision;
   264 
   210 	struct ccat_device *ccatdev = kmalloc(sizeof(*ccatdev), GFP_KERNEL);
   265 	ccatdev = devm_kzalloc(&pdev->dev, sizeof(*ccatdev), GFP_KERNEL);
   211 
       
   212 	if (!ccatdev) {
   266 	if (!ccatdev) {
   213 		pr_err("%s() out of memory.\n", __FUNCTION__);
   267 		pr_err("%s() out of memory.\n", __FUNCTION__);
   214 		return -ENOMEM;
   268 		return -ENOMEM;
   215 	}
   269 	}
   216 	memset(ccatdev, 0, sizeof(*ccatdev));
       
   217 	ccatdev->pdev = pdev;
   270 	ccatdev->pdev = pdev;
   218 	pci_set_drvdata(pdev, ccatdev);
   271 	pci_set_drvdata(pdev, ccatdev);
   219 
   272 
   220 	status = pci_enable_device_mem(pdev);
   273 	status = pci_enable_device_mem(pdev);
   221 	if (status) {
   274 	if (status) {
   222 		pr_info("enable %s failed: %d\n", pdev->dev.kobj.name, status);
   275 		pr_err("enable %s failed: %d\n", pdev->dev.kobj.name, status);
   223 		return status;
   276 		return status;
   224 	}
   277 	}
   225 
   278 
   226 	status = pci_read_config_byte(pdev, PCI_REVISION_ID, &revision);
   279 	status = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
   227 	if (status) {
   280 	if (status) {
   228 		pr_warn("read CCAT pci revision failed with %d\n", status);
   281 		pr_err("read CCAT pci revision failed with %d\n", status);
   229 		return status;
   282 		goto disable_device;
   230 	}
   283 	}
   231 
   284 
   232 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
   285 	status = pci_request_regions(pdev, KBUILD_MODNAME);
   233 	if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) {
   286 	if (status) {
   234 		pr_debug("64 bit DMA supported, pci rev: %u\n", revision);
   287 		pr_err("allocate mem_regions failed.\n");
   235 	} else if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
   288 		goto disable_device;
   236 		pr_debug("32 bit DMA supported, pci rev: %u\n", revision);
   289 	}
       
   290 
       
   291 	status = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
       
   292 	if (status) {
       
   293 		status =
       
   294 		    dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
       
   295 		if (status) {
       
   296 			pr_err("No suitable DMA available, pci rev: %u\n", rev);
       
   297 			goto release_regions;
       
   298 		}
       
   299 		pr_debug("32 bit DMA supported, pci rev: %u\n", rev);
   237 	} else {
   300 	} else {
   238 		pr_warn("No suitable DMA available, pci rev: %u\n", revision);
   301 		pr_debug("64 bit DMA supported, pci rev: %u\n", rev);
   239 	}
   302 	}
   240 #else
   303 
   241 	if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
   304 	ccatdev->bar_0 = pci_iomap(pdev, 0, 0);
   242 		pr_debug("64 bit DMA supported, pci rev: %u\n", revision);
   305 	if (!ccatdev->bar_0) {
   243 	} else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
   306 		pr_err("initialization of bar0 failed.\n");
   244 		pr_debug("32 bit DMA supported, pci rev: %u\n", revision);
   307 		status = -EIO;
   245 	} else {
   308 		goto release_regions;
   246 		pr_warn("No suitable DMA available, pci rev: %u\n", revision);
   309 	}
   247 	}
   310 
   248 #endif
   311 	ccatdev->bar_2 = pci_iomap(pdev, 2, 0);
   249 
   312 	if (!ccatdev->bar_2) {
   250 	if (ccat_bar_init(&ccatdev->bar[0], 0, pdev)) {
   313 		pr_warn("initialization of optional bar2 failed.\n");
   251 		pr_warn("initialization of bar0 failed.\n");
       
   252 		return -EIO;
       
   253 	}
       
   254 
       
   255 	if (ccat_bar_init(&ccatdev->bar[2], 2, pdev)) {
       
   256 		pr_warn("initialization of bar2 failed.\n");
       
   257 		return -EIO;
       
   258 	}
   314 	}
   259 
   315 
   260 	pci_set_master(pdev);
   316 	pci_set_master(pdev);
   261 	if (ccat_functions_init(ccatdev)) {
   317 	if (ccat_functions_init(ccatdev)) {
   262 		pr_warn("some functions couldn't be initialized\n");
   318 		pr_warn("some functions couldn't be initialized\n");
   263 	}
   319 	}
   264 	return 0;
   320 	return 0;
   265 }
   321 
   266 
   322 release_regions:
   267 static void ccat_remove(struct pci_dev *pdev)
   323 	pci_release_regions(pdev);
       
   324 disable_device:
       
   325 	pci_disable_device(pdev);
       
   326 	return status;
       
   327 }
       
   328 
       
   329 static void ccat_pci_remove(struct pci_dev *pdev)
   268 {
   330 {
   269 	struct ccat_device *ccatdev = pci_get_drvdata(pdev);
   331 	struct ccat_device *ccatdev = pci_get_drvdata(pdev);
   270 
   332 
   271 	if (ccatdev) {
   333 	if (ccatdev) {
   272 		ccat_functions_remove(ccatdev);
   334 		ccat_functions_remove(ccatdev);
   273 		ccat_bar_free(&ccatdev->bar[2]);
   335 		if (ccatdev->bar_2)
   274 		ccat_bar_free(&ccatdev->bar[0]);
   336 			pci_iounmap(pdev, ccatdev->bar_2);
       
   337 		pci_iounmap(pdev, ccatdev->bar_0);
       
   338 		pci_release_regions(pdev);
   275 		pci_disable_device(pdev);
   339 		pci_disable_device(pdev);
   276 		pci_set_drvdata(pdev, NULL);
   340 	}
   277 		kfree(ccatdev);
       
   278 	}
       
   279 	pr_debug("%s() done.\n", __FUNCTION__);
       
   280 }
   341 }
   281 
   342 
   282 #define PCI_DEVICE_ID_BECKHOFF_CCAT 0x5000
   343 #define PCI_DEVICE_ID_BECKHOFF_CCAT 0x5000
   283 #define PCI_VENDOR_ID_BECKHOFF 0x15EC
   344 #define PCI_VENDOR_ID_BECKHOFF 0x15EC
   284 
   345 
   285 static const struct pci_device_id pci_ids[] = {
   346 static const struct pci_device_id pci_ids[] = {
   286 	{PCI_DEVICE(PCI_VENDOR_ID_BECKHOFF, PCI_DEVICE_ID_BECKHOFF_CCAT)},
   347 	{PCI_DEVICE(PCI_VENDOR_ID_BECKHOFF, PCI_DEVICE_ID_BECKHOFF_CCAT)},
   287 	{0,},
   348 	{0,},
   288 };
   349 };
   289 
   350 
   290 #if 0 /* prevent auto-loading */
       
   291 MODULE_DEVICE_TABLE(pci, pci_ids);
   351 MODULE_DEVICE_TABLE(pci, pci_ids);
   292 #endif
   352 
   293 
   353 static struct pci_driver ccat_pci_driver = {
   294 static struct pci_driver pci_driver = {
       
   295 	.name = KBUILD_MODNAME,
   354 	.name = KBUILD_MODNAME,
   296 	.id_table = pci_ids,
   355 	.id_table = pci_ids,
   297 	.probe = ccat_probe,
   356 	.probe = ccat_pci_probe,
   298 	.remove = ccat_remove,
   357 	.remove = ccat_pci_remove,
   299 };
   358 };
   300 
   359 
   301 static void __exit ccat_exit_module(void)
   360 module_pci_driver(ccat_pci_driver);
   302 {
   361 
   303 	pci_unregister_driver(&pci_driver);
   362 #else /* #ifdef CONFIG_PCI */
   304 }
   363 
   305 
   364 static int ccat_eim_probe(struct platform_device *pdev)
   306 static int __init ccat_init_module(void)
   365 {
   307 {
   366 	struct ccat_device *ccatdev;
   308 	pr_info("%s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
   367 
   309 	return pci_register_driver(&pci_driver);
   368 	ccatdev = devm_kzalloc(&pdev->dev, sizeof(*ccatdev), GFP_KERNEL);
   310 }
   369 	if (!ccatdev) {
   311 
   370 		pr_err("%s() out of memory.\n", __FUNCTION__);
   312 module_exit(ccat_exit_module);
   371 		return -ENOMEM;
   313 module_init(ccat_init_module);
   372 	}
       
   373 	ccatdev->pdev = pdev;
       
   374 	platform_set_drvdata(pdev, ccatdev);
       
   375 
       
   376 	if (!request_mem_region(0xf0000000, 0x02000000, pdev->name)) {
       
   377 		pr_warn("request mem region failed.\n");
       
   378 		return -EIO;
       
   379 	}
       
   380 
       
   381 	if (!(ccatdev->bar_0 = ioremap(0xf0000000, 0x02000000))) {
       
   382 		pr_warn("initialization of bar0 failed.\n");
       
   383 		return -EIO;
       
   384 	}
       
   385 
       
   386 	ccatdev->bar_2 = NULL;
       
   387 
       
   388 	if (ccat_functions_init(ccatdev)) {
       
   389 		pr_warn("some functions couldn't be initialized\n");
       
   390 	}
       
   391 	return 0;
       
   392 }
       
   393 
       
   394 static int ccat_eim_remove(struct platform_device *pdev)
       
   395 {
       
   396 	struct ccat_device *ccatdev = platform_get_drvdata(pdev);
       
   397 
       
   398 	if (ccatdev) {
       
   399 		ccat_functions_remove(ccatdev);
       
   400 		iounmap(ccatdev->bar_0);
       
   401 		release_mem_region(0xf0000000, 0x02000000);
       
   402 	}
       
   403 	return 0;
       
   404 }
       
   405 
       
   406 static const struct of_device_id bhf_eim_ccat_ids[] = {
       
   407 	{.compatible = "bhf,emi-ccat",},
       
   408 	{}
       
   409 };
       
   410 
       
   411 MODULE_DEVICE_TABLE(of, bhf_eim_ccat_ids);
       
   412 
       
   413 static struct platform_driver ccat_eim_driver = {
       
   414 	.driver = {
       
   415 		   .name = KBUILD_MODNAME,
       
   416 		   .of_match_table = bhf_eim_ccat_ids,
       
   417 		   },
       
   418 	.probe = ccat_eim_probe,
       
   419 	.remove = ccat_eim_remove,
       
   420 };
       
   421 
       
   422 module_platform_driver(ccat_eim_driver);
       
   423 #endif /* #ifdef CONFIG_PCI */