diff options
Diffstat (limited to 'drivers/comedi')
44 files changed, 592 insertions, 341 deletions
diff --git a/drivers/comedi/Kconfig b/drivers/comedi/Kconfig index 9af280735cba..93c68a40a17b 100644 --- a/drivers/comedi/Kconfig +++ b/drivers/comedi/Kconfig @@ -67,6 +67,7 @@ config COMEDI_TEST config COMEDI_PARPORT tristate "Parallel port support" + depends on HAS_IOPORT help Enable support for the standard parallel port. A cheap and easy way to get a few more digital I/O lines. Steal @@ -79,6 +80,7 @@ config COMEDI_PARPORT config COMEDI_SSV_DNP tristate "SSV Embedded Systems DIL/Net-PC support" depends on X86_32 || COMPILE_TEST + depends on HAS_IOPORT help Enable support for SSV Embedded Systems DIL/Net-PC @@ -89,6 +91,8 @@ endif # COMEDI_MISC_DRIVERS menuconfig COMEDI_ISA_DRIVERS bool "Comedi ISA and PC/104 drivers" + depends on ISA || ISA_BUS || PC104 + depends on HAS_IOPORT help Enable comedi ISA and PC/104 drivers to be built @@ -589,6 +593,7 @@ config COMEDI_8255_PCI config COMEDI_ADDI_WATCHDOG tristate + depends on HAS_IOPORT help Provides support for the watchdog subdevice found on many ADDI-DATA boards. This module will be automatically selected when needed. The @@ -596,6 +601,7 @@ config COMEDI_ADDI_WATCHDOG config COMEDI_ADDI_APCI_1032 tristate "ADDI-DATA APCI_1032 support" + depends on HAS_IOPORT help Enable support for ADDI-DATA APCI_1032 cards @@ -604,6 +610,7 @@ config COMEDI_ADDI_APCI_1032 config COMEDI_ADDI_APCI_1500 tristate "ADDI-DATA APCI_1500 support" + depends on HAS_IOPORT help Enable support for ADDI-DATA APCI_1500 cards @@ -612,6 +619,7 @@ config COMEDI_ADDI_APCI_1500 config COMEDI_ADDI_APCI_1516 tristate "ADDI-DATA APCI-1016/1516/2016 support" + depends on HAS_IOPORT select COMEDI_ADDI_WATCHDOG help Enable support for ADDI-DATA APCI-1016, APCI-1516 and APCI-2016 boards. @@ -623,6 +631,7 @@ config COMEDI_ADDI_APCI_1516 config COMEDI_ADDI_APCI_1564 tristate "ADDI-DATA APCI_1564 support" + depends on HAS_IOPORT select COMEDI_ADDI_WATCHDOG help Enable support for ADDI-DATA APCI_1564 cards @@ -632,6 +641,7 @@ config COMEDI_ADDI_APCI_1564 config COMEDI_ADDI_APCI_16XX tristate "ADDI-DATA APCI_16xx support" + depends on HAS_IOPORT help Enable support for ADDI-DATA APCI_16xx cards @@ -640,6 +650,7 @@ config COMEDI_ADDI_APCI_16XX config COMEDI_ADDI_APCI_2032 tristate "ADDI-DATA APCI_2032 support" + depends on HAS_IOPORT select COMEDI_ADDI_WATCHDOG help Enable support for ADDI-DATA APCI_2032 cards @@ -649,6 +660,7 @@ config COMEDI_ADDI_APCI_2032 config COMEDI_ADDI_APCI_2200 tristate "ADDI-DATA APCI_2200 support" + depends on HAS_IOPORT select COMEDI_ADDI_WATCHDOG help Enable support for ADDI-DATA APCI_2200 cards @@ -658,6 +670,7 @@ config COMEDI_ADDI_APCI_2200 config COMEDI_ADDI_APCI_3120 tristate "ADDI-DATA APCI_3120/3001 support" + depends on HAS_IOPORT depends on HAS_DMA help Enable support for ADDI-DATA APCI_3120/3001 cards @@ -667,6 +680,7 @@ config COMEDI_ADDI_APCI_3120 config COMEDI_ADDI_APCI_3501 tristate "ADDI-DATA APCI_3501 support" + depends on HAS_IOPORT help Enable support for ADDI-DATA APCI_3501 cards @@ -675,6 +689,7 @@ config COMEDI_ADDI_APCI_3501 config COMEDI_ADDI_APCI_3XXX tristate "ADDI-DATA APCI_3xxx support" + depends on HAS_IOPORT help Enable support for ADDI-DATA APCI_3xxx cards @@ -683,6 +698,7 @@ config COMEDI_ADDI_APCI_3XXX config COMEDI_ADL_PCI6208 tristate "ADLink PCI-6208A support" + depends on HAS_IOPORT help Enable support for ADLink PCI-6208A cards @@ -691,6 +707,7 @@ config COMEDI_ADL_PCI6208 config COMEDI_ADL_PCI7X3X tristate "ADLink PCI-723X/743X isolated digital i/o board support" + depends on HAS_IOPORT help Enable support for ADlink PCI-723X/743X isolated digital i/o boards. Supported boards include the 32-channel PCI-7230 (16 in/16 out), @@ -702,6 +719,7 @@ config COMEDI_ADL_PCI7X3X config COMEDI_ADL_PCI8164 tristate "ADLink PCI-8164 4 Axes Motion Control board support" + depends on HAS_IOPORT help Enable support for ADlink PCI-8164 4 Axes Motion Control board @@ -710,6 +728,7 @@ config COMEDI_ADL_PCI8164 config COMEDI_ADL_PCI9111 tristate "ADLink PCI-9111HR support" + depends on HAS_IOPORT select COMEDI_8254 help Enable support for ADlink PCI9111 cards @@ -719,6 +738,7 @@ config COMEDI_ADL_PCI9111 config COMEDI_ADL_PCI9118 tristate "ADLink PCI-9118DG, PCI-9118HG, PCI-9118HR support" + depends on HAS_IOPORT depends on HAS_DMA select COMEDI_8254 help @@ -729,6 +749,7 @@ config COMEDI_ADL_PCI9118 config COMEDI_ADV_PCI1710 tristate "Advantech PCI-171x and PCI-1731 support" + depends on HAS_IOPORT select COMEDI_8254 help Enable support for Advantech PCI-1710, PCI-1710HG, PCI-1711, @@ -739,6 +760,7 @@ config COMEDI_ADV_PCI1710 config COMEDI_ADV_PCI1720 tristate "Advantech PCI-1720 support" + depends on HAS_IOPORT help Enable support for Advantech PCI-1720 Analog Output board. @@ -747,6 +769,7 @@ config COMEDI_ADV_PCI1720 config COMEDI_ADV_PCI1723 tristate "Advantech PCI-1723 support" + depends on HAS_IOPORT help Enable support for Advantech PCI-1723 cards @@ -755,6 +778,7 @@ config COMEDI_ADV_PCI1723 config COMEDI_ADV_PCI1724 tristate "Advantech PCI-1724U support" + depends on HAS_IOPORT help Enable support for Advantech PCI-1724U cards. These are 32-channel analog output cards with voltage and current loop output ranges and @@ -765,6 +789,7 @@ config COMEDI_ADV_PCI1724 config COMEDI_ADV_PCI1760 tristate "Advantech PCI-1760 support" + depends on HAS_IOPORT help Enable support for Advantech PCI-1760 board. @@ -773,6 +798,7 @@ config COMEDI_ADV_PCI1760 config COMEDI_ADV_PCI_DIO tristate "Advantech PCI DIO card support" + depends on HAS_IOPORT select COMEDI_8254 select COMEDI_8255 help @@ -796,6 +822,7 @@ config COMEDI_AMPLC_DIO200_PCI config COMEDI_AMPLC_PC236_PCI tristate "Amplicon PCI236 DIO board support" + depends on HAS_IOPORT select COMEDI_AMPLC_PC236 help Enable support for Amplicon PCI236 DIO board. @@ -805,6 +832,7 @@ config COMEDI_AMPLC_PC236_PCI config COMEDI_AMPLC_PC263_PCI tristate "Amplicon PCI263 relay board support" + depends on HAS_IOPORT help Enable support for Amplicon PCI263 relay board. This is a PCI board with 16 reed relay output channels. @@ -814,6 +842,7 @@ config COMEDI_AMPLC_PC263_PCI config COMEDI_AMPLC_PCI224 tristate "Amplicon PCI224 and PCI234 support" + depends on HAS_IOPORT select COMEDI_8254 help Enable support for Amplicon PCI224 and PCI234 AO boards @@ -823,6 +852,7 @@ config COMEDI_AMPLC_PCI224 config COMEDI_AMPLC_PCI230 tristate "Amplicon PCI230 and PCI260 support" + depends on HAS_IOPORT select COMEDI_8254 select COMEDI_8255 help @@ -834,6 +864,7 @@ config COMEDI_AMPLC_PCI230 config COMEDI_CONTEC_PCI_DIO tristate "Contec PIO1616L digital I/O board support" + depends on HAS_IOPORT help Enable support for the Contec PIO1616L digital I/O board @@ -842,6 +873,7 @@ config COMEDI_CONTEC_PCI_DIO config COMEDI_DAS08_PCI tristate "DAS-08 PCI support" + depends on HAS_IOPORT select COMEDI_DAS08 help Enable support for PCI DAS-08 cards. @@ -861,6 +893,7 @@ config COMEDI_DT3000 config COMEDI_DYNA_PCI10XX tristate "Dynalog PCI DAQ series support" + depends on HAS_IOPORT help Enable support for Dynalog PCI DAQ series PCI-1050 @@ -911,6 +944,7 @@ config COMEDI_JR3_PCI config COMEDI_KE_COUNTER tristate "Kolter-Electronic PCI Counter 1 card support" + depends on HAS_IOPORT help Enable support for Kolter-Electronic PCI Counter 1 cards @@ -929,6 +963,7 @@ config COMEDI_CB_PCIDAS64 config COMEDI_CB_PCIDAS tristate "MeasurementComputing PCI-DAS support" + depends on HAS_IOPORT select COMEDI_8254 select COMEDI_8255 help @@ -942,6 +977,7 @@ config COMEDI_CB_PCIDAS config COMEDI_CB_PCIDDA tristate "MeasurementComputing PCI-DDA series support" + depends on HAS_IOPORT select COMEDI_8255 help Enable support for ComputerBoards/MeasurementComputing PCI-DDA @@ -953,6 +989,7 @@ config COMEDI_CB_PCIDDA config COMEDI_CB_PCIMDAS tristate "MeasurementComputing PCIM-DAS1602/16, PCIe-DAS1602/16 support" + depends on HAS_IOPORT select COMEDI_8254 select COMEDI_8255 help @@ -964,6 +1001,7 @@ config COMEDI_CB_PCIMDAS config COMEDI_CB_PCIMDDA tristate "MeasurementComputing PCIM-DDA06-16 support" + depends on HAS_IOPORT select COMEDI_8255 help Enable support for ComputerBoards/MeasurementComputing PCIM-DDA06-16 @@ -973,6 +1011,7 @@ config COMEDI_CB_PCIMDDA config COMEDI_ME4000 tristate "Meilhaus ME-4000 support" + depends on HAS_IOPORT select COMEDI_8254 help Enable support for Meilhaus PCI data acquisition cards @@ -1042,7 +1081,6 @@ config COMEDI_NI_PCIDIO tristate "NI PCI-DIO32HS, PCI-6533, PCI-6534 support" depends on HAS_DMA select COMEDI_MITE - select COMEDI_8255 help Enable support for National Instruments PCI-DIO-32HS, PXI-6533, PCI-6533 and PCI-6534 @@ -1103,7 +1141,7 @@ endif # COMEDI_PCI_DRIVERS menuconfig COMEDI_PCMCIA_DRIVERS tristate "Comedi PCMCIA drivers" - depends on PCMCIA + depends on PCMCIA && HAS_IOPORT help Enable support for comedi PCMCIA drivers. @@ -1254,6 +1292,7 @@ config COMEDI_8255 config COMEDI_8255_SA tristate "Standalone 8255 support" + depends on HAS_IOPORT select COMEDI_8255 help Enable support for 8255 digital I/O as a standalone driver. @@ -1290,10 +1329,12 @@ config COMEDI_AMPLC_DIO200 config COMEDI_AMPLC_PC236 tristate + depends on HAS_IOPORT select COMEDI_8255 config COMEDI_DAS08 tristate + depends on HAS_IOPORT select COMEDI_8254 select COMEDI_8255 diff --git a/drivers/comedi/drivers.c b/drivers/comedi/drivers.c index d4e2ed709bfc..376130bfba8a 100644 --- a/drivers/comedi/drivers.c +++ b/drivers/comedi/drivers.c @@ -177,7 +177,8 @@ static void comedi_device_detach_cleanup(struct comedi_device *dev) dev->n_subdevices = 0; } kfree(dev->private); - kfree(dev->pacer); + if (!IS_ERR(dev->pacer)) + kfree(dev->pacer); dev->private = NULL; dev->pacer = NULL; dev->driver = NULL; diff --git a/drivers/comedi/drivers/8255.c b/drivers/comedi/drivers/8255.c index ced8ea09d4fa..f45f7bd1c61a 100644 --- a/drivers/comedi/drivers/8255.c +++ b/drivers/comedi/drivers/8255.c @@ -80,7 +80,7 @@ static int dev_8255_attach(struct comedi_device *dev, if (ret) { s->type = COMEDI_SUBD_UNUSED; } else { - ret = subdev_8255_init(dev, s, NULL, iobase); + ret = subdev_8255_io_init(dev, s, iobase); if (ret) { /* * Release the I/O port region here, as the diff --git a/drivers/comedi/drivers/8255_pci.c b/drivers/comedi/drivers/8255_pci.c index 0fec048e3a53..8498cabe4d91 100644 --- a/drivers/comedi/drivers/8255_pci.c +++ b/drivers/comedi/drivers/8255_pci.c @@ -57,6 +57,7 @@ #include <linux/comedi/comedi_8255.h> enum pci_8255_boardid { +#ifdef CONFIG_HAS_IOPORT BOARD_ADLINK_PCI7224, BOARD_ADLINK_PCI7248, BOARD_ADLINK_PCI7296, @@ -65,6 +66,7 @@ enum pci_8255_boardid { BOARD_CB_PCIDIO48H_OLD, BOARD_CB_PCIDIO48H_NEW, BOARD_CB_PCIDIO96H, +#endif /* CONFIG_HAS_IOPORT */ BOARD_NI_PCIDIO96, BOARD_NI_PCIDIO96B, BOARD_NI_PXI6508, @@ -82,6 +84,7 @@ struct pci_8255_boardinfo { }; static const struct pci_8255_boardinfo pci_8255_boards[] = { +#ifdef CONFIG_HAS_IOPORT [BOARD_ADLINK_PCI7224] = { .name = "adl_pci-7224", .dio_badr = 2, @@ -122,6 +125,7 @@ static const struct pci_8255_boardinfo pci_8255_boards[] = { .dio_badr = 2, .n_8255 = 4, }, +#endif /* CONFIG_HAS_IOPORT */ [BOARD_NI_PCIDIO96] = { .name = "ni_pci-dio-96", .dio_badr = 1, @@ -219,8 +223,11 @@ static int pci_8255_auto_attach(struct comedi_device *dev, dev->mmio = pci_ioremap_bar(pcidev, board->dio_badr); if (!dev->mmio) return -ENOMEM; - } else { + } else if (IS_ENABLED(CONFIG_HAS_IOPORT)) { dev->iobase = pci_resource_start(pcidev, board->dio_badr); + } else { + dev_err(dev->class_dev, "error! need I/O port support\n"); + return -ENXIO; } /* @@ -235,9 +242,9 @@ static int pci_8255_auto_attach(struct comedi_device *dev, for (i = 0; i < board->n_8255; i++) { s = &dev->subdevices[i]; if (dev->mmio) - ret = subdev_8255_mm_init(dev, s, NULL, i * I8255_SIZE); + ret = subdev_8255_mm_init(dev, s, i * I8255_SIZE); else - ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE); + ret = subdev_8255_io_init(dev, s, i * I8255_SIZE); if (ret) return ret; } @@ -259,6 +266,7 @@ static int pci_8255_pci_probe(struct pci_dev *dev, } static const struct pci_device_id pci_8255_pci_table[] = { +#ifdef CONFIG_HAS_IOPORT { PCI_VDEVICE(ADLINK, 0x7224), BOARD_ADLINK_PCI7224 }, { PCI_VDEVICE(ADLINK, 0x7248), BOARD_ADLINK_PCI7248 }, { PCI_VDEVICE(ADLINK, 0x7296), BOARD_ADLINK_PCI7296 }, @@ -269,6 +277,7 @@ static const struct pci_device_id pci_8255_pci_table[] = { { PCI_DEVICE_SUB(PCI_VENDOR_ID_CB, 0x000b, PCI_VENDOR_ID_CB, 0x000b), .driver_data = BOARD_CB_PCIDIO48H_NEW }, { PCI_VDEVICE(CB, 0x0017), BOARD_CB_PCIDIO96H }, +#endif /* CONFIG_HAS_IOPORT */ { PCI_VDEVICE(NI, 0x0160), BOARD_NI_PCIDIO96 }, { PCI_VDEVICE(NI, 0x1630), BOARD_NI_PCIDIO96B }, { PCI_VDEVICE(NI, 0x13c0), BOARD_NI_PXI6508 }, diff --git a/drivers/comedi/drivers/adl_pci9111.c b/drivers/comedi/drivers/adl_pci9111.c index c50f94272a74..086d93f40cb9 100644 --- a/drivers/comedi/drivers/adl_pci9111.c +++ b/drivers/comedi/drivers/adl_pci9111.c @@ -647,10 +647,10 @@ static int pci9111_auto_attach(struct comedi_device *dev, dev->irq = pcidev->irq; } - dev->pacer = comedi_8254_init(dev->iobase + PCI9111_8254_BASE_REG, - I8254_OSC_BASE_2MHZ, I8254_IO16, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + PCI9111_8254_BASE_REG, + I8254_OSC_BASE_2MHZ, I8254_IO16, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); ret = comedi_alloc_subdevices(dev, 4); if (ret) diff --git a/drivers/comedi/drivers/adl_pci9118.c b/drivers/comedi/drivers/adl_pci9118.c index 9a816c718303..a76e2666d583 100644 --- a/drivers/comedi/drivers/adl_pci9118.c +++ b/drivers/comedi/drivers/adl_pci9118.c @@ -1524,10 +1524,10 @@ static int pci9118_common_attach(struct comedi_device *dev, devpriv->iobase_a = pci_resource_start(pcidev, 0); dev->iobase = pci_resource_start(pcidev, 2); - dev->pacer = comedi_8254_init(dev->iobase + PCI9118_TIMER_BASE, - I8254_OSC_BASE_4MHZ, I8254_IO32, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + PCI9118_TIMER_BASE, + I8254_OSC_BASE_4MHZ, I8254_IO32, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); pci9118_reset(dev); diff --git a/drivers/comedi/drivers/adv_pci1710.c b/drivers/comedi/drivers/adv_pci1710.c index 4f2639968260..c49b0f1f5228 100644 --- a/drivers/comedi/drivers/adv_pci1710.c +++ b/drivers/comedi/drivers/adv_pci1710.c @@ -767,10 +767,10 @@ static int pci1710_auto_attach(struct comedi_device *dev, return ret; dev->iobase = pci_resource_start(pcidev, 2); - dev->pacer = comedi_8254_init(dev->iobase + PCI171X_TIMER_BASE, - I8254_OSC_BASE_10MHZ, I8254_IO16, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + PCI171X_TIMER_BASE, + I8254_OSC_BASE_10MHZ, I8254_IO16, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); n_subdevices = 1; /* all boards have analog inputs */ if (board->has_ao) diff --git a/drivers/comedi/drivers/adv_pci_dio.c b/drivers/comedi/drivers/adv_pci_dio.c index efa3e46b554b..ca8054504760 100644 --- a/drivers/comedi/drivers/adv_pci_dio.c +++ b/drivers/comedi/drivers/adv_pci_dio.c @@ -642,8 +642,8 @@ static int pci_dio_auto_attach(struct comedi_device *dev, for (j = 0; j < d->chans; j++) { s = &dev->subdevices[subdev++]; - ret = subdev_8255_init(dev, s, NULL, - d->addr + j * I8255_SIZE); + ret = subdev_8255_io_init(dev, s, + d->addr + j * I8255_SIZE); if (ret) return ret; } @@ -664,11 +664,11 @@ static int pci_dio_auto_attach(struct comedi_device *dev, if (board->timer_regbase) { s = &dev->subdevices[subdev++]; - dev->pacer = comedi_8254_init(dev->iobase + - board->timer_regbase, - 0, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = + comedi_8254_io_alloc(dev->iobase + board->timer_regbase, + 0, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); comedi_8254_subdevice_init(s, dev->pacer); } diff --git a/drivers/comedi/drivers/aio_aio12_8.c b/drivers/comedi/drivers/aio_aio12_8.c index 30b8a32204d8..227a86a3a760 100644 --- a/drivers/comedi/drivers/aio_aio12_8.c +++ b/drivers/comedi/drivers/aio_aio12_8.c @@ -206,10 +206,10 @@ static int aio_aio12_8_attach(struct comedi_device *dev, if (ret) return ret; - dev->pacer = comedi_8254_init(dev->iobase + AIO12_8_8254_BASE_REG, - 0, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + AIO12_8_8254_BASE_REG, + 0, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); ret = comedi_alloc_subdevices(dev, 4); if (ret) @@ -247,7 +247,7 @@ static int aio_aio12_8_attach(struct comedi_device *dev, /* Digital I/O subdevice (8255) */ s = &dev->subdevices[2]; - ret = subdev_8255_init(dev, s, NULL, AIO12_8_8255_BASE_REG); + ret = subdev_8255_io_init(dev, s, AIO12_8_8255_BASE_REG); if (ret) return ret; diff --git a/drivers/comedi/drivers/amplc_dio200_common.c b/drivers/comedi/drivers/amplc_dio200_common.c index ff651f2eb86c..b1a9b4c4a185 100644 --- a/drivers/comedi/drivers/amplc_dio200_common.c +++ b/drivers/comedi/drivers/amplc_dio200_common.c @@ -86,6 +86,70 @@ struct dio200_subdev_intr { unsigned int active:1; }; +#ifdef CONFIG_HAS_IOPORT + +static unsigned char dio200___read8(struct comedi_device *dev, + unsigned int offset) +{ + if (dev->mmio) + return readb(dev->mmio + offset); + return inb(dev->iobase + offset); +} + +static void dio200___write8(struct comedi_device *dev, + unsigned int offset, unsigned char val) +{ + if (dev->mmio) + writeb(val, dev->mmio + offset); + else + outb(val, dev->iobase + offset); +} + +static unsigned int dio200___read32(struct comedi_device *dev, + unsigned int offset) +{ + if (dev->mmio) + return readl(dev->mmio + offset); + return inl(dev->iobase + offset); +} + +static void dio200___write32(struct comedi_device *dev, + unsigned int offset, unsigned int val) +{ + if (dev->mmio) + writel(val, dev->mmio + offset); + else + outl(val, dev->iobase + offset); +} + +#else /* CONFIG_HAS_IOPORT */ + +static unsigned char dio200___read8(struct comedi_device *dev, + unsigned int offset) +{ + return readb(dev->mmio + offset); +} + +static void dio200___write8(struct comedi_device *dev, + unsigned int offset, unsigned char val) +{ + writeb(val, dev->mmio + offset); +} + +static unsigned int dio200___read32(struct comedi_device *dev, + unsigned int offset) +{ + return readl(dev->mmio + offset); +} + +static void dio200___write32(struct comedi_device *dev, + unsigned int offset, unsigned int val) +{ + writel(val, dev->mmio + offset); +} + +#endif /* CONFIG_HAS_IOPORT */ + static unsigned char dio200_read8(struct comedi_device *dev, unsigned int offset) { @@ -94,9 +158,7 @@ static unsigned char dio200_read8(struct comedi_device *dev, if (board->is_pcie) offset <<= 3; - if (dev->mmio) - return readb(dev->mmio + offset); - return inb(dev->iobase + offset); + return dio200___read8(dev, offset); } static void dio200_write8(struct comedi_device *dev, @@ -107,10 +169,7 @@ static void dio200_write8(struct comedi_device *dev, if (board->is_pcie) offset <<= 3; - if (dev->mmio) - writeb(val, dev->mmio + offset); - else - outb(val, dev->iobase + offset); + dio200___write8(dev, offset, val); } static unsigned int dio200_read32(struct comedi_device *dev, @@ -121,9 +180,7 @@ static unsigned int dio200_read32(struct comedi_device *dev, if (board->is_pcie) offset <<= 3; - if (dev->mmio) - return readl(dev->mmio + offset); - return inl(dev->iobase + offset); + return dio200___read32(dev, offset); } static void dio200_write32(struct comedi_device *dev, @@ -134,10 +191,7 @@ static void dio200_write32(struct comedi_device *dev, if (board->is_pcie) offset <<= 3; - if (dev->mmio) - writel(val, dev->mmio + offset); - else - outl(val, dev->iobase + offset); + dio200___write32(dev, offset, val); } static unsigned int dio200_subdev_8254_offset(struct comedi_device *dev, @@ -149,9 +203,9 @@ static unsigned int dio200_subdev_8254_offset(struct comedi_device *dev, /* get the offset that was passed to comedi_8254_*_init() */ if (dev->mmio) - offset = i8254->mmio - dev->mmio; + offset = (void __iomem *)i8254->context - dev->mmio; else - offset = i8254->iobase - dev->iobase; + offset = i8254->context - dev->iobase; /* remove the shift that was added for PCIe boards */ if (board->is_pcie) @@ -556,14 +610,14 @@ static int dio200_subdev_8254_init(struct comedi_device *dev, } if (dev->mmio) { - i8254 = comedi_8254_mm_init(dev->mmio + offset, - 0, I8254_IO8, regshift); + i8254 = comedi_8254_mm_alloc(dev->mmio + offset, + 0, I8254_IO8, regshift); } else { - i8254 = comedi_8254_init(dev->iobase + offset, - 0, I8254_IO8, regshift); + i8254 = comedi_8254_io_alloc(dev->iobase + offset, + 0, I8254_IO8, regshift); } - if (!i8254) - return -ENOMEM; + if (IS_ERR(i8254)) + return PTR_ERR(i8254); comedi_8254_subdevice_init(s, i8254); @@ -779,6 +833,12 @@ int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq, unsigned int n; int ret; + if (!IS_ENABLED(CONFIG_HAS_IOPORT) && !dev->mmio) { + dev_err(dev->class_dev, + "error! need I/O port support\n"); + return -ENXIO; + } + ret = comedi_alloc_subdevices(dev, board->n_subdevs); if (ret) return ret; diff --git a/drivers/comedi/drivers/amplc_dio200_pci.c b/drivers/comedi/drivers/amplc_dio200_pci.c index 527994d82a1f..cb5b328a28e3 100644 --- a/drivers/comedi/drivers/amplc_dio200_pci.c +++ b/drivers/comedi/drivers/amplc_dio200_pci.c @@ -223,14 +223,17 @@ */ enum dio200_pci_model { +#ifdef CONFIG_HAS_IOPORT pci215_model, pci272_model, +#endif /* CONFIG_HAS_IOPORT */ pcie215_model, pcie236_model, pcie296_model }; static const struct dio200_board dio200_pci_boards[] = { +#ifdef CONFIG_HAS_IOPORT [pci215_model] = { .name = "pci215", .mainbar = 2, @@ -252,6 +255,7 @@ static const struct dio200_board dio200_pci_boards[] = { .sdinfo = { 0x00, 0x08, 0x10, 0x3f }, .has_int_sce = true, }, +#endif /* CONFIG_HAS_IOPORT */ [pcie215_model] = { .name = "pcie215", .mainbar = 1, @@ -364,8 +368,12 @@ static int dio200_pci_auto_attach(struct comedi_device *dev, "error! cannot remap registers\n"); return -ENOMEM; } - } else { + } else if (IS_ENABLED(CONFIG_HAS_IOPORT)) { dev->iobase = pci_resource_start(pci_dev, bar); + } else { + dev_err(dev->class_dev, + "error! need I/O port support\n"); + return -ENXIO; } if (board->is_pcie) { @@ -385,8 +393,10 @@ static struct comedi_driver dio200_pci_comedi_driver = { }; static const struct pci_device_id dio200_pci_table[] = { +#ifdef CONFIG_HAS_IOPORT { PCI_VDEVICE(AMPLICON, 0x000b), pci215_model }, { PCI_VDEVICE(AMPLICON, 0x000a), pci272_model }, +#endif /* CONFIG_HAS_IOPORT */ { PCI_VDEVICE(AMPLICON, 0x0011), pcie236_model }, { PCI_VDEVICE(AMPLICON, 0x0012), pcie215_model }, { PCI_VDEVICE(AMPLICON, 0x0014), pcie296_model }, diff --git a/drivers/comedi/drivers/amplc_pc236_common.c b/drivers/comedi/drivers/amplc_pc236_common.c index 9f4f89b1ef23..326ca72c24ec 100644 --- a/drivers/comedi/drivers/amplc_pc236_common.c +++ b/drivers/comedi/drivers/amplc_pc236_common.c @@ -147,7 +147,7 @@ int amplc_pc236_common_attach(struct comedi_device *dev, unsigned long iobase, s = &dev->subdevices[0]; /* digital i/o subdevice (8255) */ - ret = subdev_8255_init(dev, s, NULL, 0x00); + ret = subdev_8255_io_init(dev, s, 0x00); if (ret) return ret; diff --git a/drivers/comedi/drivers/amplc_pci224.c b/drivers/comedi/drivers/amplc_pci224.c index 5a04e55daeea..1373637c2ca2 100644 --- a/drivers/comedi/drivers/amplc_pci224.c +++ b/drivers/comedi/drivers/amplc_pci224.c @@ -1051,10 +1051,10 @@ pci224_auto_attach(struct comedi_device *dev, unsigned long context_model) outw(devpriv->daccon | PCI224_DACCON_FIFORESET, dev->iobase + PCI224_DACCON); - dev->pacer = comedi_8254_init(devpriv->iobase1 + PCI224_Z2_BASE, - I8254_OSC_BASE_10MHZ, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(devpriv->iobase1 + PCI224_Z2_BASE, + I8254_OSC_BASE_10MHZ, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); ret = comedi_alloc_subdevices(dev, 1); if (ret) diff --git a/drivers/comedi/drivers/amplc_pci230.c b/drivers/comedi/drivers/amplc_pci230.c index 92ba8b8c0172..c74209c2e83a 100644 --- a/drivers/comedi/drivers/amplc_pci230.c +++ b/drivers/comedi/drivers/amplc_pci230.c @@ -2475,10 +2475,10 @@ static int pci230_auto_attach(struct comedi_device *dev, dev->irq = pci_dev->irq; } - dev->pacer = comedi_8254_init(dev->iobase + PCI230_Z2_CT_BASE, - 0, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + PCI230_Z2_CT_BASE, + 0, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); rc = comedi_alloc_subdevices(dev, 3); if (rc) @@ -2529,7 +2529,7 @@ static int pci230_auto_attach(struct comedi_device *dev, s = &dev->subdevices[2]; /* digital i/o subdevice */ if (board->have_dio) { - rc = subdev_8255_init(dev, s, NULL, PCI230_PPI_X_BASE); + rc = subdev_8255_io_init(dev, s, PCI230_PPI_X_BASE); if (rc) return rc; } else { diff --git a/drivers/comedi/drivers/cb_das16_cs.c b/drivers/comedi/drivers/cb_das16_cs.c index 8e0d2fa5f95d..306208a0695b 100644 --- a/drivers/comedi/drivers/cb_das16_cs.c +++ b/drivers/comedi/drivers/cb_das16_cs.c @@ -363,10 +363,10 @@ static int das16cs_auto_attach(struct comedi_device *dev, if (!devpriv) return -ENOMEM; - dev->pacer = comedi_8254_init(dev->iobase + DAS16CS_TIMER_BASE, - I8254_OSC_BASE_10MHZ, I8254_IO16, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS16CS_TIMER_BASE, + I8254_OSC_BASE_10MHZ, I8254_IO16, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); ret = comedi_alloc_subdevices(dev, 4); if (ret) diff --git a/drivers/comedi/drivers/cb_pcidas.c b/drivers/comedi/drivers/cb_pcidas.c index 0c7576b967fc..8bb9b0623869 100644 --- a/drivers/comedi/drivers/cb_pcidas.c +++ b/drivers/comedi/drivers/cb_pcidas.c @@ -1288,16 +1288,16 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, } dev->irq = pcidev->irq; - dev->pacer = comedi_8254_init(dev->iobase + PCIDAS_AI_8254_BASE, - I8254_OSC_BASE_10MHZ, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + PCIDAS_AI_8254_BASE, + I8254_OSC_BASE_10MHZ, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); - devpriv->ao_pacer = comedi_8254_init(dev->iobase + PCIDAS_AO_8254_BASE, - I8254_OSC_BASE_10MHZ, - I8254_IO8, 0); - if (!devpriv->ao_pacer) - return -ENOMEM; + devpriv->ao_pacer = + comedi_8254_io_alloc(dev->iobase + PCIDAS_AO_8254_BASE, + I8254_OSC_BASE_10MHZ, I8254_IO8, 0); + if (IS_ERR(devpriv->ao_pacer)) + return PTR_ERR(devpriv->ao_pacer); ret = comedi_alloc_subdevices(dev, 7); if (ret) @@ -1352,7 +1352,7 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, /* 8255 */ s = &dev->subdevices[2]; - ret = subdev_8255_init(dev, s, NULL, PCIDAS_8255_BASE); + ret = subdev_8255_io_init(dev, s, PCIDAS_8255_BASE); if (ret) return ret; @@ -1453,7 +1453,8 @@ static void cb_pcidas_detach(struct comedi_device *dev) if (devpriv->amcc) outl(INTCSR_INBOX_INTR_STATUS, devpriv->amcc + AMCC_OP_REG_INTCSR); - kfree(devpriv->ao_pacer); + if (!IS_ERR(devpriv->ao_pacer)) + kfree(devpriv->ao_pacer); } comedi_pci_detach(dev); } diff --git a/drivers/comedi/drivers/cb_pcidas64.c b/drivers/comedi/drivers/cb_pcidas64.c index ca6038a25f26..ff19fc3859e4 100644 --- a/drivers/comedi/drivers/cb_pcidas64.c +++ b/drivers/comedi/drivers/cb_pcidas64.c @@ -3877,11 +3877,10 @@ static int setup_subdevices(struct comedi_device *dev) s = &dev->subdevices[4]; if (board->has_8255) { if (board->layout == LAYOUT_4020) { - ret = subdev_8255_init(dev, s, dio_callback_4020, - I8255_4020_REG); + ret = subdev_8255_cb_init(dev, s, dio_callback_4020, + I8255_4020_REG); } else { - ret = subdev_8255_mm_init(dev, s, NULL, - DIO_8255_OFFSET); + ret = subdev_8255_mm_init(dev, s, DIO_8255_OFFSET); } if (ret) return ret; diff --git a/drivers/comedi/drivers/cb_pcidda.c b/drivers/comedi/drivers/cb_pcidda.c index c52204a6bda4..c353d0f87da9 100644 --- a/drivers/comedi/drivers/cb_pcidda.c +++ b/drivers/comedi/drivers/cb_pcidda.c @@ -365,7 +365,7 @@ static int cb_pcidda_auto_attach(struct comedi_device *dev, /* two 8255 digital io subdevices */ for (i = 0; i < 2; i++) { s = &dev->subdevices[1 + i]; - ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE); + ret = subdev_8255_io_init(dev, s, i * I8255_SIZE); if (ret) return ret; } diff --git a/drivers/comedi/drivers/cb_pcimdas.c b/drivers/comedi/drivers/cb_pcimdas.c index 8bdb00774f11..641c30df392e 100644 --- a/drivers/comedi/drivers/cb_pcimdas.c +++ b/drivers/comedi/drivers/cb_pcimdas.c @@ -364,11 +364,11 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev, devpriv->BADR3 = pci_resource_start(pcidev, 3); dev->iobase = pci_resource_start(pcidev, 4); - dev->pacer = comedi_8254_init(devpriv->BADR3 + PCIMDAS_8254_BASE, - cb_pcimdas_pacer_clk(dev), - I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(devpriv->BADR3 + PCIMDAS_8254_BASE, + cb_pcimdas_pacer_clk(dev), + I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); ret = comedi_alloc_subdevices(dev, 6); if (ret) @@ -405,7 +405,7 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev, /* Digital I/O subdevice */ s = &dev->subdevices[2]; - ret = subdev_8255_init(dev, s, NULL, PCIMDAS_8255_BASE); + ret = subdev_8255_io_init(dev, s, PCIMDAS_8255_BASE); if (ret) return ret; diff --git a/drivers/comedi/drivers/cb_pcimdda.c b/drivers/comedi/drivers/cb_pcimdda.c index bf8093a10315..541b5742bb1b 100644 --- a/drivers/comedi/drivers/cb_pcimdda.c +++ b/drivers/comedi/drivers/cb_pcimdda.c @@ -154,7 +154,7 @@ static int cb_pcimdda_auto_attach(struct comedi_device *dev, s = &dev->subdevices[1]; /* digital i/o subdevice */ - return subdev_8255_init(dev, s, NULL, PCIMDDA_8255_BASE_REG); + return subdev_8255_io_init(dev, s, PCIMDDA_8255_BASE_REG); } static struct comedi_driver cb_pcimdda_driver = { diff --git a/drivers/comedi/drivers/comedi_8254.c b/drivers/comedi/drivers/comedi_8254.c index b4185c1b2695..6beca2a6d66e 100644 --- a/drivers/comedi/drivers/comedi_8254.c +++ b/drivers/comedi/drivers/comedi_8254.c @@ -24,14 +24,17 @@ * * This module provides the following basic functions: * - * comedi_8254_init() / comedi_8254_mm_init() + * comedi_8254_io_alloc() / comedi_8254_mm_alloc() * Initializes this module to access the 8254 registers. The _mm version - * sets up the module for MMIO register access the other for PIO access. - * The pointer returned from these functions is normally stored in the - * comedi_device dev->pacer and will be freed by the comedi core during - * the driver (*detach). If a driver has multiple 8254 devices, they need - * to be stored in the drivers private data and freed when the driver is - * detached. + * sets up the module for MMIO register access; the _io version sets it + * up for PIO access. These functions return a pointer to a struct + * comedi_8254 on success, or an ERR_PTR value on failure. The pointer + * returned from these functions is normally stored in the comedi_device + * dev->pacer and will be freed by the comedi core during the driver + * (*detach). If a driver has multiple 8254 devices, they need to be + * stored in the drivers private data and freed when the driver is + * detached. If the ERR_PTR value is stored, code should check the + * pointer value with !IS_ERR(pointer) before freeing. * * NOTE: The counters are reset by setting them to I8254_MODE0 as part of * this initialization. @@ -119,63 +122,105 @@ #include <linux/comedi/comedidev.h> #include <linux/comedi/comedi_8254.h> -static unsigned int __i8254_read(struct comedi_8254 *i8254, unsigned int reg) +#ifdef CONFIG_HAS_IOPORT + +static unsigned int i8254_io8_cb(struct comedi_8254 *i8254, int dir, + unsigned int reg, unsigned int val) { - unsigned int reg_offset = (reg * i8254->iosize) << i8254->regshift; - unsigned int val; + unsigned long iobase = i8254->context; + unsigned int reg_offset = (reg * I8254_IO8) << i8254->regshift; - switch (i8254->iosize) { - default: - case I8254_IO8: - if (i8254->mmio) - val = readb(i8254->mmio + reg_offset); - else - val = inb(i8254->iobase + reg_offset); - break; - case I8254_IO16: - if (i8254->mmio) - val = readw(i8254->mmio + reg_offset); - else - val = inw(i8254->iobase + reg_offset); - break; - case I8254_IO32: - if (i8254->mmio) - val = readl(i8254->mmio + reg_offset); - else - val = inl(i8254->iobase + reg_offset); - break; + if (dir) { + outb(val, iobase + reg_offset); + return 0; + } else { + return inb(iobase + reg_offset); } - return val & 0xff; } -static void __i8254_write(struct comedi_8254 *i8254, - unsigned int val, unsigned int reg) +static unsigned int i8254_io16_cb(struct comedi_8254 *i8254, int dir, + unsigned int reg, unsigned int val) { - unsigned int reg_offset = (reg * i8254->iosize) << i8254->regshift; + unsigned long iobase = i8254->context; + unsigned int reg_offset = (reg * I8254_IO16) << i8254->regshift; - switch (i8254->iosize) { - default: - case I8254_IO8: - if (i8254->mmio) - writeb(val, i8254->mmio + reg_offset); - else - outb(val, i8254->iobase + reg_offset); - break; - case I8254_IO16: - if (i8254->mmio) - writew(val, i8254->mmio + reg_offset); - else - outw(val, i8254->iobase + reg_offset); - break; - case I8254_IO32: - if (i8254->mmio) - writel(val, i8254->mmio + reg_offset); - else - outl(val, i8254->iobase + reg_offset); - break; + if (dir) { + outw(val, iobase + reg_offset); + return 0; + } else { + return inw(iobase + reg_offset); } } +static unsigned int i8254_io32_cb(struct comedi_8254 *i8254, int dir, + unsigned int reg, unsigned int val) +{ + unsigned long iobase = i8254->context; + unsigned int reg_offset = (reg * I8254_IO32) << i8254->regshift; + + if (dir) { + outl(val, iobase + reg_offset); + return 0; + } else { + return inl(iobase + reg_offset); + } +} + +#endif /* CONFIG_HAS_IOPORT */ + +static unsigned int i8254_mmio8_cb(struct comedi_8254 *i8254, int dir, + unsigned int reg, unsigned int val) +{ + void __iomem *mmiobase = (void __iomem *)i8254->context; + unsigned int reg_offset = (reg * I8254_IO8) << i8254->regshift; + + if (dir) { + writeb(val, mmiobase + reg_offset); + return 0; + } else { + return readb(mmiobase + reg_offset); + } +} + +static unsigned int i8254_mmio16_cb(struct comedi_8254 *i8254, int dir, + unsigned int reg, unsigned int val) +{ + void __iomem *mmiobase = (void __iomem *)i8254->context; + unsigned int reg_offset = (reg * I8254_IO16) << i8254->regshift; + + if (dir) { + writew(val, mmiobase + reg_offset); + return 0; + } else { + return readw(mmiobase + reg_offset); + } +} + +static unsigned int i8254_mmio32_cb(struct comedi_8254 *i8254, int dir, + unsigned int reg, unsigned int val) +{ + void __iomem *mmiobase = (void __iomem *)i8254->context; + unsigned int reg_offset = (reg * I8254_IO32) << i8254->regshift; + + if (dir) { + writel(val, mmiobase + reg_offset); + return 0; + } else { + return readl(mmiobase + reg_offset); + } +} + +static unsigned int __i8254_read(struct comedi_8254 *i8254, unsigned int reg) +{ + return 0xff & i8254->iocb(i8254, 0, reg, 0); +} + +static void __i8254_write(struct comedi_8254 *i8254, + unsigned int val, unsigned int reg) +{ + i8254->iocb(i8254, 1, reg, val); +} + /** * comedi_8254_status - return the status of a counter * @i8254: comedi_8254 struct for the timer @@ -571,8 +616,8 @@ void comedi_8254_subdevice_init(struct comedi_subdevice *s, } EXPORT_SYMBOL_GPL(comedi_8254_subdevice_init); -static struct comedi_8254 *__i8254_init(unsigned long iobase, - void __iomem *mmio, +static struct comedi_8254 *__i8254_init(comedi_8254_iocb_fn *iocb, + unsigned long context, unsigned int osc_base, unsigned int iosize, unsigned int regshift) @@ -583,14 +628,17 @@ static struct comedi_8254 *__i8254_init(unsigned long iobase, /* sanity check that the iosize is valid */ if (!(iosize == I8254_IO8 || iosize == I8254_IO16 || iosize == I8254_IO32)) - return NULL; + return ERR_PTR(-EINVAL); + + if (!iocb) + return ERR_PTR(-EINVAL); i8254 = kzalloc(sizeof(*i8254), GFP_KERNEL); if (!i8254) - return NULL; + return ERR_PTR(-ENOMEM); - i8254->iobase = iobase; - i8254->mmio = mmio; + i8254->iocb = iocb; + i8254->context = context; i8254->iosize = iosize; i8254->regshift = regshift; @@ -604,39 +652,77 @@ static struct comedi_8254 *__i8254_init(unsigned long iobase, return i8254; } +#ifdef CONFIG_HAS_IOPORT + /** - * comedi_8254_init - allocate and initialize the 8254 device for pio access + * comedi_8254_io_alloc - allocate and initialize the 8254 device for pio access * @iobase: port I/O base address * @osc_base: base time of the counter in ns * OPTIONAL - only used by comedi_8254_cascade_ns_to_timer() * @iosize: I/O register size * @regshift: register gap shift + * + * Return: A pointer to a struct comedi_8254 or an ERR_PTR value. */ -struct comedi_8254 *comedi_8254_init(unsigned long iobase, - unsigned int osc_base, - unsigned int iosize, - unsigned int regshift) +struct comedi_8254 *comedi_8254_io_alloc(unsigned long iobase, + unsigned int osc_base, + unsigned int iosize, + unsigned int regshift) { - return __i8254_init(iobase, NULL, osc_base, iosize, regshift); + comedi_8254_iocb_fn *iocb; + + switch (iosize) { + case I8254_IO8: + iocb = i8254_io8_cb; + break; + case I8254_IO16: + iocb = i8254_io16_cb; + break; + case I8254_IO32: + iocb = i8254_io32_cb; + break; + default: + return ERR_PTR(-EINVAL); + } + return __i8254_init(iocb, iobase, osc_base, iosize, regshift); } -EXPORT_SYMBOL_GPL(comedi_8254_init); +EXPORT_SYMBOL_GPL(comedi_8254_io_alloc); + +#endif /* CONFIG_HAS_IOPORT */ /** - * comedi_8254_mm_init - allocate and initialize the 8254 device for mmio access + * comedi_8254_mm_alloc - allocate and initialize the 8254 device for mmio access * @mmio: memory mapped I/O base address * @osc_base: base time of the counter in ns * OPTIONAL - only used by comedi_8254_cascade_ns_to_timer() * @iosize: I/O register size * @regshift: register gap shift + * + * Return: A pointer to a struct comedi_8254 or an ERR_PTR value. */ -struct comedi_8254 *comedi_8254_mm_init(void __iomem *mmio, - unsigned int osc_base, - unsigned int iosize, - unsigned int regshift) +struct comedi_8254 *comedi_8254_mm_alloc(void __iomem *mmio, + unsigned int osc_base, + unsigned int iosize, + unsigned int regshift) { - return __i8254_init(0, mmio, osc_base, iosize, regshift); + comedi_8254_iocb_fn *iocb; + + switch (iosize) { + case I8254_IO8: + iocb = i8254_mmio8_cb; + break; + case I8254_IO16: + iocb = i8254_mmio16_cb; + break; + case I8254_IO32: + iocb = i8254_mmio32_cb; + break; + default: + return ERR_PTR(-EINVAL); + } + return __i8254_init(iocb, (unsigned long)mmio, osc_base, iosize, regshift); } -EXPORT_SYMBOL_GPL(comedi_8254_mm_init); +EXPORT_SYMBOL_GPL(comedi_8254_mm_alloc); static int __init comedi_8254_module_init(void) { diff --git a/drivers/comedi/drivers/comedi_8255.c b/drivers/comedi/drivers/comedi_8255.c index 5562b9cd0a17..e4974b508328 100644 --- a/drivers/comedi/drivers/comedi_8255.c +++ b/drivers/comedi/drivers/comedi_8255.c @@ -33,11 +33,13 @@ #include <linux/comedi/comedi_8255.h> struct subdev_8255_private { - unsigned long regbase; + unsigned long context; int (*io)(struct comedi_device *dev, int dir, int port, int data, - unsigned long regbase); + unsigned long context); }; +#ifdef CONFIG_HAS_IOPORT + static int subdev_8255_io(struct comedi_device *dev, int dir, int port, int data, unsigned long regbase) { @@ -48,6 +50,8 @@ static int subdev_8255_io(struct comedi_device *dev, return inb(dev->iobase + regbase + port); } +#endif /* CONFIG_HAS_IOPORT */ + static int subdev_8255_mmio(struct comedi_device *dev, int dir, int port, int data, unsigned long regbase) { @@ -64,7 +68,7 @@ static int subdev_8255_insn(struct comedi_device *dev, unsigned int *data) { struct subdev_8255_private *spriv = s->private; - unsigned long regbase = spriv->regbase; + unsigned long context = spriv->context; unsigned int mask; unsigned int v; @@ -72,18 +76,18 @@ static int subdev_8255_insn(struct comedi_device *dev, if (mask) { if (mask & 0xff) spriv->io(dev, 1, I8255_DATA_A_REG, - s->state & 0xff, regbase); + s->state & 0xff, context); if (mask & 0xff00) spriv->io(dev, 1, I8255_DATA_B_REG, - (s->state >> 8) & 0xff, regbase); + (s->state >> 8) & 0xff, context); if (mask & 0xff0000) spriv->io(dev, 1, I8255_DATA_C_REG, - (s->state >> 16) & 0xff, regbase); + (s->state >> 16) & 0xff, context); } - v = spriv->io(dev, 0, I8255_DATA_A_REG, 0, regbase); - v |= (spriv->io(dev, 0, I8255_DATA_B_REG, 0, regbase) << 8); - v |= (spriv->io(dev, 0, I8255_DATA_C_REG, 0, regbase) << 16); + v = spriv->io(dev, 0, I8255_DATA_A_REG, 0, context); + v |= (spriv->io(dev, 0, I8255_DATA_B_REG, 0, context) << 8); + v |= (spriv->io(dev, 0, I8255_DATA_C_REG, 0, context) << 16); data[1] = v; @@ -94,7 +98,7 @@ static void subdev_8255_do_config(struct comedi_device *dev, struct comedi_subdevice *s) { struct subdev_8255_private *spriv = s->private; - unsigned long regbase = spriv->regbase; + unsigned long context = spriv->context; int config; config = I8255_CTRL_CW; @@ -108,7 +112,7 @@ static void subdev_8255_do_config(struct comedi_device *dev, if (!(s->io_bits & 0xf00000)) config |= I8255_CTRL_C_HI_IO; - spriv->io(dev, 1, I8255_CTRL_REG, config, regbase); + spriv->io(dev, 1, I8255_CTRL_REG, config, context); } static int subdev_8255_insn_config(struct comedi_device *dev, @@ -142,23 +146,19 @@ static int __subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, int (*io)(struct comedi_device *dev, int dir, int port, int data, - unsigned long regbase), - unsigned long regbase, - bool is_mmio) + unsigned long context), + unsigned long context) { struct subdev_8255_private *spriv; + if (!io) + return -EINVAL; + spriv = comedi_alloc_spriv(s, sizeof(*spriv)); if (!spriv) return -ENOMEM; - if (io) - spriv->io = io; - else if (is_mmio) - spriv->io = subdev_8255_mmio; - else - spriv->io = subdev_8255_io; - spriv->regbase = regbase; + spriv->context = context; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; @@ -173,89 +173,88 @@ static int __subdev_8255_init(struct comedi_device *dev, return 0; } +#ifdef CONFIG_HAS_IOPORT + /** - * subdev_8255_init - initialize DIO subdevice for driving I/O mapped 8255 + * subdev_8255_io_init - initialize DIO subdevice for driving I/O mapped 8255 * @dev: comedi device owning subdevice * @s: comedi subdevice to initialize - * @io: (optional) register I/O call-back function - * @regbase: offset of 8255 registers from dev->iobase, or call-back context + * @regbase: offset of 8255 registers from dev->iobase * * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip. * - * If the optional I/O call-back function is provided, its prototype is of - * the following form: - * - * int my_8255_callback(struct comedi_device *dev, int dir, int port, - * int data, unsigned long regbase); - * - * where 'dev', and 'regbase' match the values passed to this function, - * 'port' is the 8255 port number 0 to 3 (including the control port), 'dir' - * is the direction (0 for read, 1 for write) and 'data' is the value to be - * written. It should return 0 if writing or the value read if reading. - * - * If the optional I/O call-back function is not provided, an internal - * call-back function is used which uses consecutive I/O port addresses - * starting at dev->iobase + regbase. - * * Return: -ENOMEM if failed to allocate memory, zero on success. */ -int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, - int (*io)(struct comedi_device *dev, int dir, int port, - int data, unsigned long regbase), +int subdev_8255_io_init(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long regbase) { - return __subdev_8255_init(dev, s, io, regbase, false); + return __subdev_8255_init(dev, s, subdev_8255_io, regbase); } -EXPORT_SYMBOL_GPL(subdev_8255_init); +EXPORT_SYMBOL_GPL(subdev_8255_io_init); + +#endif /* CONFIG_HAS_IOPORT */ /** * subdev_8255_mm_init - initialize DIO subdevice for driving mmio-mapped 8255 * @dev: comedi device owning subdevice * @s: comedi subdevice to initialize - * @io: (optional) register I/O call-back function - * @regbase: offset of 8255 registers from dev->mmio, or call-back context + * @regbase: offset of 8255 registers from dev->mmio * * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip. * - * If the optional I/O call-back function is provided, its prototype is of - * the following form: + * Return: -ENOMEM if failed to allocate memory, zero on success. + */ +int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s, + unsigned long regbase) +{ + return __subdev_8255_init(dev, s, subdev_8255_mmio, regbase); +} +EXPORT_SYMBOL_GPL(subdev_8255_mm_init); + +/** + * subdev_8255_cb_init - initialize DIO subdevice for driving callback-mapped 8255 + * @dev: comedi device owning subdevice + * @s: comedi subdevice to initialize + * @io: register I/O call-back function + * @context: call-back context + * + * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip. + * + * The prototype of the I/O call-back function is of the following form: * * int my_8255_callback(struct comedi_device *dev, int dir, int port, - * int data, unsigned long regbase); + * int data, unsigned long context); * - * where 'dev', and 'regbase' match the values passed to this function, + * where 'dev', and 'context' match the values passed to this function, * 'port' is the 8255 port number 0 to 3 (including the control port), 'dir' * is the direction (0 for read, 1 for write) and 'data' is the value to be * written. It should return 0 if writing or the value read if reading. * - * If the optional I/O call-back function is not provided, an internal - * call-back function is used which uses consecutive MMIO virtual addresses - * starting at dev->mmio + regbase. * * Return: -ENOMEM if failed to allocate memory, zero on success. */ -int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s, +int subdev_8255_cb_init(struct comedi_device *dev, struct comedi_subdevice *s, int (*io)(struct comedi_device *dev, int dir, int port, - int data, unsigned long regbase), - unsigned long regbase) + int data, unsigned long context), + unsigned long context) { - return __subdev_8255_init(dev, s, io, regbase, true); + return __subdev_8255_init(dev, s, io, context); } -EXPORT_SYMBOL_GPL(subdev_8255_mm_init); +EXPORT_SYMBOL_GPL(subdev_8255_cb_init); /** * subdev_8255_regbase - get offset of 8255 registers or call-back context * @s: comedi subdevice * - * Returns the 'regbase' parameter that was previously passed to - * subdev_8255_init() or subdev_8255_mm_init() to set up the subdevice. - * Only valid if the subdevice was set up successfully. + * Returns the 'regbase' or 'context' parameter that was previously passed to + * subdev_8255_io_init(), subdev_8255_mm_init(), or subdev_8255_cb_init() to + * set up the subdevice. Only valid if the subdevice was set up successfully. */ unsigned long subdev_8255_regbase(struct comedi_subdevice *s) { struct subdev_8255_private *spriv = s->private; - return spriv->regbase; + return spriv->context; } EXPORT_SYMBOL_GPL(subdev_8255_regbase); diff --git a/drivers/comedi/drivers/daqboard2000.c b/drivers/comedi/drivers/daqboard2000.c index c0a4e1b06fb3..897bf46b95ee 100644 --- a/drivers/comedi/drivers/daqboard2000.c +++ b/drivers/comedi/drivers/daqboard2000.c @@ -738,8 +738,8 @@ static int db2k_auto_attach(struct comedi_device *dev, unsigned long context) return result; s = &dev->subdevices[2]; - return subdev_8255_init(dev, s, db2k_8255_cb, - DB2K_REG_DIO_P2_EXP_IO_8_BIT); + return subdev_8255_cb_init(dev, s, db2k_8255_cb, + DB2K_REG_DIO_P2_EXP_IO_8_BIT); } static void db2k_detach(struct comedi_device *dev) diff --git a/drivers/comedi/drivers/das08.c b/drivers/comedi/drivers/das08.c index f8ab3af2e391..5d5b9174f88a 100644 --- a/drivers/comedi/drivers/das08.c +++ b/drivers/comedi/drivers/das08.c @@ -429,7 +429,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) s = &dev->subdevices[4]; /* 8255 */ if (board->i8255_offset != 0) { - ret = subdev_8255_init(dev, s, NULL, board->i8255_offset); + ret = subdev_8255_io_init(dev, s, board->i8255_offset); if (ret) return ret; } else { @@ -439,10 +439,11 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) /* Counter subdevice (8254) */ s = &dev->subdevices[5]; if (board->i8254_offset) { - dev->pacer = comedi_8254_init(dev->iobase + board->i8254_offset, - 0, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = + comedi_8254_io_alloc(dev->iobase + board->i8254_offset, + 0, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); comedi_8254_subdevice_init(s, dev->pacer); } else { diff --git a/drivers/comedi/drivers/das16.c b/drivers/comedi/drivers/das16.c index 728dc02156c8..4ed56a02150e 100644 --- a/drivers/comedi/drivers/das16.c +++ b/drivers/comedi/drivers/das16.c @@ -1067,10 +1067,10 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) osc_base = I8254_OSC_BASE_1MHZ / it->options[3]; } - dev->pacer = comedi_8254_init(dev->iobase + DAS16_TIMER_BASE_REG, - osc_base, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS16_TIMER_BASE_REG, + osc_base, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); das16_alloc_dma(dev, it->options[2]); @@ -1145,7 +1145,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* 8255 Digital I/O subdevice */ if (board->has_8255) { s = &dev->subdevices[4]; - ret = subdev_8255_init(dev, s, NULL, board->i8255_offset); + ret = subdev_8255_io_init(dev, s, board->i8255_offset); if (ret) return ret; } diff --git a/drivers/comedi/drivers/das16m1.c b/drivers/comedi/drivers/das16m1.c index 275effb77746..b8ea737ad3d1 100644 --- a/drivers/comedi/drivers/das16m1.c +++ b/drivers/comedi/drivers/das16m1.c @@ -529,15 +529,16 @@ static int das16m1_attach(struct comedi_device *dev, dev->irq = it->options[1]; } - dev->pacer = comedi_8254_init(dev->iobase + DAS16M1_8254_IOBASE2, - I8254_OSC_BASE_10MHZ, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS16M1_8254_IOBASE2, + I8254_OSC_BASE_10MHZ, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); - devpriv->counter = comedi_8254_init(dev->iobase + DAS16M1_8254_IOBASE1, - 0, I8254_IO8, 0); - if (!devpriv->counter) - return -ENOMEM; + devpriv->counter = + comedi_8254_io_alloc(dev->iobase + DAS16M1_8254_IOBASE1, + 0, I8254_IO8, 0); + if (IS_ERR(devpriv->counter)) + return PTR_ERR(devpriv->counter); ret = comedi_alloc_subdevices(dev, 4); if (ret) @@ -582,7 +583,7 @@ static int das16m1_attach(struct comedi_device *dev, /* Digital I/O subdevice (8255) */ s = &dev->subdevices[3]; - ret = subdev_8255_init(dev, s, NULL, DAS16M1_8255_IOBASE); + ret = subdev_8255_io_init(dev, s, DAS16M1_8255_IOBASE); if (ret) return ret; @@ -603,7 +604,8 @@ static void das16m1_detach(struct comedi_device *dev) if (devpriv) { if (devpriv->extra_iobase) release_region(devpriv->extra_iobase, DAS16M1_SIZE2); - kfree(devpriv->counter); + if (!IS_ERR(devpriv->counter)) + kfree(devpriv->counter); } comedi_legacy_detach(dev); } diff --git a/drivers/comedi/drivers/das1800.c b/drivers/comedi/drivers/das1800.c index f09608c0f4ff..7117c67aee7e 100644 --- a/drivers/comedi/drivers/das1800.c +++ b/drivers/comedi/drivers/das1800.c @@ -1233,10 +1233,10 @@ static int das1800_attach(struct comedi_device *dev, if (!devpriv->fifo_buf) return -ENOMEM; - dev->pacer = comedi_8254_init(dev->iobase + DAS1800_COUNTER, - I8254_OSC_BASE_5MHZ, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS1800_COUNTER, + I8254_OSC_BASE_5MHZ, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); ret = comedi_alloc_subdevices(dev, 4); if (ret) diff --git a/drivers/comedi/drivers/das6402.c b/drivers/comedi/drivers/das6402.c index 1af394591e74..68f95330de45 100644 --- a/drivers/comedi/drivers/das6402.c +++ b/drivers/comedi/drivers/das6402.c @@ -590,10 +590,10 @@ static int das6402_attach(struct comedi_device *dev, } } - dev->pacer = comedi_8254_init(dev->iobase + DAS6402_TIMER_BASE, - I8254_OSC_BASE_10MHZ, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS6402_TIMER_BASE, + I8254_OSC_BASE_10MHZ, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); ret = comedi_alloc_subdevices(dev, 4); if (ret) diff --git a/drivers/comedi/drivers/das800.c b/drivers/comedi/drivers/das800.c index 4ca33f46eaa7..300775523031 100644 --- a/drivers/comedi/drivers/das800.c +++ b/drivers/comedi/drivers/das800.c @@ -672,10 +672,10 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->irq = irq; } - dev->pacer = comedi_8254_init(dev->iobase + DAS800_8254, - I8254_OSC_BASE_1MHZ, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS800_8254, + I8254_OSC_BASE_1MHZ, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); ret = comedi_alloc_subdevices(dev, 3); if (ret) diff --git a/drivers/comedi/drivers/dmm32at.c b/drivers/comedi/drivers/dmm32at.c index fe023c722aa3..644e3b643c79 100644 --- a/drivers/comedi/drivers/dmm32at.c +++ b/drivers/comedi/drivers/dmm32at.c @@ -599,7 +599,8 @@ static int dmm32at_attach(struct comedi_device *dev, /* Digital I/O subdevice */ s = &dev->subdevices[2]; - return subdev_8255_init(dev, s, dmm32at_8255_io, DMM32AT_8255_IOBASE); + return subdev_8255_cb_init(dev, s, dmm32at_8255_io, + DMM32AT_8255_IOBASE); } static struct comedi_driver dmm32at_driver = { diff --git a/drivers/comedi/drivers/me4000.c b/drivers/comedi/drivers/me4000.c index 9aea02b86ed9..7dd3a0071863 100644 --- a/drivers/comedi/drivers/me4000.c +++ b/drivers/comedi/drivers/me4000.c @@ -1209,9 +1209,9 @@ static int me4000_auto_attach(struct comedi_device *dev, if (!timer_base) return -ENODEV; - dev->pacer = comedi_8254_init(timer_base, 0, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(timer_base, 0, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); comedi_8254_subdevice_init(s, dev->pacer); } else { diff --git a/drivers/comedi/drivers/ni_at_a2150.c b/drivers/comedi/drivers/ni_at_a2150.c index df8d219e6723..e4e5a0ebd195 100644 --- a/drivers/comedi/drivers/ni_at_a2150.c +++ b/drivers/comedi/drivers/ni_at_a2150.c @@ -707,10 +707,10 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* an IRQ and DMA are required to support async commands */ a2150_alloc_irq_and_dma(dev, it); - dev->pacer = comedi_8254_init(dev->iobase + I8253_BASE_REG, - 0, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + I8253_BASE_REG, + 0, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); ret = comedi_alloc_subdevices(dev, 1); if (ret) diff --git a/drivers/comedi/drivers/ni_at_ao.c b/drivers/comedi/drivers/ni_at_ao.c index 9f3147b72aa8..9cf6b4ff6b65 100644 --- a/drivers/comedi/drivers/ni_at_ao.c +++ b/drivers/comedi/drivers/ni_at_ao.c @@ -303,10 +303,10 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!devpriv) return -ENOMEM; - dev->pacer = comedi_8254_init(dev->iobase + ATAO_82C53_BASE, - 0, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + ATAO_82C53_BASE, + 0, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); ret = comedi_alloc_subdevices(dev, 4); if (ret) diff --git a/drivers/comedi/drivers/ni_atmio16d.c b/drivers/comedi/drivers/ni_atmio16d.c index 9fa902529a8e..e5e7cc423c87 100644 --- a/drivers/comedi/drivers/ni_atmio16d.c +++ b/drivers/comedi/drivers/ni_atmio16d.c @@ -677,7 +677,7 @@ static int atmio16d_attach(struct comedi_device *dev, /* 8255 subdevice */ s = &dev->subdevices[3]; if (board->has_8255) { - ret = subdev_8255_init(dev, s, NULL, 0x00); + ret = subdev_8255_io_init(dev, s, 0x00); if (ret) return ret; } else { diff --git a/drivers/comedi/drivers/ni_daq_dio24.c b/drivers/comedi/drivers/ni_daq_dio24.c index 487733111023..9419caf02edc 100644 --- a/drivers/comedi/drivers/ni_daq_dio24.c +++ b/drivers/comedi/drivers/ni_daq_dio24.c @@ -45,7 +45,7 @@ static int dio24_auto_attach(struct comedi_device *dev, /* 8255 dio */ s = &dev->subdevices[0]; - return subdev_8255_init(dev, s, NULL, 0x00); + return subdev_8255_io_init(dev, s, 0x00); } static struct comedi_driver driver_dio24 = { diff --git a/drivers/comedi/drivers/ni_labpc_common.c b/drivers/comedi/drivers/ni_labpc_common.c index 763249653228..7e0ce0ce0adf 100644 --- a/drivers/comedi/drivers/ni_labpc_common.c +++ b/drivers/comedi/drivers/ni_labpc_common.c @@ -78,6 +78,9 @@ static const struct comedi_lrange range_labpc_ao = { * functions that do inb/outb and readb/writeb so we can use * function pointers to decide which to use */ + +#ifdef CONFIG_HAS_IOPORT + static unsigned int labpc_inb(struct comedi_device *dev, unsigned long reg) { return inb(dev->iobase + reg); @@ -89,6 +92,8 @@ static void labpc_outb(struct comedi_device *dev, outb(byte, dev->iobase + reg); } +#endif /* CONFIG_HAS_IOPORT */ + static unsigned int labpc_readb(struct comedi_device *dev, unsigned long reg) { return readb(dev->mmio + reg); @@ -1200,8 +1205,12 @@ int labpc_common_attach(struct comedi_device *dev, devpriv->read_byte = labpc_readb; devpriv->write_byte = labpc_writeb; } else { +#ifdef CONFIG_HAS_IOPORT devpriv->read_byte = labpc_inb; devpriv->write_byte = labpc_outb; +#else + return -ENXIO; +#endif } /* initialize board's command registers */ @@ -1222,24 +1231,24 @@ int labpc_common_attach(struct comedi_device *dev, } if (dev->mmio) { - dev->pacer = comedi_8254_mm_init(dev->mmio + COUNTER_B_BASE_REG, - I8254_OSC_BASE_2MHZ, - I8254_IO8, 0); - devpriv->counter = comedi_8254_mm_init(dev->mmio + - COUNTER_A_BASE_REG, - I8254_OSC_BASE_2MHZ, - I8254_IO8, 0); + dev->pacer = + comedi_8254_mm_alloc(dev->mmio + COUNTER_B_BASE_REG, + I8254_OSC_BASE_2MHZ, I8254_IO8, 0); + devpriv->counter = + comedi_8254_mm_alloc(dev->mmio + COUNTER_A_BASE_REG, + I8254_OSC_BASE_2MHZ, I8254_IO8, 0); } else { - dev->pacer = comedi_8254_init(dev->iobase + COUNTER_B_BASE_REG, - I8254_OSC_BASE_2MHZ, - I8254_IO8, 0); - devpriv->counter = comedi_8254_init(dev->iobase + - COUNTER_A_BASE_REG, - I8254_OSC_BASE_2MHZ, - I8254_IO8, 0); + dev->pacer = + comedi_8254_io_alloc(dev->iobase + COUNTER_B_BASE_REG, + I8254_OSC_BASE_2MHZ, I8254_IO8, 0); + devpriv->counter = + comedi_8254_io_alloc(dev->iobase + COUNTER_A_BASE_REG, + I8254_OSC_BASE_2MHZ, I8254_IO8, 0); } - if (!dev->pacer || !devpriv->counter) - return -ENOMEM; + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); + if (IS_ERR(devpriv->counter)) + return PTR_ERR(devpriv->counter); ret = comedi_alloc_subdevices(dev, 5); if (ret) @@ -1287,9 +1296,9 @@ int labpc_common_attach(struct comedi_device *dev, /* 8255 dio */ s = &dev->subdevices[2]; if (dev->mmio) - ret = subdev_8255_mm_init(dev, s, NULL, DIO_BASE_REG); + ret = subdev_8255_mm_init(dev, s, DIO_BASE_REG); else - ret = subdev_8255_init(dev, s, NULL, DIO_BASE_REG); + ret = subdev_8255_io_init(dev, s, DIO_BASE_REG); if (ret) return ret; @@ -1341,8 +1350,10 @@ void labpc_common_detach(struct comedi_device *dev) { struct labpc_private *devpriv = dev->private; - if (devpriv) - kfree(devpriv->counter); + if (devpriv) { + if (!IS_ERR(devpriv->counter)) + kfree(devpriv->counter); + } } EXPORT_SYMBOL_GPL(labpc_common_detach); diff --git a/drivers/comedi/drivers/ni_mio_common.c b/drivers/comedi/drivers/ni_mio_common.c index d39998565808..980f309d6de7 100644 --- a/drivers/comedi/drivers/ni_mio_common.c +++ b/drivers/comedi/drivers/ni_mio_common.c @@ -46,6 +46,12 @@ #include <linux/comedi/comedi_8255.h> #include "mite.h" +#ifdef PCIDMA +#define IS_PCIMIO 1 +#else +#define IS_PCIMIO 0 +#endif + /* A timeout count */ #define NI_TIMEOUT 1000 @@ -219,54 +225,72 @@ enum timebase_nanoseconds { static const int num_adc_stages_611x = 3; +#ifdef PCIDMA + static void ni_writel(struct comedi_device *dev, unsigned int data, int reg) { - if (dev->mmio) - writel(data, dev->mmio + reg); - else - outl(data, dev->iobase + reg); + writel(data, dev->mmio + reg); } static void ni_writew(struct comedi_device *dev, unsigned int data, int reg) { - if (dev->mmio) - writew(data, dev->mmio + reg); - else - outw(data, dev->iobase + reg); + writew(data, dev->mmio + reg); } static void ni_writeb(struct comedi_device *dev, unsigned int data, int reg) { - if (dev->mmio) - writeb(data, dev->mmio + reg); - else - outb(data, dev->iobase + reg); + writeb(data, dev->mmio + reg); } static unsigned int ni_readl(struct comedi_device *dev, int reg) { - if (dev->mmio) - return readl(dev->mmio + reg); + return readl(dev->mmio + reg); +} + +static unsigned int ni_readw(struct comedi_device *dev, int reg) +{ + return readw(dev->mmio + reg); +} + +static unsigned int ni_readb(struct comedi_device *dev, int reg) +{ + return readb(dev->mmio + reg); +} +#else /* PCIDMA */ + +static void ni_writel(struct comedi_device *dev, unsigned int data, int reg) +{ + outl(data, dev->iobase + reg); +} + +static void ni_writew(struct comedi_device *dev, unsigned int data, int reg) +{ + outw(data, dev->iobase + reg); +} + +static void ni_writeb(struct comedi_device *dev, unsigned int data, int reg) +{ + outb(data, dev->iobase + reg); +} + +static unsigned int ni_readl(struct comedi_device *dev, int reg) +{ return inl(dev->iobase + reg); } static unsigned int ni_readw(struct comedi_device *dev, int reg) { - if (dev->mmio) - return readw(dev->mmio + reg); - return inw(dev->iobase + reg); } static unsigned int ni_readb(struct comedi_device *dev, int reg) { - if (dev->mmio) - return readb(dev->mmio + reg); - return inb(dev->iobase + reg); } +#endif /* PCIDMA */ + /* * We automatically take advantage of STC registers that can be * read/written directly in the I/O space of the board. @@ -5977,6 +6001,12 @@ static int ni_E_init(struct comedi_device *dev, int i; const char *dev_family = devpriv->is_m_series ? "ni_mseries" : "ni_eseries"; + if (!IS_PCIMIO != !dev->mmio) { + dev_err(dev->class_dev, + "%s: bug! %s device not supported.\n", + KBUILD_MODNAME, board->name); + return -ENXIO; + } /* prepare the device for globally-named routes. */ if (ni_assign_device_routes(dev_family, board->name, @@ -6137,8 +6167,8 @@ static int ni_E_init(struct comedi_device *dev, /* 8255 device */ s = &dev->subdevices[NI_8255_DIO_SUBDEV]; if (board->has_8255) { - ret = subdev_8255_init(dev, s, ni_8255_callback, - NI_E_8255_BASE); + ret = subdev_8255_cb_init(dev, s, ni_8255_callback, + NI_E_8255_BASE); if (ret) return ret; } else { diff --git a/drivers/comedi/drivers/pcl711.c b/drivers/comedi/drivers/pcl711.c index 05172c553c8a..0cf3917defe7 100644 --- a/drivers/comedi/drivers/pcl711.c +++ b/drivers/comedi/drivers/pcl711.c @@ -429,10 +429,10 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->irq = it->options[1]; } - dev->pacer = comedi_8254_init(dev->iobase + PCL711_TIMER_BASE, - I8254_OSC_BASE_2MHZ, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + PCL711_TIMER_BASE, + I8254_OSC_BASE_2MHZ, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); ret = comedi_alloc_subdevices(dev, 4); if (ret) diff --git a/drivers/comedi/drivers/pcl724.c b/drivers/comedi/drivers/pcl724.c index 948a0576c9ef..00474710b81f 100644 --- a/drivers/comedi/drivers/pcl724.c +++ b/drivers/comedi/drivers/pcl724.c @@ -124,10 +124,10 @@ static int pcl724_attach(struct comedi_device *dev, s = &dev->subdevices[i]; if (board->is_pet48) { iobase = dev->iobase + (i * 0x1000); - ret = subdev_8255_init(dev, s, pcl724_8255mapped_io, - iobase); + ret = subdev_8255_cb_init(dev, s, pcl724_8255mapped_io, + iobase); } else { - ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE); + ret = subdev_8255_io_init(dev, s, i * I8255_SIZE); } if (ret) return ret; diff --git a/drivers/comedi/drivers/pcl812.c b/drivers/comedi/drivers/pcl812.c index 70dbc129fcf5..0df639c6a595 100644 --- a/drivers/comedi/drivers/pcl812.c +++ b/drivers/comedi/drivers/pcl812.c @@ -1143,11 +1143,11 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; if (board->irq_bits) { - dev->pacer = comedi_8254_init(dev->iobase + PCL812_TIMER_BASE, - I8254_OSC_BASE_2MHZ, - I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = + comedi_8254_io_alloc(dev->iobase + PCL812_TIMER_BASE, + I8254_OSC_BASE_2MHZ, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); if ((1 << it->options[1]) & board->irq_bits) { ret = request_irq(it->options[1], pcl812_interrupt, 0, diff --git a/drivers/comedi/drivers/pcl816.c b/drivers/comedi/drivers/pcl816.c index a5e5320be648..28d1a88c50f6 100644 --- a/drivers/comedi/drivers/pcl816.c +++ b/drivers/comedi/drivers/pcl816.c @@ -615,10 +615,10 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* an IRQ and DMA are required to support async commands */ pcl816_alloc_irq_and_dma(dev, it); - dev->pacer = comedi_8254_init(dev->iobase + PCL816_TIMER_BASE, - I8254_OSC_BASE_10MHZ, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + PCL816_TIMER_BASE, + I8254_OSC_BASE_10MHZ, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); ret = comedi_alloc_subdevices(dev, 4); if (ret) diff --git a/drivers/comedi/drivers/pcl818.c b/drivers/comedi/drivers/pcl818.c index 29e503de8267..4127adcfb229 100644 --- a/drivers/comedi/drivers/pcl818.c +++ b/drivers/comedi/drivers/pcl818.c @@ -1015,10 +1015,10 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) else osc_base = I8254_OSC_BASE_1MHZ; - dev->pacer = comedi_8254_init(dev->iobase + PCL818_TIMER_BASE, - osc_base, I8254_IO8, 0); - if (!dev->pacer) - return -ENOMEM; + dev->pacer = comedi_8254_io_alloc(dev->iobase + PCL818_TIMER_BASE, + osc_base, I8254_IO8, 0); + if (IS_ERR(dev->pacer)) + return PTR_ERR(dev->pacer); /* max sampling speed */ devpriv->ns_min = board->ns_min; diff --git a/drivers/comedi/drivers/pcm3724.c b/drivers/comedi/drivers/pcm3724.c index ca8bef54dacc..fb41de3baef8 100644 --- a/drivers/comedi/drivers/pcm3724.c +++ b/drivers/comedi/drivers/pcm3724.c @@ -204,7 +204,7 @@ static int pcm3724_attach(struct comedi_device *dev, for (i = 0; i < dev->n_subdevices; i++) { s = &dev->subdevices[i]; - ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE); + ret = subdev_8255_io_init(dev, s, i * I8255_SIZE); if (ret) return ret; s->insn_config = subdev_3724_insn_config; diff --git a/drivers/comedi/drivers/rtd520.c b/drivers/comedi/drivers/rtd520.c index 7e0ec1a2a2ca..44bb0decd7a4 100644 --- a/drivers/comedi/drivers/rtd520.c +++ b/drivers/comedi/drivers/rtd520.c @@ -1289,9 +1289,9 @@ static int rtd_auto_attach(struct comedi_device *dev, /* 8254 Timer/Counter subdevice */ s = &dev->subdevices[3]; - dev->pacer = comedi_8254_mm_init(dev->mmio + LAS0_8254_TIMER_BASE, - RTD_CLOCK_BASE, I8254_IO8, 2); - if (!dev->pacer) + dev->pacer = comedi_8254_mm_alloc(dev->mmio + LAS0_8254_TIMER_BASE, + RTD_CLOCK_BASE, I8254_IO8, 2); + if (IS_ERR(dev->pacer)) return -ENOMEM; comedi_8254_subdevice_init(s, dev->pacer); |