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

staging: comedi: addi_apci_1516: use addi_watchdog module

Use the addi_watchdog module to provide support for the watchdog
subdevice.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

H Hartley Sweeten and committed by
Greg Kroah-Hartman
1445ea15 9901a4d7

+11 -95
+1
drivers/staging/comedi/Kconfig
··· 599 599 600 600 config COMEDI_ADDI_APCI_1516 601 601 tristate "ADDI-DATA APCI-1016/1516/2016 support" 602 + select COMEDI_ADDI_WATCHDOG 602 603 ---help--- 603 604 Enable support for ADDI-DATA APCI-1016, APCI-1516 and APCI-2016 boards. 604 605 These are 16 channel, optically isolated, digital I/O boards. The 1516
+10 -95
drivers/staging/comedi/drivers/addi_apci_1516.c
··· 30 30 */ 31 31 32 32 #include "../comedidev.h" 33 + #include "addi_watchdog.h" 33 34 #include "comedi_fc.h" 34 35 35 36 /* ··· 50 49 * PCI bar 2 I/O Register map - Watchdog (APCI-1516 and APCI-2016) 51 50 */ 52 51 #define APCI1516_WDOG_REG 0x00 53 - #define APCI1516_WDOG_RELOAD_REG 0x04 54 - #define APCI1516_WDOG_CTRL_REG 0x0c 55 - #define APCI1516_WDOG_CTRL_ENABLE (1 << 0) 56 - #define APCI1516_WDOG_CTRL_SW_TRIG (1 << 9) 57 - #define APCI1516_WDOG_STATUS_REG 0x10 58 - #define APCI1516_WDOG_STATUS_ENABLED (1 << 0) 59 - #define APCI1516_WDOG_STATUS_SW_TRIG (1 << 1) 60 52 61 53 struct apci1516_boardinfo { 62 54 const char *name; ··· 80 86 81 87 struct apci1516_private { 82 88 unsigned long wdog_iobase; 83 - unsigned int ctrl; 84 89 }; 85 90 86 91 static int apci1516_di_insn_bits(struct comedi_device *dev, ··· 113 120 return insn->n; 114 121 } 115 122 116 - /* 117 - * The watchdog subdevice is configured with two INSN_CONFIG instructions: 118 - * 119 - * Enable the watchdog and set the reload timeout: 120 - * data[0] = INSN_CONFIG_ARM 121 - * data[1] = timeout reload value 122 - * 123 - * Disable the watchdog: 124 - * data[0] = INSN_CONFIG_DISARM 125 - */ 126 - static int apci1516_wdog_insn_config(struct comedi_device *dev, 127 - struct comedi_subdevice *s, 128 - struct comedi_insn *insn, 129 - unsigned int *data) 130 - { 131 - struct apci1516_private *devpriv = dev->private; 132 - unsigned int reload; 133 - 134 - switch (data[0]) { 135 - case INSN_CONFIG_ARM: 136 - devpriv->ctrl = APCI1516_WDOG_CTRL_ENABLE; 137 - reload = data[1] & s->maxdata; 138 - outw(reload, devpriv->wdog_iobase + APCI1516_WDOG_RELOAD_REG); 139 - 140 - /* Time base is 20ms, let the user know the timeout */ 141 - dev_info(dev->class_dev, "watchdog enabled, timeout:%dms\n", 142 - 20 * reload + 20); 143 - break; 144 - case INSN_CONFIG_DISARM: 145 - devpriv->ctrl = 0; 146 - break; 147 - default: 148 - return -EINVAL; 149 - } 150 - 151 - outw(devpriv->ctrl, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); 152 - 153 - return insn->n; 154 - } 155 - 156 - static int apci1516_wdog_insn_write(struct comedi_device *dev, 157 - struct comedi_subdevice *s, 158 - struct comedi_insn *insn, 159 - unsigned int *data) 160 - { 161 - struct apci1516_private *devpriv = dev->private; 162 - int i; 163 - 164 - if (devpriv->ctrl == 0) { 165 - dev_warn(dev->class_dev, "watchdog is disabled\n"); 166 - return -EINVAL; 167 - } 168 - 169 - /* "ping" the watchdog */ 170 - for (i = 0; i < insn->n; i++) { 171 - outw(devpriv->ctrl | APCI1516_WDOG_CTRL_SW_TRIG, 172 - devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); 173 - } 174 - 175 - return insn->n; 176 - } 177 - 178 - static int apci1516_wdog_insn_read(struct comedi_device *dev, 179 - struct comedi_subdevice *s, 180 - struct comedi_insn *insn, 181 - unsigned int *data) 182 - { 183 - struct apci1516_private *devpriv = dev->private; 184 - int i; 185 - 186 - for (i = 0; i < insn->n; i++) 187 - data[i] = inw(devpriv->wdog_iobase + APCI1516_WDOG_STATUS_REG); 188 - 189 - return insn->n; 190 - } 191 - 192 123 static int apci1516_reset(struct comedi_device *dev) 193 124 { 194 125 const struct apci1516_boardinfo *this_board = comedi_board(dev); ··· 122 205 return 0; 123 206 124 207 outw(0x0, dev->iobase + APCI1516_DO_REG); 125 - outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); 126 - outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_RELOAD_REG); 208 + 209 + addi_watchdog_reset(devpriv->wdog_iobase); 127 210 128 211 return 0; 129 212 } ··· 202 285 /* Initialize the watchdog subdevice */ 203 286 s = &dev->subdevices[2]; 204 287 if (this_board->has_wdog) { 205 - s->type = COMEDI_SUBD_TIMER; 206 - s->subdev_flags = SDF_WRITEABLE; 207 - s->n_chan = 1; 208 - s->maxdata = 0xff; 209 - s->insn_write = apci1516_wdog_insn_write; 210 - s->insn_read = apci1516_wdog_insn_read; 211 - s->insn_config = apci1516_wdog_insn_config; 288 + ret = addi_watchdog_init(s, devpriv->wdog_iobase); 289 + if (ret) 290 + return ret; 212 291 } else { 213 292 s->type = COMEDI_SUBD_UNUSED; 214 293 } ··· 217 304 { 218 305 struct pci_dev *pcidev = comedi_to_pci_dev(dev); 219 306 220 - if (dev->iobase) { 307 + if (dev->iobase) 221 308 apci1516_reset(dev); 309 + if (dev->subdevices) 310 + addi_watchdog_cleanup(&dev->subdevices[2]); 311 + if (dev->iobase) 222 312 comedi_pci_disable(pcidev); 223 - } 224 313 } 225 314 226 315 static struct comedi_driver apci1516_driver = {