gsmi: fix null-deref in gsmi_get_variable
[platform/kernel/linux-starfive.git] / drivers / counter / 104-quad-8.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Counter driver for the ACCES 104-QUAD-8
4  * Copyright (C) 2016 William Breathitt Gray
5  *
6  * This driver supports the ACCES 104-QUAD-8 and ACCES 104-QUAD-4.
7  */
8 #include <linux/bitops.h>
9 #include <linux/counter.h>
10 #include <linux/device.h>
11 #include <linux/errno.h>
12 #include <linux/io.h>
13 #include <linux/ioport.h>
14 #include <linux/interrupt.h>
15 #include <linux/isa.h>
16 #include <linux/kernel.h>
17 #include <linux/list.h>
18 #include <linux/module.h>
19 #include <linux/moduleparam.h>
20 #include <linux/types.h>
21 #include <linux/spinlock.h>
22
23 #define QUAD8_EXTENT 32
24
25 static unsigned int base[max_num_isa_dev(QUAD8_EXTENT)];
26 static unsigned int num_quad8;
27 module_param_hw_array(base, uint, ioport, &num_quad8, 0);
28 MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
29
30 static unsigned int irq[max_num_isa_dev(QUAD8_EXTENT)];
31 static unsigned int num_irq;
32 module_param_hw_array(irq, uint, irq, &num_irq, 0);
33 MODULE_PARM_DESC(irq, "ACCES 104-QUAD-8 interrupt line numbers");
34
35 #define QUAD8_NUM_COUNTERS 8
36
37 /**
38  * struct channel_reg - channel register structure
39  * @data:       Count data
40  * @control:    Channel flags and control
41  */
42 struct channel_reg {
43         u8 data;
44         u8 control;
45 };
46
47 /**
48  * struct quad8_reg - device register structure
49  * @channel:            quadrature counter data and control
50  * @interrupt_status:   channel interrupt status
51  * @channel_oper:       enable/reset counters and interrupt functions
52  * @index_interrupt:    enable channel interrupts
53  * @reserved:           reserved for Factory Use
54  * @index_input_levels: index signal logical input level
55  * @cable_status:       differential encoder cable status
56  */
57 struct quad8_reg {
58         struct channel_reg channel[QUAD8_NUM_COUNTERS];
59         u8 interrupt_status;
60         u8 channel_oper;
61         u8 index_interrupt;
62         u8 reserved[3];
63         u8 index_input_levels;
64         u8 cable_status;
65 };
66
67 /**
68  * struct quad8 - device private data structure
69  * @lock:               lock to prevent clobbering device states during R/W ops
70  * @counter:            instance of the counter_device
71  * @fck_prescaler:      array of filter clock prescaler configurations
72  * @preset:             array of preset values
73  * @count_mode:         array of count mode configurations
74  * @quadrature_mode:    array of quadrature mode configurations
75  * @quadrature_scale:   array of quadrature mode scale configurations
76  * @ab_enable:          array of A and B inputs enable configurations
77  * @preset_enable:      array of set_to_preset_on_index attribute configurations
78  * @irq_trigger:        array of current IRQ trigger function configurations
79  * @synchronous_mode:   array of index function synchronous mode configurations
80  * @index_polarity:     array of index function polarity configurations
81  * @cable_fault_enable: differential encoder cable status enable configurations
82  * @reg:                I/O address offset for the device registers
83  */
84 struct quad8 {
85         spinlock_t lock;
86         unsigned int fck_prescaler[QUAD8_NUM_COUNTERS];
87         unsigned int preset[QUAD8_NUM_COUNTERS];
88         unsigned int count_mode[QUAD8_NUM_COUNTERS];
89         unsigned int quadrature_mode[QUAD8_NUM_COUNTERS];
90         unsigned int quadrature_scale[QUAD8_NUM_COUNTERS];
91         unsigned int ab_enable[QUAD8_NUM_COUNTERS];
92         unsigned int preset_enable[QUAD8_NUM_COUNTERS];
93         unsigned int irq_trigger[QUAD8_NUM_COUNTERS];
94         unsigned int synchronous_mode[QUAD8_NUM_COUNTERS];
95         unsigned int index_polarity[QUAD8_NUM_COUNTERS];
96         unsigned int cable_fault_enable;
97         struct quad8_reg __iomem *reg;
98 };
99
100 /* Borrow Toggle flip-flop */
101 #define QUAD8_FLAG_BT BIT(0)
102 /* Carry Toggle flip-flop */
103 #define QUAD8_FLAG_CT BIT(1)
104 /* Error flag */
105 #define QUAD8_FLAG_E BIT(4)
106 /* Up/Down flag */
107 #define QUAD8_FLAG_UD BIT(5)
108 /* Reset and Load Signal Decoders */
109 #define QUAD8_CTR_RLD 0x00
110 /* Counter Mode Register */
111 #define QUAD8_CTR_CMR 0x20
112 /* Input / Output Control Register */
113 #define QUAD8_CTR_IOR 0x40
114 /* Index Control Register */
115 #define QUAD8_CTR_IDR 0x60
116 /* Reset Byte Pointer (three byte data pointer) */
117 #define QUAD8_RLD_RESET_BP 0x01
118 /* Reset Counter */
119 #define QUAD8_RLD_RESET_CNTR 0x02
120 /* Reset Borrow Toggle, Carry Toggle, Compare Toggle, and Sign flags */
121 #define QUAD8_RLD_RESET_FLAGS 0x04
122 /* Reset Error flag */
123 #define QUAD8_RLD_RESET_E 0x06
124 /* Preset Register to Counter */
125 #define QUAD8_RLD_PRESET_CNTR 0x08
126 /* Transfer Counter to Output Latch */
127 #define QUAD8_RLD_CNTR_OUT 0x10
128 /* Transfer Preset Register LSB to FCK Prescaler */
129 #define QUAD8_RLD_PRESET_PSC 0x18
130 #define QUAD8_CHAN_OP_RESET_COUNTERS 0x01
131 #define QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC 0x04
132 #define QUAD8_CMR_QUADRATURE_X1 0x08
133 #define QUAD8_CMR_QUADRATURE_X2 0x10
134 #define QUAD8_CMR_QUADRATURE_X4 0x18
135
136 static int quad8_signal_read(struct counter_device *counter,
137                              struct counter_signal *signal,
138                              enum counter_signal_level *level)
139 {
140         const struct quad8 *const priv = counter_priv(counter);
141         unsigned int state;
142
143         /* Only Index signal levels can be read */
144         if (signal->id < 16)
145                 return -EINVAL;
146
147         state = ioread8(&priv->reg->index_input_levels) & BIT(signal->id - 16);
148
149         *level = (state) ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
150
151         return 0;
152 }
153
154 static int quad8_count_read(struct counter_device *counter,
155                             struct counter_count *count, u64 *val)
156 {
157         struct quad8 *const priv = counter_priv(counter);
158         struct channel_reg __iomem *const chan = priv->reg->channel + count->id;
159         unsigned int flags;
160         unsigned int borrow;
161         unsigned int carry;
162         unsigned long irqflags;
163         int i;
164
165         flags = ioread8(&chan->control);
166         borrow = flags & QUAD8_FLAG_BT;
167         carry = !!(flags & QUAD8_FLAG_CT);
168
169         /* Borrow XOR Carry effectively doubles count range */
170         *val = (unsigned long)(borrow ^ carry) << 24;
171
172         spin_lock_irqsave(&priv->lock, irqflags);
173
174         /* Reset Byte Pointer; transfer Counter to Output Latch */
175         iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
176                  &chan->control);
177
178         for (i = 0; i < 3; i++)
179                 *val |= (unsigned long)ioread8(&chan->data) << (8 * i);
180
181         spin_unlock_irqrestore(&priv->lock, irqflags);
182
183         return 0;
184 }
185
186 static int quad8_count_write(struct counter_device *counter,
187                              struct counter_count *count, u64 val)
188 {
189         struct quad8 *const priv = counter_priv(counter);
190         struct channel_reg __iomem *const chan = priv->reg->channel + count->id;
191         unsigned long irqflags;
192         int i;
193
194         /* Only 24-bit values are supported */
195         if (val > 0xFFFFFF)
196                 return -ERANGE;
197
198         spin_lock_irqsave(&priv->lock, irqflags);
199
200         /* Reset Byte Pointer */
201         iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, &chan->control);
202
203         /* Counter can only be set via Preset Register */
204         for (i = 0; i < 3; i++)
205                 iowrite8(val >> (8 * i), &chan->data);
206
207         /* Transfer Preset Register to Counter */
208         iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_PRESET_CNTR, &chan->control);
209
210         /* Reset Byte Pointer */
211         iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, &chan->control);
212
213         /* Set Preset Register back to original value */
214         val = priv->preset[count->id];
215         for (i = 0; i < 3; i++)
216                 iowrite8(val >> (8 * i), &chan->data);
217
218         /* Reset Borrow, Carry, Compare, and Sign flags */
219         iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_FLAGS, &chan->control);
220         /* Reset Error flag */
221         iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, &chan->control);
222
223         spin_unlock_irqrestore(&priv->lock, irqflags);
224
225         return 0;
226 }
227
228 static const enum counter_function quad8_count_functions_list[] = {
229         COUNTER_FUNCTION_PULSE_DIRECTION,
230         COUNTER_FUNCTION_QUADRATURE_X1_A,
231         COUNTER_FUNCTION_QUADRATURE_X2_A,
232         COUNTER_FUNCTION_QUADRATURE_X4,
233 };
234
235 static int quad8_function_get(const struct quad8 *const priv, const size_t id,
236                               enum counter_function *const function)
237 {
238         if (!priv->quadrature_mode[id]) {
239                 *function = COUNTER_FUNCTION_PULSE_DIRECTION;
240                 return 0;
241         }
242
243         switch (priv->quadrature_scale[id]) {
244         case 0:
245                 *function = COUNTER_FUNCTION_QUADRATURE_X1_A;
246                 return 0;
247         case 1:
248                 *function = COUNTER_FUNCTION_QUADRATURE_X2_A;
249                 return 0;
250         case 2:
251                 *function = COUNTER_FUNCTION_QUADRATURE_X4;
252                 return 0;
253         default:
254                 /* should never reach this path */
255                 return -EINVAL;
256         }
257 }
258
259 static int quad8_function_read(struct counter_device *counter,
260                                struct counter_count *count,
261                                enum counter_function *function)
262 {
263         struct quad8 *const priv = counter_priv(counter);
264         unsigned long irqflags;
265         int retval;
266
267         spin_lock_irqsave(&priv->lock, irqflags);
268
269         retval = quad8_function_get(priv, count->id, function);
270
271         spin_unlock_irqrestore(&priv->lock, irqflags);
272
273         return retval;
274 }
275
276 static int quad8_function_write(struct counter_device *counter,
277                                 struct counter_count *count,
278                                 enum counter_function function)
279 {
280         struct quad8 *const priv = counter_priv(counter);
281         const int id = count->id;
282         unsigned int *const quadrature_mode = priv->quadrature_mode + id;
283         unsigned int *const scale = priv->quadrature_scale + id;
284         unsigned int *const synchronous_mode = priv->synchronous_mode + id;
285         u8 __iomem *const control = &priv->reg->channel[id].control;
286         unsigned long irqflags;
287         unsigned int mode_cfg;
288         unsigned int idr_cfg;
289
290         spin_lock_irqsave(&priv->lock, irqflags);
291
292         mode_cfg = priv->count_mode[id] << 1;
293         idr_cfg = priv->index_polarity[id] << 1;
294
295         if (function == COUNTER_FUNCTION_PULSE_DIRECTION) {
296                 *quadrature_mode = 0;
297
298                 /* Quadrature scaling only available in quadrature mode */
299                 *scale = 0;
300
301                 /* Synchronous function not supported in non-quadrature mode */
302                 if (*synchronous_mode) {
303                         *synchronous_mode = 0;
304                         /* Disable synchronous function mode */
305                         iowrite8(QUAD8_CTR_IDR | idr_cfg, control);
306                 }
307         } else {
308                 *quadrature_mode = 1;
309
310                 switch (function) {
311                 case COUNTER_FUNCTION_QUADRATURE_X1_A:
312                         *scale = 0;
313                         mode_cfg |= QUAD8_CMR_QUADRATURE_X1;
314                         break;
315                 case COUNTER_FUNCTION_QUADRATURE_X2_A:
316                         *scale = 1;
317                         mode_cfg |= QUAD8_CMR_QUADRATURE_X2;
318                         break;
319                 case COUNTER_FUNCTION_QUADRATURE_X4:
320                         *scale = 2;
321                         mode_cfg |= QUAD8_CMR_QUADRATURE_X4;
322                         break;
323                 default:
324                         /* should never reach this path */
325                         spin_unlock_irqrestore(&priv->lock, irqflags);
326                         return -EINVAL;
327                 }
328         }
329
330         /* Load mode configuration to Counter Mode Register */
331         iowrite8(QUAD8_CTR_CMR | mode_cfg, control);
332
333         spin_unlock_irqrestore(&priv->lock, irqflags);
334
335         return 0;
336 }
337
338 static int quad8_direction_read(struct counter_device *counter,
339                                 struct counter_count *count,
340                                 enum counter_count_direction *direction)
341 {
342         const struct quad8 *const priv = counter_priv(counter);
343         unsigned int ud_flag;
344         u8 __iomem *const flag_addr = &priv->reg->channel[count->id].control;
345
346         /* U/D flag: nonzero = up, zero = down */
347         ud_flag = ioread8(flag_addr) & QUAD8_FLAG_UD;
348
349         *direction = (ud_flag) ? COUNTER_COUNT_DIRECTION_FORWARD :
350                 COUNTER_COUNT_DIRECTION_BACKWARD;
351
352         return 0;
353 }
354
355 static const enum counter_synapse_action quad8_index_actions_list[] = {
356         COUNTER_SYNAPSE_ACTION_NONE,
357         COUNTER_SYNAPSE_ACTION_RISING_EDGE,
358 };
359
360 static const enum counter_synapse_action quad8_synapse_actions_list[] = {
361         COUNTER_SYNAPSE_ACTION_NONE,
362         COUNTER_SYNAPSE_ACTION_RISING_EDGE,
363         COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
364         COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
365 };
366
367 static int quad8_action_read(struct counter_device *counter,
368                              struct counter_count *count,
369                              struct counter_synapse *synapse,
370                              enum counter_synapse_action *action)
371 {
372         struct quad8 *const priv = counter_priv(counter);
373         unsigned long irqflags;
374         int err;
375         enum counter_function function;
376         const size_t signal_a_id = count->synapses[0].signal->id;
377         enum counter_count_direction direction;
378
379         /* Handle Index signals */
380         if (synapse->signal->id >= 16) {
381                 if (priv->preset_enable[count->id])
382                         *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
383                 else
384                         *action = COUNTER_SYNAPSE_ACTION_NONE;
385
386                 return 0;
387         }
388
389         spin_lock_irqsave(&priv->lock, irqflags);
390
391         /* Get Count function and direction atomically */
392         err = quad8_function_get(priv, count->id, &function);
393         if (err) {
394                 spin_unlock_irqrestore(&priv->lock, irqflags);
395                 return err;
396         }
397         err = quad8_direction_read(counter, count, &direction);
398         if (err) {
399                 spin_unlock_irqrestore(&priv->lock, irqflags);
400                 return err;
401         }
402
403         spin_unlock_irqrestore(&priv->lock, irqflags);
404
405         /* Default action mode */
406         *action = COUNTER_SYNAPSE_ACTION_NONE;
407
408         /* Determine action mode based on current count function mode */
409         switch (function) {
410         case COUNTER_FUNCTION_PULSE_DIRECTION:
411                 if (synapse->signal->id == signal_a_id)
412                         *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
413                 return 0;
414         case COUNTER_FUNCTION_QUADRATURE_X1_A:
415                 if (synapse->signal->id == signal_a_id) {
416                         if (direction == COUNTER_COUNT_DIRECTION_FORWARD)
417                                 *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
418                         else
419                                 *action = COUNTER_SYNAPSE_ACTION_FALLING_EDGE;
420                 }
421                 return 0;
422         case COUNTER_FUNCTION_QUADRATURE_X2_A:
423                 if (synapse->signal->id == signal_a_id)
424                         *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
425                 return 0;
426         case COUNTER_FUNCTION_QUADRATURE_X4:
427                 *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
428                 return 0;
429         default:
430                 /* should never reach this path */
431                 return -EINVAL;
432         }
433 }
434
435 enum {
436         QUAD8_EVENT_CARRY = 0,
437         QUAD8_EVENT_COMPARE = 1,
438         QUAD8_EVENT_CARRY_BORROW = 2,
439         QUAD8_EVENT_INDEX = 3,
440 };
441
442 static int quad8_events_configure(struct counter_device *counter)
443 {
444         struct quad8 *const priv = counter_priv(counter);
445         unsigned long irq_enabled = 0;
446         unsigned long irqflags;
447         struct counter_event_node *event_node;
448         unsigned int next_irq_trigger;
449         unsigned long ior_cfg;
450
451         spin_lock_irqsave(&priv->lock, irqflags);
452
453         list_for_each_entry(event_node, &counter->events_list, l) {
454                 switch (event_node->event) {
455                 case COUNTER_EVENT_OVERFLOW:
456                         next_irq_trigger = QUAD8_EVENT_CARRY;
457                         break;
458                 case COUNTER_EVENT_THRESHOLD:
459                         next_irq_trigger = QUAD8_EVENT_COMPARE;
460                         break;
461                 case COUNTER_EVENT_OVERFLOW_UNDERFLOW:
462                         next_irq_trigger = QUAD8_EVENT_CARRY_BORROW;
463                         break;
464                 case COUNTER_EVENT_INDEX:
465                         next_irq_trigger = QUAD8_EVENT_INDEX;
466                         break;
467                 default:
468                         /* should never reach this path */
469                         spin_unlock_irqrestore(&priv->lock, irqflags);
470                         return -EINVAL;
471                 }
472
473                 /* Enable IRQ line */
474                 irq_enabled |= BIT(event_node->channel);
475
476                 /* Skip configuration if it is the same as previously set */
477                 if (priv->irq_trigger[event_node->channel] == next_irq_trigger)
478                         continue;
479
480                 /* Save new IRQ function configuration */
481                 priv->irq_trigger[event_node->channel] = next_irq_trigger;
482
483                 /* Load configuration to I/O Control Register */
484                 ior_cfg = priv->ab_enable[event_node->channel] |
485                           priv->preset_enable[event_node->channel] << 1 |
486                           priv->irq_trigger[event_node->channel] << 3;
487                 iowrite8(QUAD8_CTR_IOR | ior_cfg,
488                          &priv->reg->channel[event_node->channel].control);
489         }
490
491         iowrite8(irq_enabled, &priv->reg->index_interrupt);
492
493         spin_unlock_irqrestore(&priv->lock, irqflags);
494
495         return 0;
496 }
497
498 static int quad8_watch_validate(struct counter_device *counter,
499                                 const struct counter_watch *watch)
500 {
501         struct counter_event_node *event_node;
502
503         if (watch->channel > QUAD8_NUM_COUNTERS - 1)
504                 return -EINVAL;
505
506         switch (watch->event) {
507         case COUNTER_EVENT_OVERFLOW:
508         case COUNTER_EVENT_THRESHOLD:
509         case COUNTER_EVENT_OVERFLOW_UNDERFLOW:
510         case COUNTER_EVENT_INDEX:
511                 list_for_each_entry(event_node, &counter->next_events_list, l)
512                         if (watch->channel == event_node->channel &&
513                                 watch->event != event_node->event)
514                                 return -EINVAL;
515                 return 0;
516         default:
517                 return -EINVAL;
518         }
519 }
520
521 static const struct counter_ops quad8_ops = {
522         .signal_read = quad8_signal_read,
523         .count_read = quad8_count_read,
524         .count_write = quad8_count_write,
525         .function_read = quad8_function_read,
526         .function_write = quad8_function_write,
527         .action_read = quad8_action_read,
528         .events_configure = quad8_events_configure,
529         .watch_validate = quad8_watch_validate,
530 };
531
532 static const char *const quad8_index_polarity_modes[] = {
533         "negative",
534         "positive"
535 };
536
537 static int quad8_index_polarity_get(struct counter_device *counter,
538                                     struct counter_signal *signal,
539                                     u32 *index_polarity)
540 {
541         const struct quad8 *const priv = counter_priv(counter);
542         const size_t channel_id = signal->id - 16;
543
544         *index_polarity = priv->index_polarity[channel_id];
545
546         return 0;
547 }
548
549 static int quad8_index_polarity_set(struct counter_device *counter,
550                                     struct counter_signal *signal,
551                                     u32 index_polarity)
552 {
553         struct quad8 *const priv = counter_priv(counter);
554         const size_t channel_id = signal->id - 16;
555         u8 __iomem *const control = &priv->reg->channel[channel_id].control;
556         unsigned long irqflags;
557         unsigned int idr_cfg = index_polarity << 1;
558
559         spin_lock_irqsave(&priv->lock, irqflags);
560
561         idr_cfg |= priv->synchronous_mode[channel_id];
562
563         priv->index_polarity[channel_id] = index_polarity;
564
565         /* Load Index Control configuration to Index Control Register */
566         iowrite8(QUAD8_CTR_IDR | idr_cfg, control);
567
568         spin_unlock_irqrestore(&priv->lock, irqflags);
569
570         return 0;
571 }
572
573 static int quad8_polarity_read(struct counter_device *counter,
574                                struct counter_signal *signal,
575                                enum counter_signal_polarity *polarity)
576 {
577         int err;
578         u32 index_polarity;
579
580         err = quad8_index_polarity_get(counter, signal, &index_polarity);
581         if (err)
582                 return err;
583
584         *polarity = (index_polarity) ? COUNTER_SIGNAL_POLARITY_POSITIVE :
585                 COUNTER_SIGNAL_POLARITY_NEGATIVE;
586
587         return 0;
588 }
589
590 static int quad8_polarity_write(struct counter_device *counter,
591                                 struct counter_signal *signal,
592                                 enum counter_signal_polarity polarity)
593 {
594         const u32 pol = (polarity == COUNTER_SIGNAL_POLARITY_POSITIVE) ? 1 : 0;
595
596         return quad8_index_polarity_set(counter, signal, pol);
597 }
598
599 static const char *const quad8_synchronous_modes[] = {
600         "non-synchronous",
601         "synchronous"
602 };
603
604 static int quad8_synchronous_mode_get(struct counter_device *counter,
605                                       struct counter_signal *signal,
606                                       u32 *synchronous_mode)
607 {
608         const struct quad8 *const priv = counter_priv(counter);
609         const size_t channel_id = signal->id - 16;
610
611         *synchronous_mode = priv->synchronous_mode[channel_id];
612
613         return 0;
614 }
615
616 static int quad8_synchronous_mode_set(struct counter_device *counter,
617                                       struct counter_signal *signal,
618                                       u32 synchronous_mode)
619 {
620         struct quad8 *const priv = counter_priv(counter);
621         const size_t channel_id = signal->id - 16;
622         u8 __iomem *const control = &priv->reg->channel[channel_id].control;
623         unsigned long irqflags;
624         unsigned int idr_cfg = synchronous_mode;
625
626         spin_lock_irqsave(&priv->lock, irqflags);
627
628         idr_cfg |= priv->index_polarity[channel_id] << 1;
629
630         /* Index function must be non-synchronous in non-quadrature mode */
631         if (synchronous_mode && !priv->quadrature_mode[channel_id]) {
632                 spin_unlock_irqrestore(&priv->lock, irqflags);
633                 return -EINVAL;
634         }
635
636         priv->synchronous_mode[channel_id] = synchronous_mode;
637
638         /* Load Index Control configuration to Index Control Register */
639         iowrite8(QUAD8_CTR_IDR | idr_cfg, control);
640
641         spin_unlock_irqrestore(&priv->lock, irqflags);
642
643         return 0;
644 }
645
646 static int quad8_count_floor_read(struct counter_device *counter,
647                                   struct counter_count *count, u64 *floor)
648 {
649         /* Only a floor of 0 is supported */
650         *floor = 0;
651
652         return 0;
653 }
654
655 static int quad8_count_mode_read(struct counter_device *counter,
656                                  struct counter_count *count,
657                                  enum counter_count_mode *cnt_mode)
658 {
659         const struct quad8 *const priv = counter_priv(counter);
660
661         /* Map 104-QUAD-8 count mode to Generic Counter count mode */
662         switch (priv->count_mode[count->id]) {
663         case 0:
664                 *cnt_mode = COUNTER_COUNT_MODE_NORMAL;
665                 break;
666         case 1:
667                 *cnt_mode = COUNTER_COUNT_MODE_RANGE_LIMIT;
668                 break;
669         case 2:
670                 *cnt_mode = COUNTER_COUNT_MODE_NON_RECYCLE;
671                 break;
672         case 3:
673                 *cnt_mode = COUNTER_COUNT_MODE_MODULO_N;
674                 break;
675         }
676
677         return 0;
678 }
679
680 static int quad8_count_mode_write(struct counter_device *counter,
681                                   struct counter_count *count,
682                                   enum counter_count_mode cnt_mode)
683 {
684         struct quad8 *const priv = counter_priv(counter);
685         unsigned int count_mode;
686         unsigned int mode_cfg;
687         u8 __iomem *const control = &priv->reg->channel[count->id].control;
688         unsigned long irqflags;
689
690         /* Map Generic Counter count mode to 104-QUAD-8 count mode */
691         switch (cnt_mode) {
692         case COUNTER_COUNT_MODE_NORMAL:
693                 count_mode = 0;
694                 break;
695         case COUNTER_COUNT_MODE_RANGE_LIMIT:
696                 count_mode = 1;
697                 break;
698         case COUNTER_COUNT_MODE_NON_RECYCLE:
699                 count_mode = 2;
700                 break;
701         case COUNTER_COUNT_MODE_MODULO_N:
702                 count_mode = 3;
703                 break;
704         default:
705                 /* should never reach this path */
706                 return -EINVAL;
707         }
708
709         spin_lock_irqsave(&priv->lock, irqflags);
710
711         priv->count_mode[count->id] = count_mode;
712
713         /* Set count mode configuration value */
714         mode_cfg = count_mode << 1;
715
716         /* Add quadrature mode configuration */
717         if (priv->quadrature_mode[count->id])
718                 mode_cfg |= (priv->quadrature_scale[count->id] + 1) << 3;
719
720         /* Load mode configuration to Counter Mode Register */
721         iowrite8(QUAD8_CTR_CMR | mode_cfg, control);
722
723         spin_unlock_irqrestore(&priv->lock, irqflags);
724
725         return 0;
726 }
727
728 static int quad8_count_enable_read(struct counter_device *counter,
729                                    struct counter_count *count, u8 *enable)
730 {
731         const struct quad8 *const priv = counter_priv(counter);
732
733         *enable = priv->ab_enable[count->id];
734
735         return 0;
736 }
737
738 static int quad8_count_enable_write(struct counter_device *counter,
739                                     struct counter_count *count, u8 enable)
740 {
741         struct quad8 *const priv = counter_priv(counter);
742         u8 __iomem *const control = &priv->reg->channel[count->id].control;
743         unsigned long irqflags;
744         unsigned int ior_cfg;
745
746         spin_lock_irqsave(&priv->lock, irqflags);
747
748         priv->ab_enable[count->id] = enable;
749
750         ior_cfg = enable | priv->preset_enable[count->id] << 1 |
751                   priv->irq_trigger[count->id] << 3;
752
753         /* Load I/O control configuration */
754         iowrite8(QUAD8_CTR_IOR | ior_cfg, control);
755
756         spin_unlock_irqrestore(&priv->lock, irqflags);
757
758         return 0;
759 }
760
761 static const char *const quad8_noise_error_states[] = {
762         "No excessive noise is present at the count inputs",
763         "Excessive noise is present at the count inputs"
764 };
765
766 static int quad8_error_noise_get(struct counter_device *counter,
767                                  struct counter_count *count, u32 *noise_error)
768 {
769         const struct quad8 *const priv = counter_priv(counter);
770         u8 __iomem *const flag_addr = &priv->reg->channel[count->id].control;
771
772         *noise_error = !!(ioread8(flag_addr) & QUAD8_FLAG_E);
773
774         return 0;
775 }
776
777 static int quad8_count_preset_read(struct counter_device *counter,
778                                    struct counter_count *count, u64 *preset)
779 {
780         const struct quad8 *const priv = counter_priv(counter);
781
782         *preset = priv->preset[count->id];
783
784         return 0;
785 }
786
787 static void quad8_preset_register_set(struct quad8 *const priv, const int id,
788                                       const unsigned int preset)
789 {
790         struct channel_reg __iomem *const chan = priv->reg->channel + id;
791         int i;
792
793         priv->preset[id] = preset;
794
795         /* Reset Byte Pointer */
796         iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, &chan->control);
797
798         /* Set Preset Register */
799         for (i = 0; i < 3; i++)
800                 iowrite8(preset >> (8 * i), &chan->data);
801 }
802
803 static int quad8_count_preset_write(struct counter_device *counter,
804                                     struct counter_count *count, u64 preset)
805 {
806         struct quad8 *const priv = counter_priv(counter);
807         unsigned long irqflags;
808
809         /* Only 24-bit values are supported */
810         if (preset > 0xFFFFFF)
811                 return -ERANGE;
812
813         spin_lock_irqsave(&priv->lock, irqflags);
814
815         quad8_preset_register_set(priv, count->id, preset);
816
817         spin_unlock_irqrestore(&priv->lock, irqflags);
818
819         return 0;
820 }
821
822 static int quad8_count_ceiling_read(struct counter_device *counter,
823                                     struct counter_count *count, u64 *ceiling)
824 {
825         struct quad8 *const priv = counter_priv(counter);
826         unsigned long irqflags;
827
828         spin_lock_irqsave(&priv->lock, irqflags);
829
830         /* Range Limit and Modulo-N count modes use preset value as ceiling */
831         switch (priv->count_mode[count->id]) {
832         case 1:
833         case 3:
834                 *ceiling = priv->preset[count->id];
835                 break;
836         default:
837                 /* By default 0x1FFFFFF (25 bits unsigned) is maximum count */
838                 *ceiling = 0x1FFFFFF;
839                 break;
840         }
841
842         spin_unlock_irqrestore(&priv->lock, irqflags);
843
844         return 0;
845 }
846
847 static int quad8_count_ceiling_write(struct counter_device *counter,
848                                      struct counter_count *count, u64 ceiling)
849 {
850         struct quad8 *const priv = counter_priv(counter);
851         unsigned long irqflags;
852
853         /* Only 24-bit values are supported */
854         if (ceiling > 0xFFFFFF)
855                 return -ERANGE;
856
857         spin_lock_irqsave(&priv->lock, irqflags);
858
859         /* Range Limit and Modulo-N count modes use preset value as ceiling */
860         switch (priv->count_mode[count->id]) {
861         case 1:
862         case 3:
863                 quad8_preset_register_set(priv, count->id, ceiling);
864                 spin_unlock_irqrestore(&priv->lock, irqflags);
865                 return 0;
866         }
867
868         spin_unlock_irqrestore(&priv->lock, irqflags);
869
870         return -EINVAL;
871 }
872
873 static int quad8_count_preset_enable_read(struct counter_device *counter,
874                                           struct counter_count *count,
875                                           u8 *preset_enable)
876 {
877         const struct quad8 *const priv = counter_priv(counter);
878
879         *preset_enable = !priv->preset_enable[count->id];
880
881         return 0;
882 }
883
884 static int quad8_count_preset_enable_write(struct counter_device *counter,
885                                            struct counter_count *count,
886                                            u8 preset_enable)
887 {
888         struct quad8 *const priv = counter_priv(counter);
889         u8 __iomem *const control = &priv->reg->channel[count->id].control;
890         unsigned long irqflags;
891         unsigned int ior_cfg;
892
893         /* Preset enable is active low in Input/Output Control register */
894         preset_enable = !preset_enable;
895
896         spin_lock_irqsave(&priv->lock, irqflags);
897
898         priv->preset_enable[count->id] = preset_enable;
899
900         ior_cfg = priv->ab_enable[count->id] | preset_enable << 1 |
901                   priv->irq_trigger[count->id] << 3;
902
903         /* Load I/O control configuration to Input / Output Control Register */
904         iowrite8(QUAD8_CTR_IOR | ior_cfg, control);
905
906         spin_unlock_irqrestore(&priv->lock, irqflags);
907
908         return 0;
909 }
910
911 static int quad8_signal_cable_fault_read(struct counter_device *counter,
912                                          struct counter_signal *signal,
913                                          u8 *cable_fault)
914 {
915         struct quad8 *const priv = counter_priv(counter);
916         const size_t channel_id = signal->id / 2;
917         unsigned long irqflags;
918         bool disabled;
919         unsigned int status;
920
921         spin_lock_irqsave(&priv->lock, irqflags);
922
923         disabled = !(priv->cable_fault_enable & BIT(channel_id));
924
925         if (disabled) {
926                 spin_unlock_irqrestore(&priv->lock, irqflags);
927                 return -EINVAL;
928         }
929
930         /* Logic 0 = cable fault */
931         status = ioread8(&priv->reg->cable_status);
932
933         spin_unlock_irqrestore(&priv->lock, irqflags);
934
935         /* Mask respective channel and invert logic */
936         *cable_fault = !(status & BIT(channel_id));
937
938         return 0;
939 }
940
941 static int quad8_signal_cable_fault_enable_read(struct counter_device *counter,
942                                                 struct counter_signal *signal,
943                                                 u8 *enable)
944 {
945         const struct quad8 *const priv = counter_priv(counter);
946         const size_t channel_id = signal->id / 2;
947
948         *enable = !!(priv->cable_fault_enable & BIT(channel_id));
949
950         return 0;
951 }
952
953 static int quad8_signal_cable_fault_enable_write(struct counter_device *counter,
954                                                  struct counter_signal *signal,
955                                                  u8 enable)
956 {
957         struct quad8 *const priv = counter_priv(counter);
958         const size_t channel_id = signal->id / 2;
959         unsigned long irqflags;
960         unsigned int cable_fault_enable;
961
962         spin_lock_irqsave(&priv->lock, irqflags);
963
964         if (enable)
965                 priv->cable_fault_enable |= BIT(channel_id);
966         else
967                 priv->cable_fault_enable &= ~BIT(channel_id);
968
969         /* Enable is active low in Differential Encoder Cable Status register */
970         cable_fault_enable = ~priv->cable_fault_enable;
971
972         iowrite8(cable_fault_enable, &priv->reg->cable_status);
973
974         spin_unlock_irqrestore(&priv->lock, irqflags);
975
976         return 0;
977 }
978
979 static int quad8_signal_fck_prescaler_read(struct counter_device *counter,
980                                            struct counter_signal *signal,
981                                            u8 *prescaler)
982 {
983         const struct quad8 *const priv = counter_priv(counter);
984
985         *prescaler = priv->fck_prescaler[signal->id / 2];
986
987         return 0;
988 }
989
990 static int quad8_signal_fck_prescaler_write(struct counter_device *counter,
991                                             struct counter_signal *signal,
992                                             u8 prescaler)
993 {
994         struct quad8 *const priv = counter_priv(counter);
995         const size_t channel_id = signal->id / 2;
996         struct channel_reg __iomem *const chan = priv->reg->channel + channel_id;
997         unsigned long irqflags;
998
999         spin_lock_irqsave(&priv->lock, irqflags);
1000
1001         priv->fck_prescaler[channel_id] = prescaler;
1002
1003         /* Reset Byte Pointer */
1004         iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, &chan->control);
1005
1006         /* Set filter clock factor */
1007         iowrite8(prescaler, &chan->data);
1008         iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC,
1009                  &chan->control);
1010
1011         spin_unlock_irqrestore(&priv->lock, irqflags);
1012
1013         return 0;
1014 }
1015
1016 static struct counter_comp quad8_signal_ext[] = {
1017         COUNTER_COMP_SIGNAL_BOOL("cable_fault", quad8_signal_cable_fault_read,
1018                                  NULL),
1019         COUNTER_COMP_SIGNAL_BOOL("cable_fault_enable",
1020                                  quad8_signal_cable_fault_enable_read,
1021                                  quad8_signal_cable_fault_enable_write),
1022         COUNTER_COMP_SIGNAL_U8("filter_clock_prescaler",
1023                                quad8_signal_fck_prescaler_read,
1024                                quad8_signal_fck_prescaler_write)
1025 };
1026
1027 static const enum counter_signal_polarity quad8_polarities[] = {
1028         COUNTER_SIGNAL_POLARITY_POSITIVE,
1029         COUNTER_SIGNAL_POLARITY_NEGATIVE,
1030 };
1031
1032 static DEFINE_COUNTER_AVAILABLE(quad8_polarity_available, quad8_polarities);
1033
1034 static DEFINE_COUNTER_ENUM(quad8_index_pol_enum, quad8_index_polarity_modes);
1035 static DEFINE_COUNTER_ENUM(quad8_synch_mode_enum, quad8_synchronous_modes);
1036
1037 static struct counter_comp quad8_index_ext[] = {
1038         COUNTER_COMP_SIGNAL_ENUM("index_polarity", quad8_index_polarity_get,
1039                                  quad8_index_polarity_set,
1040                                  quad8_index_pol_enum),
1041         COUNTER_COMP_POLARITY(quad8_polarity_read, quad8_polarity_write,
1042                               quad8_polarity_available),
1043         COUNTER_COMP_SIGNAL_ENUM("synchronous_mode", quad8_synchronous_mode_get,
1044                                  quad8_synchronous_mode_set,
1045                                  quad8_synch_mode_enum),
1046 };
1047
1048 #define QUAD8_QUAD_SIGNAL(_id, _name) {         \
1049         .id = (_id),                            \
1050         .name = (_name),                        \
1051         .ext = quad8_signal_ext,                \
1052         .num_ext = ARRAY_SIZE(quad8_signal_ext) \
1053 }
1054
1055 #define QUAD8_INDEX_SIGNAL(_id, _name) {        \
1056         .id = (_id),                            \
1057         .name = (_name),                        \
1058         .ext = quad8_index_ext,                 \
1059         .num_ext = ARRAY_SIZE(quad8_index_ext)  \
1060 }
1061
1062 static struct counter_signal quad8_signals[] = {
1063         QUAD8_QUAD_SIGNAL(0, "Channel 1 Quadrature A"),
1064         QUAD8_QUAD_SIGNAL(1, "Channel 1 Quadrature B"),
1065         QUAD8_QUAD_SIGNAL(2, "Channel 2 Quadrature A"),
1066         QUAD8_QUAD_SIGNAL(3, "Channel 2 Quadrature B"),
1067         QUAD8_QUAD_SIGNAL(4, "Channel 3 Quadrature A"),
1068         QUAD8_QUAD_SIGNAL(5, "Channel 3 Quadrature B"),
1069         QUAD8_QUAD_SIGNAL(6, "Channel 4 Quadrature A"),
1070         QUAD8_QUAD_SIGNAL(7, "Channel 4 Quadrature B"),
1071         QUAD8_QUAD_SIGNAL(8, "Channel 5 Quadrature A"),
1072         QUAD8_QUAD_SIGNAL(9, "Channel 5 Quadrature B"),
1073         QUAD8_QUAD_SIGNAL(10, "Channel 6 Quadrature A"),
1074         QUAD8_QUAD_SIGNAL(11, "Channel 6 Quadrature B"),
1075         QUAD8_QUAD_SIGNAL(12, "Channel 7 Quadrature A"),
1076         QUAD8_QUAD_SIGNAL(13, "Channel 7 Quadrature B"),
1077         QUAD8_QUAD_SIGNAL(14, "Channel 8 Quadrature A"),
1078         QUAD8_QUAD_SIGNAL(15, "Channel 8 Quadrature B"),
1079         QUAD8_INDEX_SIGNAL(16, "Channel 1 Index"),
1080         QUAD8_INDEX_SIGNAL(17, "Channel 2 Index"),
1081         QUAD8_INDEX_SIGNAL(18, "Channel 3 Index"),
1082         QUAD8_INDEX_SIGNAL(19, "Channel 4 Index"),
1083         QUAD8_INDEX_SIGNAL(20, "Channel 5 Index"),
1084         QUAD8_INDEX_SIGNAL(21, "Channel 6 Index"),
1085         QUAD8_INDEX_SIGNAL(22, "Channel 7 Index"),
1086         QUAD8_INDEX_SIGNAL(23, "Channel 8 Index")
1087 };
1088
1089 #define QUAD8_COUNT_SYNAPSES(_id) {                                     \
1090         {                                                               \
1091                 .actions_list = quad8_synapse_actions_list,             \
1092                 .num_actions = ARRAY_SIZE(quad8_synapse_actions_list),  \
1093                 .signal = quad8_signals + 2 * (_id)                     \
1094         },                                                              \
1095         {                                                               \
1096                 .actions_list = quad8_synapse_actions_list,             \
1097                 .num_actions = ARRAY_SIZE(quad8_synapse_actions_list),  \
1098                 .signal = quad8_signals + 2 * (_id) + 1                 \
1099         },                                                              \
1100         {                                                               \
1101                 .actions_list = quad8_index_actions_list,               \
1102                 .num_actions = ARRAY_SIZE(quad8_index_actions_list),    \
1103                 .signal = quad8_signals + 2 * (_id) + 16                \
1104         }                                                               \
1105 }
1106
1107 static struct counter_synapse quad8_count_synapses[][3] = {
1108         QUAD8_COUNT_SYNAPSES(0), QUAD8_COUNT_SYNAPSES(1),
1109         QUAD8_COUNT_SYNAPSES(2), QUAD8_COUNT_SYNAPSES(3),
1110         QUAD8_COUNT_SYNAPSES(4), QUAD8_COUNT_SYNAPSES(5),
1111         QUAD8_COUNT_SYNAPSES(6), QUAD8_COUNT_SYNAPSES(7)
1112 };
1113
1114 static const enum counter_count_mode quad8_cnt_modes[] = {
1115         COUNTER_COUNT_MODE_NORMAL,
1116         COUNTER_COUNT_MODE_RANGE_LIMIT,
1117         COUNTER_COUNT_MODE_NON_RECYCLE,
1118         COUNTER_COUNT_MODE_MODULO_N,
1119 };
1120
1121 static DEFINE_COUNTER_AVAILABLE(quad8_count_mode_available, quad8_cnt_modes);
1122
1123 static DEFINE_COUNTER_ENUM(quad8_error_noise_enum, quad8_noise_error_states);
1124
1125 static struct counter_comp quad8_count_ext[] = {
1126         COUNTER_COMP_CEILING(quad8_count_ceiling_read,
1127                              quad8_count_ceiling_write),
1128         COUNTER_COMP_FLOOR(quad8_count_floor_read, NULL),
1129         COUNTER_COMP_COUNT_MODE(quad8_count_mode_read, quad8_count_mode_write,
1130                                 quad8_count_mode_available),
1131         COUNTER_COMP_DIRECTION(quad8_direction_read),
1132         COUNTER_COMP_ENABLE(quad8_count_enable_read, quad8_count_enable_write),
1133         COUNTER_COMP_COUNT_ENUM("error_noise", quad8_error_noise_get, NULL,
1134                                 quad8_error_noise_enum),
1135         COUNTER_COMP_PRESET(quad8_count_preset_read, quad8_count_preset_write),
1136         COUNTER_COMP_PRESET_ENABLE(quad8_count_preset_enable_read,
1137                                    quad8_count_preset_enable_write),
1138 };
1139
1140 #define QUAD8_COUNT(_id, _cntname) {                                    \
1141         .id = (_id),                                                    \
1142         .name = (_cntname),                                             \
1143         .functions_list = quad8_count_functions_list,                   \
1144         .num_functions = ARRAY_SIZE(quad8_count_functions_list),        \
1145         .synapses = quad8_count_synapses[(_id)],                        \
1146         .num_synapses = 2,                                              \
1147         .ext = quad8_count_ext,                                         \
1148         .num_ext = ARRAY_SIZE(quad8_count_ext)                          \
1149 }
1150
1151 static struct counter_count quad8_counts[] = {
1152         QUAD8_COUNT(0, "Channel 1 Count"),
1153         QUAD8_COUNT(1, "Channel 2 Count"),
1154         QUAD8_COUNT(2, "Channel 3 Count"),
1155         QUAD8_COUNT(3, "Channel 4 Count"),
1156         QUAD8_COUNT(4, "Channel 5 Count"),
1157         QUAD8_COUNT(5, "Channel 6 Count"),
1158         QUAD8_COUNT(6, "Channel 7 Count"),
1159         QUAD8_COUNT(7, "Channel 8 Count")
1160 };
1161
1162 static irqreturn_t quad8_irq_handler(int irq, void *private)
1163 {
1164         struct counter_device *counter = private;
1165         struct quad8 *const priv = counter_priv(counter);
1166         unsigned long irq_status;
1167         unsigned long channel;
1168         u8 event;
1169
1170         irq_status = ioread8(&priv->reg->interrupt_status);
1171         if (!irq_status)
1172                 return IRQ_NONE;
1173
1174         for_each_set_bit(channel, &irq_status, QUAD8_NUM_COUNTERS) {
1175                 switch (priv->irq_trigger[channel]) {
1176                 case QUAD8_EVENT_CARRY:
1177                         event = COUNTER_EVENT_OVERFLOW;
1178                                 break;
1179                 case QUAD8_EVENT_COMPARE:
1180                         event = COUNTER_EVENT_THRESHOLD;
1181                                 break;
1182                 case QUAD8_EVENT_CARRY_BORROW:
1183                         event = COUNTER_EVENT_OVERFLOW_UNDERFLOW;
1184                                 break;
1185                 case QUAD8_EVENT_INDEX:
1186                         event = COUNTER_EVENT_INDEX;
1187                                 break;
1188                 default:
1189                         /* should never reach this path */
1190                         WARN_ONCE(true, "invalid interrupt trigger function %u configured for channel %lu\n",
1191                                   priv->irq_trigger[channel], channel);
1192                         continue;
1193                 }
1194
1195                 counter_push_event(counter, event, channel);
1196         }
1197
1198         /* Clear pending interrupts on device */
1199         iowrite8(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, &priv->reg->channel_oper);
1200
1201         return IRQ_HANDLED;
1202 }
1203
1204 static void quad8_init_counter(struct channel_reg __iomem *const chan)
1205 {
1206         unsigned long i;
1207
1208         /* Reset Byte Pointer */
1209         iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, &chan->control);
1210         /* Reset filter clock factor */
1211         iowrite8(0, &chan->data);
1212         iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC,
1213                  &chan->control);
1214         /* Reset Byte Pointer */
1215         iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, &chan->control);
1216         /* Reset Preset Register */
1217         for (i = 0; i < 3; i++)
1218                 iowrite8(0x00, &chan->data);
1219         /* Reset Borrow, Carry, Compare, and Sign flags */
1220         iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_FLAGS, &chan->control);
1221         /* Reset Error flag */
1222         iowrite8(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, &chan->control);
1223         /* Binary encoding; Normal count; non-quadrature mode */
1224         iowrite8(QUAD8_CTR_CMR, &chan->control);
1225         /* Disable A and B inputs; preset on index; FLG1 as Carry */
1226         iowrite8(QUAD8_CTR_IOR, &chan->control);
1227         /* Disable index function; negative index polarity */
1228         iowrite8(QUAD8_CTR_IDR, &chan->control);
1229 }
1230
1231 static int quad8_probe(struct device *dev, unsigned int id)
1232 {
1233         struct counter_device *counter;
1234         struct quad8 *priv;
1235         unsigned long i;
1236         int err;
1237
1238         if (!devm_request_region(dev, base[id], QUAD8_EXTENT, dev_name(dev))) {
1239                 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
1240                         base[id], base[id] + QUAD8_EXTENT);
1241                 return -EBUSY;
1242         }
1243
1244         counter = devm_counter_alloc(dev, sizeof(*priv));
1245         if (!counter)
1246                 return -ENOMEM;
1247         priv = counter_priv(counter);
1248
1249         priv->reg = devm_ioport_map(dev, base[id], QUAD8_EXTENT);
1250         if (!priv->reg)
1251                 return -ENOMEM;
1252
1253         /* Initialize Counter device and driver data */
1254         counter->name = dev_name(dev);
1255         counter->parent = dev;
1256         counter->ops = &quad8_ops;
1257         counter->counts = quad8_counts;
1258         counter->num_counts = ARRAY_SIZE(quad8_counts);
1259         counter->signals = quad8_signals;
1260         counter->num_signals = ARRAY_SIZE(quad8_signals);
1261
1262         spin_lock_init(&priv->lock);
1263
1264         /* Reset Index/Interrupt Register */
1265         iowrite8(0x00, &priv->reg->index_interrupt);
1266         /* Reset all counters and disable interrupt function */
1267         iowrite8(QUAD8_CHAN_OP_RESET_COUNTERS, &priv->reg->channel_oper);
1268         /* Set initial configuration for all counters */
1269         for (i = 0; i < QUAD8_NUM_COUNTERS; i++)
1270                 quad8_init_counter(priv->reg->channel + i);
1271         /* Disable Differential Encoder Cable Status for all channels */
1272         iowrite8(0xFF, &priv->reg->cable_status);
1273         /* Enable all counters and enable interrupt function */
1274         iowrite8(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, &priv->reg->channel_oper);
1275
1276         err = devm_request_irq(&counter->dev, irq[id], quad8_irq_handler,
1277                                IRQF_SHARED, counter->name, counter);
1278         if (err)
1279                 return err;
1280
1281         err = devm_counter_add(dev, counter);
1282         if (err < 0)
1283                 return dev_err_probe(dev, err, "Failed to add counter\n");
1284
1285         return 0;
1286 }
1287
1288 static struct isa_driver quad8_driver = {
1289         .probe = quad8_probe,
1290         .driver = {
1291                 .name = "104-quad-8"
1292         }
1293 };
1294
1295 module_isa_driver_with_irq(quad8_driver, num_quad8, num_irq);
1296
1297 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
1298 MODULE_DESCRIPTION("ACCES 104-QUAD-8 driver");
1299 MODULE_LICENSE("GPL v2");
1300 MODULE_IMPORT_NS(COUNTER);