Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

comedi: comedi_8255: Rework subdevice initialization functions

Comedi drivers can initialize an 8255 subdevice in I/O space by calling
`subdev_8255_init()`, or in memory-mapped I/O space by calling
`subdev_8255_mm_init()`, or by supplying a call-back function pointer
and context to either of those functions. Change it so that a new
function `subdev_8255_cb_init()` shall be called instead when supplying
a callback function and context, and remove the call-back function
parameter from `subdev_8255_init()` and `subdev_8255_mm_init()`.

Also rename `subdev_8255_init()` to `subdev_8255_io_init()`. The
parameters are changing, so might as well rename it at the same time.

Also rename the `regbase` member of `struct subdev_8255_private` to
`context` since this holds the context for the call-back function call.

Cc: Arnd Bergmann <arnd@kernel.org>
Cc: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://lore.kernel.org/r/20230913170712.111719-7-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Ian Abbott and committed by
Greg Kroah-Hartman
5c57b1cc 0ccb86a6

+98 -106
+1 -1
drivers/comedi/drivers/8255.c
··· 80 80 if (ret) { 81 81 s->type = COMEDI_SUBD_UNUSED; 82 82 } else { 83 - ret = subdev_8255_init(dev, s, NULL, iobase); 83 + ret = subdev_8255_io_init(dev, s, iobase); 84 84 if (ret) { 85 85 /* 86 86 * Release the I/O port region here, as the
+2 -2
drivers/comedi/drivers/8255_pci.c
··· 242 242 for (i = 0; i < board->n_8255; i++) { 243 243 s = &dev->subdevices[i]; 244 244 if (dev->mmio) 245 - ret = subdev_8255_mm_init(dev, s, NULL, i * I8255_SIZE); 245 + ret = subdev_8255_mm_init(dev, s, i * I8255_SIZE); 246 246 else 247 - ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE); 247 + ret = subdev_8255_io_init(dev, s, i * I8255_SIZE); 248 248 if (ret) 249 249 return ret; 250 250 }
+2 -2
drivers/comedi/drivers/adv_pci_dio.c
··· 642 642 643 643 for (j = 0; j < d->chans; j++) { 644 644 s = &dev->subdevices[subdev++]; 645 - ret = subdev_8255_init(dev, s, NULL, 646 - d->addr + j * I8255_SIZE); 645 + ret = subdev_8255_io_init(dev, s, 646 + d->addr + j * I8255_SIZE); 647 647 if (ret) 648 648 return ret; 649 649 }
+1 -1
drivers/comedi/drivers/aio_aio12_8.c
··· 247 247 248 248 /* Digital I/O subdevice (8255) */ 249 249 s = &dev->subdevices[2]; 250 - ret = subdev_8255_init(dev, s, NULL, AIO12_8_8255_BASE_REG); 250 + ret = subdev_8255_io_init(dev, s, AIO12_8_8255_BASE_REG); 251 251 if (ret) 252 252 return ret; 253 253
+1 -1
drivers/comedi/drivers/amplc_pc236_common.c
··· 147 147 148 148 s = &dev->subdevices[0]; 149 149 /* digital i/o subdevice (8255) */ 150 - ret = subdev_8255_init(dev, s, NULL, 0x00); 150 + ret = subdev_8255_io_init(dev, s, 0x00); 151 151 if (ret) 152 152 return ret; 153 153
+1 -1
drivers/comedi/drivers/amplc_pci230.c
··· 2529 2529 s = &dev->subdevices[2]; 2530 2530 /* digital i/o subdevice */ 2531 2531 if (board->have_dio) { 2532 - rc = subdev_8255_init(dev, s, NULL, PCI230_PPI_X_BASE); 2532 + rc = subdev_8255_io_init(dev, s, PCI230_PPI_X_BASE); 2533 2533 if (rc) 2534 2534 return rc; 2535 2535 } else {
+1 -1
drivers/comedi/drivers/cb_pcidas.c
··· 1352 1352 1353 1353 /* 8255 */ 1354 1354 s = &dev->subdevices[2]; 1355 - ret = subdev_8255_init(dev, s, NULL, PCIDAS_8255_BASE); 1355 + ret = subdev_8255_io_init(dev, s, PCIDAS_8255_BASE); 1356 1356 if (ret) 1357 1357 return ret; 1358 1358
+3 -4
drivers/comedi/drivers/cb_pcidas64.c
··· 3877 3877 s = &dev->subdevices[4]; 3878 3878 if (board->has_8255) { 3879 3879 if (board->layout == LAYOUT_4020) { 3880 - ret = subdev_8255_init(dev, s, dio_callback_4020, 3881 - I8255_4020_REG); 3880 + ret = subdev_8255_cb_init(dev, s, dio_callback_4020, 3881 + I8255_4020_REG); 3882 3882 } else { 3883 - ret = subdev_8255_mm_init(dev, s, NULL, 3884 - DIO_8255_OFFSET); 3883 + ret = subdev_8255_mm_init(dev, s, DIO_8255_OFFSET); 3885 3884 } 3886 3885 if (ret) 3887 3886 return ret;
+1 -1
drivers/comedi/drivers/cb_pcidda.c
··· 365 365 /* two 8255 digital io subdevices */ 366 366 for (i = 0; i < 2; i++) { 367 367 s = &dev->subdevices[1 + i]; 368 - ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE); 368 + ret = subdev_8255_io_init(dev, s, i * I8255_SIZE); 369 369 if (ret) 370 370 return ret; 371 371 }
+1 -1
drivers/comedi/drivers/cb_pcimdas.c
··· 405 405 406 406 /* Digital I/O subdevice */ 407 407 s = &dev->subdevices[2]; 408 - ret = subdev_8255_init(dev, s, NULL, PCIMDAS_8255_BASE); 408 + ret = subdev_8255_io_init(dev, s, PCIMDAS_8255_BASE); 409 409 if (ret) 410 410 return ret; 411 411
+1 -1
drivers/comedi/drivers/cb_pcimdda.c
··· 154 154 155 155 s = &dev->subdevices[1]; 156 156 /* digital i/o subdevice */ 157 - return subdev_8255_init(dev, s, NULL, PCIMDDA_8255_BASE_REG); 157 + return subdev_8255_io_init(dev, s, PCIMDDA_8255_BASE_REG); 158 158 } 159 159 160 160 static struct comedi_driver cb_pcimdda_driver = {
+59 -68
drivers/comedi/drivers/comedi_8255.c
··· 33 33 #include <linux/comedi/comedi_8255.h> 34 34 35 35 struct subdev_8255_private { 36 - unsigned long regbase; 36 + unsigned long context; 37 37 int (*io)(struct comedi_device *dev, int dir, int port, int data, 38 - unsigned long regbase); 38 + unsigned long context); 39 39 }; 40 40 41 41 static int subdev_8255_io(struct comedi_device *dev, ··· 64 64 unsigned int *data) 65 65 { 66 66 struct subdev_8255_private *spriv = s->private; 67 - unsigned long regbase = spriv->regbase; 67 + unsigned long context = spriv->context; 68 68 unsigned int mask; 69 69 unsigned int v; 70 70 ··· 72 72 if (mask) { 73 73 if (mask & 0xff) 74 74 spriv->io(dev, 1, I8255_DATA_A_REG, 75 - s->state & 0xff, regbase); 75 + s->state & 0xff, context); 76 76 if (mask & 0xff00) 77 77 spriv->io(dev, 1, I8255_DATA_B_REG, 78 - (s->state >> 8) & 0xff, regbase); 78 + (s->state >> 8) & 0xff, context); 79 79 if (mask & 0xff0000) 80 80 spriv->io(dev, 1, I8255_DATA_C_REG, 81 - (s->state >> 16) & 0xff, regbase); 81 + (s->state >> 16) & 0xff, context); 82 82 } 83 83 84 - v = spriv->io(dev, 0, I8255_DATA_A_REG, 0, regbase); 85 - v |= (spriv->io(dev, 0, I8255_DATA_B_REG, 0, regbase) << 8); 86 - v |= (spriv->io(dev, 0, I8255_DATA_C_REG, 0, regbase) << 16); 84 + v = spriv->io(dev, 0, I8255_DATA_A_REG, 0, context); 85 + v |= (spriv->io(dev, 0, I8255_DATA_B_REG, 0, context) << 8); 86 + v |= (spriv->io(dev, 0, I8255_DATA_C_REG, 0, context) << 16); 87 87 88 88 data[1] = v; 89 89 ··· 94 94 struct comedi_subdevice *s) 95 95 { 96 96 struct subdev_8255_private *spriv = s->private; 97 - unsigned long regbase = spriv->regbase; 97 + unsigned long context = spriv->context; 98 98 int config; 99 99 100 100 config = I8255_CTRL_CW; ··· 108 108 if (!(s->io_bits & 0xf00000)) 109 109 config |= I8255_CTRL_C_HI_IO; 110 110 111 - spriv->io(dev, 1, I8255_CTRL_REG, config, regbase); 111 + spriv->io(dev, 1, I8255_CTRL_REG, config, context); 112 112 } 113 113 114 114 static int subdev_8255_insn_config(struct comedi_device *dev, ··· 142 142 struct comedi_subdevice *s, 143 143 int (*io)(struct comedi_device *dev, 144 144 int dir, int port, int data, 145 - unsigned long regbase), 146 - unsigned long regbase, 147 - bool is_mmio) 145 + unsigned long context), 146 + unsigned long context) 148 147 { 149 148 struct subdev_8255_private *spriv; 149 + 150 + if (!io) 151 + return -EINVAL; 150 152 151 153 spriv = comedi_alloc_spriv(s, sizeof(*spriv)); 152 154 if (!spriv) 153 155 return -ENOMEM; 154 156 155 - if (io) 156 - spriv->io = io; 157 - else if (is_mmio) 158 - spriv->io = subdev_8255_mmio; 159 - else 160 - spriv->io = subdev_8255_io; 161 - spriv->regbase = regbase; 157 + spriv->context = context; 162 158 163 159 s->type = COMEDI_SUBD_DIO; 164 160 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; ··· 170 174 } 171 175 172 176 /** 173 - * subdev_8255_init - initialize DIO subdevice for driving I/O mapped 8255 177 + * subdev_8255_io_init - initialize DIO subdevice for driving I/O mapped 8255 174 178 * @dev: comedi device owning subdevice 175 179 * @s: comedi subdevice to initialize 176 - * @io: (optional) register I/O call-back function 177 - * @regbase: offset of 8255 registers from dev->iobase, or call-back context 180 + * @regbase: offset of 8255 registers from dev->iobase 178 181 * 179 182 * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip. 180 183 * 181 - * If the optional I/O call-back function is provided, its prototype is of 182 - * the following form: 183 - * 184 - * int my_8255_callback(struct comedi_device *dev, int dir, int port, 185 - * int data, unsigned long regbase); 186 - * 187 - * where 'dev', and 'regbase' match the values passed to this function, 188 - * 'port' is the 8255 port number 0 to 3 (including the control port), 'dir' 189 - * is the direction (0 for read, 1 for write) and 'data' is the value to be 190 - * written. It should return 0 if writing or the value read if reading. 191 - * 192 - * If the optional I/O call-back function is not provided, an internal 193 - * call-back function is used which uses consecutive I/O port addresses 194 - * starting at dev->iobase + regbase. 195 - * 196 184 * Return: -ENOMEM if failed to allocate memory, zero on success. 197 185 */ 198 - int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, 199 - int (*io)(struct comedi_device *dev, int dir, int port, 200 - int data, unsigned long regbase), 186 + int subdev_8255_io_init(struct comedi_device *dev, struct comedi_subdevice *s, 201 187 unsigned long regbase) 202 188 { 203 - return __subdev_8255_init(dev, s, io, regbase, false); 189 + return __subdev_8255_init(dev, s, subdev_8255_io, regbase); 204 190 } 205 - EXPORT_SYMBOL_GPL(subdev_8255_init); 191 + EXPORT_SYMBOL_GPL(subdev_8255_io_init); 206 192 207 193 /** 208 194 * subdev_8255_mm_init - initialize DIO subdevice for driving mmio-mapped 8255 209 195 * @dev: comedi device owning subdevice 210 196 * @s: comedi subdevice to initialize 211 - * @io: (optional) register I/O call-back function 212 - * @regbase: offset of 8255 registers from dev->mmio, or call-back context 197 + * @regbase: offset of 8255 registers from dev->mmio 213 198 * 214 199 * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip. 215 - * 216 - * If the optional I/O call-back function is provided, its prototype is of 217 - * the following form: 218 - * 219 - * int my_8255_callback(struct comedi_device *dev, int dir, int port, 220 - * int data, unsigned long regbase); 221 - * 222 - * where 'dev', and 'regbase' match the values passed to this function, 223 - * 'port' is the 8255 port number 0 to 3 (including the control port), 'dir' 224 - * is the direction (0 for read, 1 for write) and 'data' is the value to be 225 - * written. It should return 0 if writing or the value read if reading. 226 - * 227 - * If the optional I/O call-back function is not provided, an internal 228 - * call-back function is used which uses consecutive MMIO virtual addresses 229 - * starting at dev->mmio + regbase. 230 200 * 231 201 * Return: -ENOMEM if failed to allocate memory, zero on success. 232 202 */ 233 203 int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s, 234 - int (*io)(struct comedi_device *dev, int dir, int port, 235 - int data, unsigned long regbase), 236 204 unsigned long regbase) 237 205 { 238 - return __subdev_8255_init(dev, s, io, regbase, true); 206 + return __subdev_8255_init(dev, s, subdev_8255_mmio, regbase); 239 207 } 240 208 EXPORT_SYMBOL_GPL(subdev_8255_mm_init); 209 + 210 + /** 211 + * subdev_8255_cb_init - initialize DIO subdevice for driving callback-mapped 8255 212 + * @dev: comedi device owning subdevice 213 + * @s: comedi subdevice to initialize 214 + * @io: register I/O call-back function 215 + * @context: call-back context 216 + * 217 + * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip. 218 + * 219 + * The prototype of the I/O call-back function is of the following form: 220 + * 221 + * int my_8255_callback(struct comedi_device *dev, int dir, int port, 222 + * int data, unsigned long context); 223 + * 224 + * where 'dev', and 'context' match the values passed to this function, 225 + * 'port' is the 8255 port number 0 to 3 (including the control port), 'dir' 226 + * is the direction (0 for read, 1 for write) and 'data' is the value to be 227 + * written. It should return 0 if writing or the value read if reading. 228 + * 229 + * 230 + * Return: -ENOMEM if failed to allocate memory, zero on success. 231 + */ 232 + int subdev_8255_cb_init(struct comedi_device *dev, struct comedi_subdevice *s, 233 + int (*io)(struct comedi_device *dev, int dir, int port, 234 + int data, unsigned long context), 235 + unsigned long context) 236 + { 237 + return __subdev_8255_init(dev, s, io, context); 238 + } 239 + EXPORT_SYMBOL_GPL(subdev_8255_cb_init); 241 240 242 241 /** 243 242 * subdev_8255_regbase - get offset of 8255 registers or call-back context 244 243 * @s: comedi subdevice 245 244 * 246 - * Returns the 'regbase' parameter that was previously passed to 247 - * subdev_8255_init() or subdev_8255_mm_init() to set up the subdevice. 248 - * Only valid if the subdevice was set up successfully. 245 + * Returns the 'regbase' or 'context' parameter that was previously passed to 246 + * subdev_8255_io_init(), subdev_8255_mm_init(), or subdev_8255_cb_init() to 247 + * set up the subdevice. Only valid if the subdevice was set up successfully. 249 248 */ 250 249 unsigned long subdev_8255_regbase(struct comedi_subdevice *s) 251 250 { 252 251 struct subdev_8255_private *spriv = s->private; 253 252 254 - return spriv->regbase; 253 + return spriv->context; 255 254 } 256 255 EXPORT_SYMBOL_GPL(subdev_8255_regbase); 257 256
+2 -2
drivers/comedi/drivers/daqboard2000.c
··· 738 738 return result; 739 739 740 740 s = &dev->subdevices[2]; 741 - return subdev_8255_init(dev, s, db2k_8255_cb, 742 - DB2K_REG_DIO_P2_EXP_IO_8_BIT); 741 + return subdev_8255_cb_init(dev, s, db2k_8255_cb, 742 + DB2K_REG_DIO_P2_EXP_IO_8_BIT); 743 743 } 744 744 745 745 static void db2k_detach(struct comedi_device *dev)
+1 -1
drivers/comedi/drivers/das08.c
··· 429 429 s = &dev->subdevices[4]; 430 430 /* 8255 */ 431 431 if (board->i8255_offset != 0) { 432 - ret = subdev_8255_init(dev, s, NULL, board->i8255_offset); 432 + ret = subdev_8255_io_init(dev, s, board->i8255_offset); 433 433 if (ret) 434 434 return ret; 435 435 } else {
+1 -1
drivers/comedi/drivers/das16.c
··· 1145 1145 /* 8255 Digital I/O subdevice */ 1146 1146 if (board->has_8255) { 1147 1147 s = &dev->subdevices[4]; 1148 - ret = subdev_8255_init(dev, s, NULL, board->i8255_offset); 1148 + ret = subdev_8255_io_init(dev, s, board->i8255_offset); 1149 1149 if (ret) 1150 1150 return ret; 1151 1151 }
+1 -1
drivers/comedi/drivers/das16m1.c
··· 583 583 584 584 /* Digital I/O subdevice (8255) */ 585 585 s = &dev->subdevices[3]; 586 - ret = subdev_8255_init(dev, s, NULL, DAS16M1_8255_IOBASE); 586 + ret = subdev_8255_io_init(dev, s, DAS16M1_8255_IOBASE); 587 587 if (ret) 588 588 return ret; 589 589
+2 -1
drivers/comedi/drivers/dmm32at.c
··· 599 599 600 600 /* Digital I/O subdevice */ 601 601 s = &dev->subdevices[2]; 602 - return subdev_8255_init(dev, s, dmm32at_8255_io, DMM32AT_8255_IOBASE); 602 + return subdev_8255_cb_init(dev, s, dmm32at_8255_io, 603 + DMM32AT_8255_IOBASE); 603 604 } 604 605 605 606 static struct comedi_driver dmm32at_driver = {
+1 -1
drivers/comedi/drivers/ni_atmio16d.c
··· 677 677 /* 8255 subdevice */ 678 678 s = &dev->subdevices[3]; 679 679 if (board->has_8255) { 680 - ret = subdev_8255_init(dev, s, NULL, 0x00); 680 + ret = subdev_8255_io_init(dev, s, 0x00); 681 681 if (ret) 682 682 return ret; 683 683 } else {
+1 -1
drivers/comedi/drivers/ni_daq_dio24.c
··· 45 45 46 46 /* 8255 dio */ 47 47 s = &dev->subdevices[0]; 48 - return subdev_8255_init(dev, s, NULL, 0x00); 48 + return subdev_8255_io_init(dev, s, 0x00); 49 49 } 50 50 51 51 static struct comedi_driver driver_dio24 = {
+2 -2
drivers/comedi/drivers/ni_labpc_common.c
··· 1287 1287 /* 8255 dio */ 1288 1288 s = &dev->subdevices[2]; 1289 1289 if (dev->mmio) 1290 - ret = subdev_8255_mm_init(dev, s, NULL, DIO_BASE_REG); 1290 + ret = subdev_8255_mm_init(dev, s, DIO_BASE_REG); 1291 1291 else 1292 - ret = subdev_8255_init(dev, s, NULL, DIO_BASE_REG); 1292 + ret = subdev_8255_io_init(dev, s, DIO_BASE_REG); 1293 1293 if (ret) 1294 1294 return ret; 1295 1295
+2 -2
drivers/comedi/drivers/ni_mio_common.c
··· 6137 6137 /* 8255 device */ 6138 6138 s = &dev->subdevices[NI_8255_DIO_SUBDEV]; 6139 6139 if (board->has_8255) { 6140 - ret = subdev_8255_init(dev, s, ni_8255_callback, 6141 - NI_E_8255_BASE); 6140 + ret = subdev_8255_cb_init(dev, s, ni_8255_callback, 6141 + NI_E_8255_BASE); 6142 6142 if (ret) 6143 6143 return ret; 6144 6144 } else {
+3 -3
drivers/comedi/drivers/pcl724.c
··· 124 124 s = &dev->subdevices[i]; 125 125 if (board->is_pet48) { 126 126 iobase = dev->iobase + (i * 0x1000); 127 - ret = subdev_8255_init(dev, s, pcl724_8255mapped_io, 128 - iobase); 127 + ret = subdev_8255_cb_init(dev, s, pcl724_8255mapped_io, 128 + iobase); 129 129 } else { 130 - ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE); 130 + ret = subdev_8255_io_init(dev, s, i * I8255_SIZE); 131 131 } 132 132 if (ret) 133 133 return ret;
+1 -1
drivers/comedi/drivers/pcm3724.c
··· 204 204 205 205 for (i = 0; i < dev->n_subdevices; i++) { 206 206 s = &dev->subdevices[i]; 207 - ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE); 207 + ret = subdev_8255_io_init(dev, s, i * I8255_SIZE); 208 208 if (ret) 209 209 return ret; 210 210 s->insn_config = subdev_3724_insn_config;
+7 -6
include/linux/comedi/comedi_8255.h
··· 27 27 struct comedi_device; 28 28 struct comedi_subdevice; 29 29 30 - int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, 31 - int (*io)(struct comedi_device *dev, int dir, int port, 32 - int data, unsigned long regbase), 33 - unsigned long regbase); 30 + int subdev_8255_io_init(struct comedi_device *dev, struct comedi_subdevice *s, 31 + unsigned long regbase); 34 32 35 33 int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s, 36 - int (*io)(struct comedi_device *dev, int dir, int port, 37 - int data, unsigned long regbase), 38 34 unsigned long regbase); 35 + 36 + int subdev_8255_cb_init(struct comedi_device *dev, struct comedi_subdevice *s, 37 + int (*io)(struct comedi_device *dev, int dir, int port, 38 + int data, unsigned long context), 39 + unsigned long context); 39 40 40 41 unsigned long subdev_8255_regbase(struct comedi_subdevice *s); 41 42