0001
0002
0003
0004
0005
0006 #ifndef _COUNTER_H_
0007 #define _COUNTER_H_
0008
0009 #include <linux/cdev.h>
0010 #include <linux/device.h>
0011 #include <linux/kernel.h>
0012 #include <linux/kfifo.h>
0013 #include <linux/mutex.h>
0014 #include <linux/spinlock_types.h>
0015 #include <linux/types.h>
0016 #include <linux/wait.h>
0017 #include <uapi/linux/counter.h>
0018
0019 struct counter_device;
0020 struct counter_count;
0021 struct counter_synapse;
0022 struct counter_signal;
0023
0024 enum counter_comp_type {
0025 COUNTER_COMP_U8,
0026 COUNTER_COMP_U64,
0027 COUNTER_COMP_BOOL,
0028 COUNTER_COMP_SIGNAL_LEVEL,
0029 COUNTER_COMP_FUNCTION,
0030 COUNTER_COMP_SYNAPSE_ACTION,
0031 COUNTER_COMP_ENUM,
0032 COUNTER_COMP_COUNT_DIRECTION,
0033 COUNTER_COMP_COUNT_MODE,
0034 };
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102 struct counter_comp {
0103 enum counter_comp_type type;
0104 const char *name;
0105 void *priv;
0106 union {
0107 int (*action_read)(struct counter_device *counter,
0108 struct counter_count *count,
0109 struct counter_synapse *synapse,
0110 enum counter_synapse_action *action);
0111 int (*device_u8_read)(struct counter_device *counter, u8 *val);
0112 int (*count_u8_read)(struct counter_device *counter,
0113 struct counter_count *count, u8 *val);
0114 int (*signal_u8_read)(struct counter_device *counter,
0115 struct counter_signal *signal, u8 *val);
0116 int (*device_u32_read)(struct counter_device *counter,
0117 u32 *val);
0118 int (*count_u32_read)(struct counter_device *counter,
0119 struct counter_count *count, u32 *val);
0120 int (*signal_u32_read)(struct counter_device *counter,
0121 struct counter_signal *signal, u32 *val);
0122 int (*device_u64_read)(struct counter_device *counter,
0123 u64 *val);
0124 int (*count_u64_read)(struct counter_device *counter,
0125 struct counter_count *count, u64 *val);
0126 int (*signal_u64_read)(struct counter_device *counter,
0127 struct counter_signal *signal, u64 *val);
0128 };
0129 union {
0130 int (*action_write)(struct counter_device *counter,
0131 struct counter_count *count,
0132 struct counter_synapse *synapse,
0133 enum counter_synapse_action action);
0134 int (*device_u8_write)(struct counter_device *counter, u8 val);
0135 int (*count_u8_write)(struct counter_device *counter,
0136 struct counter_count *count, u8 val);
0137 int (*signal_u8_write)(struct counter_device *counter,
0138 struct counter_signal *signal, u8 val);
0139 int (*device_u32_write)(struct counter_device *counter,
0140 u32 val);
0141 int (*count_u32_write)(struct counter_device *counter,
0142 struct counter_count *count, u32 val);
0143 int (*signal_u32_write)(struct counter_device *counter,
0144 struct counter_signal *signal, u32 val);
0145 int (*device_u64_write)(struct counter_device *counter,
0146 u64 val);
0147 int (*count_u64_write)(struct counter_device *counter,
0148 struct counter_count *count, u64 val);
0149 int (*signal_u64_write)(struct counter_device *counter,
0150 struct counter_signal *signal, u64 val);
0151 };
0152 };
0153
0154
0155
0156
0157
0158
0159
0160
0161 struct counter_signal {
0162 int id;
0163 const char *name;
0164
0165 struct counter_comp *ext;
0166 size_t num_ext;
0167 };
0168
0169
0170
0171
0172
0173
0174
0175 struct counter_synapse {
0176 const enum counter_synapse_action *actions_list;
0177 size_t num_actions;
0178
0179 struct counter_signal *signal;
0180 };
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193 struct counter_count {
0194 int id;
0195 const char *name;
0196
0197 const enum counter_function *functions_list;
0198 size_t num_functions;
0199
0200 struct counter_synapse *synapses;
0201 size_t num_synapses;
0202
0203 struct counter_comp *ext;
0204 size_t num_ext;
0205 };
0206
0207
0208
0209
0210
0211
0212
0213
0214 struct counter_event_node {
0215 struct list_head l;
0216 u8 event;
0217 u8 channel;
0218 struct list_head comp_list;
0219 };
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252 struct counter_ops {
0253 int (*signal_read)(struct counter_device *counter,
0254 struct counter_signal *signal,
0255 enum counter_signal_level *level);
0256 int (*count_read)(struct counter_device *counter,
0257 struct counter_count *count, u64 *value);
0258 int (*count_write)(struct counter_device *counter,
0259 struct counter_count *count, u64 value);
0260 int (*function_read)(struct counter_device *counter,
0261 struct counter_count *count,
0262 enum counter_function *function);
0263 int (*function_write)(struct counter_device *counter,
0264 struct counter_count *count,
0265 enum counter_function function);
0266 int (*action_read)(struct counter_device *counter,
0267 struct counter_count *count,
0268 struct counter_synapse *synapse,
0269 enum counter_synapse_action *action);
0270 int (*action_write)(struct counter_device *counter,
0271 struct counter_count *count,
0272 struct counter_synapse *synapse,
0273 enum counter_synapse_action action);
0274 int (*events_configure)(struct counter_device *counter);
0275 int (*watch_validate)(struct counter_device *counter,
0276 const struct counter_watch *watch);
0277 };
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303 struct counter_device {
0304 const char *name;
0305 struct device *parent;
0306
0307 const struct counter_ops *ops;
0308
0309 struct counter_signal *signals;
0310 size_t num_signals;
0311 struct counter_count *counts;
0312 size_t num_counts;
0313
0314 struct counter_comp *ext;
0315 size_t num_ext;
0316
0317 struct device dev;
0318 struct cdev chrdev;
0319 struct list_head events_list;
0320 spinlock_t events_list_lock;
0321 struct list_head next_events_list;
0322 struct mutex n_events_list_lock;
0323 DECLARE_KFIFO_PTR(events, struct counter_event);
0324 wait_queue_head_t events_wait;
0325 spinlock_t events_in_lock;
0326 struct mutex events_out_lock;
0327 struct mutex ops_exist_lock;
0328 };
0329
0330 void *counter_priv(const struct counter_device *const counter);
0331
0332 struct counter_device *counter_alloc(size_t sizeof_priv);
0333 void counter_put(struct counter_device *const counter);
0334 int counter_add(struct counter_device *const counter);
0335
0336 void counter_unregister(struct counter_device *const counter);
0337 struct counter_device *devm_counter_alloc(struct device *dev,
0338 size_t sizeof_priv);
0339 int devm_counter_add(struct device *dev,
0340 struct counter_device *const counter);
0341 void counter_push_event(struct counter_device *const counter, const u8 event,
0342 const u8 channel);
0343
0344 #define COUNTER_COMP_DEVICE_U8(_name, _read, _write) \
0345 { \
0346 .type = COUNTER_COMP_U8, \
0347 .name = (_name), \
0348 .device_u8_read = (_read), \
0349 .device_u8_write = (_write), \
0350 }
0351 #define COUNTER_COMP_COUNT_U8(_name, _read, _write) \
0352 { \
0353 .type = COUNTER_COMP_U8, \
0354 .name = (_name), \
0355 .count_u8_read = (_read), \
0356 .count_u8_write = (_write), \
0357 }
0358 #define COUNTER_COMP_SIGNAL_U8(_name, _read, _write) \
0359 { \
0360 .type = COUNTER_COMP_U8, \
0361 .name = (_name), \
0362 .signal_u8_read = (_read), \
0363 .signal_u8_write = (_write), \
0364 }
0365
0366 #define COUNTER_COMP_DEVICE_U64(_name, _read, _write) \
0367 { \
0368 .type = COUNTER_COMP_U64, \
0369 .name = (_name), \
0370 .device_u64_read = (_read), \
0371 .device_u64_write = (_write), \
0372 }
0373 #define COUNTER_COMP_COUNT_U64(_name, _read, _write) \
0374 { \
0375 .type = COUNTER_COMP_U64, \
0376 .name = (_name), \
0377 .count_u64_read = (_read), \
0378 .count_u64_write = (_write), \
0379 }
0380 #define COUNTER_COMP_SIGNAL_U64(_name, _read, _write) \
0381 { \
0382 .type = COUNTER_COMP_U64, \
0383 .name = (_name), \
0384 .signal_u64_read = (_read), \
0385 .signal_u64_write = (_write), \
0386 }
0387
0388 #define COUNTER_COMP_DEVICE_BOOL(_name, _read, _write) \
0389 { \
0390 .type = COUNTER_COMP_BOOL, \
0391 .name = (_name), \
0392 .device_u8_read = (_read), \
0393 .device_u8_write = (_write), \
0394 }
0395 #define COUNTER_COMP_COUNT_BOOL(_name, _read, _write) \
0396 { \
0397 .type = COUNTER_COMP_BOOL, \
0398 .name = (_name), \
0399 .count_u8_read = (_read), \
0400 .count_u8_write = (_write), \
0401 }
0402 #define COUNTER_COMP_SIGNAL_BOOL(_name, _read, _write) \
0403 { \
0404 .type = COUNTER_COMP_BOOL, \
0405 .name = (_name), \
0406 .signal_u8_read = (_read), \
0407 .signal_u8_write = (_write), \
0408 }
0409
0410 struct counter_available {
0411 union {
0412 const u32 *enums;
0413 const char *const *strs;
0414 };
0415 size_t num_items;
0416 };
0417
0418 #define DEFINE_COUNTER_AVAILABLE(_name, _enums) \
0419 struct counter_available _name = { \
0420 .enums = (_enums), \
0421 .num_items = ARRAY_SIZE(_enums), \
0422 }
0423
0424 #define DEFINE_COUNTER_ENUM(_name, _strs) \
0425 struct counter_available _name = { \
0426 .strs = (_strs), \
0427 .num_items = ARRAY_SIZE(_strs), \
0428 }
0429
0430 #define COUNTER_COMP_DEVICE_ENUM(_name, _get, _set, _available) \
0431 { \
0432 .type = COUNTER_COMP_ENUM, \
0433 .name = (_name), \
0434 .device_u32_read = (_get), \
0435 .device_u32_write = (_set), \
0436 .priv = &(_available), \
0437 }
0438 #define COUNTER_COMP_COUNT_ENUM(_name, _get, _set, _available) \
0439 { \
0440 .type = COUNTER_COMP_ENUM, \
0441 .name = (_name), \
0442 .count_u32_read = (_get), \
0443 .count_u32_write = (_set), \
0444 .priv = &(_available), \
0445 }
0446 #define COUNTER_COMP_SIGNAL_ENUM(_name, _get, _set, _available) \
0447 { \
0448 .type = COUNTER_COMP_ENUM, \
0449 .name = (_name), \
0450 .signal_u32_read = (_get), \
0451 .signal_u32_write = (_set), \
0452 .priv = &(_available), \
0453 }
0454
0455 #define COUNTER_COMP_CEILING(_read, _write) \
0456 COUNTER_COMP_COUNT_U64("ceiling", _read, _write)
0457
0458 #define COUNTER_COMP_COUNT_MODE(_read, _write, _available) \
0459 { \
0460 .type = COUNTER_COMP_COUNT_MODE, \
0461 .name = "count_mode", \
0462 .count_u32_read = (_read), \
0463 .count_u32_write = (_write), \
0464 .priv = &(_available), \
0465 }
0466
0467 #define COUNTER_COMP_DIRECTION(_read) \
0468 { \
0469 .type = COUNTER_COMP_COUNT_DIRECTION, \
0470 .name = "direction", \
0471 .count_u32_read = (_read), \
0472 }
0473
0474 #define COUNTER_COMP_ENABLE(_read, _write) \
0475 COUNTER_COMP_COUNT_BOOL("enable", _read, _write)
0476
0477 #define COUNTER_COMP_FLOOR(_read, _write) \
0478 COUNTER_COMP_COUNT_U64("floor", _read, _write)
0479
0480 #define COUNTER_COMP_PRESET(_read, _write) \
0481 COUNTER_COMP_COUNT_U64("preset", _read, _write)
0482
0483 #define COUNTER_COMP_PRESET_ENABLE(_read, _write) \
0484 COUNTER_COMP_COUNT_BOOL("preset_enable", _read, _write)
0485
0486 #endif