diff options
-rw-r--r-- | drivers/staging/comedi/drivers/ii_pci20kc.c | 32 |
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 | ||
530 | static 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 | |||
512 | static struct comedi_driver ii20k_driver = { | 538 | static 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 | }; |
518 | module_comedi_driver(ii20k_driver); | 544 | module_comedi_driver(ii20k_driver); |
519 | 545 | ||