Commit | Line | Data |
---|---|---|
09e7d4ed WBG |
1 | .. SPDX-License-Identifier: GPL-2.0 |
2 | ||
3 | ========================= | |
4 | Generic Counter Interface | |
5 | ========================= | |
6 | ||
7 | Introduction | |
8 | ============ | |
9 | ||
e58cbfd2 | 10 | Counter devices are prevalent among a diverse spectrum of industries. |
09e7d4ed WBG |
11 | The ubiquitous presence of these devices necessitates a common interface |
12 | and standard of interaction and exposure. This driver API attempts to | |
13 | resolve the issue of duplicate code found among existing counter device | |
14 | drivers by introducing a generic counter interface for consumption. The | |
15 | Generic Counter interface enables drivers to support and expose a common | |
16 | set of components and functionality present in counter devices. | |
17 | ||
18 | Theory | |
19 | ====== | |
20 | ||
21 | Counter devices can vary greatly in design, but regardless of whether | |
22 | some devices are quadrature encoder counters or tally counters, all | |
23 | counter devices consist of a core set of components. This core set of | |
24 | components, shared by all counter devices, is what forms the essence of | |
25 | the Generic Counter interface. | |
26 | ||
27 | There are three core components to a counter: | |
28 | ||
09e7d4ed | 29 | * Signal: |
e58cbfd2 | 30 | Stream of data to be evaluated by the counter. |
09e7d4ed WBG |
31 | |
32 | * Synapse: | |
e58cbfd2 WBG |
33 | Association of a Signal, and evaluation trigger, with a Count. |
34 | ||
35 | * Count: | |
36 | Accumulation of the effects of connected Synapses. | |
37 | ||
38 | SIGNAL | |
39 | ------ | |
40 | A Signal represents a stream of data. This is the input data that is | |
41 | evaluated by the counter to determine the count data; e.g. a quadrature | |
42 | signal output line of a rotary encoder. Not all counter devices provide | |
43 | user access to the Signal data, so exposure is optional for drivers. | |
44 | ||
45 | When the Signal data is available for user access, the Generic Counter | |
46 | interface provides the following available signal values: | |
47 | ||
48 | * SIGNAL_LOW: | |
49 | Signal line is in a low state. | |
50 | ||
51 | * SIGNAL_HIGH: | |
52 | Signal line is in a high state. | |
53 | ||
54 | A Signal may be associated with one or more Counts. | |
55 | ||
56 | SYNAPSE | |
57 | ------- | |
58 | A Synapse represents the association of a Signal with a Count. Signal | |
59 | data affects respective Count data, and the Synapse represents this | |
60 | relationship. | |
61 | ||
62 | The Synapse action mode specifies the Signal data condition that | |
63 | triggers the respective Count's count function evaluation to update the | |
64 | count data. The Generic Counter interface provides the following | |
65 | available action modes: | |
66 | ||
67 | * None: | |
68 | Signal does not trigger the count function. In Pulse-Direction count | |
69 | function mode, this Signal is evaluated as Direction. | |
70 | ||
71 | * Rising Edge: | |
72 | Low state transitions to high state. | |
73 | ||
74 | * Falling Edge: | |
75 | High state transitions to low state. | |
76 | ||
77 | * Both Edges: | |
78 | Any state transition. | |
79 | ||
80 | A counter is defined as a set of input signals associated with count | |
81 | data that are generated by the evaluation of the state of the associated | |
82 | input signals as defined by the respective count functions. Within the | |
83 | context of the Generic Counter interface, a counter consists of Counts | |
84 | each associated with a set of Signals, whose respective Synapse | |
85 | instances represent the count function update conditions for the | |
86 | associated Counts. | |
87 | ||
88 | A Synapse associates one Signal with one Count. | |
09e7d4ed WBG |
89 | |
90 | COUNT | |
91 | ----- | |
e58cbfd2 WBG |
92 | A Count represents the accumulation of the effects of connected |
93 | Synapses; i.e. the count data for a set of Signals. The Generic | |
94 | Counter interface represents the count data as a natural number. | |
09e7d4ed WBG |
95 | |
96 | A Count has a count function mode which represents the update behavior | |
97 | for the count data. The Generic Counter interface provides the following | |
98 | available count function modes: | |
99 | ||
100 | * Increase: | |
101 | Accumulated count is incremented. | |
102 | ||
103 | * Decrease: | |
104 | Accumulated count is decremented. | |
105 | ||
106 | * Pulse-Direction: | |
107 | Rising edges on signal A updates the respective count. The input level | |
108 | of signal B determines direction. | |
109 | ||
110 | * Quadrature: | |
111 | A pair of quadrature encoding signals are evaluated to determine | |
112 | position and direction. The following Quadrature modes are available: | |
113 | ||
114 | - x1 A: | |
115 | If direction is forward, rising edges on quadrature pair signal A | |
116 | updates the respective count; if the direction is backward, falling | |
117 | edges on quadrature pair signal A updates the respective count. | |
118 | Quadrature encoding determines the direction. | |
119 | ||
120 | - x1 B: | |
121 | If direction is forward, rising edges on quadrature pair signal B | |
122 | updates the respective count; if the direction is backward, falling | |
123 | edges on quadrature pair signal B updates the respective count. | |
124 | Quadrature encoding determines the direction. | |
125 | ||
126 | - x2 A: | |
127 | Any state transition on quadrature pair signal A updates the | |
128 | respective count. Quadrature encoding determines the direction. | |
129 | ||
130 | - x2 B: | |
131 | Any state transition on quadrature pair signal B updates the | |
132 | respective count. Quadrature encoding determines the direction. | |
133 | ||
134 | - x4: | |
135 | Any state transition on either quadrature pair signals updates the | |
136 | respective count. Quadrature encoding determines the direction. | |
137 | ||
e58cbfd2 | 138 | A Count has a set of one or more associated Synapses. |
09e7d4ed WBG |
139 | |
140 | Paradigm | |
141 | ======== | |
142 | ||
143 | The most basic counter device may be expressed as a single Count | |
144 | associated with a single Signal via a single Synapse. Take for example | |
145 | a counter device which simply accumulates a count of rising edges on a | |
146 | source input line:: | |
147 | ||
148 | Count Synapse Signal | |
149 | ----- ------- ------ | |
150 | +---------------------+ | |
151 | | Data: Count | Rising Edge ________ | |
152 | | Function: Increase | <------------- / Source \ | |
153 | | | ____________ | |
154 | +---------------------+ | |
155 | ||
156 | In this example, the Signal is a source input line with a pulsing | |
157 | voltage, while the Count is a persistent count value which is repeatedly | |
158 | incremented. The Signal is associated with the respective Count via a | |
159 | Synapse. The increase function is triggered by the Signal data condition | |
160 | specified by the Synapse -- in this case a rising edge condition on the | |
161 | voltage input line. In summary, the counter device existence and | |
162 | behavior is aptly represented by respective Count, Signal, and Synapse | |
163 | components: a rising edge condition triggers an increase function on an | |
164 | accumulating count datum. | |
165 | ||
166 | A counter device is not limited to a single Signal; in fact, in theory | |
167 | many Signals may be associated with even a single Count. For example, a | |
168 | quadrature encoder counter device can keep track of position based on | |
169 | the states of two input lines:: | |
170 | ||
171 | Count Synapse Signal | |
172 | ----- ------- ------ | |
173 | +-------------------------+ | |
174 | | Data: Position | Both Edges ___ | |
175 | | Function: Quadrature x4 | <------------ / A \ | |
176 | | | _______ | |
177 | | | | |
178 | | | Both Edges ___ | |
179 | | | <------------ / B \ | |
180 | | | _______ | |
181 | +-------------------------+ | |
182 | ||
183 | In this example, two Signals (quadrature encoder lines A and B) are | |
184 | associated with a single Count: a rising or falling edge on either A or | |
185 | B triggers the "Quadrature x4" function which determines the direction | |
186 | of movement and updates the respective position data. The "Quadrature | |
187 | x4" function is likely implemented in the hardware of the quadrature | |
188 | encoder counter device; the Count, Signals, and Synapses simply | |
189 | represent this hardware behavior and functionality. | |
190 | ||
191 | Signals associated with the same Count can have differing Synapse action | |
192 | mode conditions. For example, a quadrature encoder counter device | |
193 | operating in a non-quadrature Pulse-Direction mode could have one input | |
194 | line dedicated for movement and a second input line dedicated for | |
195 | direction:: | |
196 | ||
197 | Count Synapse Signal | |
198 | ----- ------- ------ | |
199 | +---------------------------+ | |
200 | | Data: Position | Rising Edge ___ | |
201 | | Function: Pulse-Direction | <------------- / A \ (Movement) | |
202 | | | _______ | |
203 | | | | |
204 | | | None ___ | |
205 | | | <------------- / B \ (Direction) | |
206 | | | _______ | |
207 | +---------------------------+ | |
208 | ||
209 | Only Signal A triggers the "Pulse-Direction" update function, but the | |
210 | instantaneous state of Signal B is still required in order to know the | |
211 | direction so that the position data may be properly updated. Ultimately, | |
212 | both Signals are associated with the same Count via two respective | |
213 | Synapses, but only one Synapse has an active action mode condition which | |
214 | triggers the respective count function while the other is left with a | |
215 | "None" condition action mode to indicate its respective Signal's | |
216 | availability for state evaluation despite its non-triggering mode. | |
217 | ||
218 | Keep in mind that the Signal, Synapse, and Count are abstract | |
219 | representations which do not need to be closely married to their | |
220 | respective physical sources. This allows the user of a counter to | |
221 | divorce themselves from the nuances of physical components (such as | |
222 | whether an input line is differential or single-ended) and instead focus | |
223 | on the core idea of what the data and process represent (e.g. position | |
224 | as interpreted from quadrature encoding data). | |
225 | ||
09e7d4ed WBG |
226 | Driver API |
227 | ========== | |
228 | ||
229 | Driver authors may utilize the Generic Counter interface in their code | |
230 | by including the include/linux/counter.h header file. This header file | |
231 | provides several core data structures, function prototypes, and macros | |
232 | for defining a counter device. | |
233 | ||
234 | .. kernel-doc:: include/linux/counter.h | |
235 | :internal: | |
236 | ||
7110acbd | 237 | .. kernel-doc:: drivers/counter/counter-core.c |
09e7d4ed WBG |
238 | :export: |
239 | ||
49af37fc WBG |
240 | .. kernel-doc:: drivers/counter/counter-chrdev.c |
241 | :export: | |
242 | ||
de8daf30 WBG |
243 | Driver Implementation |
244 | ===================== | |
09e7d4ed WBG |
245 | |
246 | To support a counter device, a driver must first allocate the available | |
247 | Counter Signals via counter_signal structures. These Signals should | |
248 | be stored as an array and set to the signals array member of an | |
249 | allocated counter_device structure before the Counter is registered to | |
250 | the system. | |
251 | ||
252 | Counter Counts may be allocated via counter_count structures, and | |
253 | respective Counter Signal associations (Synapses) made via | |
254 | counter_synapse structures. Associated counter_synapse structures are | |
10f32254 | 255 | stored as an array and set to the synapses array member of the |
09e7d4ed WBG |
256 | respective counter_count structure. These counter_count structures are |
257 | set to the counts array member of an allocated counter_device structure | |
258 | before the Counter is registered to the system. | |
259 | ||
de8daf30 WBG |
260 | Driver callbacks must be provided to the counter_device structure in |
261 | order to communicate with the device: to read and write various Signals | |
262 | and Counts, and to set and get the "action mode" and "function mode" for | |
263 | various Synapses and Counts respectively. | |
09e7d4ed | 264 | |
98644726 UKK |
265 | A counter_device structure is allocated using counter_alloc() and then |
266 | registered to the system by passing it to the counter_add() function, and | |
267 | unregistered by passing it to the counter_unregister function. There are | |
268 | device managed variants of these functions: devm_counter_alloc() and | |
269 | devm_counter_add(). | |
de8daf30 WBG |
270 | |
271 | The struct counter_comp structure is used to define counter extensions | |
272 | for Signals, Synapses, and Counts. | |
273 | ||
274 | The "type" member specifies the type of high-level data (e.g. BOOL, | |
275 | COUNT_DIRECTION, etc.) handled by this extension. The "``*_read``" and | |
276 | "``*_write``" members can then be set by the counter device driver with | |
277 | callbacks to handle that data using native C data types (i.e. u8, u64, | |
278 | etc.). | |
279 | ||
280 | Convenience macros such as ``COUNTER_COMP_COUNT_U64`` are provided for | |
281 | use by driver authors. In particular, driver authors are expected to use | |
282 | the provided macros for standard Counter subsystem attributes in order | |
283 | to maintain a consistent interface for userspace. For example, a counter | |
284 | device driver may define several standard attributes like so:: | |
285 | ||
286 | struct counter_comp count_ext[] = { | |
287 | COUNTER_COMP_DIRECTION(count_direction_read), | |
288 | COUNTER_COMP_ENABLE(count_enable_read, count_enable_write), | |
289 | COUNTER_COMP_CEILING(count_ceiling_read, count_ceiling_write), | |
290 | }; | |
291 | ||
292 | This makes it simple to see, add, and modify the attributes that are | |
293 | supported by this driver ("direction", "enable", and "ceiling") and to | |
294 | maintain this code without getting lost in a web of struct braces. | |
295 | ||
296 | Callbacks must match the function type expected for the respective | |
297 | component or extension. These function types are defined in the struct | |
298 | counter_comp structure as the "``*_read``" and "``*_write``" union | |
299 | members. | |
300 | ||
301 | The corresponding callback prototypes for the extensions mentioned in | |
302 | the previous example above would be:: | |
303 | ||
304 | int count_direction_read(struct counter_device *counter, | |
305 | struct counter_count *count, | |
306 | enum counter_count_direction *direction); | |
307 | int count_enable_read(struct counter_device *counter, | |
308 | struct counter_count *count, u8 *enable); | |
309 | int count_enable_write(struct counter_device *counter, | |
310 | struct counter_count *count, u8 enable); | |
311 | int count_ceiling_read(struct counter_device *counter, | |
312 | struct counter_count *count, u64 *ceiling); | |
313 | int count_ceiling_write(struct counter_device *counter, | |
314 | struct counter_count *count, u64 ceiling); | |
e58cbfd2 WBG |
315 | |
316 | Determining the type of extension to create is a matter of scope. | |
317 | ||
318 | * Signal extensions are attributes that expose information/control | |
319 | specific to a Signal. These types of attributes will exist under a | |
320 | Signal's directory in sysfs. | |
321 | ||
322 | For example, if you have an invert feature for a Signal, you can have | |
323 | a Signal extension called "invert" that toggles that feature: | |
324 | /sys/bus/counter/devices/counterX/signalY/invert | |
325 | ||
326 | * Count extensions are attributes that expose information/control | |
327 | specific to a Count. These type of attributes will exist under a | |
328 | Count's directory in sysfs. | |
329 | ||
330 | For example, if you want to pause/unpause a Count from updating, you | |
331 | can have a Count extension called "enable" that toggles such: | |
332 | /sys/bus/counter/devices/counterX/countY/enable | |
333 | ||
334 | * Device extensions are attributes that expose information/control | |
335 | non-specific to a particular Count or Signal. This is where you would | |
c316424d | 336 | put your global features or other miscellaneous functionality. |
e58cbfd2 WBG |
337 | |
338 | For example, if your device has an overtemp sensor, you can report the | |
339 | chip overheated via a device extension called "error_overtemp": | |
340 | /sys/bus/counter/devices/counterX/error_overtemp | |
09e7d4ed | 341 | |
de8daf30 WBG |
342 | Subsystem Architecture |
343 | ====================== | |
344 | ||
345 | Counter drivers pass and take data natively (i.e. ``u8``, ``u64``, etc.) | |
346 | and the shared counter module handles the translation between the sysfs | |
347 | interface. This guarantees a standard userspace interface for all | |
348 | counter drivers, and enables a Generic Counter chrdev interface via a | |
349 | generalized device driver ABI. | |
350 | ||
351 | A high-level view of how a count value is passed down from a counter | |
352 | driver is exemplified by the following. The driver callbacks are first | |
353 | registered to the Counter core component for use by the Counter | |
354 | userspace interface components:: | |
355 | ||
356 | Driver callbacks registration: | |
357 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
358 | +----------------------------+ | |
359 | | Counter device driver | | |
360 | +----------------------------+ | |
361 | | Processes data from device | | |
362 | +----------------------------+ | |
363 | | | |
364 | ------------------- | |
365 | / driver callbacks / | |
366 | ------------------- | |
367 | | | |
368 | V | |
369 | +----------------------+ | |
370 | | Counter core | | |
371 | +----------------------+ | |
372 | | Routes device driver | | |
373 | | callbacks to the | | |
374 | | userspace interfaces | | |
375 | +----------------------+ | |
376 | | | |
377 | ------------------- | |
378 | / driver callbacks / | |
379 | ------------------- | |
380 | | | |
a8a28737 WBG |
381 | +---------------+---------------+ |
382 | | | | |
383 | V V | |
384 | +--------------------+ +---------------------+ | |
385 | | Counter sysfs | | Counter chrdev | | |
386 | +--------------------+ +---------------------+ | |
387 | | Translates to the | | Translates to the | | |
388 | | standard Counter | | standard Counter | | |
389 | | sysfs output | | character device | | |
390 | +--------------------+ +---------------------+ | |
de8daf30 WBG |
391 | |
392 | Thereafter, data can be transferred directly between the Counter device | |
393 | driver and Counter userspace interface:: | |
394 | ||
395 | Count data request: | |
396 | ~~~~~~~~~~~~~~~~~~~ | |
397 | ---------------------- | |
398 | / Counter device \ | |
399 | +----------------------+ | |
400 | | Count register: 0x28 | | |
401 | +----------------------+ | |
402 | | | |
403 | ----------------- | |
404 | / raw count data / | |
405 | ----------------- | |
406 | | | |
407 | V | |
408 | +----------------------------+ | |
409 | | Counter device driver | | |
410 | +----------------------------+ | |
411 | | Processes data from device | | |
412 | |----------------------------| | |
413 | | Type: u64 | | |
414 | | Value: 42 | | |
415 | +----------------------------+ | |
416 | | | |
417 | ---------- | |
418 | / u64 / | |
419 | ---------- | |
420 | | | |
a8a28737 WBG |
421 | +---------------+---------------+ |
422 | | | | |
423 | V V | |
424 | +--------------------+ +---------------------+ | |
425 | | Counter sysfs | | Counter chrdev | | |
426 | +--------------------+ +---------------------+ | |
427 | | Translates to the | | Translates to the | | |
428 | | standard Counter | | standard Counter | | |
429 | | sysfs output | | character device | | |
430 | |--------------------| |---------------------| | |
431 | | Type: const char * | | Type: u64 | | |
432 | | Value: "42" | | Value: 42 | | |
433 | +--------------------+ +---------------------+ | |
434 | | | | |
435 | --------------- ----------------------- | |
436 | / const char * / / struct counter_event / | |
437 | --------------- ----------------------- | |
438 | | | | |
439 | | V | |
440 | | +-----------+ | |
441 | | | read | | |
442 | | +-----------+ | |
443 | | \ Count: 42 / | |
444 | | ----------- | |
de8daf30 WBG |
445 | | |
446 | V | |
447 | +--------------------------------------------------+ | |
448 | | `/sys/bus/counter/devices/counterX/countY/count` | | |
449 | +--------------------------------------------------+ | |
450 | \ Count: "42" / | |
451 | -------------------------------------------------- | |
452 | ||
a8a28737 | 453 | There are four primary components involved: |
de8daf30 WBG |
454 | |
455 | Counter device driver | |
456 | --------------------- | |
457 | Communicates with the hardware device to read/write data; e.g. counter | |
458 | drivers for quadrature encoders, timers, etc. | |
459 | ||
460 | Counter core | |
461 | ------------ | |
462 | Registers the counter device driver to the system so that the respective | |
463 | callbacks are called during userspace interaction. | |
464 | ||
465 | Counter sysfs | |
466 | ------------- | |
467 | Translates counter data to the standard Counter sysfs interface format | |
468 | and vice versa. | |
469 | ||
470 | Please refer to the ``Documentation/ABI/testing/sysfs-bus-counter`` file | |
471 | for a detailed breakdown of the available Generic Counter interface | |
472 | sysfs attributes. | |
a8a28737 WBG |
473 | |
474 | Counter chrdev | |
475 | -------------- | |
476 | Translates Counter events to the standard Counter character device; data | |
477 | is transferred via standard character device read calls, while Counter | |
478 | events are configured via ioctl calls. | |
479 | ||
480 | Sysfs Interface | |
481 | =============== | |
482 | ||
483 | Several sysfs attributes are generated by the Generic Counter interface, | |
484 | and reside under the ``/sys/bus/counter/devices/counterX`` directory, | |
485 | where ``X`` is to the respective counter device id. Please see | |
486 | ``Documentation/ABI/testing/sysfs-bus-counter`` for detailed information | |
487 | on each Generic Counter interface sysfs attribute. | |
488 | ||
489 | Through these sysfs attributes, programs and scripts may interact with | |
490 | the Generic Counter paradigm Counts, Signals, and Synapses of respective | |
491 | counter devices. | |
492 | ||
493 | Counter Character Device | |
494 | ======================== | |
495 | ||
496 | Counter character device nodes are created under the ``/dev`` directory | |
497 | as ``counterX``, where ``X`` is the respective counter device id. | |
498 | Defines for the standard Counter data types are exposed via the | |
499 | userspace ``include/uapi/linux/counter.h`` file. | |
500 | ||
501 | Counter events | |
502 | -------------- | |
503 | Counter device drivers can support Counter events by utilizing the | |
504 | ``counter_push_event`` function:: | |
505 | ||
506 | void counter_push_event(struct counter_device *const counter, const u8 event, | |
507 | const u8 channel); | |
508 | ||
509 | The event id is specified by the ``event`` parameter; the event channel | |
510 | id is specified by the ``channel`` parameter. When this function is | |
511 | called, the Counter data associated with the respective event is | |
512 | gathered, and a ``struct counter_event`` is generated for each datum and | |
513 | pushed to userspace. | |
514 | ||
515 | Counter events can be configured by users to report various Counter | |
516 | data of interest. This can be conceptualized as a list of Counter | |
517 | component read calls to perform. For example: | |
518 | ||
519 | +------------------------+------------------------+ | |
520 | | COUNTER_EVENT_OVERFLOW | COUNTER_EVENT_INDEX | | |
521 | +========================+========================+ | |
522 | | Channel 0 | Channel 0 | | |
523 | +------------------------+------------------------+ | |
524 | | * Count 0 | * Signal 0 | | |
525 | | * Count 1 | * Signal 0 Extension 0 | | |
526 | | * Signal 3 | * Extension 4 | | |
527 | | * Count 4 Extension 2 +------------------------+ | |
528 | | * Signal 5 Extension 0 | Channel 1 | | |
529 | | +------------------------+ | |
530 | | | * Signal 4 | | |
531 | | | * Signal 4 Extension 0 | | |
532 | | | * Count 7 | | |
533 | +------------------------+------------------------+ | |
534 | ||
535 | When ``counter_push_event(counter, COUNTER_EVENT_INDEX, 1)`` is called | |
536 | for example, it will go down the list for the ``COUNTER_EVENT_INDEX`` | |
537 | event channel 1 and execute the read callbacks for Signal 4, Signal 4 | |
538 | Extension 0, and Count 7 -- the data returned for each is pushed to a | |
539 | kfifo as a ``struct counter_event``, which userspace can retrieve via a | |
540 | standard read operation on the respective character device node. | |
541 | ||
542 | Userspace | |
543 | --------- | |
544 | Userspace applications can configure Counter events via ioctl operations | |
545 | on the Counter character device node. There following ioctl codes are | |
546 | supported and provided by the ``linux/counter.h`` userspace header file: | |
547 | ||
548 | * :c:macro:`COUNTER_ADD_WATCH_IOCTL` | |
549 | ||
550 | * :c:macro:`COUNTER_ENABLE_EVENTS_IOCTL` | |
551 | ||
552 | * :c:macro:`COUNTER_DISABLE_EVENTS_IOCTL` | |
553 | ||
554 | To configure events to gather Counter data, users first populate a | |
555 | ``struct counter_watch`` with the relevant event id, event channel id, | |
556 | and the information for the desired Counter component from which to | |
557 | read, and then pass it via the ``COUNTER_ADD_WATCH_IOCTL`` ioctl | |
558 | command. | |
559 | ||
560 | Note that an event can be watched without gathering Counter data by | |
561 | setting the ``component.type`` member equal to | |
562 | ``COUNTER_COMPONENT_NONE``. With this configuration the Counter | |
563 | character device will simply populate the event timestamps for those | |
564 | respective ``struct counter_event`` elements and ignore the component | |
565 | value. | |
566 | ||
567 | The ``COUNTER_ADD_WATCH_IOCTL`` command will buffer these Counter | |
568 | watches. When ready, the ``COUNTER_ENABLE_EVENTS_IOCTL`` ioctl command | |
569 | may be used to activate these Counter watches. | |
570 | ||
571 | Userspace applications can then execute a ``read`` operation (optionally | |
572 | calling ``poll`` first) on the Counter character device node to retrieve | |
573 | ``struct counter_event`` elements with the desired data. |