aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/comedi/drivers/ii_pci20kc.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
index b1f44b31162b..687db433e131 100644
--- a/drivers/staging/comedi/drivers/ii_pci20kc.c
+++ b/drivers/staging/comedi/drivers/ii_pci20kc.c
@@ -33,6 +33,7 @@
33/* 33/*
34 * Register I/O map 34 * Register I/O map
35 */ 35 */
36#define II20K_SIZE 0x400
36#define II20K_MOD_OFFSET 0x100 37#define II20K_MOD_OFFSET 0x100
37#define II20K_ID_REG 0x00 38#define II20K_ID_REG 0x00
38#define II20K_ID_MOD1_EMPTY (1 << 7) 39#define II20K_ID_MOD1_EMPTY (1 << 7)
@@ -439,12 +440,29 @@ static int ii20k_attach(struct comedi_device *dev,
439 struct comedi_devconfig *it) 440 struct comedi_devconfig *it)
440{ 441{
441 struct comedi_subdevice *s; 442 struct comedi_subdevice *s;
443 unsigned int membase;
442 unsigned char id; 444 unsigned char id;
443 bool has_dio; 445 bool has_dio;
444 int ret; 446 int ret;
445 447
446 /* FIXME: this doesn't seem right, should 'mmio' be ioremap'ed? */ 448 membase = it->options[0];
447 dev->mmio = (void __iomem *)(unsigned long)it->options[0]; 449 if (!membase || (membase & ~(0x100000 - II20K_SIZE))) {
450 dev_warn(dev->class_dev,
451 "%s: invalid memory address specified\n",
452 dev->board_name);
453 return -EINVAL;
454 }
455
456 if (!request_mem_region(membase, II20K_SIZE, dev->board_name)) {
457 dev_warn(dev->class_dev, "%s: I/O mem conflict (%#x,%u)\n",
458 dev->board_name, membase, II20K_SIZE);
459 return -EIO;
460 }
461 dev->iobase = membase; /* actually, a memory address */
462
463 dev->mmio = ioremap(membase, II20K_SIZE);
464 if (!dev->mmio)
465 return -ENOMEM;
448 466
449 id = readb(dev->mmio + II20K_ID_REG); 467 id = readb(dev->mmio + II20K_ID_REG);
450 switch (id & II20K_ID_MASK) { 468 switch (id & II20K_ID_MASK) {
@@ -509,11 +527,19 @@ static int ii20k_attach(struct comedi_device *dev,
509 return 0; 527 return 0;
510} 528}
511 529
530static void ii20k_detach(struct comedi_device *dev)
531{
532 if (dev->mmio)
533 iounmap(dev->mmio);
534 if (dev->iobase) /* actually, a memory address */
535 release_mem_region(dev->iobase, II20K_SIZE);
536}
537
512static struct comedi_driver ii20k_driver = { 538static struct comedi_driver ii20k_driver = {
513 .driver_name = "ii_pci20kc", 539 .driver_name = "ii_pci20kc",
514 .module = THIS_MODULE, 540 .module = THIS_MODULE,
515 .attach = ii20k_attach, 541 .attach = ii20k_attach,
516 .detach = comedi_legacy_detach, 542 .detach = ii20k_detach,
517}; 543};
518module_comedi_driver(ii20k_driver); 544module_comedi_driver(ii20k_driver);
519 545