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

counter: Internalize sysfs interface code

This is a reimplementation of the Generic Counter driver interface.
There are no modifications to the Counter subsystem userspace interface,
so existing userspace applications should continue to run seamlessly.

The purpose of this patch is to internalize the sysfs interface code
among the various counter drivers into a shared module. Counter drivers
pass and take data natively (i.e. u8, u64, etc.) and the shared counter
module handles the translation between the sysfs interface and the
device drivers. This guarantees a standard userspace interface for all
counter drivers, and helps generalize the Generic Counter driver ABI in
order to support the Generic Counter chrdev interface (introduced in a
subsequent patch) without significant changes to the existing counter
drivers.

Note, Counter device registration is the same as before: drivers
populate a struct counter_device with components and callbacks, then
pass the structure to the devm_counter_register function. However,
what's different now is how the Counter subsystem code handles this
registration internally.

Whereas before callbacks would interact directly with sysfs data, this
interaction is now abstracted and instead callbacks interact with native
C data types. The counter_comp structure forms the basis for Counter
extensions.

The counter-sysfs.c file contains the code to parse through the
counter_device structure and register the requested components and
extensions. Attributes are created and populated based on type, with
respective translation functions to handle the mapping between sysfs and
the counter driver callbacks.

The translation performed for each attribute is straightforward: the
attribute type and data is parsed from the counter_attribute structure,
the respective counter driver read/write callback is called, and sysfs
I/O is handled before or after the driver read/write function is called.

Cc: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Kamel Bouhara <kamel.bouhara@bootlin.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Acked-by: Syed Nayyar Waris <syednwaris@gmail.com>
Reviewed-by: David Lechner <david@lechnology.com>
Tested-by: David Lechner <david@lechnology.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
Reviewed-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com> # for stm32
Link: https://lore.kernel.org/r/c68b4a1ffb195c1a2f65e8dd5ad7b7c14e79c6ef.1630031207.git.vilhelm.gray@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

William Breathitt Gray and committed by
Jonathan Cameron
aaec1a0f ea434ff8

+1956 -2640
-1
MAINTAINERS
··· 4804 4804 F: Documentation/driver-api/generic-counter.rst 4805 4805 F: drivers/counter/ 4806 4806 F: include/linux/counter.h 4807 - F: include/linux/counter_enum.h 4808 4807 4809 4808 CP2615 I2C DRIVER 4810 4809 M: Bence Csókás <bence98@sch.bme.hu>
+191 -258
drivers/counter/104-quad-8.c
··· 117 117 } 118 118 119 119 static int quad8_count_read(struct counter_device *counter, 120 - struct counter_count *count, unsigned long *val) 120 + struct counter_count *count, u64 *val) 121 121 { 122 122 struct quad8 *const priv = counter->priv; 123 123 const int base_offset = priv->base + 2 * count->id; ··· 148 148 } 149 149 150 150 static int quad8_count_write(struct counter_device *counter, 151 - struct counter_count *count, unsigned long val) 151 + struct counter_count *count, u64 val) 152 152 { 153 153 struct quad8 *const priv = counter->priv; 154 154 const int base_offset = priv->base + 2 * count->id; ··· 188 188 return 0; 189 189 } 190 190 191 - enum quad8_count_function { 192 - QUAD8_COUNT_FUNCTION_PULSE_DIRECTION = 0, 193 - QUAD8_COUNT_FUNCTION_QUADRATURE_X1, 194 - QUAD8_COUNT_FUNCTION_QUADRATURE_X2, 195 - QUAD8_COUNT_FUNCTION_QUADRATURE_X4 196 - }; 197 - 198 191 static const enum counter_function quad8_count_functions_list[] = { 199 - [QUAD8_COUNT_FUNCTION_PULSE_DIRECTION] = COUNTER_FUNCTION_PULSE_DIRECTION, 200 - [QUAD8_COUNT_FUNCTION_QUADRATURE_X1] = COUNTER_FUNCTION_QUADRATURE_X1_A, 201 - [QUAD8_COUNT_FUNCTION_QUADRATURE_X2] = COUNTER_FUNCTION_QUADRATURE_X2_A, 202 - [QUAD8_COUNT_FUNCTION_QUADRATURE_X4] = COUNTER_FUNCTION_QUADRATURE_X4 192 + COUNTER_FUNCTION_PULSE_DIRECTION, 193 + COUNTER_FUNCTION_QUADRATURE_X1_A, 194 + COUNTER_FUNCTION_QUADRATURE_X2_A, 195 + COUNTER_FUNCTION_QUADRATURE_X4, 203 196 }; 204 197 205 - static int quad8_function_get(struct counter_device *counter, 206 - struct counter_count *count, size_t *function) 198 + static int quad8_function_read(struct counter_device *counter, 199 + struct counter_count *count, 200 + enum counter_function *function) 207 201 { 208 202 struct quad8 *const priv = counter->priv; 209 203 const int id = count->id; ··· 207 213 if (priv->quadrature_mode[id]) 208 214 switch (priv->quadrature_scale[id]) { 209 215 case 0: 210 - *function = QUAD8_COUNT_FUNCTION_QUADRATURE_X1; 216 + *function = COUNTER_FUNCTION_QUADRATURE_X1_A; 211 217 break; 212 218 case 1: 213 - *function = QUAD8_COUNT_FUNCTION_QUADRATURE_X2; 219 + *function = COUNTER_FUNCTION_QUADRATURE_X2_A; 214 220 break; 215 221 case 2: 216 - *function = QUAD8_COUNT_FUNCTION_QUADRATURE_X4; 222 + *function = COUNTER_FUNCTION_QUADRATURE_X4; 217 223 break; 218 224 } 219 225 else 220 - *function = QUAD8_COUNT_FUNCTION_PULSE_DIRECTION; 226 + *function = COUNTER_FUNCTION_PULSE_DIRECTION; 221 227 222 228 mutex_unlock(&priv->lock); 223 229 224 230 return 0; 225 231 } 226 232 227 - static int quad8_function_set(struct counter_device *counter, 228 - struct counter_count *count, size_t function) 233 + static int quad8_function_write(struct counter_device *counter, 234 + struct counter_count *count, 235 + enum counter_function function) 229 236 { 230 237 struct quad8 *const priv = counter->priv; 231 238 const int id = count->id; ··· 242 247 mode_cfg = priv->count_mode[id] << 1; 243 248 idr_cfg = priv->index_polarity[id] << 1; 244 249 245 - if (function == QUAD8_COUNT_FUNCTION_PULSE_DIRECTION) { 250 + if (function == COUNTER_FUNCTION_PULSE_DIRECTION) { 246 251 *quadrature_mode = 0; 247 252 248 253 /* Quadrature scaling only available in quadrature mode */ ··· 258 263 *quadrature_mode = 1; 259 264 260 265 switch (function) { 261 - case QUAD8_COUNT_FUNCTION_QUADRATURE_X1: 266 + case COUNTER_FUNCTION_QUADRATURE_X1_A: 262 267 *scale = 0; 263 268 mode_cfg |= QUAD8_CMR_QUADRATURE_X1; 264 269 break; 265 - case QUAD8_COUNT_FUNCTION_QUADRATURE_X2: 270 + case COUNTER_FUNCTION_QUADRATURE_X2_A: 266 271 *scale = 1; 267 272 mode_cfg |= QUAD8_CMR_QUADRATURE_X2; 268 273 break; 269 - case QUAD8_COUNT_FUNCTION_QUADRATURE_X4: 274 + case COUNTER_FUNCTION_QUADRATURE_X4: 270 275 *scale = 2; 271 276 mode_cfg |= QUAD8_CMR_QUADRATURE_X4; 272 277 break; ··· 285 290 return 0; 286 291 } 287 292 288 - static void quad8_direction_get(struct counter_device *counter, 289 - struct counter_count *count, enum counter_count_direction *direction) 293 + static int quad8_direction_read(struct counter_device *counter, 294 + struct counter_count *count, 295 + enum counter_count_direction *direction) 290 296 { 291 297 const struct quad8 *const priv = counter->priv; 292 298 unsigned int ud_flag; ··· 298 302 299 303 *direction = (ud_flag) ? COUNTER_COUNT_DIRECTION_FORWARD : 300 304 COUNTER_COUNT_DIRECTION_BACKWARD; 305 + 306 + return 0; 301 307 } 302 308 303 - enum quad8_synapse_action { 304 - QUAD8_SYNAPSE_ACTION_NONE = 0, 305 - QUAD8_SYNAPSE_ACTION_RISING_EDGE, 306 - QUAD8_SYNAPSE_ACTION_FALLING_EDGE, 307 - QUAD8_SYNAPSE_ACTION_BOTH_EDGES 308 - }; 309 - 310 309 static const enum counter_synapse_action quad8_index_actions_list[] = { 311 - [QUAD8_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, 312 - [QUAD8_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE 310 + COUNTER_SYNAPSE_ACTION_NONE, 311 + COUNTER_SYNAPSE_ACTION_RISING_EDGE, 313 312 }; 314 313 315 314 static const enum counter_synapse_action quad8_synapse_actions_list[] = { 316 - [QUAD8_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, 317 - [QUAD8_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE, 318 - [QUAD8_SYNAPSE_ACTION_FALLING_EDGE] = COUNTER_SYNAPSE_ACTION_FALLING_EDGE, 319 - [QUAD8_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES 315 + COUNTER_SYNAPSE_ACTION_NONE, 316 + COUNTER_SYNAPSE_ACTION_RISING_EDGE, 317 + COUNTER_SYNAPSE_ACTION_FALLING_EDGE, 318 + COUNTER_SYNAPSE_ACTION_BOTH_EDGES, 320 319 }; 321 320 322 - static int quad8_action_get(struct counter_device *counter, 323 - struct counter_count *count, struct counter_synapse *synapse, 324 - size_t *action) 321 + static int quad8_action_read(struct counter_device *counter, 322 + struct counter_count *count, 323 + struct counter_synapse *synapse, 324 + enum counter_synapse_action *action) 325 325 { 326 326 struct quad8 *const priv = counter->priv; 327 327 int err; 328 - size_t function = 0; 328 + enum counter_function function; 329 329 const size_t signal_a_id = count->synapses[0].signal->id; 330 330 enum counter_count_direction direction; 331 331 332 332 /* Handle Index signals */ 333 333 if (synapse->signal->id >= 16) { 334 334 if (priv->preset_enable[count->id]) 335 - *action = QUAD8_SYNAPSE_ACTION_RISING_EDGE; 335 + *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; 336 336 else 337 - *action = QUAD8_SYNAPSE_ACTION_NONE; 337 + *action = COUNTER_SYNAPSE_ACTION_NONE; 338 338 339 339 return 0; 340 340 } 341 341 342 - err = quad8_function_get(counter, count, &function); 342 + err = quad8_function_read(counter, count, &function); 343 343 if (err) 344 344 return err; 345 345 346 346 /* Default action mode */ 347 - *action = QUAD8_SYNAPSE_ACTION_NONE; 347 + *action = COUNTER_SYNAPSE_ACTION_NONE; 348 348 349 349 /* Determine action mode based on current count function mode */ 350 350 switch (function) { 351 - case QUAD8_COUNT_FUNCTION_PULSE_DIRECTION: 351 + case COUNTER_FUNCTION_PULSE_DIRECTION: 352 352 if (synapse->signal->id == signal_a_id) 353 - *action = QUAD8_SYNAPSE_ACTION_RISING_EDGE; 353 + *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; 354 354 return 0; 355 - case QUAD8_COUNT_FUNCTION_QUADRATURE_X1: 355 + case COUNTER_FUNCTION_QUADRATURE_X1_A: 356 356 if (synapse->signal->id == signal_a_id) { 357 - quad8_direction_get(counter, count, &direction); 357 + err = quad8_direction_read(counter, count, &direction); 358 + if (err) 359 + return err; 358 360 359 361 if (direction == COUNTER_COUNT_DIRECTION_FORWARD) 360 - *action = QUAD8_SYNAPSE_ACTION_RISING_EDGE; 362 + *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; 361 363 else 362 - *action = QUAD8_SYNAPSE_ACTION_FALLING_EDGE; 364 + *action = COUNTER_SYNAPSE_ACTION_FALLING_EDGE; 363 365 } 364 366 return 0; 365 - case QUAD8_COUNT_FUNCTION_QUADRATURE_X2: 367 + case COUNTER_FUNCTION_QUADRATURE_X2_A: 366 368 if (synapse->signal->id == signal_a_id) 367 - *action = QUAD8_SYNAPSE_ACTION_BOTH_EDGES; 369 + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; 368 370 return 0; 369 - case QUAD8_COUNT_FUNCTION_QUADRATURE_X4: 370 - *action = QUAD8_SYNAPSE_ACTION_BOTH_EDGES; 371 + case COUNTER_FUNCTION_QUADRATURE_X4: 372 + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; 371 373 return 0; 372 374 default: 373 375 /* should never reach this path */ ··· 377 383 .signal_read = quad8_signal_read, 378 384 .count_read = quad8_count_read, 379 385 .count_write = quad8_count_write, 380 - .function_get = quad8_function_get, 381 - .function_set = quad8_function_set, 382 - .action_get = quad8_action_get 386 + .function_read = quad8_function_read, 387 + .function_write = quad8_function_write, 388 + .action_read = quad8_action_read 383 389 }; 384 390 385 391 static const char *const quad8_index_polarity_modes[] = { ··· 388 394 }; 389 395 390 396 static int quad8_index_polarity_get(struct counter_device *counter, 391 - struct counter_signal *signal, size_t *index_polarity) 397 + struct counter_signal *signal, 398 + u32 *index_polarity) 392 399 { 393 400 const struct quad8 *const priv = counter->priv; 394 401 const size_t channel_id = signal->id - 16; ··· 400 405 } 401 406 402 407 static int quad8_index_polarity_set(struct counter_device *counter, 403 - struct counter_signal *signal, size_t index_polarity) 408 + struct counter_signal *signal, 409 + u32 index_polarity) 404 410 { 405 411 struct quad8 *const priv = counter->priv; 406 412 const size_t channel_id = signal->id - 16; ··· 422 426 return 0; 423 427 } 424 428 425 - static struct counter_signal_enum_ext quad8_index_pol_enum = { 426 - .items = quad8_index_polarity_modes, 427 - .num_items = ARRAY_SIZE(quad8_index_polarity_modes), 428 - .get = quad8_index_polarity_get, 429 - .set = quad8_index_polarity_set 430 - }; 431 - 432 429 static const char *const quad8_synchronous_modes[] = { 433 430 "non-synchronous", 434 431 "synchronous" 435 432 }; 436 433 437 434 static int quad8_synchronous_mode_get(struct counter_device *counter, 438 - struct counter_signal *signal, size_t *synchronous_mode) 435 + struct counter_signal *signal, 436 + u32 *synchronous_mode) 439 437 { 440 438 const struct quad8 *const priv = counter->priv; 441 439 const size_t channel_id = signal->id - 16; ··· 440 450 } 441 451 442 452 static int quad8_synchronous_mode_set(struct counter_device *counter, 443 - struct counter_signal *signal, size_t synchronous_mode) 453 + struct counter_signal *signal, 454 + u32 synchronous_mode) 444 455 { 445 456 struct quad8 *const priv = counter->priv; 446 457 const size_t channel_id = signal->id - 16; ··· 468 477 return 0; 469 478 } 470 479 471 - static struct counter_signal_enum_ext quad8_syn_mode_enum = { 472 - .items = quad8_synchronous_modes, 473 - .num_items = ARRAY_SIZE(quad8_synchronous_modes), 474 - .get = quad8_synchronous_mode_get, 475 - .set = quad8_synchronous_mode_set 476 - }; 477 - 478 - static ssize_t quad8_count_floor_read(struct counter_device *counter, 479 - struct counter_count *count, void *private, char *buf) 480 + static int quad8_count_floor_read(struct counter_device *counter, 481 + struct counter_count *count, u64 *floor) 480 482 { 481 483 /* Only a floor of 0 is supported */ 482 - return sprintf(buf, "0\n"); 484 + *floor = 0; 485 + 486 + return 0; 483 487 } 484 488 485 - static int quad8_count_mode_get(struct counter_device *counter, 486 - struct counter_count *count, size_t *cnt_mode) 489 + static int quad8_count_mode_read(struct counter_device *counter, 490 + struct counter_count *count, 491 + enum counter_count_mode *cnt_mode) 487 492 { 488 493 const struct quad8 *const priv = counter->priv; 489 494 ··· 502 515 return 0; 503 516 } 504 517 505 - static int quad8_count_mode_set(struct counter_device *counter, 506 - struct counter_count *count, size_t cnt_mode) 518 + static int quad8_count_mode_write(struct counter_device *counter, 519 + struct counter_count *count, 520 + enum counter_count_mode cnt_mode) 507 521 { 508 522 struct quad8 *const priv = counter->priv; 523 + unsigned int count_mode; 509 524 unsigned int mode_cfg; 510 525 const int base_offset = priv->base + 2 * count->id + 1; 511 526 512 527 /* Map Generic Counter count mode to 104-QUAD-8 count mode */ 513 528 switch (cnt_mode) { 514 529 case COUNTER_COUNT_MODE_NORMAL: 515 - cnt_mode = 0; 530 + count_mode = 0; 516 531 break; 517 532 case COUNTER_COUNT_MODE_RANGE_LIMIT: 518 - cnt_mode = 1; 533 + count_mode = 1; 519 534 break; 520 535 case COUNTER_COUNT_MODE_NON_RECYCLE: 521 - cnt_mode = 2; 536 + count_mode = 2; 522 537 break; 523 538 case COUNTER_COUNT_MODE_MODULO_N: 524 - cnt_mode = 3; 539 + count_mode = 3; 525 540 break; 526 541 default: 527 542 /* should never reach this path */ ··· 532 543 533 544 mutex_lock(&priv->lock); 534 545 535 - priv->count_mode[count->id] = cnt_mode; 546 + priv->count_mode[count->id] = count_mode; 536 547 537 548 /* Set count mode configuration value */ 538 - mode_cfg = cnt_mode << 1; 549 + mode_cfg = count_mode << 1; 539 550 540 551 /* Add quadrature mode configuration */ 541 552 if (priv->quadrature_mode[count->id]) ··· 549 560 return 0; 550 561 } 551 562 552 - static struct counter_count_enum_ext quad8_cnt_mode_enum = { 553 - .items = counter_count_mode_str, 554 - .num_items = ARRAY_SIZE(counter_count_mode_str), 555 - .get = quad8_count_mode_get, 556 - .set = quad8_count_mode_set 557 - }; 558 - 559 - static ssize_t quad8_count_direction_read(struct counter_device *counter, 560 - struct counter_count *count, void *priv, char *buf) 561 - { 562 - enum counter_count_direction dir; 563 - 564 - quad8_direction_get(counter, count, &dir); 565 - 566 - return sprintf(buf, "%s\n", counter_count_direction_str[dir]); 567 - } 568 - 569 - static ssize_t quad8_count_enable_read(struct counter_device *counter, 570 - struct counter_count *count, void *private, char *buf) 563 + static int quad8_count_enable_read(struct counter_device *counter, 564 + struct counter_count *count, u8 *enable) 571 565 { 572 566 const struct quad8 *const priv = counter->priv; 573 567 574 - return sprintf(buf, "%u\n", priv->ab_enable[count->id]); 568 + *enable = priv->ab_enable[count->id]; 569 + 570 + return 0; 575 571 } 576 572 577 - static ssize_t quad8_count_enable_write(struct counter_device *counter, 578 - struct counter_count *count, void *private, const char *buf, size_t len) 573 + static int quad8_count_enable_write(struct counter_device *counter, 574 + struct counter_count *count, u8 enable) 579 575 { 580 576 struct quad8 *const priv = counter->priv; 581 577 const int base_offset = priv->base + 2 * count->id; 582 - int err; 583 - bool ab_enable; 584 578 unsigned int ior_cfg; 585 - 586 - err = kstrtobool(buf, &ab_enable); 587 - if (err) 588 - return err; 589 579 590 580 mutex_lock(&priv->lock); 591 581 592 - priv->ab_enable[count->id] = ab_enable; 582 + priv->ab_enable[count->id] = enable; 593 583 594 - ior_cfg = ab_enable | priv->preset_enable[count->id] << 1; 584 + ior_cfg = enable | priv->preset_enable[count->id] << 1; 595 585 596 586 /* Load I/O control configuration */ 597 587 outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1); 598 588 599 589 mutex_unlock(&priv->lock); 600 590 601 - return len; 591 + return 0; 602 592 } 603 593 604 594 static const char *const quad8_noise_error_states[] = { ··· 586 618 }; 587 619 588 620 static int quad8_error_noise_get(struct counter_device *counter, 589 - struct counter_count *count, size_t *noise_error) 621 + struct counter_count *count, u32 *noise_error) 590 622 { 591 623 const struct quad8 *const priv = counter->priv; 592 624 const int base_offset = priv->base + 2 * count->id + 1; ··· 596 628 return 0; 597 629 } 598 630 599 - static struct counter_count_enum_ext quad8_error_noise_enum = { 600 - .items = quad8_noise_error_states, 601 - .num_items = ARRAY_SIZE(quad8_noise_error_states), 602 - .get = quad8_error_noise_get 603 - }; 604 - 605 - static ssize_t quad8_count_preset_read(struct counter_device *counter, 606 - struct counter_count *count, void *private, char *buf) 631 + static int quad8_count_preset_read(struct counter_device *counter, 632 + struct counter_count *count, u64 *preset) 607 633 { 608 634 const struct quad8 *const priv = counter->priv; 609 635 610 - return sprintf(buf, "%u\n", priv->preset[count->id]); 636 + *preset = priv->preset[count->id]; 637 + 638 + return 0; 611 639 } 612 640 613 641 static void quad8_preset_register_set(struct quad8 *const priv, const int id, ··· 622 658 outb(preset >> (8 * i), base_offset); 623 659 } 624 660 625 - static ssize_t quad8_count_preset_write(struct counter_device *counter, 626 - struct counter_count *count, void *private, const char *buf, size_t len) 661 + static int quad8_count_preset_write(struct counter_device *counter, 662 + struct counter_count *count, u64 preset) 627 663 { 628 664 struct quad8 *const priv = counter->priv; 629 - unsigned int preset; 630 - int ret; 631 - 632 - ret = kstrtouint(buf, 0, &preset); 633 - if (ret) 634 - return ret; 635 665 636 666 /* Only 24-bit values are supported */ 637 667 if (preset > 0xFFFFFF) ··· 637 679 638 680 mutex_unlock(&priv->lock); 639 681 640 - return len; 682 + return 0; 641 683 } 642 684 643 - static ssize_t quad8_count_ceiling_read(struct counter_device *counter, 644 - struct counter_count *count, void *private, char *buf) 685 + static int quad8_count_ceiling_read(struct counter_device *counter, 686 + struct counter_count *count, u64 *ceiling) 645 687 { 646 688 struct quad8 *const priv = counter->priv; 647 689 ··· 651 693 switch (priv->count_mode[count->id]) { 652 694 case 1: 653 695 case 3: 654 - mutex_unlock(&priv->lock); 655 - return sprintf(buf, "%u\n", priv->preset[count->id]); 696 + *ceiling = priv->preset[count->id]; 697 + break; 698 + default: 699 + /* By default 0x1FFFFFF (25 bits unsigned) is maximum count */ 700 + *ceiling = 0x1FFFFFF; 701 + break; 656 702 } 657 703 658 704 mutex_unlock(&priv->lock); 659 705 660 - /* By default 0x1FFFFFF (25 bits unsigned) is maximum count */ 661 - return sprintf(buf, "33554431\n"); 706 + return 0; 662 707 } 663 708 664 - static ssize_t quad8_count_ceiling_write(struct counter_device *counter, 665 - struct counter_count *count, void *private, const char *buf, size_t len) 709 + static int quad8_count_ceiling_write(struct counter_device *counter, 710 + struct counter_count *count, u64 ceiling) 666 711 { 667 712 struct quad8 *const priv = counter->priv; 668 - unsigned int ceiling; 669 - int ret; 670 - 671 - ret = kstrtouint(buf, 0, &ceiling); 672 - if (ret) 673 - return ret; 674 713 675 714 /* Only 24-bit values are supported */ 676 715 if (ceiling > 0xFFFFFF) ··· 681 726 case 3: 682 727 quad8_preset_register_set(priv, count->id, ceiling); 683 728 mutex_unlock(&priv->lock); 684 - return len; 729 + return 0; 685 730 } 686 731 687 732 mutex_unlock(&priv->lock); ··· 689 734 return -EINVAL; 690 735 } 691 736 692 - static ssize_t quad8_count_preset_enable_read(struct counter_device *counter, 693 - struct counter_count *count, void *private, char *buf) 737 + static int quad8_count_preset_enable_read(struct counter_device *counter, 738 + struct counter_count *count, 739 + u8 *preset_enable) 694 740 { 695 741 const struct quad8 *const priv = counter->priv; 696 742 697 - return sprintf(buf, "%u\n", !priv->preset_enable[count->id]); 743 + *preset_enable = !priv->preset_enable[count->id]; 744 + 745 + return 0; 698 746 } 699 747 700 - static ssize_t quad8_count_preset_enable_write(struct counter_device *counter, 701 - struct counter_count *count, void *private, const char *buf, size_t len) 748 + static int quad8_count_preset_enable_write(struct counter_device *counter, 749 + struct counter_count *count, 750 + u8 preset_enable) 702 751 { 703 752 struct quad8 *const priv = counter->priv; 704 753 const int base_offset = priv->base + 2 * count->id + 1; 705 - bool preset_enable; 706 - int ret; 707 754 unsigned int ior_cfg; 708 - 709 - ret = kstrtobool(buf, &preset_enable); 710 - if (ret) 711 - return ret; 712 755 713 756 /* Preset enable is active low in Input/Output Control register */ 714 757 preset_enable = !preset_enable; ··· 715 762 716 763 priv->preset_enable[count->id] = preset_enable; 717 764 718 - ior_cfg = priv->ab_enable[count->id] | (unsigned int)preset_enable << 1; 765 + ior_cfg = priv->ab_enable[count->id] | preset_enable << 1; 719 766 720 767 /* Load I/O control configuration to Input / Output Control Register */ 721 768 outb(QUAD8_CTR_IOR | ior_cfg, base_offset); 722 769 723 770 mutex_unlock(&priv->lock); 724 771 725 - return len; 772 + return 0; 726 773 } 727 774 728 - static ssize_t quad8_signal_cable_fault_read(struct counter_device *counter, 729 - struct counter_signal *signal, 730 - void *private, char *buf) 775 + static int quad8_signal_cable_fault_read(struct counter_device *counter, 776 + struct counter_signal *signal, 777 + u8 *cable_fault) 731 778 { 732 779 struct quad8 *const priv = counter->priv; 733 780 const size_t channel_id = signal->id / 2; 734 781 bool disabled; 735 782 unsigned int status; 736 - unsigned int fault; 737 783 738 784 mutex_lock(&priv->lock); 739 785 ··· 749 797 mutex_unlock(&priv->lock); 750 798 751 799 /* Mask respective channel and invert logic */ 752 - fault = !(status & BIT(channel_id)); 800 + *cable_fault = !(status & BIT(channel_id)); 753 801 754 - return sprintf(buf, "%u\n", fault); 802 + return 0; 755 803 } 756 804 757 - static ssize_t quad8_signal_cable_fault_enable_read( 758 - struct counter_device *counter, struct counter_signal *signal, 759 - void *private, char *buf) 805 + static int quad8_signal_cable_fault_enable_read(struct counter_device *counter, 806 + struct counter_signal *signal, 807 + u8 *enable) 760 808 { 761 809 const struct quad8 *const priv = counter->priv; 762 810 const size_t channel_id = signal->id / 2; 763 - const unsigned int enb = !!(priv->cable_fault_enable & BIT(channel_id)); 764 811 765 - return sprintf(buf, "%u\n", enb); 812 + *enable = !!(priv->cable_fault_enable & BIT(channel_id)); 813 + 814 + return 0; 766 815 } 767 816 768 - static ssize_t quad8_signal_cable_fault_enable_write( 769 - struct counter_device *counter, struct counter_signal *signal, 770 - void *private, const char *buf, size_t len) 817 + static int quad8_signal_cable_fault_enable_write(struct counter_device *counter, 818 + struct counter_signal *signal, 819 + u8 enable) 771 820 { 772 821 struct quad8 *const priv = counter->priv; 773 822 const size_t channel_id = signal->id / 2; 774 - bool enable; 775 - int ret; 776 823 unsigned int cable_fault_enable; 777 - 778 - ret = kstrtobool(buf, &enable); 779 - if (ret) 780 - return ret; 781 824 782 825 mutex_lock(&priv->lock); 783 826 ··· 788 841 789 842 mutex_unlock(&priv->lock); 790 843 791 - return len; 844 + return 0; 792 845 } 793 846 794 - static ssize_t quad8_signal_fck_prescaler_read(struct counter_device *counter, 795 - struct counter_signal *signal, void *private, char *buf) 847 + static int quad8_signal_fck_prescaler_read(struct counter_device *counter, 848 + struct counter_signal *signal, 849 + u8 *prescaler) 796 850 { 797 851 const struct quad8 *const priv = counter->priv; 798 - const size_t channel_id = signal->id / 2; 799 852 800 - return sprintf(buf, "%u\n", priv->fck_prescaler[channel_id]); 853 + *prescaler = priv->fck_prescaler[signal->id / 2]; 854 + 855 + return 0; 801 856 } 802 857 803 - static ssize_t quad8_signal_fck_prescaler_write(struct counter_device *counter, 804 - struct counter_signal *signal, void *private, const char *buf, 805 - size_t len) 858 + static int quad8_signal_fck_prescaler_write(struct counter_device *counter, 859 + struct counter_signal *signal, 860 + u8 prescaler) 806 861 { 807 862 struct quad8 *const priv = counter->priv; 808 863 const size_t channel_id = signal->id / 2; 809 864 const int base_offset = priv->base + 2 * channel_id; 810 - u8 prescaler; 811 - int ret; 812 - 813 - ret = kstrtou8(buf, 0, &prescaler); 814 - if (ret) 815 - return ret; 816 865 817 866 mutex_lock(&priv->lock); 818 867 ··· 824 881 825 882 mutex_unlock(&priv->lock); 826 883 827 - return len; 884 + return 0; 828 885 } 829 886 830 - static const struct counter_signal_ext quad8_signal_ext[] = { 831 - { 832 - .name = "cable_fault", 833 - .read = quad8_signal_cable_fault_read 834 - }, 835 - { 836 - .name = "cable_fault_enable", 837 - .read = quad8_signal_cable_fault_enable_read, 838 - .write = quad8_signal_cable_fault_enable_write 839 - }, 840 - { 841 - .name = "filter_clock_prescaler", 842 - .read = quad8_signal_fck_prescaler_read, 843 - .write = quad8_signal_fck_prescaler_write 844 - } 887 + static struct counter_comp quad8_signal_ext[] = { 888 + COUNTER_COMP_SIGNAL_BOOL("cable_fault", quad8_signal_cable_fault_read, 889 + NULL), 890 + COUNTER_COMP_SIGNAL_BOOL("cable_fault_enable", 891 + quad8_signal_cable_fault_enable_read, 892 + quad8_signal_cable_fault_enable_write), 893 + COUNTER_COMP_SIGNAL_U8("filter_clock_prescaler", 894 + quad8_signal_fck_prescaler_read, 895 + quad8_signal_fck_prescaler_write) 845 896 }; 846 897 847 - static const struct counter_signal_ext quad8_index_ext[] = { 848 - COUNTER_SIGNAL_ENUM("index_polarity", &quad8_index_pol_enum), 849 - COUNTER_SIGNAL_ENUM_AVAILABLE("index_polarity", &quad8_index_pol_enum), 850 - COUNTER_SIGNAL_ENUM("synchronous_mode", &quad8_syn_mode_enum), 851 - COUNTER_SIGNAL_ENUM_AVAILABLE("synchronous_mode", &quad8_syn_mode_enum) 898 + static DEFINE_COUNTER_ENUM(quad8_index_pol_enum, quad8_index_polarity_modes); 899 + static DEFINE_COUNTER_ENUM(quad8_synch_mode_enum, quad8_synchronous_modes); 900 + 901 + static struct counter_comp quad8_index_ext[] = { 902 + COUNTER_COMP_SIGNAL_ENUM("index_polarity", quad8_index_polarity_get, 903 + quad8_index_polarity_set, 904 + quad8_index_pol_enum), 905 + COUNTER_COMP_SIGNAL_ENUM("synchronous_mode", quad8_synchronous_mode_get, 906 + quad8_synchronous_mode_set, 907 + quad8_synch_mode_enum), 852 908 }; 853 909 854 910 #define QUAD8_QUAD_SIGNAL(_id, _name) { \ ··· 916 974 QUAD8_COUNT_SYNAPSES(6), QUAD8_COUNT_SYNAPSES(7) 917 975 }; 918 976 919 - static const struct counter_count_ext quad8_count_ext[] = { 920 - { 921 - .name = "ceiling", 922 - .read = quad8_count_ceiling_read, 923 - .write = quad8_count_ceiling_write 924 - }, 925 - { 926 - .name = "floor", 927 - .read = quad8_count_floor_read 928 - }, 929 - COUNTER_COUNT_ENUM("count_mode", &quad8_cnt_mode_enum), 930 - COUNTER_COUNT_ENUM_AVAILABLE("count_mode", &quad8_cnt_mode_enum), 931 - { 932 - .name = "direction", 933 - .read = quad8_count_direction_read 934 - }, 935 - { 936 - .name = "enable", 937 - .read = quad8_count_enable_read, 938 - .write = quad8_count_enable_write 939 - }, 940 - COUNTER_COUNT_ENUM("error_noise", &quad8_error_noise_enum), 941 - COUNTER_COUNT_ENUM_AVAILABLE("error_noise", &quad8_error_noise_enum), 942 - { 943 - .name = "preset", 944 - .read = quad8_count_preset_read, 945 - .write = quad8_count_preset_write 946 - }, 947 - { 948 - .name = "preset_enable", 949 - .read = quad8_count_preset_enable_read, 950 - .write = quad8_count_preset_enable_write 951 - } 977 + static const enum counter_count_mode quad8_cnt_modes[] = { 978 + COUNTER_COUNT_MODE_NORMAL, 979 + COUNTER_COUNT_MODE_RANGE_LIMIT, 980 + COUNTER_COUNT_MODE_NON_RECYCLE, 981 + COUNTER_COUNT_MODE_MODULO_N, 982 + }; 983 + 984 + static DEFINE_COUNTER_AVAILABLE(quad8_count_mode_available, quad8_cnt_modes); 985 + 986 + static DEFINE_COUNTER_ENUM(quad8_error_noise_enum, quad8_noise_error_states); 987 + 988 + static struct counter_comp quad8_count_ext[] = { 989 + COUNTER_COMP_CEILING(quad8_count_ceiling_read, 990 + quad8_count_ceiling_write), 991 + COUNTER_COMP_FLOOR(quad8_count_floor_read, NULL), 992 + COUNTER_COMP_COUNT_MODE(quad8_count_mode_read, quad8_count_mode_write, 993 + quad8_count_mode_available), 994 + COUNTER_COMP_DIRECTION(quad8_direction_read), 995 + COUNTER_COMP_ENABLE(quad8_count_enable_read, quad8_count_enable_write), 996 + COUNTER_COMP_COUNT_ENUM("error_noise", quad8_error_noise_get, NULL, 997 + quad8_error_noise_enum), 998 + COUNTER_COMP_PRESET(quad8_count_preset_read, quad8_count_preset_write), 999 + COUNTER_COMP_PRESET_ENABLE(quad8_count_preset_enable_read, 1000 + quad8_count_preset_enable_write), 952 1001 }; 953 1002 954 1003 #define QUAD8_COUNT(_id, _cntname) { \
+1
drivers/counter/Makefile
··· 4 4 # 5 5 6 6 obj-$(CONFIG_COUNTER) += counter.o 7 + counter-y := counter-core.o counter-sysfs.o 7 8 8 9 obj-$(CONFIG_104_QUAD_8) += 104-quad-8.o 9 10 obj-$(CONFIG_INTERRUPT_CNT) += interrupt-cnt.o
+142
drivers/counter/counter-core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Generic Counter interface 4 + * Copyright (C) 2020 William Breathitt Gray 5 + */ 6 + #include <linux/counter.h> 7 + #include <linux/device.h> 8 + #include <linux/export.h> 9 + #include <linux/gfp.h> 10 + #include <linux/idr.h> 11 + #include <linux/init.h> 12 + #include <linux/module.h> 13 + 14 + #include "counter-sysfs.h" 15 + 16 + /* Provides a unique ID for each counter device */ 17 + static DEFINE_IDA(counter_ida); 18 + 19 + static void counter_device_release(struct device *dev) 20 + { 21 + ida_free(&counter_ida, dev->id); 22 + } 23 + 24 + static struct device_type counter_device_type = { 25 + .name = "counter_device", 26 + .release = counter_device_release, 27 + }; 28 + 29 + static struct bus_type counter_bus_type = { 30 + .name = "counter", 31 + .dev_name = "counter", 32 + }; 33 + 34 + /** 35 + * counter_register - register Counter to the system 36 + * @counter: pointer to Counter to register 37 + * 38 + * This function registers a Counter to the system. A sysfs "counter" directory 39 + * will be created and populated with sysfs attributes correlating with the 40 + * Counter Signals, Synapses, and Counts respectively. 41 + */ 42 + int counter_register(struct counter_device *const counter) 43 + { 44 + struct device *const dev = &counter->dev; 45 + int id; 46 + int err; 47 + 48 + /* Acquire unique ID */ 49 + id = ida_alloc(&counter_ida, GFP_KERNEL); 50 + if (id < 0) 51 + return id; 52 + 53 + /* Configure device structure for Counter */ 54 + dev->id = id; 55 + dev->type = &counter_device_type; 56 + dev->bus = &counter_bus_type; 57 + if (counter->parent) { 58 + dev->parent = counter->parent; 59 + dev->of_node = counter->parent->of_node; 60 + } 61 + device_initialize(dev); 62 + dev_set_drvdata(dev, counter); 63 + 64 + /* Add Counter sysfs attributes */ 65 + err = counter_sysfs_add(counter); 66 + if (err < 0) 67 + goto err_free_id; 68 + 69 + /* Add device to system */ 70 + err = device_add(dev); 71 + if (err < 0) 72 + goto err_free_id; 73 + 74 + return 0; 75 + 76 + err_free_id: 77 + put_device(dev); 78 + return err; 79 + } 80 + EXPORT_SYMBOL_GPL(counter_register); 81 + 82 + /** 83 + * counter_unregister - unregister Counter from the system 84 + * @counter: pointer to Counter to unregister 85 + * 86 + * The Counter is unregistered from the system. 87 + */ 88 + void counter_unregister(struct counter_device *const counter) 89 + { 90 + if (!counter) 91 + return; 92 + 93 + device_unregister(&counter->dev); 94 + } 95 + EXPORT_SYMBOL_GPL(counter_unregister); 96 + 97 + static void devm_counter_release(void *counter) 98 + { 99 + counter_unregister(counter); 100 + } 101 + 102 + /** 103 + * devm_counter_register - Resource-managed counter_register 104 + * @dev: device to allocate counter_device for 105 + * @counter: pointer to Counter to register 106 + * 107 + * Managed counter_register. The Counter registered with this function is 108 + * automatically unregistered on driver detach. This function calls 109 + * counter_register internally. Refer to that function for more information. 110 + * 111 + * RETURNS: 112 + * 0 on success, negative error number on failure. 113 + */ 114 + int devm_counter_register(struct device *dev, 115 + struct counter_device *const counter) 116 + { 117 + int err; 118 + 119 + err = counter_register(counter); 120 + if (err < 0) 121 + return err; 122 + 123 + return devm_add_action_or_reset(dev, devm_counter_release, counter); 124 + } 125 + EXPORT_SYMBOL_GPL(devm_counter_register); 126 + 127 + static int __init counter_init(void) 128 + { 129 + return bus_register(&counter_bus_type); 130 + } 131 + 132 + static void __exit counter_exit(void) 133 + { 134 + bus_unregister(&counter_bus_type); 135 + } 136 + 137 + subsys_initcall(counter_init); 138 + module_exit(counter_exit); 139 + 140 + MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); 141 + MODULE_DESCRIPTION("Generic Counter interface"); 142 + MODULE_LICENSE("GPL v2");
+849
drivers/counter/counter-sysfs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Generic Counter sysfs interface 4 + * Copyright (C) 2020 William Breathitt Gray 5 + */ 6 + #include <linux/counter.h> 7 + #include <linux/device.h> 8 + #include <linux/err.h> 9 + #include <linux/gfp.h> 10 + #include <linux/kernel.h> 11 + #include <linux/kstrtox.h> 12 + #include <linux/list.h> 13 + #include <linux/string.h> 14 + #include <linux/sysfs.h> 15 + #include <linux/types.h> 16 + 17 + #include "counter-sysfs.h" 18 + 19 + /** 20 + * struct counter_attribute - Counter sysfs attribute 21 + * @dev_attr: device attribute for sysfs 22 + * @l: node to add Counter attribute to attribute group list 23 + * @comp: Counter component callbacks and data 24 + * @scope: Counter scope of the attribute 25 + * @parent: pointer to the parent component 26 + */ 27 + struct counter_attribute { 28 + struct device_attribute dev_attr; 29 + struct list_head l; 30 + 31 + struct counter_comp comp; 32 + enum counter_scope scope; 33 + void *parent; 34 + }; 35 + 36 + #define to_counter_attribute(_dev_attr) \ 37 + container_of(_dev_attr, struct counter_attribute, dev_attr) 38 + 39 + /** 40 + * struct counter_attribute_group - container for attribute group 41 + * @name: name of the attribute group 42 + * @attr_list: list to keep track of created attributes 43 + * @num_attr: number of attributes 44 + */ 45 + struct counter_attribute_group { 46 + const char *name; 47 + struct list_head attr_list; 48 + size_t num_attr; 49 + }; 50 + 51 + static const char *const counter_function_str[] = { 52 + [COUNTER_FUNCTION_INCREASE] = "increase", 53 + [COUNTER_FUNCTION_DECREASE] = "decrease", 54 + [COUNTER_FUNCTION_PULSE_DIRECTION] = "pulse-direction", 55 + [COUNTER_FUNCTION_QUADRATURE_X1_A] = "quadrature x1 a", 56 + [COUNTER_FUNCTION_QUADRATURE_X1_B] = "quadrature x1 b", 57 + [COUNTER_FUNCTION_QUADRATURE_X2_A] = "quadrature x2 a", 58 + [COUNTER_FUNCTION_QUADRATURE_X2_B] = "quadrature x2 b", 59 + [COUNTER_FUNCTION_QUADRATURE_X4] = "quadrature x4" 60 + }; 61 + 62 + static const char *const counter_signal_value_str[] = { 63 + [COUNTER_SIGNAL_LEVEL_LOW] = "low", 64 + [COUNTER_SIGNAL_LEVEL_HIGH] = "high" 65 + }; 66 + 67 + static const char *const counter_synapse_action_str[] = { 68 + [COUNTER_SYNAPSE_ACTION_NONE] = "none", 69 + [COUNTER_SYNAPSE_ACTION_RISING_EDGE] = "rising edge", 70 + [COUNTER_SYNAPSE_ACTION_FALLING_EDGE] = "falling edge", 71 + [COUNTER_SYNAPSE_ACTION_BOTH_EDGES] = "both edges" 72 + }; 73 + 74 + static const char *const counter_count_direction_str[] = { 75 + [COUNTER_COUNT_DIRECTION_FORWARD] = "forward", 76 + [COUNTER_COUNT_DIRECTION_BACKWARD] = "backward" 77 + }; 78 + 79 + static const char *const counter_count_mode_str[] = { 80 + [COUNTER_COUNT_MODE_NORMAL] = "normal", 81 + [COUNTER_COUNT_MODE_RANGE_LIMIT] = "range limit", 82 + [COUNTER_COUNT_MODE_NON_RECYCLE] = "non-recycle", 83 + [COUNTER_COUNT_MODE_MODULO_N] = "modulo-n" 84 + }; 85 + 86 + static ssize_t counter_comp_u8_show(struct device *dev, 87 + struct device_attribute *attr, char *buf) 88 + { 89 + const struct counter_attribute *const a = to_counter_attribute(attr); 90 + struct counter_device *const counter = dev_get_drvdata(dev); 91 + int err; 92 + u8 data = 0; 93 + 94 + switch (a->scope) { 95 + case COUNTER_SCOPE_DEVICE: 96 + err = a->comp.device_u8_read(counter, &data); 97 + break; 98 + case COUNTER_SCOPE_SIGNAL: 99 + err = a->comp.signal_u8_read(counter, a->parent, &data); 100 + break; 101 + case COUNTER_SCOPE_COUNT: 102 + err = a->comp.count_u8_read(counter, a->parent, &data); 103 + break; 104 + default: 105 + return -EINVAL; 106 + } 107 + if (err < 0) 108 + return err; 109 + 110 + if (a->comp.type == COUNTER_COMP_BOOL) 111 + /* data should already be boolean but ensure just to be safe */ 112 + data = !!data; 113 + 114 + return sprintf(buf, "%u\n", (unsigned int)data); 115 + } 116 + 117 + static ssize_t counter_comp_u8_store(struct device *dev, 118 + struct device_attribute *attr, 119 + const char *buf, size_t len) 120 + { 121 + const struct counter_attribute *const a = to_counter_attribute(attr); 122 + struct counter_device *const counter = dev_get_drvdata(dev); 123 + int err; 124 + bool bool_data = 0; 125 + u8 data = 0; 126 + 127 + if (a->comp.type == COUNTER_COMP_BOOL) { 128 + err = kstrtobool(buf, &bool_data); 129 + data = bool_data; 130 + } else 131 + err = kstrtou8(buf, 0, &data); 132 + if (err < 0) 133 + return err; 134 + 135 + switch (a->scope) { 136 + case COUNTER_SCOPE_DEVICE: 137 + err = a->comp.device_u8_write(counter, data); 138 + break; 139 + case COUNTER_SCOPE_SIGNAL: 140 + err = a->comp.signal_u8_write(counter, a->parent, data); 141 + break; 142 + case COUNTER_SCOPE_COUNT: 143 + err = a->comp.count_u8_write(counter, a->parent, data); 144 + break; 145 + default: 146 + return -EINVAL; 147 + } 148 + if (err < 0) 149 + return err; 150 + 151 + return len; 152 + } 153 + 154 + static ssize_t counter_comp_u32_show(struct device *dev, 155 + struct device_attribute *attr, char *buf) 156 + { 157 + const struct counter_attribute *const a = to_counter_attribute(attr); 158 + struct counter_device *const counter = dev_get_drvdata(dev); 159 + const struct counter_available *const avail = a->comp.priv; 160 + int err; 161 + u32 data = 0; 162 + 163 + switch (a->scope) { 164 + case COUNTER_SCOPE_DEVICE: 165 + err = a->comp.device_u32_read(counter, &data); 166 + break; 167 + case COUNTER_SCOPE_SIGNAL: 168 + err = a->comp.signal_u32_read(counter, a->parent, &data); 169 + break; 170 + case COUNTER_SCOPE_COUNT: 171 + if (a->comp.type == COUNTER_COMP_SYNAPSE_ACTION) 172 + err = a->comp.action_read(counter, a->parent, 173 + a->comp.priv, &data); 174 + else 175 + err = a->comp.count_u32_read(counter, a->parent, &data); 176 + break; 177 + default: 178 + return -EINVAL; 179 + } 180 + if (err < 0) 181 + return err; 182 + 183 + switch (a->comp.type) { 184 + case COUNTER_COMP_FUNCTION: 185 + return sysfs_emit(buf, "%s\n", counter_function_str[data]); 186 + case COUNTER_COMP_SIGNAL_LEVEL: 187 + return sysfs_emit(buf, "%s\n", counter_signal_value_str[data]); 188 + case COUNTER_COMP_SYNAPSE_ACTION: 189 + return sysfs_emit(buf, "%s\n", counter_synapse_action_str[data]); 190 + case COUNTER_COMP_ENUM: 191 + return sysfs_emit(buf, "%s\n", avail->strs[data]); 192 + case COUNTER_COMP_COUNT_DIRECTION: 193 + return sysfs_emit(buf, "%s\n", counter_count_direction_str[data]); 194 + case COUNTER_COMP_COUNT_MODE: 195 + return sysfs_emit(buf, "%s\n", counter_count_mode_str[data]); 196 + default: 197 + return sprintf(buf, "%u\n", (unsigned int)data); 198 + } 199 + } 200 + 201 + static int counter_find_enum(u32 *const enum_item, const u32 *const enums, 202 + const size_t num_enums, const char *const buf, 203 + const char *const string_array[]) 204 + { 205 + size_t index; 206 + 207 + for (index = 0; index < num_enums; index++) { 208 + *enum_item = enums[index]; 209 + if (sysfs_streq(buf, string_array[*enum_item])) 210 + return 0; 211 + } 212 + 213 + return -EINVAL; 214 + } 215 + 216 + static ssize_t counter_comp_u32_store(struct device *dev, 217 + struct device_attribute *attr, 218 + const char *buf, size_t len) 219 + { 220 + const struct counter_attribute *const a = to_counter_attribute(attr); 221 + struct counter_device *const counter = dev_get_drvdata(dev); 222 + struct counter_count *const count = a->parent; 223 + struct counter_synapse *const synapse = a->comp.priv; 224 + const struct counter_available *const avail = a->comp.priv; 225 + int err; 226 + u32 data = 0; 227 + 228 + switch (a->comp.type) { 229 + case COUNTER_COMP_FUNCTION: 230 + err = counter_find_enum(&data, count->functions_list, 231 + count->num_functions, buf, 232 + counter_function_str); 233 + break; 234 + case COUNTER_COMP_SYNAPSE_ACTION: 235 + err = counter_find_enum(&data, synapse->actions_list, 236 + synapse->num_actions, buf, 237 + counter_synapse_action_str); 238 + break; 239 + case COUNTER_COMP_ENUM: 240 + err = __sysfs_match_string(avail->strs, avail->num_items, buf); 241 + data = err; 242 + break; 243 + case COUNTER_COMP_COUNT_MODE: 244 + err = counter_find_enum(&data, avail->enums, avail->num_items, 245 + buf, counter_count_mode_str); 246 + break; 247 + default: 248 + err = kstrtou32(buf, 0, &data); 249 + break; 250 + } 251 + if (err < 0) 252 + return err; 253 + 254 + switch (a->scope) { 255 + case COUNTER_SCOPE_DEVICE: 256 + err = a->comp.device_u32_write(counter, data); 257 + break; 258 + case COUNTER_SCOPE_SIGNAL: 259 + err = a->comp.signal_u32_write(counter, a->parent, data); 260 + break; 261 + case COUNTER_SCOPE_COUNT: 262 + if (a->comp.type == COUNTER_COMP_SYNAPSE_ACTION) 263 + err = a->comp.action_write(counter, count, synapse, 264 + data); 265 + else 266 + err = a->comp.count_u32_write(counter, count, data); 267 + break; 268 + default: 269 + return -EINVAL; 270 + } 271 + if (err < 0) 272 + return err; 273 + 274 + return len; 275 + } 276 + 277 + static ssize_t counter_comp_u64_show(struct device *dev, 278 + struct device_attribute *attr, char *buf) 279 + { 280 + const struct counter_attribute *const a = to_counter_attribute(attr); 281 + struct counter_device *const counter = dev_get_drvdata(dev); 282 + int err; 283 + u64 data = 0; 284 + 285 + switch (a->scope) { 286 + case COUNTER_SCOPE_DEVICE: 287 + err = a->comp.device_u64_read(counter, &data); 288 + break; 289 + case COUNTER_SCOPE_SIGNAL: 290 + err = a->comp.signal_u64_read(counter, a->parent, &data); 291 + break; 292 + case COUNTER_SCOPE_COUNT: 293 + err = a->comp.count_u64_read(counter, a->parent, &data); 294 + break; 295 + default: 296 + return -EINVAL; 297 + } 298 + if (err < 0) 299 + return err; 300 + 301 + return sprintf(buf, "%llu\n", (unsigned long long)data); 302 + } 303 + 304 + static ssize_t counter_comp_u64_store(struct device *dev, 305 + struct device_attribute *attr, 306 + const char *buf, size_t len) 307 + { 308 + const struct counter_attribute *const a = to_counter_attribute(attr); 309 + struct counter_device *const counter = dev_get_drvdata(dev); 310 + int err; 311 + u64 data = 0; 312 + 313 + err = kstrtou64(buf, 0, &data); 314 + if (err < 0) 315 + return err; 316 + 317 + switch (a->scope) { 318 + case COUNTER_SCOPE_DEVICE: 319 + err = a->comp.device_u64_write(counter, data); 320 + break; 321 + case COUNTER_SCOPE_SIGNAL: 322 + err = a->comp.signal_u64_write(counter, a->parent, data); 323 + break; 324 + case COUNTER_SCOPE_COUNT: 325 + err = a->comp.count_u64_write(counter, a->parent, data); 326 + break; 327 + default: 328 + return -EINVAL; 329 + } 330 + if (err < 0) 331 + return err; 332 + 333 + return len; 334 + } 335 + 336 + static ssize_t enums_available_show(const u32 *const enums, 337 + const size_t num_enums, 338 + const char *const strs[], char *buf) 339 + { 340 + size_t len = 0; 341 + size_t index; 342 + 343 + for (index = 0; index < num_enums; index++) 344 + len += sysfs_emit_at(buf, len, "%s\n", strs[enums[index]]); 345 + 346 + return len; 347 + } 348 + 349 + static ssize_t strs_available_show(const struct counter_available *const avail, 350 + char *buf) 351 + { 352 + size_t len = 0; 353 + size_t index; 354 + 355 + for (index = 0; index < avail->num_items; index++) 356 + len += sysfs_emit_at(buf, len, "%s\n", avail->strs[index]); 357 + 358 + return len; 359 + } 360 + 361 + static ssize_t counter_comp_available_show(struct device *dev, 362 + struct device_attribute *attr, 363 + char *buf) 364 + { 365 + const struct counter_attribute *const a = to_counter_attribute(attr); 366 + const struct counter_count *const count = a->parent; 367 + const struct counter_synapse *const synapse = a->comp.priv; 368 + const struct counter_available *const avail = a->comp.priv; 369 + 370 + switch (a->comp.type) { 371 + case COUNTER_COMP_FUNCTION: 372 + return enums_available_show(count->functions_list, 373 + count->num_functions, 374 + counter_function_str, buf); 375 + case COUNTER_COMP_SYNAPSE_ACTION: 376 + return enums_available_show(synapse->actions_list, 377 + synapse->num_actions, 378 + counter_synapse_action_str, buf); 379 + case COUNTER_COMP_ENUM: 380 + return strs_available_show(avail, buf); 381 + case COUNTER_COMP_COUNT_MODE: 382 + return enums_available_show(avail->enums, avail->num_items, 383 + counter_count_mode_str, buf); 384 + default: 385 + return -EINVAL; 386 + } 387 + } 388 + 389 + static int counter_avail_attr_create(struct device *const dev, 390 + struct counter_attribute_group *const group, 391 + const struct counter_comp *const comp, void *const parent) 392 + { 393 + struct counter_attribute *counter_attr; 394 + struct device_attribute *dev_attr; 395 + 396 + counter_attr = devm_kzalloc(dev, sizeof(*counter_attr), GFP_KERNEL); 397 + if (!counter_attr) 398 + return -ENOMEM; 399 + 400 + /* Configure Counter attribute */ 401 + counter_attr->comp.type = comp->type; 402 + counter_attr->comp.priv = comp->priv; 403 + counter_attr->parent = parent; 404 + 405 + /* Initialize sysfs attribute */ 406 + dev_attr = &counter_attr->dev_attr; 407 + sysfs_attr_init(&dev_attr->attr); 408 + 409 + /* Configure device attribute */ 410 + dev_attr->attr.name = devm_kasprintf(dev, GFP_KERNEL, "%s_available", 411 + comp->name); 412 + if (!dev_attr->attr.name) 413 + return -ENOMEM; 414 + dev_attr->attr.mode = 0444; 415 + dev_attr->show = counter_comp_available_show; 416 + 417 + /* Store list node */ 418 + list_add(&counter_attr->l, &group->attr_list); 419 + group->num_attr++; 420 + 421 + return 0; 422 + } 423 + 424 + static int counter_attr_create(struct device *const dev, 425 + struct counter_attribute_group *const group, 426 + const struct counter_comp *const comp, 427 + const enum counter_scope scope, 428 + void *const parent) 429 + { 430 + struct counter_attribute *counter_attr; 431 + struct device_attribute *dev_attr; 432 + 433 + counter_attr = devm_kzalloc(dev, sizeof(*counter_attr), GFP_KERNEL); 434 + if (!counter_attr) 435 + return -ENOMEM; 436 + 437 + /* Configure Counter attribute */ 438 + counter_attr->comp = *comp; 439 + counter_attr->scope = scope; 440 + counter_attr->parent = parent; 441 + 442 + /* Configure device attribute */ 443 + dev_attr = &counter_attr->dev_attr; 444 + sysfs_attr_init(&dev_attr->attr); 445 + dev_attr->attr.name = comp->name; 446 + switch (comp->type) { 447 + case COUNTER_COMP_U8: 448 + case COUNTER_COMP_BOOL: 449 + if (comp->device_u8_read) { 450 + dev_attr->attr.mode |= 0444; 451 + dev_attr->show = counter_comp_u8_show; 452 + } 453 + if (comp->device_u8_write) { 454 + dev_attr->attr.mode |= 0200; 455 + dev_attr->store = counter_comp_u8_store; 456 + } 457 + break; 458 + case COUNTER_COMP_SIGNAL_LEVEL: 459 + case COUNTER_COMP_FUNCTION: 460 + case COUNTER_COMP_SYNAPSE_ACTION: 461 + case COUNTER_COMP_ENUM: 462 + case COUNTER_COMP_COUNT_DIRECTION: 463 + case COUNTER_COMP_COUNT_MODE: 464 + if (comp->device_u32_read) { 465 + dev_attr->attr.mode |= 0444; 466 + dev_attr->show = counter_comp_u32_show; 467 + } 468 + if (comp->device_u32_write) { 469 + dev_attr->attr.mode |= 0200; 470 + dev_attr->store = counter_comp_u32_store; 471 + } 472 + break; 473 + case COUNTER_COMP_U64: 474 + if (comp->device_u64_read) { 475 + dev_attr->attr.mode |= 0444; 476 + dev_attr->show = counter_comp_u64_show; 477 + } 478 + if (comp->device_u64_write) { 479 + dev_attr->attr.mode |= 0200; 480 + dev_attr->store = counter_comp_u64_store; 481 + } 482 + break; 483 + default: 484 + return -EINVAL; 485 + } 486 + 487 + /* Store list node */ 488 + list_add(&counter_attr->l, &group->attr_list); 489 + group->num_attr++; 490 + 491 + /* Create "*_available" attribute if needed */ 492 + switch (comp->type) { 493 + case COUNTER_COMP_FUNCTION: 494 + case COUNTER_COMP_SYNAPSE_ACTION: 495 + case COUNTER_COMP_ENUM: 496 + case COUNTER_COMP_COUNT_MODE: 497 + return counter_avail_attr_create(dev, group, comp, parent); 498 + default: 499 + return 0; 500 + } 501 + } 502 + 503 + static ssize_t counter_comp_name_show(struct device *dev, 504 + struct device_attribute *attr, char *buf) 505 + { 506 + return sysfs_emit(buf, "%s\n", to_counter_attribute(attr)->comp.name); 507 + } 508 + 509 + static int counter_name_attr_create(struct device *const dev, 510 + struct counter_attribute_group *const group, 511 + const char *const name) 512 + { 513 + struct counter_attribute *counter_attr; 514 + 515 + counter_attr = devm_kzalloc(dev, sizeof(*counter_attr), GFP_KERNEL); 516 + if (!counter_attr) 517 + return -ENOMEM; 518 + 519 + /* Configure Counter attribute */ 520 + counter_attr->comp.name = name; 521 + 522 + /* Configure device attribute */ 523 + sysfs_attr_init(&counter_attr->dev_attr.attr); 524 + counter_attr->dev_attr.attr.name = "name"; 525 + counter_attr->dev_attr.attr.mode = 0444; 526 + counter_attr->dev_attr.show = counter_comp_name_show; 527 + 528 + /* Store list node */ 529 + list_add(&counter_attr->l, &group->attr_list); 530 + group->num_attr++; 531 + 532 + return 0; 533 + } 534 + 535 + static struct counter_comp counter_signal_comp = { 536 + .type = COUNTER_COMP_SIGNAL_LEVEL, 537 + .name = "signal", 538 + }; 539 + 540 + static int counter_signal_attrs_create(struct counter_device *const counter, 541 + struct counter_attribute_group *const cattr_group, 542 + struct counter_signal *const signal) 543 + { 544 + const enum counter_scope scope = COUNTER_SCOPE_SIGNAL; 545 + struct device *const dev = &counter->dev; 546 + int err; 547 + struct counter_comp comp; 548 + size_t i; 549 + 550 + /* Create main Signal attribute */ 551 + comp = counter_signal_comp; 552 + comp.signal_u32_read = counter->ops->signal_read; 553 + err = counter_attr_create(dev, cattr_group, &comp, scope, signal); 554 + if (err < 0) 555 + return err; 556 + 557 + /* Create Signal name attribute */ 558 + err = counter_name_attr_create(dev, cattr_group, signal->name); 559 + if (err < 0) 560 + return err; 561 + 562 + /* Create an attribute for each extension */ 563 + for (i = 0; i < signal->num_ext; i++) { 564 + err = counter_attr_create(dev, cattr_group, signal->ext + i, 565 + scope, signal); 566 + if (err < 0) 567 + return err; 568 + } 569 + 570 + return 0; 571 + } 572 + 573 + static int counter_sysfs_signals_add(struct counter_device *const counter, 574 + struct counter_attribute_group *const groups) 575 + { 576 + size_t i; 577 + int err; 578 + 579 + /* Add each Signal */ 580 + for (i = 0; i < counter->num_signals; i++) { 581 + /* Generate Signal attribute directory name */ 582 + groups[i].name = devm_kasprintf(&counter->dev, GFP_KERNEL, 583 + "signal%zu", i); 584 + if (!groups[i].name) 585 + return -ENOMEM; 586 + 587 + /* Create all attributes associated with Signal */ 588 + err = counter_signal_attrs_create(counter, groups + i, 589 + counter->signals + i); 590 + if (err < 0) 591 + return err; 592 + } 593 + 594 + return 0; 595 + } 596 + 597 + static int counter_sysfs_synapses_add(struct counter_device *const counter, 598 + struct counter_attribute_group *const group, 599 + struct counter_count *const count) 600 + { 601 + size_t i; 602 + 603 + /* Add each Synapse */ 604 + for (i = 0; i < count->num_synapses; i++) { 605 + struct device *const dev = &counter->dev; 606 + struct counter_synapse *synapse; 607 + size_t id; 608 + struct counter_comp comp; 609 + int err; 610 + 611 + synapse = count->synapses + i; 612 + 613 + /* Generate Synapse action name */ 614 + id = synapse->signal - counter->signals; 615 + comp.name = devm_kasprintf(dev, GFP_KERNEL, "signal%zu_action", 616 + id); 617 + if (!comp.name) 618 + return -ENOMEM; 619 + 620 + /* Create action attribute */ 621 + comp.type = COUNTER_COMP_SYNAPSE_ACTION; 622 + comp.action_read = counter->ops->action_read; 623 + comp.action_write = counter->ops->action_write; 624 + comp.priv = synapse; 625 + err = counter_attr_create(dev, group, &comp, 626 + COUNTER_SCOPE_COUNT, count); 627 + if (err < 0) 628 + return err; 629 + } 630 + 631 + return 0; 632 + } 633 + 634 + static struct counter_comp counter_count_comp = 635 + COUNTER_COMP_COUNT_U64("count", NULL, NULL); 636 + 637 + static struct counter_comp counter_function_comp = { 638 + .type = COUNTER_COMP_FUNCTION, 639 + .name = "function", 640 + }; 641 + 642 + static int counter_count_attrs_create(struct counter_device *const counter, 643 + struct counter_attribute_group *const cattr_group, 644 + struct counter_count *const count) 645 + { 646 + const enum counter_scope scope = COUNTER_SCOPE_COUNT; 647 + struct device *const dev = &counter->dev; 648 + int err; 649 + struct counter_comp comp; 650 + size_t i; 651 + 652 + /* Create main Count attribute */ 653 + comp = counter_count_comp; 654 + comp.count_u64_read = counter->ops->count_read; 655 + comp.count_u64_write = counter->ops->count_write; 656 + err = counter_attr_create(dev, cattr_group, &comp, scope, count); 657 + if (err < 0) 658 + return err; 659 + 660 + /* Create Count name attribute */ 661 + err = counter_name_attr_create(dev, cattr_group, count->name); 662 + if (err < 0) 663 + return err; 664 + 665 + /* Create Count function attribute */ 666 + comp = counter_function_comp; 667 + comp.count_u32_read = counter->ops->function_read; 668 + comp.count_u32_write = counter->ops->function_write; 669 + err = counter_attr_create(dev, cattr_group, &comp, scope, count); 670 + if (err < 0) 671 + return err; 672 + 673 + /* Create an attribute for each extension */ 674 + for (i = 0; i < count->num_ext; i++) { 675 + err = counter_attr_create(dev, cattr_group, count->ext + i, 676 + scope, count); 677 + if (err < 0) 678 + return err; 679 + } 680 + 681 + return 0; 682 + } 683 + 684 + static int counter_sysfs_counts_add(struct counter_device *const counter, 685 + struct counter_attribute_group *const groups) 686 + { 687 + size_t i; 688 + struct counter_count *count; 689 + int err; 690 + 691 + /* Add each Count */ 692 + for (i = 0; i < counter->num_counts; i++) { 693 + count = counter->counts + i; 694 + 695 + /* Generate Count attribute directory name */ 696 + groups[i].name = devm_kasprintf(&counter->dev, GFP_KERNEL, 697 + "count%zu", i); 698 + if (!groups[i].name) 699 + return -ENOMEM; 700 + 701 + /* Add sysfs attributes of the Synapses */ 702 + err = counter_sysfs_synapses_add(counter, groups + i, count); 703 + if (err < 0) 704 + return err; 705 + 706 + /* Create all attributes associated with Count */ 707 + err = counter_count_attrs_create(counter, groups + i, count); 708 + if (err < 0) 709 + return err; 710 + } 711 + 712 + return 0; 713 + } 714 + 715 + static int counter_num_signals_read(struct counter_device *counter, u8 *val) 716 + { 717 + *val = counter->num_signals; 718 + return 0; 719 + } 720 + 721 + static int counter_num_counts_read(struct counter_device *counter, u8 *val) 722 + { 723 + *val = counter->num_counts; 724 + return 0; 725 + } 726 + 727 + static struct counter_comp counter_num_signals_comp = 728 + COUNTER_COMP_DEVICE_U8("num_signals", counter_num_signals_read, NULL); 729 + 730 + static struct counter_comp counter_num_counts_comp = 731 + COUNTER_COMP_DEVICE_U8("num_counts", counter_num_counts_read, NULL); 732 + 733 + static int counter_sysfs_attr_add(struct counter_device *const counter, 734 + struct counter_attribute_group *cattr_group) 735 + { 736 + const enum counter_scope scope = COUNTER_SCOPE_DEVICE; 737 + struct device *const dev = &counter->dev; 738 + int err; 739 + size_t i; 740 + 741 + /* Add Signals sysfs attributes */ 742 + err = counter_sysfs_signals_add(counter, cattr_group); 743 + if (err < 0) 744 + return err; 745 + cattr_group += counter->num_signals; 746 + 747 + /* Add Counts sysfs attributes */ 748 + err = counter_sysfs_counts_add(counter, cattr_group); 749 + if (err < 0) 750 + return err; 751 + cattr_group += counter->num_counts; 752 + 753 + /* Create name attribute */ 754 + err = counter_name_attr_create(dev, cattr_group, counter->name); 755 + if (err < 0) 756 + return err; 757 + 758 + /* Create num_signals attribute */ 759 + err = counter_attr_create(dev, cattr_group, &counter_num_signals_comp, 760 + scope, NULL); 761 + if (err < 0) 762 + return err; 763 + 764 + /* Create num_counts attribute */ 765 + err = counter_attr_create(dev, cattr_group, &counter_num_counts_comp, 766 + scope, NULL); 767 + if (err < 0) 768 + return err; 769 + 770 + /* Create an attribute for each extension */ 771 + for (i = 0; i < counter->num_ext; i++) { 772 + err = counter_attr_create(dev, cattr_group, counter->ext + i, 773 + scope, NULL); 774 + if (err < 0) 775 + return err; 776 + } 777 + 778 + return 0; 779 + } 780 + 781 + /** 782 + * counter_sysfs_add - Adds Counter sysfs attributes to the device structure 783 + * @counter: Pointer to the Counter device structure 784 + * 785 + * Counter sysfs attributes are created and added to the respective device 786 + * structure for later registration to the system. Resource-managed memory 787 + * allocation is performed by this function, and this memory should be freed 788 + * when no longer needed (automatically by a device_unregister call, or 789 + * manually by a devres_release_all call). 790 + */ 791 + int counter_sysfs_add(struct counter_device *const counter) 792 + { 793 + struct device *const dev = &counter->dev; 794 + const size_t num_groups = counter->num_signals + counter->num_counts + 1; 795 + struct counter_attribute_group *cattr_groups; 796 + size_t i, j; 797 + int err; 798 + struct attribute_group *groups; 799 + struct counter_attribute *p; 800 + 801 + /* Allocate space for attribute groups (signals, counts, and ext) */ 802 + cattr_groups = devm_kcalloc(dev, num_groups, sizeof(*cattr_groups), 803 + GFP_KERNEL); 804 + if (!cattr_groups) 805 + return -ENOMEM; 806 + 807 + /* Initialize attribute lists */ 808 + for (i = 0; i < num_groups; i++) 809 + INIT_LIST_HEAD(&cattr_groups[i].attr_list); 810 + 811 + /* Add Counter device sysfs attributes */ 812 + err = counter_sysfs_attr_add(counter, cattr_groups); 813 + if (err < 0) 814 + return err; 815 + 816 + /* Allocate attribute group pointers for association with device */ 817 + dev->groups = devm_kcalloc(dev, num_groups + 1, sizeof(*dev->groups), 818 + GFP_KERNEL); 819 + if (!dev->groups) 820 + return -ENOMEM; 821 + 822 + /* Allocate space for attribute groups */ 823 + groups = devm_kcalloc(dev, num_groups, sizeof(*groups), GFP_KERNEL); 824 + if (!groups) 825 + return -ENOMEM; 826 + 827 + /* Prepare each group of attributes for association */ 828 + for (i = 0; i < num_groups; i++) { 829 + groups[i].name = cattr_groups[i].name; 830 + 831 + /* Allocate space for attribute pointers */ 832 + groups[i].attrs = devm_kcalloc(dev, 833 + cattr_groups[i].num_attr + 1, 834 + sizeof(*groups[i].attrs), 835 + GFP_KERNEL); 836 + if (!groups[i].attrs) 837 + return -ENOMEM; 838 + 839 + /* Add attribute pointers to attribute group */ 840 + j = 0; 841 + list_for_each_entry(p, &cattr_groups[i].attr_list, l) 842 + groups[i].attrs[j++] = &p->dev_attr.attr; 843 + 844 + /* Associate attribute group */ 845 + dev->groups[i] = &groups[i]; 846 + } 847 + 848 + return 0; 849 + }
+13
drivers/counter/counter-sysfs.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Counter sysfs interface 4 + * Copyright (C) 2020 William Breathitt Gray 5 + */ 6 + #ifndef _COUNTER_SYSFS_H_ 7 + #define _COUNTER_SYSFS_H_ 8 + 9 + #include <linux/counter.h> 10 + 11 + int counter_sysfs_add(struct counter_device *const counter); 12 + 13 + #endif /* _COUNTER_SYSFS_H_ */
-1496
drivers/counter/counter.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * Generic Counter interface 4 - * Copyright (C) 2018 William Breathitt Gray 5 - */ 6 - #include <linux/counter.h> 7 - #include <linux/device.h> 8 - #include <linux/err.h> 9 - #include <linux/export.h> 10 - #include <linux/fs.h> 11 - #include <linux/gfp.h> 12 - #include <linux/idr.h> 13 - #include <linux/init.h> 14 - #include <linux/kernel.h> 15 - #include <linux/list.h> 16 - #include <linux/module.h> 17 - #include <linux/printk.h> 18 - #include <linux/slab.h> 19 - #include <linux/string.h> 20 - #include <linux/sysfs.h> 21 - #include <linux/types.h> 22 - 23 - const char *const counter_count_direction_str[2] = { 24 - [COUNTER_COUNT_DIRECTION_FORWARD] = "forward", 25 - [COUNTER_COUNT_DIRECTION_BACKWARD] = "backward" 26 - }; 27 - EXPORT_SYMBOL_GPL(counter_count_direction_str); 28 - 29 - const char *const counter_count_mode_str[4] = { 30 - [COUNTER_COUNT_MODE_NORMAL] = "normal", 31 - [COUNTER_COUNT_MODE_RANGE_LIMIT] = "range limit", 32 - [COUNTER_COUNT_MODE_NON_RECYCLE] = "non-recycle", 33 - [COUNTER_COUNT_MODE_MODULO_N] = "modulo-n" 34 - }; 35 - EXPORT_SYMBOL_GPL(counter_count_mode_str); 36 - 37 - ssize_t counter_signal_enum_read(struct counter_device *counter, 38 - struct counter_signal *signal, void *priv, 39 - char *buf) 40 - { 41 - const struct counter_signal_enum_ext *const e = priv; 42 - int err; 43 - size_t index; 44 - 45 - if (!e->get) 46 - return -EINVAL; 47 - 48 - err = e->get(counter, signal, &index); 49 - if (err) 50 - return err; 51 - 52 - if (index >= e->num_items) 53 - return -EINVAL; 54 - 55 - return sprintf(buf, "%s\n", e->items[index]); 56 - } 57 - EXPORT_SYMBOL_GPL(counter_signal_enum_read); 58 - 59 - ssize_t counter_signal_enum_write(struct counter_device *counter, 60 - struct counter_signal *signal, void *priv, 61 - const char *buf, size_t len) 62 - { 63 - const struct counter_signal_enum_ext *const e = priv; 64 - ssize_t index; 65 - int err; 66 - 67 - if (!e->set) 68 - return -EINVAL; 69 - 70 - index = __sysfs_match_string(e->items, e->num_items, buf); 71 - if (index < 0) 72 - return index; 73 - 74 - err = e->set(counter, signal, index); 75 - if (err) 76 - return err; 77 - 78 - return len; 79 - } 80 - EXPORT_SYMBOL_GPL(counter_signal_enum_write); 81 - 82 - ssize_t counter_signal_enum_available_read(struct counter_device *counter, 83 - struct counter_signal *signal, 84 - void *priv, char *buf) 85 - { 86 - const struct counter_signal_enum_ext *const e = priv; 87 - size_t i; 88 - size_t len = 0; 89 - 90 - if (!e->num_items) 91 - return 0; 92 - 93 - for (i = 0; i < e->num_items; i++) 94 - len += sprintf(buf + len, "%s\n", e->items[i]); 95 - 96 - return len; 97 - } 98 - EXPORT_SYMBOL_GPL(counter_signal_enum_available_read); 99 - 100 - ssize_t counter_count_enum_read(struct counter_device *counter, 101 - struct counter_count *count, void *priv, 102 - char *buf) 103 - { 104 - const struct counter_count_enum_ext *const e = priv; 105 - int err; 106 - size_t index; 107 - 108 - if (!e->get) 109 - return -EINVAL; 110 - 111 - err = e->get(counter, count, &index); 112 - if (err) 113 - return err; 114 - 115 - if (index >= e->num_items) 116 - return -EINVAL; 117 - 118 - return sprintf(buf, "%s\n", e->items[index]); 119 - } 120 - EXPORT_SYMBOL_GPL(counter_count_enum_read); 121 - 122 - ssize_t counter_count_enum_write(struct counter_device *counter, 123 - struct counter_count *count, void *priv, 124 - const char *buf, size_t len) 125 - { 126 - const struct counter_count_enum_ext *const e = priv; 127 - ssize_t index; 128 - int err; 129 - 130 - if (!e->set) 131 - return -EINVAL; 132 - 133 - index = __sysfs_match_string(e->items, e->num_items, buf); 134 - if (index < 0) 135 - return index; 136 - 137 - err = e->set(counter, count, index); 138 - if (err) 139 - return err; 140 - 141 - return len; 142 - } 143 - EXPORT_SYMBOL_GPL(counter_count_enum_write); 144 - 145 - ssize_t counter_count_enum_available_read(struct counter_device *counter, 146 - struct counter_count *count, 147 - void *priv, char *buf) 148 - { 149 - const struct counter_count_enum_ext *const e = priv; 150 - size_t i; 151 - size_t len = 0; 152 - 153 - if (!e->num_items) 154 - return 0; 155 - 156 - for (i = 0; i < e->num_items; i++) 157 - len += sprintf(buf + len, "%s\n", e->items[i]); 158 - 159 - return len; 160 - } 161 - EXPORT_SYMBOL_GPL(counter_count_enum_available_read); 162 - 163 - ssize_t counter_device_enum_read(struct counter_device *counter, void *priv, 164 - char *buf) 165 - { 166 - const struct counter_device_enum_ext *const e = priv; 167 - int err; 168 - size_t index; 169 - 170 - if (!e->get) 171 - return -EINVAL; 172 - 173 - err = e->get(counter, &index); 174 - if (err) 175 - return err; 176 - 177 - if (index >= e->num_items) 178 - return -EINVAL; 179 - 180 - return sprintf(buf, "%s\n", e->items[index]); 181 - } 182 - EXPORT_SYMBOL_GPL(counter_device_enum_read); 183 - 184 - ssize_t counter_device_enum_write(struct counter_device *counter, void *priv, 185 - const char *buf, size_t len) 186 - { 187 - const struct counter_device_enum_ext *const e = priv; 188 - ssize_t index; 189 - int err; 190 - 191 - if (!e->set) 192 - return -EINVAL; 193 - 194 - index = __sysfs_match_string(e->items, e->num_items, buf); 195 - if (index < 0) 196 - return index; 197 - 198 - err = e->set(counter, index); 199 - if (err) 200 - return err; 201 - 202 - return len; 203 - } 204 - EXPORT_SYMBOL_GPL(counter_device_enum_write); 205 - 206 - ssize_t counter_device_enum_available_read(struct counter_device *counter, 207 - void *priv, char *buf) 208 - { 209 - const struct counter_device_enum_ext *const e = priv; 210 - size_t i; 211 - size_t len = 0; 212 - 213 - if (!e->num_items) 214 - return 0; 215 - 216 - for (i = 0; i < e->num_items; i++) 217 - len += sprintf(buf + len, "%s\n", e->items[i]); 218 - 219 - return len; 220 - } 221 - EXPORT_SYMBOL_GPL(counter_device_enum_available_read); 222 - 223 - struct counter_attr_parm { 224 - struct counter_device_attr_group *group; 225 - const char *prefix; 226 - const char *name; 227 - ssize_t (*show)(struct device *dev, struct device_attribute *attr, 228 - char *buf); 229 - ssize_t (*store)(struct device *dev, struct device_attribute *attr, 230 - const char *buf, size_t len); 231 - void *component; 232 - }; 233 - 234 - struct counter_device_attr { 235 - struct device_attribute dev_attr; 236 - struct list_head l; 237 - void *component; 238 - }; 239 - 240 - static int counter_attribute_create(const struct counter_attr_parm *const parm) 241 - { 242 - struct counter_device_attr *counter_attr; 243 - struct device_attribute *dev_attr; 244 - int err; 245 - struct list_head *const attr_list = &parm->group->attr_list; 246 - 247 - /* Allocate a Counter device attribute */ 248 - counter_attr = kzalloc(sizeof(*counter_attr), GFP_KERNEL); 249 - if (!counter_attr) 250 - return -ENOMEM; 251 - dev_attr = &counter_attr->dev_attr; 252 - 253 - sysfs_attr_init(&dev_attr->attr); 254 - 255 - /* Configure device attribute */ 256 - dev_attr->attr.name = kasprintf(GFP_KERNEL, "%s%s", parm->prefix, 257 - parm->name); 258 - if (!dev_attr->attr.name) { 259 - err = -ENOMEM; 260 - goto err_free_counter_attr; 261 - } 262 - if (parm->show) { 263 - dev_attr->attr.mode |= 0444; 264 - dev_attr->show = parm->show; 265 - } 266 - if (parm->store) { 267 - dev_attr->attr.mode |= 0200; 268 - dev_attr->store = parm->store; 269 - } 270 - 271 - /* Store associated Counter component with attribute */ 272 - counter_attr->component = parm->component; 273 - 274 - /* Keep track of the attribute for later cleanup */ 275 - list_add(&counter_attr->l, attr_list); 276 - parm->group->num_attr++; 277 - 278 - return 0; 279 - 280 - err_free_counter_attr: 281 - kfree(counter_attr); 282 - return err; 283 - } 284 - 285 - #define to_counter_attr(_dev_attr) \ 286 - container_of(_dev_attr, struct counter_device_attr, dev_attr) 287 - 288 - struct counter_signal_unit { 289 - struct counter_signal *signal; 290 - }; 291 - 292 - static const char *const counter_signal_level_str[] = { 293 - [COUNTER_SIGNAL_LEVEL_LOW] = "low", 294 - [COUNTER_SIGNAL_LEVEL_HIGH] = "high" 295 - }; 296 - 297 - static ssize_t counter_signal_show(struct device *dev, 298 - struct device_attribute *attr, char *buf) 299 - { 300 - struct counter_device *const counter = dev_get_drvdata(dev); 301 - const struct counter_device_attr *const devattr = to_counter_attr(attr); 302 - const struct counter_signal_unit *const component = devattr->component; 303 - struct counter_signal *const signal = component->signal; 304 - int err; 305 - enum counter_signal_level level; 306 - 307 - err = counter->ops->signal_read(counter, signal, &level); 308 - if (err) 309 - return err; 310 - 311 - return sprintf(buf, "%s\n", counter_signal_level_str[level]); 312 - } 313 - 314 - struct counter_name_unit { 315 - const char *name; 316 - }; 317 - 318 - static ssize_t counter_device_attr_name_show(struct device *dev, 319 - struct device_attribute *attr, 320 - char *buf) 321 - { 322 - const struct counter_name_unit *const comp = to_counter_attr(attr)->component; 323 - 324 - return sprintf(buf, "%s\n", comp->name); 325 - } 326 - 327 - static int counter_name_attribute_create( 328 - struct counter_device_attr_group *const group, 329 - const char *const name) 330 - { 331 - struct counter_name_unit *name_comp; 332 - struct counter_attr_parm parm; 333 - int err; 334 - 335 - /* Skip if no name */ 336 - if (!name) 337 - return 0; 338 - 339 - /* Allocate name attribute component */ 340 - name_comp = kmalloc(sizeof(*name_comp), GFP_KERNEL); 341 - if (!name_comp) 342 - return -ENOMEM; 343 - name_comp->name = name; 344 - 345 - /* Allocate Signal name attribute */ 346 - parm.group = group; 347 - parm.prefix = ""; 348 - parm.name = "name"; 349 - parm.show = counter_device_attr_name_show; 350 - parm.store = NULL; 351 - parm.component = name_comp; 352 - err = counter_attribute_create(&parm); 353 - if (err) 354 - goto err_free_name_comp; 355 - 356 - return 0; 357 - 358 - err_free_name_comp: 359 - kfree(name_comp); 360 - return err; 361 - } 362 - 363 - struct counter_signal_ext_unit { 364 - struct counter_signal *signal; 365 - const struct counter_signal_ext *ext; 366 - }; 367 - 368 - static ssize_t counter_signal_ext_show(struct device *dev, 369 - struct device_attribute *attr, char *buf) 370 - { 371 - const struct counter_device_attr *const devattr = to_counter_attr(attr); 372 - const struct counter_signal_ext_unit *const comp = devattr->component; 373 - const struct counter_signal_ext *const ext = comp->ext; 374 - 375 - return ext->read(dev_get_drvdata(dev), comp->signal, ext->priv, buf); 376 - } 377 - 378 - static ssize_t counter_signal_ext_store(struct device *dev, 379 - struct device_attribute *attr, 380 - const char *buf, size_t len) 381 - { 382 - const struct counter_device_attr *const devattr = to_counter_attr(attr); 383 - const struct counter_signal_ext_unit *const comp = devattr->component; 384 - const struct counter_signal_ext *const ext = comp->ext; 385 - 386 - return ext->write(dev_get_drvdata(dev), comp->signal, ext->priv, buf, 387 - len); 388 - } 389 - 390 - static void counter_device_attr_list_free(struct list_head *attr_list) 391 - { 392 - struct counter_device_attr *p, *n; 393 - 394 - list_for_each_entry_safe(p, n, attr_list, l) { 395 - /* free attribute name and associated component memory */ 396 - kfree(p->dev_attr.attr.name); 397 - kfree(p->component); 398 - list_del(&p->l); 399 - kfree(p); 400 - } 401 - } 402 - 403 - static int counter_signal_ext_register( 404 - struct counter_device_attr_group *const group, 405 - struct counter_signal *const signal) 406 - { 407 - const size_t num_ext = signal->num_ext; 408 - size_t i; 409 - const struct counter_signal_ext *ext; 410 - struct counter_signal_ext_unit *signal_ext_comp; 411 - struct counter_attr_parm parm; 412 - int err; 413 - 414 - /* Create an attribute for each extension */ 415 - for (i = 0 ; i < num_ext; i++) { 416 - ext = signal->ext + i; 417 - 418 - /* Allocate signal_ext attribute component */ 419 - signal_ext_comp = kmalloc(sizeof(*signal_ext_comp), GFP_KERNEL); 420 - if (!signal_ext_comp) { 421 - err = -ENOMEM; 422 - goto err_free_attr_list; 423 - } 424 - signal_ext_comp->signal = signal; 425 - signal_ext_comp->ext = ext; 426 - 427 - /* Allocate a Counter device attribute */ 428 - parm.group = group; 429 - parm.prefix = ""; 430 - parm.name = ext->name; 431 - parm.show = (ext->read) ? counter_signal_ext_show : NULL; 432 - parm.store = (ext->write) ? counter_signal_ext_store : NULL; 433 - parm.component = signal_ext_comp; 434 - err = counter_attribute_create(&parm); 435 - if (err) { 436 - kfree(signal_ext_comp); 437 - goto err_free_attr_list; 438 - } 439 - } 440 - 441 - return 0; 442 - 443 - err_free_attr_list: 444 - counter_device_attr_list_free(&group->attr_list); 445 - return err; 446 - } 447 - 448 - static int counter_signal_attributes_create( 449 - struct counter_device_attr_group *const group, 450 - const struct counter_device *const counter, 451 - struct counter_signal *const signal) 452 - { 453 - struct counter_signal_unit *signal_comp; 454 - struct counter_attr_parm parm; 455 - int err; 456 - 457 - /* Allocate Signal attribute component */ 458 - signal_comp = kmalloc(sizeof(*signal_comp), GFP_KERNEL); 459 - if (!signal_comp) 460 - return -ENOMEM; 461 - signal_comp->signal = signal; 462 - 463 - /* Create main Signal attribute */ 464 - parm.group = group; 465 - parm.prefix = ""; 466 - parm.name = "signal"; 467 - parm.show = (counter->ops->signal_read) ? counter_signal_show : NULL; 468 - parm.store = NULL; 469 - parm.component = signal_comp; 470 - err = counter_attribute_create(&parm); 471 - if (err) { 472 - kfree(signal_comp); 473 - return err; 474 - } 475 - 476 - /* Create Signal name attribute */ 477 - err = counter_name_attribute_create(group, signal->name); 478 - if (err) 479 - goto err_free_attr_list; 480 - 481 - /* Register Signal extension attributes */ 482 - err = counter_signal_ext_register(group, signal); 483 - if (err) 484 - goto err_free_attr_list; 485 - 486 - return 0; 487 - 488 - err_free_attr_list: 489 - counter_device_attr_list_free(&group->attr_list); 490 - return err; 491 - } 492 - 493 - static int counter_signals_register( 494 - struct counter_device_attr_group *const groups_list, 495 - const struct counter_device *const counter) 496 - { 497 - const size_t num_signals = counter->num_signals; 498 - size_t i; 499 - struct counter_signal *signal; 500 - const char *name; 501 - int err; 502 - 503 - /* Register each Signal */ 504 - for (i = 0; i < num_signals; i++) { 505 - signal = counter->signals + i; 506 - 507 - /* Generate Signal attribute directory name */ 508 - name = kasprintf(GFP_KERNEL, "signal%d", signal->id); 509 - if (!name) { 510 - err = -ENOMEM; 511 - goto err_free_attr_groups; 512 - } 513 - groups_list[i].attr_group.name = name; 514 - 515 - /* Create all attributes associated with Signal */ 516 - err = counter_signal_attributes_create(groups_list + i, counter, 517 - signal); 518 - if (err) 519 - goto err_free_attr_groups; 520 - } 521 - 522 - return 0; 523 - 524 - err_free_attr_groups: 525 - do { 526 - kfree(groups_list[i].attr_group.name); 527 - counter_device_attr_list_free(&groups_list[i].attr_list); 528 - } while (i--); 529 - return err; 530 - } 531 - 532 - static const char *const counter_synapse_action_str[] = { 533 - [COUNTER_SYNAPSE_ACTION_NONE] = "none", 534 - [COUNTER_SYNAPSE_ACTION_RISING_EDGE] = "rising edge", 535 - [COUNTER_SYNAPSE_ACTION_FALLING_EDGE] = "falling edge", 536 - [COUNTER_SYNAPSE_ACTION_BOTH_EDGES] = "both edges" 537 - }; 538 - 539 - struct counter_action_unit { 540 - struct counter_synapse *synapse; 541 - struct counter_count *count; 542 - }; 543 - 544 - static ssize_t counter_action_show(struct device *dev, 545 - struct device_attribute *attr, char *buf) 546 - { 547 - const struct counter_device_attr *const devattr = to_counter_attr(attr); 548 - int err; 549 - struct counter_device *const counter = dev_get_drvdata(dev); 550 - const struct counter_action_unit *const component = devattr->component; 551 - struct counter_count *const count = component->count; 552 - struct counter_synapse *const synapse = component->synapse; 553 - size_t action_index; 554 - enum counter_synapse_action action; 555 - 556 - err = counter->ops->action_get(counter, count, synapse, &action_index); 557 - if (err) 558 - return err; 559 - 560 - synapse->action = action_index; 561 - 562 - action = synapse->actions_list[action_index]; 563 - return sprintf(buf, "%s\n", counter_synapse_action_str[action]); 564 - } 565 - 566 - static ssize_t counter_action_store(struct device *dev, 567 - struct device_attribute *attr, 568 - const char *buf, size_t len) 569 - { 570 - const struct counter_device_attr *const devattr = to_counter_attr(attr); 571 - const struct counter_action_unit *const component = devattr->component; 572 - struct counter_synapse *const synapse = component->synapse; 573 - size_t action_index; 574 - const size_t num_actions = synapse->num_actions; 575 - enum counter_synapse_action action; 576 - int err; 577 - struct counter_device *const counter = dev_get_drvdata(dev); 578 - struct counter_count *const count = component->count; 579 - 580 - /* Find requested action mode */ 581 - for (action_index = 0; action_index < num_actions; action_index++) { 582 - action = synapse->actions_list[action_index]; 583 - if (sysfs_streq(buf, counter_synapse_action_str[action])) 584 - break; 585 - } 586 - /* If requested action mode not found */ 587 - if (action_index >= num_actions) 588 - return -EINVAL; 589 - 590 - err = counter->ops->action_set(counter, count, synapse, action_index); 591 - if (err) 592 - return err; 593 - 594 - synapse->action = action_index; 595 - 596 - return len; 597 - } 598 - 599 - struct counter_action_avail_unit { 600 - const enum counter_synapse_action *actions_list; 601 - size_t num_actions; 602 - }; 603 - 604 - static ssize_t counter_synapse_action_available_show(struct device *dev, 605 - struct device_attribute *attr, char *buf) 606 - { 607 - const struct counter_device_attr *const devattr = to_counter_attr(attr); 608 - const struct counter_action_avail_unit *const component = devattr->component; 609 - size_t i; 610 - enum counter_synapse_action action; 611 - ssize_t len = 0; 612 - 613 - for (i = 0; i < component->num_actions; i++) { 614 - action = component->actions_list[i]; 615 - len += sprintf(buf + len, "%s\n", 616 - counter_synapse_action_str[action]); 617 - } 618 - 619 - return len; 620 - } 621 - 622 - static int counter_synapses_register( 623 - struct counter_device_attr_group *const group, 624 - const struct counter_device *const counter, 625 - struct counter_count *const count, const char *const count_attr_name) 626 - { 627 - size_t i; 628 - struct counter_synapse *synapse; 629 - const char *prefix; 630 - struct counter_action_unit *action_comp; 631 - struct counter_attr_parm parm; 632 - int err; 633 - struct counter_action_avail_unit *avail_comp; 634 - 635 - /* Register each Synapse */ 636 - for (i = 0; i < count->num_synapses; i++) { 637 - synapse = count->synapses + i; 638 - 639 - /* Generate attribute prefix */ 640 - prefix = kasprintf(GFP_KERNEL, "signal%d_", 641 - synapse->signal->id); 642 - if (!prefix) { 643 - err = -ENOMEM; 644 - goto err_free_attr_list; 645 - } 646 - 647 - /* Allocate action attribute component */ 648 - action_comp = kmalloc(sizeof(*action_comp), GFP_KERNEL); 649 - if (!action_comp) { 650 - err = -ENOMEM; 651 - goto err_free_prefix; 652 - } 653 - action_comp->synapse = synapse; 654 - action_comp->count = count; 655 - 656 - /* Create action attribute */ 657 - parm.group = group; 658 - parm.prefix = prefix; 659 - parm.name = "action"; 660 - parm.show = (counter->ops->action_get) ? counter_action_show : NULL; 661 - parm.store = (counter->ops->action_set) ? counter_action_store : NULL; 662 - parm.component = action_comp; 663 - err = counter_attribute_create(&parm); 664 - if (err) { 665 - kfree(action_comp); 666 - goto err_free_prefix; 667 - } 668 - 669 - /* Allocate action available attribute component */ 670 - avail_comp = kmalloc(sizeof(*avail_comp), GFP_KERNEL); 671 - if (!avail_comp) { 672 - err = -ENOMEM; 673 - goto err_free_prefix; 674 - } 675 - avail_comp->actions_list = synapse->actions_list; 676 - avail_comp->num_actions = synapse->num_actions; 677 - 678 - /* Create action_available attribute */ 679 - parm.group = group; 680 - parm.prefix = prefix; 681 - parm.name = "action_available"; 682 - parm.show = counter_synapse_action_available_show; 683 - parm.store = NULL; 684 - parm.component = avail_comp; 685 - err = counter_attribute_create(&parm); 686 - if (err) { 687 - kfree(avail_comp); 688 - goto err_free_prefix; 689 - } 690 - 691 - kfree(prefix); 692 - } 693 - 694 - return 0; 695 - 696 - err_free_prefix: 697 - kfree(prefix); 698 - err_free_attr_list: 699 - counter_device_attr_list_free(&group->attr_list); 700 - return err; 701 - } 702 - 703 - struct counter_count_unit { 704 - struct counter_count *count; 705 - }; 706 - 707 - static ssize_t counter_count_show(struct device *dev, 708 - struct device_attribute *attr, 709 - char *buf) 710 - { 711 - struct counter_device *const counter = dev_get_drvdata(dev); 712 - const struct counter_device_attr *const devattr = to_counter_attr(attr); 713 - const struct counter_count_unit *const component = devattr->component; 714 - struct counter_count *const count = component->count; 715 - int err; 716 - unsigned long val; 717 - 718 - err = counter->ops->count_read(counter, count, &val); 719 - if (err) 720 - return err; 721 - 722 - return sprintf(buf, "%lu\n", val); 723 - } 724 - 725 - static ssize_t counter_count_store(struct device *dev, 726 - struct device_attribute *attr, 727 - const char *buf, size_t len) 728 - { 729 - struct counter_device *const counter = dev_get_drvdata(dev); 730 - const struct counter_device_attr *const devattr = to_counter_attr(attr); 731 - const struct counter_count_unit *const component = devattr->component; 732 - struct counter_count *const count = component->count; 733 - int err; 734 - unsigned long val; 735 - 736 - err = kstrtoul(buf, 0, &val); 737 - if (err) 738 - return err; 739 - 740 - err = counter->ops->count_write(counter, count, val); 741 - if (err) 742 - return err; 743 - 744 - return len; 745 - } 746 - 747 - static const char *const counter_function_str[] = { 748 - [COUNTER_FUNCTION_INCREASE] = "increase", 749 - [COUNTER_FUNCTION_DECREASE] = "decrease", 750 - [COUNTER_FUNCTION_PULSE_DIRECTION] = "pulse-direction", 751 - [COUNTER_FUNCTION_QUADRATURE_X1_A] = "quadrature x1 a", 752 - [COUNTER_FUNCTION_QUADRATURE_X1_B] = "quadrature x1 b", 753 - [COUNTER_FUNCTION_QUADRATURE_X2_A] = "quadrature x2 a", 754 - [COUNTER_FUNCTION_QUADRATURE_X2_B] = "quadrature x2 b", 755 - [COUNTER_FUNCTION_QUADRATURE_X4] = "quadrature x4" 756 - }; 757 - 758 - static ssize_t counter_function_show(struct device *dev, 759 - struct device_attribute *attr, char *buf) 760 - { 761 - int err; 762 - struct counter_device *const counter = dev_get_drvdata(dev); 763 - const struct counter_device_attr *const devattr = to_counter_attr(attr); 764 - const struct counter_count_unit *const component = devattr->component; 765 - struct counter_count *const count = component->count; 766 - size_t func_index; 767 - enum counter_function function; 768 - 769 - err = counter->ops->function_get(counter, count, &func_index); 770 - if (err) 771 - return err; 772 - 773 - count->function = func_index; 774 - 775 - function = count->functions_list[func_index]; 776 - return sprintf(buf, "%s\n", counter_function_str[function]); 777 - } 778 - 779 - static ssize_t counter_function_store(struct device *dev, 780 - struct device_attribute *attr, 781 - const char *buf, size_t len) 782 - { 783 - const struct counter_device_attr *const devattr = to_counter_attr(attr); 784 - const struct counter_count_unit *const component = devattr->component; 785 - struct counter_count *const count = component->count; 786 - const size_t num_functions = count->num_functions; 787 - size_t func_index; 788 - enum counter_function function; 789 - int err; 790 - struct counter_device *const counter = dev_get_drvdata(dev); 791 - 792 - /* Find requested Count function mode */ 793 - for (func_index = 0; func_index < num_functions; func_index++) { 794 - function = count->functions_list[func_index]; 795 - if (sysfs_streq(buf, counter_function_str[function])) 796 - break; 797 - } 798 - /* Return error if requested Count function mode not found */ 799 - if (func_index >= num_functions) 800 - return -EINVAL; 801 - 802 - err = counter->ops->function_set(counter, count, func_index); 803 - if (err) 804 - return err; 805 - 806 - count->function = func_index; 807 - 808 - return len; 809 - } 810 - 811 - struct counter_count_ext_unit { 812 - struct counter_count *count; 813 - const struct counter_count_ext *ext; 814 - }; 815 - 816 - static ssize_t counter_count_ext_show(struct device *dev, 817 - struct device_attribute *attr, char *buf) 818 - { 819 - const struct counter_device_attr *const devattr = to_counter_attr(attr); 820 - const struct counter_count_ext_unit *const comp = devattr->component; 821 - const struct counter_count_ext *const ext = comp->ext; 822 - 823 - return ext->read(dev_get_drvdata(dev), comp->count, ext->priv, buf); 824 - } 825 - 826 - static ssize_t counter_count_ext_store(struct device *dev, 827 - struct device_attribute *attr, 828 - const char *buf, size_t len) 829 - { 830 - const struct counter_device_attr *const devattr = to_counter_attr(attr); 831 - const struct counter_count_ext_unit *const comp = devattr->component; 832 - const struct counter_count_ext *const ext = comp->ext; 833 - 834 - return ext->write(dev_get_drvdata(dev), comp->count, ext->priv, buf, 835 - len); 836 - } 837 - 838 - static int counter_count_ext_register( 839 - struct counter_device_attr_group *const group, 840 - struct counter_count *const count) 841 - { 842 - size_t i; 843 - const struct counter_count_ext *ext; 844 - struct counter_count_ext_unit *count_ext_comp; 845 - struct counter_attr_parm parm; 846 - int err; 847 - 848 - /* Create an attribute for each extension */ 849 - for (i = 0 ; i < count->num_ext; i++) { 850 - ext = count->ext + i; 851 - 852 - /* Allocate count_ext attribute component */ 853 - count_ext_comp = kmalloc(sizeof(*count_ext_comp), GFP_KERNEL); 854 - if (!count_ext_comp) { 855 - err = -ENOMEM; 856 - goto err_free_attr_list; 857 - } 858 - count_ext_comp->count = count; 859 - count_ext_comp->ext = ext; 860 - 861 - /* Allocate count_ext attribute */ 862 - parm.group = group; 863 - parm.prefix = ""; 864 - parm.name = ext->name; 865 - parm.show = (ext->read) ? counter_count_ext_show : NULL; 866 - parm.store = (ext->write) ? counter_count_ext_store : NULL; 867 - parm.component = count_ext_comp; 868 - err = counter_attribute_create(&parm); 869 - if (err) { 870 - kfree(count_ext_comp); 871 - goto err_free_attr_list; 872 - } 873 - } 874 - 875 - return 0; 876 - 877 - err_free_attr_list: 878 - counter_device_attr_list_free(&group->attr_list); 879 - return err; 880 - } 881 - 882 - struct counter_func_avail_unit { 883 - const enum counter_function *functions_list; 884 - size_t num_functions; 885 - }; 886 - 887 - static ssize_t counter_function_available_show(struct device *dev, 888 - struct device_attribute *attr, char *buf) 889 - { 890 - const struct counter_device_attr *const devattr = to_counter_attr(attr); 891 - const struct counter_func_avail_unit *const component = devattr->component; 892 - const enum counter_function *const func_list = component->functions_list; 893 - const size_t num_functions = component->num_functions; 894 - size_t i; 895 - enum counter_function function; 896 - ssize_t len = 0; 897 - 898 - for (i = 0; i < num_functions; i++) { 899 - function = func_list[i]; 900 - len += sprintf(buf + len, "%s\n", 901 - counter_function_str[function]); 902 - } 903 - 904 - return len; 905 - } 906 - 907 - static int counter_count_attributes_create( 908 - struct counter_device_attr_group *const group, 909 - const struct counter_device *const counter, 910 - struct counter_count *const count) 911 - { 912 - struct counter_count_unit *count_comp; 913 - struct counter_attr_parm parm; 914 - int err; 915 - struct counter_count_unit *func_comp; 916 - struct counter_func_avail_unit *avail_comp; 917 - 918 - /* Allocate count attribute component */ 919 - count_comp = kmalloc(sizeof(*count_comp), GFP_KERNEL); 920 - if (!count_comp) 921 - return -ENOMEM; 922 - count_comp->count = count; 923 - 924 - /* Create main Count attribute */ 925 - parm.group = group; 926 - parm.prefix = ""; 927 - parm.name = "count"; 928 - parm.show = (counter->ops->count_read) ? counter_count_show : NULL; 929 - parm.store = (counter->ops->count_write) ? counter_count_store : NULL; 930 - parm.component = count_comp; 931 - err = counter_attribute_create(&parm); 932 - if (err) { 933 - kfree(count_comp); 934 - return err; 935 - } 936 - 937 - /* Allocate function attribute component */ 938 - func_comp = kmalloc(sizeof(*func_comp), GFP_KERNEL); 939 - if (!func_comp) { 940 - err = -ENOMEM; 941 - goto err_free_attr_list; 942 - } 943 - func_comp->count = count; 944 - 945 - /* Create Count function attribute */ 946 - parm.group = group; 947 - parm.prefix = ""; 948 - parm.name = "function"; 949 - parm.show = (counter->ops->function_get) ? counter_function_show : NULL; 950 - parm.store = (counter->ops->function_set) ? counter_function_store : NULL; 951 - parm.component = func_comp; 952 - err = counter_attribute_create(&parm); 953 - if (err) { 954 - kfree(func_comp); 955 - goto err_free_attr_list; 956 - } 957 - 958 - /* Allocate function available attribute component */ 959 - avail_comp = kmalloc(sizeof(*avail_comp), GFP_KERNEL); 960 - if (!avail_comp) { 961 - err = -ENOMEM; 962 - goto err_free_attr_list; 963 - } 964 - avail_comp->functions_list = count->functions_list; 965 - avail_comp->num_functions = count->num_functions; 966 - 967 - /* Create Count function_available attribute */ 968 - parm.group = group; 969 - parm.prefix = ""; 970 - parm.name = "function_available"; 971 - parm.show = counter_function_available_show; 972 - parm.store = NULL; 973 - parm.component = avail_comp; 974 - err = counter_attribute_create(&parm); 975 - if (err) { 976 - kfree(avail_comp); 977 - goto err_free_attr_list; 978 - } 979 - 980 - /* Create Count name attribute */ 981 - err = counter_name_attribute_create(group, count->name); 982 - if (err) 983 - goto err_free_attr_list; 984 - 985 - /* Register Count extension attributes */ 986 - err = counter_count_ext_register(group, count); 987 - if (err) 988 - goto err_free_attr_list; 989 - 990 - return 0; 991 - 992 - err_free_attr_list: 993 - counter_device_attr_list_free(&group->attr_list); 994 - return err; 995 - } 996 - 997 - static int counter_counts_register( 998 - struct counter_device_attr_group *const groups_list, 999 - const struct counter_device *const counter) 1000 - { 1001 - size_t i; 1002 - struct counter_count *count; 1003 - const char *name; 1004 - int err; 1005 - 1006 - /* Register each Count */ 1007 - for (i = 0; i < counter->num_counts; i++) { 1008 - count = counter->counts + i; 1009 - 1010 - /* Generate Count attribute directory name */ 1011 - name = kasprintf(GFP_KERNEL, "count%d", count->id); 1012 - if (!name) { 1013 - err = -ENOMEM; 1014 - goto err_free_attr_groups; 1015 - } 1016 - groups_list[i].attr_group.name = name; 1017 - 1018 - /* Register the Synapses associated with each Count */ 1019 - err = counter_synapses_register(groups_list + i, counter, count, 1020 - name); 1021 - if (err) 1022 - goto err_free_attr_groups; 1023 - 1024 - /* Create all attributes associated with Count */ 1025 - err = counter_count_attributes_create(groups_list + i, counter, 1026 - count); 1027 - if (err) 1028 - goto err_free_attr_groups; 1029 - } 1030 - 1031 - return 0; 1032 - 1033 - err_free_attr_groups: 1034 - do { 1035 - kfree(groups_list[i].attr_group.name); 1036 - counter_device_attr_list_free(&groups_list[i].attr_list); 1037 - } while (i--); 1038 - return err; 1039 - } 1040 - 1041 - struct counter_size_unit { 1042 - size_t size; 1043 - }; 1044 - 1045 - static ssize_t counter_device_attr_size_show(struct device *dev, 1046 - struct device_attribute *attr, 1047 - char *buf) 1048 - { 1049 - const struct counter_size_unit *const comp = to_counter_attr(attr)->component; 1050 - 1051 - return sprintf(buf, "%zu\n", comp->size); 1052 - } 1053 - 1054 - static int counter_size_attribute_create( 1055 - struct counter_device_attr_group *const group, 1056 - const size_t size, const char *const name) 1057 - { 1058 - struct counter_size_unit *size_comp; 1059 - struct counter_attr_parm parm; 1060 - int err; 1061 - 1062 - /* Allocate size attribute component */ 1063 - size_comp = kmalloc(sizeof(*size_comp), GFP_KERNEL); 1064 - if (!size_comp) 1065 - return -ENOMEM; 1066 - size_comp->size = size; 1067 - 1068 - parm.group = group; 1069 - parm.prefix = ""; 1070 - parm.name = name; 1071 - parm.show = counter_device_attr_size_show; 1072 - parm.store = NULL; 1073 - parm.component = size_comp; 1074 - err = counter_attribute_create(&parm); 1075 - if (err) 1076 - goto err_free_size_comp; 1077 - 1078 - return 0; 1079 - 1080 - err_free_size_comp: 1081 - kfree(size_comp); 1082 - return err; 1083 - } 1084 - 1085 - struct counter_ext_unit { 1086 - const struct counter_device_ext *ext; 1087 - }; 1088 - 1089 - static ssize_t counter_device_ext_show(struct device *dev, 1090 - struct device_attribute *attr, char *buf) 1091 - { 1092 - const struct counter_device_attr *const devattr = to_counter_attr(attr); 1093 - const struct counter_ext_unit *const component = devattr->component; 1094 - const struct counter_device_ext *const ext = component->ext; 1095 - 1096 - return ext->read(dev_get_drvdata(dev), ext->priv, buf); 1097 - } 1098 - 1099 - static ssize_t counter_device_ext_store(struct device *dev, 1100 - struct device_attribute *attr, 1101 - const char *buf, size_t len) 1102 - { 1103 - const struct counter_device_attr *const devattr = to_counter_attr(attr); 1104 - const struct counter_ext_unit *const component = devattr->component; 1105 - const struct counter_device_ext *const ext = component->ext; 1106 - 1107 - return ext->write(dev_get_drvdata(dev), ext->priv, buf, len); 1108 - } 1109 - 1110 - static int counter_device_ext_register( 1111 - struct counter_device_attr_group *const group, 1112 - struct counter_device *const counter) 1113 - { 1114 - size_t i; 1115 - struct counter_ext_unit *ext_comp; 1116 - struct counter_attr_parm parm; 1117 - int err; 1118 - 1119 - /* Create an attribute for each extension */ 1120 - for (i = 0 ; i < counter->num_ext; i++) { 1121 - /* Allocate extension attribute component */ 1122 - ext_comp = kmalloc(sizeof(*ext_comp), GFP_KERNEL); 1123 - if (!ext_comp) { 1124 - err = -ENOMEM; 1125 - goto err_free_attr_list; 1126 - } 1127 - 1128 - ext_comp->ext = counter->ext + i; 1129 - 1130 - /* Allocate extension attribute */ 1131 - parm.group = group; 1132 - parm.prefix = ""; 1133 - parm.name = counter->ext[i].name; 1134 - parm.show = (counter->ext[i].read) ? counter_device_ext_show : NULL; 1135 - parm.store = (counter->ext[i].write) ? counter_device_ext_store : NULL; 1136 - parm.component = ext_comp; 1137 - err = counter_attribute_create(&parm); 1138 - if (err) { 1139 - kfree(ext_comp); 1140 - goto err_free_attr_list; 1141 - } 1142 - } 1143 - 1144 - return 0; 1145 - 1146 - err_free_attr_list: 1147 - counter_device_attr_list_free(&group->attr_list); 1148 - return err; 1149 - } 1150 - 1151 - static int counter_global_attr_register( 1152 - struct counter_device_attr_group *const group, 1153 - struct counter_device *const counter) 1154 - { 1155 - int err; 1156 - 1157 - /* Create name attribute */ 1158 - err = counter_name_attribute_create(group, counter->name); 1159 - if (err) 1160 - return err; 1161 - 1162 - /* Create num_counts attribute */ 1163 - err = counter_size_attribute_create(group, counter->num_counts, 1164 - "num_counts"); 1165 - if (err) 1166 - goto err_free_attr_list; 1167 - 1168 - /* Create num_signals attribute */ 1169 - err = counter_size_attribute_create(group, counter->num_signals, 1170 - "num_signals"); 1171 - if (err) 1172 - goto err_free_attr_list; 1173 - 1174 - /* Register Counter device extension attributes */ 1175 - err = counter_device_ext_register(group, counter); 1176 - if (err) 1177 - goto err_free_attr_list; 1178 - 1179 - return 0; 1180 - 1181 - err_free_attr_list: 1182 - counter_device_attr_list_free(&group->attr_list); 1183 - return err; 1184 - } 1185 - 1186 - static void counter_device_groups_list_free( 1187 - struct counter_device_attr_group *const groups_list, 1188 - const size_t num_groups) 1189 - { 1190 - struct counter_device_attr_group *group; 1191 - size_t i; 1192 - 1193 - /* loop through all attribute groups (signals, counts, global, etc.) */ 1194 - for (i = 0; i < num_groups; i++) { 1195 - group = groups_list + i; 1196 - 1197 - /* free all attribute group and associated attributes memory */ 1198 - kfree(group->attr_group.name); 1199 - kfree(group->attr_group.attrs); 1200 - counter_device_attr_list_free(&group->attr_list); 1201 - } 1202 - 1203 - kfree(groups_list); 1204 - } 1205 - 1206 - static int counter_device_groups_list_prepare( 1207 - struct counter_device *const counter) 1208 - { 1209 - const size_t total_num_groups = 1210 - counter->num_signals + counter->num_counts + 1; 1211 - struct counter_device_attr_group *groups_list; 1212 - size_t i; 1213 - int err; 1214 - size_t num_groups = 0; 1215 - 1216 - /* Allocate space for attribute groups (signals, counts, and ext) */ 1217 - groups_list = kcalloc(total_num_groups, sizeof(*groups_list), 1218 - GFP_KERNEL); 1219 - if (!groups_list) 1220 - return -ENOMEM; 1221 - 1222 - /* Initialize attribute lists */ 1223 - for (i = 0; i < total_num_groups; i++) 1224 - INIT_LIST_HEAD(&groups_list[i].attr_list); 1225 - 1226 - /* Register Signals */ 1227 - err = counter_signals_register(groups_list, counter); 1228 - if (err) 1229 - goto err_free_groups_list; 1230 - num_groups += counter->num_signals; 1231 - 1232 - /* Register Counts and respective Synapses */ 1233 - err = counter_counts_register(groups_list + num_groups, counter); 1234 - if (err) 1235 - goto err_free_groups_list; 1236 - num_groups += counter->num_counts; 1237 - 1238 - /* Register Counter global attributes */ 1239 - err = counter_global_attr_register(groups_list + num_groups, counter); 1240 - if (err) 1241 - goto err_free_groups_list; 1242 - num_groups++; 1243 - 1244 - /* Store groups_list in device_state */ 1245 - counter->device_state->groups_list = groups_list; 1246 - counter->device_state->num_groups = num_groups; 1247 - 1248 - return 0; 1249 - 1250 - err_free_groups_list: 1251 - counter_device_groups_list_free(groups_list, num_groups); 1252 - return err; 1253 - } 1254 - 1255 - static int counter_device_groups_prepare( 1256 - struct counter_device_state *const device_state) 1257 - { 1258 - size_t i, j; 1259 - struct counter_device_attr_group *group; 1260 - int err; 1261 - struct counter_device_attr *p; 1262 - 1263 - /* Allocate attribute groups for association with device */ 1264 - device_state->groups = kcalloc(device_state->num_groups + 1, 1265 - sizeof(*device_state->groups), 1266 - GFP_KERNEL); 1267 - if (!device_state->groups) 1268 - return -ENOMEM; 1269 - 1270 - /* Prepare each group of attributes for association */ 1271 - for (i = 0; i < device_state->num_groups; i++) { 1272 - group = device_state->groups_list + i; 1273 - 1274 - /* Allocate space for attribute pointers in attribute group */ 1275 - group->attr_group.attrs = kcalloc(group->num_attr + 1, 1276 - sizeof(*group->attr_group.attrs), GFP_KERNEL); 1277 - if (!group->attr_group.attrs) { 1278 - err = -ENOMEM; 1279 - goto err_free_groups; 1280 - } 1281 - 1282 - /* Add attribute pointers to attribute group */ 1283 - j = 0; 1284 - list_for_each_entry(p, &group->attr_list, l) 1285 - group->attr_group.attrs[j++] = &p->dev_attr.attr; 1286 - 1287 - /* Group attributes in attribute group */ 1288 - device_state->groups[i] = &group->attr_group; 1289 - } 1290 - /* Associate attributes with device */ 1291 - device_state->dev.groups = device_state->groups; 1292 - 1293 - return 0; 1294 - 1295 - err_free_groups: 1296 - do { 1297 - group = device_state->groups_list + i; 1298 - kfree(group->attr_group.attrs); 1299 - group->attr_group.attrs = NULL; 1300 - } while (i--); 1301 - kfree(device_state->groups); 1302 - return err; 1303 - } 1304 - 1305 - /* Provides a unique ID for each counter device */ 1306 - static DEFINE_IDA(counter_ida); 1307 - 1308 - static void counter_device_release(struct device *dev) 1309 - { 1310 - struct counter_device *const counter = dev_get_drvdata(dev); 1311 - struct counter_device_state *const device_state = counter->device_state; 1312 - 1313 - kfree(device_state->groups); 1314 - counter_device_groups_list_free(device_state->groups_list, 1315 - device_state->num_groups); 1316 - ida_simple_remove(&counter_ida, device_state->id); 1317 - kfree(device_state); 1318 - } 1319 - 1320 - static struct device_type counter_device_type = { 1321 - .name = "counter_device", 1322 - .release = counter_device_release 1323 - }; 1324 - 1325 - static struct bus_type counter_bus_type = { 1326 - .name = "counter" 1327 - }; 1328 - 1329 - /** 1330 - * counter_register - register Counter to the system 1331 - * @counter: pointer to Counter to register 1332 - * 1333 - * This function registers a Counter to the system. A sysfs "counter" directory 1334 - * will be created and populated with sysfs attributes correlating with the 1335 - * Counter Signals, Synapses, and Counts respectively. 1336 - */ 1337 - int counter_register(struct counter_device *const counter) 1338 - { 1339 - struct counter_device_state *device_state; 1340 - int err; 1341 - 1342 - /* Allocate internal state container for Counter device */ 1343 - device_state = kzalloc(sizeof(*device_state), GFP_KERNEL); 1344 - if (!device_state) 1345 - return -ENOMEM; 1346 - counter->device_state = device_state; 1347 - 1348 - /* Acquire unique ID */ 1349 - device_state->id = ida_simple_get(&counter_ida, 0, 0, GFP_KERNEL); 1350 - if (device_state->id < 0) { 1351 - err = device_state->id; 1352 - goto err_free_device_state; 1353 - } 1354 - 1355 - /* Configure device structure for Counter */ 1356 - device_state->dev.type = &counter_device_type; 1357 - device_state->dev.bus = &counter_bus_type; 1358 - if (counter->parent) { 1359 - device_state->dev.parent = counter->parent; 1360 - device_state->dev.of_node = counter->parent->of_node; 1361 - } 1362 - dev_set_name(&device_state->dev, "counter%d", device_state->id); 1363 - device_initialize(&device_state->dev); 1364 - dev_set_drvdata(&device_state->dev, counter); 1365 - 1366 - /* Prepare device attributes */ 1367 - err = counter_device_groups_list_prepare(counter); 1368 - if (err) 1369 - goto err_free_id; 1370 - 1371 - /* Organize device attributes to groups and match to device */ 1372 - err = counter_device_groups_prepare(device_state); 1373 - if (err) 1374 - goto err_free_groups_list; 1375 - 1376 - /* Add device to system */ 1377 - err = device_add(&device_state->dev); 1378 - if (err) 1379 - goto err_free_groups; 1380 - 1381 - return 0; 1382 - 1383 - err_free_groups: 1384 - kfree(device_state->groups); 1385 - err_free_groups_list: 1386 - counter_device_groups_list_free(device_state->groups_list, 1387 - device_state->num_groups); 1388 - err_free_id: 1389 - ida_simple_remove(&counter_ida, device_state->id); 1390 - err_free_device_state: 1391 - kfree(device_state); 1392 - return err; 1393 - } 1394 - EXPORT_SYMBOL_GPL(counter_register); 1395 - 1396 - /** 1397 - * counter_unregister - unregister Counter from the system 1398 - * @counter: pointer to Counter to unregister 1399 - * 1400 - * The Counter is unregistered from the system; all allocated memory is freed. 1401 - */ 1402 - void counter_unregister(struct counter_device *const counter) 1403 - { 1404 - if (counter) 1405 - device_del(&counter->device_state->dev); 1406 - } 1407 - EXPORT_SYMBOL_GPL(counter_unregister); 1408 - 1409 - static void devm_counter_unreg(struct device *dev, void *res) 1410 - { 1411 - counter_unregister(*(struct counter_device **)res); 1412 - } 1413 - 1414 - /** 1415 - * devm_counter_register - Resource-managed counter_register 1416 - * @dev: device to allocate counter_device for 1417 - * @counter: pointer to Counter to register 1418 - * 1419 - * Managed counter_register. The Counter registered with this function is 1420 - * automatically unregistered on driver detach. This function calls 1421 - * counter_register internally. Refer to that function for more information. 1422 - * 1423 - * If an Counter registered with this function needs to be unregistered 1424 - * separately, devm_counter_unregister must be used. 1425 - * 1426 - * RETURNS: 1427 - * 0 on success, negative error number on failure. 1428 - */ 1429 - int devm_counter_register(struct device *dev, 1430 - struct counter_device *const counter) 1431 - { 1432 - struct counter_device **ptr; 1433 - int ret; 1434 - 1435 - ptr = devres_alloc(devm_counter_unreg, sizeof(*ptr), GFP_KERNEL); 1436 - if (!ptr) 1437 - return -ENOMEM; 1438 - 1439 - ret = counter_register(counter); 1440 - if (!ret) { 1441 - *ptr = counter; 1442 - devres_add(dev, ptr); 1443 - } else { 1444 - devres_free(ptr); 1445 - } 1446 - 1447 - return ret; 1448 - } 1449 - EXPORT_SYMBOL_GPL(devm_counter_register); 1450 - 1451 - static int devm_counter_match(struct device *dev, void *res, void *data) 1452 - { 1453 - struct counter_device **r = res; 1454 - 1455 - if (!r || !*r) { 1456 - WARN_ON(!r || !*r); 1457 - return 0; 1458 - } 1459 - 1460 - return *r == data; 1461 - } 1462 - 1463 - /** 1464 - * devm_counter_unregister - Resource-managed counter_unregister 1465 - * @dev: device this counter_device belongs to 1466 - * @counter: pointer to Counter associated with the device 1467 - * 1468 - * Unregister Counter registered with devm_counter_register. 1469 - */ 1470 - void devm_counter_unregister(struct device *dev, 1471 - struct counter_device *const counter) 1472 - { 1473 - int rc; 1474 - 1475 - rc = devres_release(dev, devm_counter_unreg, devm_counter_match, 1476 - counter); 1477 - WARN_ON(rc); 1478 - } 1479 - EXPORT_SYMBOL_GPL(devm_counter_unregister); 1480 - 1481 - static int __init counter_init(void) 1482 - { 1483 - return bus_register(&counter_bus_type); 1484 - } 1485 - 1486 - static void __exit counter_exit(void) 1487 - { 1488 - bus_unregister(&counter_bus_type); 1489 - } 1490 - 1491 - subsys_initcall(counter_init); 1492 - module_exit(counter_exit); 1493 - 1494 - MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); 1495 - MODULE_DESCRIPTION("Generic Counter interface"); 1496 - MODULE_LICENSE("GPL v2");
+23 -37
drivers/counter/ftm-quaddec.c
··· 14 14 #include <linux/mutex.h> 15 15 #include <linux/counter.h> 16 16 #include <linux/bitfield.h> 17 + #include <linux/types.h> 17 18 18 19 #define FTM_FIELD_UPDATE(ftm, offset, mask, val) \ 19 20 ({ \ ··· 116 115 } 117 116 118 117 static int ftm_quaddec_get_prescaler(struct counter_device *counter, 119 - struct counter_count *count, 120 - size_t *cnt_mode) 118 + struct counter_count *count, u32 *cnt_mode) 121 119 { 122 120 struct ftm_quaddec *ftm = counter->priv; 123 121 uint32_t scflags; ··· 129 129 } 130 130 131 131 static int ftm_quaddec_set_prescaler(struct counter_device *counter, 132 - struct counter_count *count, 133 - size_t cnt_mode) 132 + struct counter_count *count, u32 cnt_mode) 134 133 { 135 134 struct ftm_quaddec *ftm = counter->priv; 136 135 ··· 150 151 "1", "2", "4", "8", "16", "32", "64", "128" 151 152 }; 152 153 153 - static struct counter_count_enum_ext ftm_quaddec_prescaler_enum = { 154 - .items = ftm_quaddec_prescaler, 155 - .num_items = ARRAY_SIZE(ftm_quaddec_prescaler), 156 - .get = ftm_quaddec_get_prescaler, 157 - .set = ftm_quaddec_set_prescaler 158 - }; 159 - 160 - enum ftm_quaddec_synapse_action { 161 - FTM_QUADDEC_SYNAPSE_ACTION_BOTH_EDGES, 162 - }; 163 - 164 154 static const enum counter_synapse_action ftm_quaddec_synapse_actions[] = { 165 - [FTM_QUADDEC_SYNAPSE_ACTION_BOTH_EDGES] = 166 155 COUNTER_SYNAPSE_ACTION_BOTH_EDGES 167 156 }; 168 157 169 - enum ftm_quaddec_count_function { 170 - FTM_QUADDEC_COUNT_ENCODER_MODE_1, 171 - }; 172 - 173 158 static const enum counter_function ftm_quaddec_count_functions[] = { 174 - [FTM_QUADDEC_COUNT_ENCODER_MODE_1] = COUNTER_FUNCTION_QUADRATURE_X4 159 + COUNTER_FUNCTION_QUADRATURE_X4 175 160 }; 176 161 177 162 static int ftm_quaddec_count_read(struct counter_device *counter, 178 163 struct counter_count *count, 179 - unsigned long *val) 164 + u64 *val) 180 165 { 181 166 struct ftm_quaddec *const ftm = counter->priv; 182 167 uint32_t cntval; ··· 174 191 175 192 static int ftm_quaddec_count_write(struct counter_device *counter, 176 193 struct counter_count *count, 177 - const unsigned long val) 194 + const u64 val) 178 195 { 179 196 struct ftm_quaddec *const ftm = counter->priv; 180 197 ··· 188 205 return 0; 189 206 } 190 207 191 - static int ftm_quaddec_count_function_get(struct counter_device *counter, 192 - struct counter_count *count, 193 - size_t *function) 208 + static int ftm_quaddec_count_function_read(struct counter_device *counter, 209 + struct counter_count *count, 210 + enum counter_function *function) 194 211 { 195 - *function = FTM_QUADDEC_COUNT_ENCODER_MODE_1; 212 + *function = COUNTER_FUNCTION_QUADRATURE_X4; 196 213 197 214 return 0; 198 215 } 199 216 200 - static int ftm_quaddec_action_get(struct counter_device *counter, 201 - struct counter_count *count, 202 - struct counter_synapse *synapse, 203 - size_t *action) 217 + static int ftm_quaddec_action_read(struct counter_device *counter, 218 + struct counter_count *count, 219 + struct counter_synapse *synapse, 220 + enum counter_synapse_action *action) 204 221 { 205 - *action = FTM_QUADDEC_SYNAPSE_ACTION_BOTH_EDGES; 222 + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; 206 223 207 224 return 0; 208 225 } ··· 210 227 static const struct counter_ops ftm_quaddec_cnt_ops = { 211 228 .count_read = ftm_quaddec_count_read, 212 229 .count_write = ftm_quaddec_count_write, 213 - .function_get = ftm_quaddec_count_function_get, 214 - .action_get = ftm_quaddec_action_get, 230 + .function_read = ftm_quaddec_count_function_read, 231 + .action_read = ftm_quaddec_action_read, 215 232 }; 216 233 217 234 static struct counter_signal ftm_quaddec_signals[] = { ··· 238 255 } 239 256 }; 240 257 241 - static const struct counter_count_ext ftm_quaddec_count_ext[] = { 242 - COUNTER_COUNT_ENUM("prescaler", &ftm_quaddec_prescaler_enum), 243 - COUNTER_COUNT_ENUM_AVAILABLE("prescaler", &ftm_quaddec_prescaler_enum), 258 + static DEFINE_COUNTER_ENUM(ftm_quaddec_prescaler_enum, ftm_quaddec_prescaler); 259 + 260 + static struct counter_comp ftm_quaddec_count_ext[] = { 261 + COUNTER_COMP_COUNT_ENUM("prescaler", ftm_quaddec_get_prescaler, 262 + ftm_quaddec_set_prescaler, 263 + ftm_quaddec_prescaler_enum), 244 264 }; 245 265 246 266 static struct counter_count ftm_quaddec_counts = {
+62 -84
drivers/counter/intel-qep.c
··· 62 62 63 63 #define INTEL_QEP_CLK_PERIOD_NS 10 64 64 65 - #define INTEL_QEP_COUNTER_EXT_RW(_name) \ 66 - { \ 67 - .name = #_name, \ 68 - .read = _name##_read, \ 69 - .write = _name##_write, \ 70 - } 71 - 72 65 struct intel_qep { 73 66 struct counter_device counter; 74 67 struct mutex lock; ··· 107 114 } 108 115 109 116 static int intel_qep_count_read(struct counter_device *counter, 110 - struct counter_count *count, 111 - unsigned long *val) 117 + struct counter_count *count, u64 *val) 112 118 { 113 119 struct intel_qep *const qep = counter->priv; 114 120 ··· 122 130 COUNTER_FUNCTION_QUADRATURE_X4, 123 131 }; 124 132 125 - static int intel_qep_function_get(struct counter_device *counter, 126 - struct counter_count *count, 127 - size_t *function) 133 + static int intel_qep_function_read(struct counter_device *counter, 134 + struct counter_count *count, 135 + enum counter_function *function) 128 136 { 129 - *function = 0; 137 + *function = COUNTER_FUNCTION_QUADRATURE_X4; 130 138 131 139 return 0; 132 140 } ··· 135 143 COUNTER_SYNAPSE_ACTION_BOTH_EDGES, 136 144 }; 137 145 138 - static int intel_qep_action_get(struct counter_device *counter, 139 - struct counter_count *count, 140 - struct counter_synapse *synapse, 141 - size_t *action) 146 + static int intel_qep_action_read(struct counter_device *counter, 147 + struct counter_count *count, 148 + struct counter_synapse *synapse, 149 + enum counter_synapse_action *action) 142 150 { 143 - *action = 0; 151 + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; 144 152 return 0; 145 153 } 146 154 147 155 static const struct counter_ops intel_qep_counter_ops = { 148 156 .count_read = intel_qep_count_read, 149 - .function_get = intel_qep_function_get, 150 - .action_get = intel_qep_action_get, 157 + .function_read = intel_qep_function_read, 158 + .action_read = intel_qep_action_read, 151 159 }; 152 160 153 161 #define INTEL_QEP_SIGNAL(_id, _name) { \ ··· 173 181 INTEL_QEP_SYNAPSE(2), 174 182 }; 175 183 176 - static ssize_t ceiling_read(struct counter_device *counter, 177 - struct counter_count *count, 178 - void *priv, char *buf) 184 + static int intel_qep_ceiling_read(struct counter_device *counter, 185 + struct counter_count *count, u64 *ceiling) 179 186 { 180 187 struct intel_qep *qep = counter->priv; 181 - u32 reg; 182 188 183 189 pm_runtime_get_sync(qep->dev); 184 - reg = intel_qep_readl(qep, INTEL_QEPMAX); 190 + *ceiling = intel_qep_readl(qep, INTEL_QEPMAX); 185 191 pm_runtime_put(qep->dev); 186 192 187 - return sysfs_emit(buf, "%u\n", reg); 193 + return 0; 188 194 } 189 195 190 - static ssize_t ceiling_write(struct counter_device *counter, 191 - struct counter_count *count, 192 - void *priv, const char *buf, size_t len) 196 + static int intel_qep_ceiling_write(struct counter_device *counter, 197 + struct counter_count *count, u64 max) 193 198 { 194 199 struct intel_qep *qep = counter->priv; 195 - u32 max; 196 - int ret; 200 + int ret = 0; 197 201 198 - ret = kstrtou32(buf, 0, &max); 199 - if (ret < 0) 200 - return ret; 202 + /* Intel QEP ceiling configuration only supports 32-bit values */ 203 + if (max != (u32)max) 204 + return -ERANGE; 201 205 202 206 mutex_lock(&qep->lock); 203 207 if (qep->enabled) { ··· 204 216 pm_runtime_get_sync(qep->dev); 205 217 intel_qep_writel(qep, INTEL_QEPMAX, max); 206 218 pm_runtime_put(qep->dev); 207 - ret = len; 208 219 209 220 out: 210 221 mutex_unlock(&qep->lock); 211 222 return ret; 212 223 } 213 224 214 - static ssize_t enable_read(struct counter_device *counter, 215 - struct counter_count *count, 216 - void *priv, char *buf) 225 + static int intel_qep_enable_read(struct counter_device *counter, 226 + struct counter_count *count, u8 *enable) 217 227 { 218 228 struct intel_qep *qep = counter->priv; 219 229 220 - return sysfs_emit(buf, "%u\n", qep->enabled); 230 + *enable = qep->enabled; 231 + 232 + return 0; 221 233 } 222 234 223 - static ssize_t enable_write(struct counter_device *counter, 224 - struct counter_count *count, 225 - void *priv, const char *buf, size_t len) 235 + static int intel_qep_enable_write(struct counter_device *counter, 236 + struct counter_count *count, u8 val) 226 237 { 227 238 struct intel_qep *qep = counter->priv; 228 239 u32 reg; 229 - bool val, changed; 230 - int ret; 231 - 232 - ret = kstrtobool(buf, &val); 233 - if (ret) 234 - return ret; 240 + bool changed; 235 241 236 242 mutex_lock(&qep->lock); 237 243 changed = val ^ qep->enabled; ··· 249 267 250 268 out: 251 269 mutex_unlock(&qep->lock); 252 - return len; 270 + return 0; 253 271 } 254 272 255 - static ssize_t spike_filter_ns_read(struct counter_device *counter, 256 - struct counter_count *count, 257 - void *priv, char *buf) 273 + static int intel_qep_spike_filter_ns_read(struct counter_device *counter, 274 + struct counter_count *count, 275 + u64 *length) 258 276 { 259 277 struct intel_qep *qep = counter->priv; 260 278 u32 reg; ··· 263 281 reg = intel_qep_readl(qep, INTEL_QEPCON); 264 282 if (!(reg & INTEL_QEPCON_FLT_EN)) { 265 283 pm_runtime_put(qep->dev); 266 - return sysfs_emit(buf, "0\n"); 284 + return 0; 267 285 } 268 286 reg = INTEL_QEPFLT_MAX_COUNT(intel_qep_readl(qep, INTEL_QEPFLT)); 269 287 pm_runtime_put(qep->dev); 270 288 271 - return sysfs_emit(buf, "%u\n", (reg + 2) * INTEL_QEP_CLK_PERIOD_NS); 289 + *length = (reg + 2) * INTEL_QEP_CLK_PERIOD_NS; 290 + 291 + return 0; 272 292 } 273 293 274 - static ssize_t spike_filter_ns_write(struct counter_device *counter, 275 - struct counter_count *count, 276 - void *priv, const char *buf, size_t len) 294 + static int intel_qep_spike_filter_ns_write(struct counter_device *counter, 295 + struct counter_count *count, 296 + u64 length) 277 297 { 278 298 struct intel_qep *qep = counter->priv; 279 - u32 reg, length; 299 + u32 reg; 280 300 bool enable; 281 - int ret; 282 - 283 - ret = kstrtou32(buf, 0, &length); 284 - if (ret < 0) 285 - return ret; 301 + int ret = 0; 286 302 287 303 /* 288 304 * Spike filter length is (MAX_COUNT + 2) clock periods. 289 305 * Disable filter when userspace writes 0, enable for valid 290 306 * nanoseconds values and error out otherwise. 291 307 */ 292 - length /= INTEL_QEP_CLK_PERIOD_NS; 308 + do_div(length, INTEL_QEP_CLK_PERIOD_NS); 293 309 if (length == 0) { 294 310 enable = false; 295 311 length = 0; ··· 316 336 intel_qep_writel(qep, INTEL_QEPFLT, length); 317 337 intel_qep_writel(qep, INTEL_QEPCON, reg); 318 338 pm_runtime_put(qep->dev); 319 - ret = len; 320 339 321 340 out: 322 341 mutex_unlock(&qep->lock); 323 342 return ret; 324 343 } 325 344 326 - static ssize_t preset_enable_read(struct counter_device *counter, 327 - struct counter_count *count, 328 - void *priv, char *buf) 345 + static int intel_qep_preset_enable_read(struct counter_device *counter, 346 + struct counter_count *count, 347 + u8 *preset_enable) 329 348 { 330 349 struct intel_qep *qep = counter->priv; 331 350 u32 reg; ··· 332 353 pm_runtime_get_sync(qep->dev); 333 354 reg = intel_qep_readl(qep, INTEL_QEPCON); 334 355 pm_runtime_put(qep->dev); 335 - return sysfs_emit(buf, "%u\n", !(reg & INTEL_QEPCON_COUNT_RST_MODE)); 356 + 357 + *preset_enable = !(reg & INTEL_QEPCON_COUNT_RST_MODE); 358 + 359 + return 0; 336 360 } 337 361 338 - static ssize_t preset_enable_write(struct counter_device *counter, 339 - struct counter_count *count, 340 - void *priv, const char *buf, size_t len) 362 + static int intel_qep_preset_enable_write(struct counter_device *counter, 363 + struct counter_count *count, u8 val) 341 364 { 342 365 struct intel_qep *qep = counter->priv; 343 366 u32 reg; 344 - bool val; 345 - int ret; 346 - 347 - ret = kstrtobool(buf, &val); 348 - if (ret) 349 - return ret; 367 + int ret = 0; 350 368 351 369 mutex_lock(&qep->lock); 352 370 if (qep->enabled) { ··· 360 384 361 385 intel_qep_writel(qep, INTEL_QEPCON, reg); 362 386 pm_runtime_put(qep->dev); 363 - ret = len; 364 387 365 388 out: 366 389 mutex_unlock(&qep->lock); ··· 367 392 return ret; 368 393 } 369 394 370 - static const struct counter_count_ext intel_qep_count_ext[] = { 371 - INTEL_QEP_COUNTER_EXT_RW(ceiling), 372 - INTEL_QEP_COUNTER_EXT_RW(enable), 373 - INTEL_QEP_COUNTER_EXT_RW(spike_filter_ns), 374 - INTEL_QEP_COUNTER_EXT_RW(preset_enable) 395 + static struct counter_comp intel_qep_count_ext[] = { 396 + COUNTER_COMP_ENABLE(intel_qep_enable_read, intel_qep_enable_write), 397 + COUNTER_COMP_CEILING(intel_qep_ceiling_read, intel_qep_ceiling_write), 398 + COUNTER_COMP_PRESET_ENABLE(intel_qep_preset_enable_read, 399 + intel_qep_preset_enable_write), 400 + COUNTER_COMP_COUNT_U64("spike_filter_ns", 401 + intel_qep_spike_filter_ns_read, 402 + intel_qep_spike_filter_ns_write), 375 403 }; 376 404 377 405 static struct counter_count intel_qep_counter_count[] = {
+26 -36
drivers/counter/interrupt-cnt.c
··· 10 10 #include <linux/mod_devicetable.h> 11 11 #include <linux/module.h> 12 12 #include <linux/platform_device.h> 13 + #include <linux/types.h> 13 14 14 15 #define INTERRUPT_CNT_NAME "interrupt-cnt" 15 16 ··· 34 33 return IRQ_HANDLED; 35 34 } 36 35 37 - static ssize_t interrupt_cnt_enable_read(struct counter_device *counter, 38 - struct counter_count *count, 39 - void *private, char *buf) 36 + static int interrupt_cnt_enable_read(struct counter_device *counter, 37 + struct counter_count *count, u8 *enable) 40 38 { 41 39 struct interrupt_cnt_priv *priv = counter->priv; 42 40 43 - return sysfs_emit(buf, "%d\n", priv->enabled); 41 + *enable = priv->enabled; 42 + 43 + return 0; 44 44 } 45 45 46 - static ssize_t interrupt_cnt_enable_write(struct counter_device *counter, 47 - struct counter_count *count, 48 - void *private, const char *buf, 49 - size_t len) 46 + static int interrupt_cnt_enable_write(struct counter_device *counter, 47 + struct counter_count *count, u8 enable) 50 48 { 51 49 struct interrupt_cnt_priv *priv = counter->priv; 52 - bool enable; 53 - ssize_t ret; 54 - 55 - ret = kstrtobool(buf, &enable); 56 - if (ret) 57 - return ret; 58 50 59 51 if (priv->enabled == enable) 60 - return len; 52 + return 0; 61 53 62 54 if (enable) { 63 55 priv->enabled = true; ··· 60 66 priv->enabled = false; 61 67 } 62 68 63 - return len; 69 + return 0; 64 70 } 65 71 66 - static const struct counter_count_ext interrupt_cnt_ext[] = { 67 - { 68 - .name = "enable", 69 - .read = interrupt_cnt_enable_read, 70 - .write = interrupt_cnt_enable_write, 71 - }, 72 + static struct counter_comp interrupt_cnt_ext[] = { 73 + COUNTER_COMP_ENABLE(interrupt_cnt_enable_read, 74 + interrupt_cnt_enable_write), 72 75 }; 73 76 74 77 static const enum counter_synapse_action interrupt_cnt_synapse_actions[] = { 75 78 COUNTER_SYNAPSE_ACTION_RISING_EDGE, 76 79 }; 77 80 78 - static int interrupt_cnt_action_get(struct counter_device *counter, 79 - struct counter_count *count, 80 - struct counter_synapse *synapse, 81 - size_t *action) 81 + static int interrupt_cnt_action_read(struct counter_device *counter, 82 + struct counter_count *count, 83 + struct counter_synapse *synapse, 84 + enum counter_synapse_action *action) 82 85 { 83 - *action = 0; 86 + *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; 84 87 85 88 return 0; 86 89 } 87 90 88 91 static int interrupt_cnt_read(struct counter_device *counter, 89 - struct counter_count *count, unsigned long *val) 92 + struct counter_count *count, u64 *val) 90 93 { 91 94 struct interrupt_cnt_priv *priv = counter->priv; 92 95 ··· 93 102 } 94 103 95 104 static int interrupt_cnt_write(struct counter_device *counter, 96 - struct counter_count *count, 97 - const unsigned long val) 105 + struct counter_count *count, const u64 val) 98 106 { 99 107 struct interrupt_cnt_priv *priv = counter->priv; 100 108 ··· 109 119 COUNTER_FUNCTION_INCREASE, 110 120 }; 111 121 112 - static int interrupt_cnt_function_get(struct counter_device *counter, 113 - struct counter_count *count, 114 - size_t *function) 122 + static int interrupt_cnt_function_read(struct counter_device *counter, 123 + struct counter_count *count, 124 + enum counter_function *function) 115 125 { 116 - *function = 0; 126 + *function = COUNTER_FUNCTION_INCREASE; 117 127 118 128 return 0; 119 129 } ··· 138 148 } 139 149 140 150 static const struct counter_ops interrupt_cnt_ops = { 141 - .action_get = interrupt_cnt_action_get, 151 + .action_read = interrupt_cnt_action_read, 142 152 .count_read = interrupt_cnt_read, 143 153 .count_write = interrupt_cnt_write, 144 - .function_get = interrupt_cnt_function_get, 154 + .function_read = interrupt_cnt_function_read, 145 155 .signal_read = interrupt_cnt_signal_read, 146 156 }; 147 157
+39 -52
drivers/counter/microchip-tcb-capture.c
··· 32 32 bool trig_inverted; 33 33 }; 34 34 35 - enum mchp_tc_count_function { 36 - MCHP_TC_FUNCTION_INCREASE, 37 - MCHP_TC_FUNCTION_QUADRATURE, 38 - }; 39 - 40 35 static const enum counter_function mchp_tc_count_functions[] = { 41 - [MCHP_TC_FUNCTION_INCREASE] = COUNTER_FUNCTION_INCREASE, 42 - [MCHP_TC_FUNCTION_QUADRATURE] = COUNTER_FUNCTION_QUADRATURE_X4, 43 - }; 44 - 45 - enum mchp_tc_synapse_action { 46 - MCHP_TC_SYNAPSE_ACTION_NONE = 0, 47 - MCHP_TC_SYNAPSE_ACTION_RISING_EDGE, 48 - MCHP_TC_SYNAPSE_ACTION_FALLING_EDGE, 49 - MCHP_TC_SYNAPSE_ACTION_BOTH_EDGE 36 + COUNTER_FUNCTION_INCREASE, 37 + COUNTER_FUNCTION_QUADRATURE_X4, 50 38 }; 51 39 52 40 static const enum counter_synapse_action mchp_tc_synapse_actions[] = { 53 - [MCHP_TC_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, 54 - [MCHP_TC_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE, 55 - [MCHP_TC_SYNAPSE_ACTION_FALLING_EDGE] = COUNTER_SYNAPSE_ACTION_FALLING_EDGE, 56 - [MCHP_TC_SYNAPSE_ACTION_BOTH_EDGE] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES, 41 + COUNTER_SYNAPSE_ACTION_NONE, 42 + COUNTER_SYNAPSE_ACTION_RISING_EDGE, 43 + COUNTER_SYNAPSE_ACTION_FALLING_EDGE, 44 + COUNTER_SYNAPSE_ACTION_BOTH_EDGES, 57 45 }; 58 46 59 47 static struct counter_signal mchp_tc_count_signals[] = { ··· 68 80 } 69 81 }; 70 82 71 - static int mchp_tc_count_function_get(struct counter_device *counter, 72 - struct counter_count *count, 73 - size_t *function) 83 + static int mchp_tc_count_function_read(struct counter_device *counter, 84 + struct counter_count *count, 85 + enum counter_function *function) 74 86 { 75 87 struct mchp_tc_data *const priv = counter->priv; 76 88 77 89 if (priv->qdec_mode) 78 - *function = MCHP_TC_FUNCTION_QUADRATURE; 90 + *function = COUNTER_FUNCTION_QUADRATURE_X4; 79 91 else 80 - *function = MCHP_TC_FUNCTION_INCREASE; 92 + *function = COUNTER_FUNCTION_INCREASE; 81 93 82 94 return 0; 83 95 } 84 96 85 - static int mchp_tc_count_function_set(struct counter_device *counter, 86 - struct counter_count *count, 87 - size_t function) 97 + static int mchp_tc_count_function_write(struct counter_device *counter, 98 + struct counter_count *count, 99 + enum counter_function function) 88 100 { 89 101 struct mchp_tc_data *const priv = counter->priv; 90 102 u32 bmr, cmr; ··· 96 108 cmr &= ~ATMEL_TC_WAVE; 97 109 98 110 switch (function) { 99 - case MCHP_TC_FUNCTION_INCREASE: 111 + case COUNTER_FUNCTION_INCREASE: 100 112 priv->qdec_mode = 0; 101 113 /* Set highest rate based on whether soc has gclk or not */ 102 114 bmr &= ~(ATMEL_TC_QDEN | ATMEL_TC_POSEN); ··· 108 120 cmr |= ATMEL_TC_CMR_MASK; 109 121 cmr &= ~(ATMEL_TC_ABETRG | ATMEL_TC_XC0); 110 122 break; 111 - case MCHP_TC_FUNCTION_QUADRATURE: 123 + case COUNTER_FUNCTION_QUADRATURE_X4: 112 124 if (!priv->tc_cfg->has_qdec) 113 125 return -EINVAL; 114 126 /* In QDEC mode settings both channels 0 and 1 are required */ ··· 164 176 return 0; 165 177 } 166 178 167 - static int mchp_tc_count_action_get(struct counter_device *counter, 168 - struct counter_count *count, 169 - struct counter_synapse *synapse, 170 - size_t *action) 179 + static int mchp_tc_count_action_read(struct counter_device *counter, 180 + struct counter_count *count, 181 + struct counter_synapse *synapse, 182 + enum counter_synapse_action *action) 171 183 { 172 184 struct mchp_tc_data *const priv = counter->priv; 173 185 u32 cmr; ··· 176 188 177 189 switch (cmr & ATMEL_TC_ETRGEDG) { 178 190 default: 179 - *action = MCHP_TC_SYNAPSE_ACTION_NONE; 191 + *action = COUNTER_SYNAPSE_ACTION_NONE; 180 192 break; 181 193 case ATMEL_TC_ETRGEDG_RISING: 182 - *action = MCHP_TC_SYNAPSE_ACTION_RISING_EDGE; 194 + *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; 183 195 break; 184 196 case ATMEL_TC_ETRGEDG_FALLING: 185 - *action = MCHP_TC_SYNAPSE_ACTION_FALLING_EDGE; 197 + *action = COUNTER_SYNAPSE_ACTION_FALLING_EDGE; 186 198 break; 187 199 case ATMEL_TC_ETRGEDG_BOTH: 188 - *action = MCHP_TC_SYNAPSE_ACTION_BOTH_EDGE; 200 + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; 189 201 break; 190 202 } 191 203 192 204 return 0; 193 205 } 194 206 195 - static int mchp_tc_count_action_set(struct counter_device *counter, 196 - struct counter_count *count, 197 - struct counter_synapse *synapse, 198 - size_t action) 207 + static int mchp_tc_count_action_write(struct counter_device *counter, 208 + struct counter_count *count, 209 + struct counter_synapse *synapse, 210 + enum counter_synapse_action action) 199 211 { 200 212 struct mchp_tc_data *const priv = counter->priv; 201 213 u32 edge = ATMEL_TC_ETRGEDG_NONE; ··· 205 217 return -EINVAL; 206 218 207 219 switch (action) { 208 - case MCHP_TC_SYNAPSE_ACTION_NONE: 220 + case COUNTER_SYNAPSE_ACTION_NONE: 209 221 edge = ATMEL_TC_ETRGEDG_NONE; 210 222 break; 211 - case MCHP_TC_SYNAPSE_ACTION_RISING_EDGE: 223 + case COUNTER_SYNAPSE_ACTION_RISING_EDGE: 212 224 edge = ATMEL_TC_ETRGEDG_RISING; 213 225 break; 214 - case MCHP_TC_SYNAPSE_ACTION_FALLING_EDGE: 226 + case COUNTER_SYNAPSE_ACTION_FALLING_EDGE: 215 227 edge = ATMEL_TC_ETRGEDG_FALLING; 216 228 break; 217 - case MCHP_TC_SYNAPSE_ACTION_BOTH_EDGE: 229 + case COUNTER_SYNAPSE_ACTION_BOTH_EDGES: 218 230 edge = ATMEL_TC_ETRGEDG_BOTH; 219 231 break; 220 232 default: ··· 228 240 } 229 241 230 242 static int mchp_tc_count_read(struct counter_device *counter, 231 - struct counter_count *count, 232 - unsigned long *val) 243 + struct counter_count *count, u64 *val) 233 244 { 234 245 struct mchp_tc_data *const priv = counter->priv; 235 246 u32 cnt; ··· 251 264 }; 252 265 253 266 static const struct counter_ops mchp_tc_ops = { 254 - .signal_read = mchp_tc_count_signal_read, 255 - .count_read = mchp_tc_count_read, 256 - .function_get = mchp_tc_count_function_get, 257 - .function_set = mchp_tc_count_function_set, 258 - .action_get = mchp_tc_count_action_get, 259 - .action_set = mchp_tc_count_action_set 267 + .signal_read = mchp_tc_count_signal_read, 268 + .count_read = mchp_tc_count_read, 269 + .function_read = mchp_tc_count_function_read, 270 + .function_write = mchp_tc_count_function_write, 271 + .action_read = mchp_tc_count_action_read, 272 + .action_write = mchp_tc_count_action_write 260 273 }; 261 274 262 275 static const struct atmel_tcb_config tcb_rm9200_config = {
+100 -112
drivers/counter/stm32-lptimer-cnt.c
··· 17 17 #include <linux/module.h> 18 18 #include <linux/pinctrl/consumer.h> 19 19 #include <linux/platform_device.h> 20 + #include <linux/types.h> 20 21 21 22 struct stm32_lptim_cnt { 22 23 struct counter_device counter; ··· 108 107 return regmap_update_bits(priv->regmap, STM32_LPTIM_CFGR, mask, val); 109 108 } 110 109 111 - /** 112 - * enum stm32_lptim_cnt_function - enumerates LPTimer counter & encoder modes 113 - * @STM32_LPTIM_COUNTER_INCREASE: up count on IN1 rising, falling or both edges 114 - * @STM32_LPTIM_ENCODER_BOTH_EDGE: count on both edges (IN1 & IN2 quadrature) 115 - * 110 + /* 116 111 * In non-quadrature mode, device counts up on active edge. 117 112 * In quadrature mode, encoder counting scenarios are as follows: 118 113 * +---------+----------+--------------------+--------------------+ ··· 126 129 * | edges | Low -> | Up | Down | Down | Up | 127 130 * +---------+----------+----------+---------+----------+---------+ 128 131 */ 129 - enum stm32_lptim_cnt_function { 130 - STM32_LPTIM_COUNTER_INCREASE, 131 - STM32_LPTIM_ENCODER_BOTH_EDGE, 132 - }; 133 - 134 132 static const enum counter_function stm32_lptim_cnt_functions[] = { 135 - [STM32_LPTIM_COUNTER_INCREASE] = COUNTER_FUNCTION_INCREASE, 136 - [STM32_LPTIM_ENCODER_BOTH_EDGE] = COUNTER_FUNCTION_QUADRATURE_X4, 137 - }; 138 - 139 - enum stm32_lptim_synapse_action { 140 - STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE = STM32_LPTIM_CKPOL_RISING_EDGE, 141 - STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE = STM32_LPTIM_CKPOL_FALLING_EDGE, 142 - STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES = STM32_LPTIM_CKPOL_BOTH_EDGES, 143 - STM32_LPTIM_SYNAPSE_ACTION_NONE, 133 + COUNTER_FUNCTION_INCREASE, 134 + COUNTER_FUNCTION_QUADRATURE_X4, 144 135 }; 145 136 146 137 static const enum counter_synapse_action stm32_lptim_cnt_synapse_actions[] = { 147 - /* Index must match with stm32_lptim_cnt_polarity[] (priv->polarity) */ 148 - [STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE, 149 - [STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE] = COUNTER_SYNAPSE_ACTION_FALLING_EDGE, 150 - [STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES, 151 - [STM32_LPTIM_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, 138 + COUNTER_SYNAPSE_ACTION_RISING_EDGE, 139 + COUNTER_SYNAPSE_ACTION_FALLING_EDGE, 140 + COUNTER_SYNAPSE_ACTION_BOTH_EDGES, 141 + COUNTER_SYNAPSE_ACTION_NONE, 152 142 }; 153 143 154 144 static int stm32_lptim_cnt_read(struct counter_device *counter, 155 - struct counter_count *count, unsigned long *val) 145 + struct counter_count *count, u64 *val) 156 146 { 157 147 struct stm32_lptim_cnt *const priv = counter->priv; 158 148 u32 cnt; ··· 154 170 return 0; 155 171 } 156 172 157 - static int stm32_lptim_cnt_function_get(struct counter_device *counter, 158 - struct counter_count *count, 159 - size_t *function) 173 + static int stm32_lptim_cnt_function_read(struct counter_device *counter, 174 + struct counter_count *count, 175 + enum counter_function *function) 160 176 { 161 177 struct stm32_lptim_cnt *const priv = counter->priv; 162 178 163 179 if (!priv->quadrature_mode) { 164 - *function = STM32_LPTIM_COUNTER_INCREASE; 180 + *function = COUNTER_FUNCTION_INCREASE; 165 181 return 0; 166 182 } 167 183 168 - if (priv->polarity == STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES) { 169 - *function = STM32_LPTIM_ENCODER_BOTH_EDGE; 184 + if (priv->polarity == STM32_LPTIM_CKPOL_BOTH_EDGES) { 185 + *function = COUNTER_FUNCTION_QUADRATURE_X4; 170 186 return 0; 171 187 } 172 188 173 189 return -EINVAL; 174 190 } 175 191 176 - static int stm32_lptim_cnt_function_set(struct counter_device *counter, 177 - struct counter_count *count, 178 - size_t function) 192 + static int stm32_lptim_cnt_function_write(struct counter_device *counter, 193 + struct counter_count *count, 194 + enum counter_function function) 179 195 { 180 196 struct stm32_lptim_cnt *const priv = counter->priv; 181 197 ··· 183 199 return -EBUSY; 184 200 185 201 switch (function) { 186 - case STM32_LPTIM_COUNTER_INCREASE: 202 + case COUNTER_FUNCTION_INCREASE: 187 203 priv->quadrature_mode = 0; 188 204 return 0; 189 - case STM32_LPTIM_ENCODER_BOTH_EDGE: 205 + case COUNTER_FUNCTION_QUADRATURE_X4: 190 206 priv->quadrature_mode = 1; 191 - priv->polarity = STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES; 207 + priv->polarity = STM32_LPTIM_CKPOL_BOTH_EDGES; 192 208 return 0; 193 209 default: 194 210 /* should never reach this path */ ··· 196 212 } 197 213 } 198 214 199 - static ssize_t stm32_lptim_cnt_enable_read(struct counter_device *counter, 200 - struct counter_count *count, 201 - void *private, char *buf) 215 + static int stm32_lptim_cnt_enable_read(struct counter_device *counter, 216 + struct counter_count *count, 217 + u8 *enable) 202 218 { 203 219 struct stm32_lptim_cnt *const priv = counter->priv; 204 220 int ret; ··· 207 223 if (ret < 0) 208 224 return ret; 209 225 210 - return scnprintf(buf, PAGE_SIZE, "%u\n", ret); 226 + *enable = ret; 227 + 228 + return 0; 211 229 } 212 230 213 - static ssize_t stm32_lptim_cnt_enable_write(struct counter_device *counter, 214 - struct counter_count *count, 215 - void *private, 216 - const char *buf, size_t len) 231 + static int stm32_lptim_cnt_enable_write(struct counter_device *counter, 232 + struct counter_count *count, 233 + u8 enable) 217 234 { 218 235 struct stm32_lptim_cnt *const priv = counter->priv; 219 - bool enable; 220 236 int ret; 221 - 222 - ret = kstrtobool(buf, &enable); 223 - if (ret) 224 - return ret; 225 237 226 238 /* Check nobody uses the timer, or already disabled/enabled */ 227 239 ret = stm32_lptim_is_enabled(priv); ··· 234 254 if (ret) 235 255 return ret; 236 256 237 - return len; 257 + return 0; 238 258 } 239 259 240 - static ssize_t stm32_lptim_cnt_ceiling_read(struct counter_device *counter, 241 - struct counter_count *count, 242 - void *private, char *buf) 260 + static int stm32_lptim_cnt_ceiling_read(struct counter_device *counter, 261 + struct counter_count *count, 262 + u64 *ceiling) 243 263 { 244 264 struct stm32_lptim_cnt *const priv = counter->priv; 245 265 246 - return snprintf(buf, PAGE_SIZE, "%u\n", priv->ceiling); 266 + *ceiling = priv->ceiling; 267 + 268 + return 0; 247 269 } 248 270 249 - static ssize_t stm32_lptim_cnt_ceiling_write(struct counter_device *counter, 250 - struct counter_count *count, 251 - void *private, 252 - const char *buf, size_t len) 271 + static int stm32_lptim_cnt_ceiling_write(struct counter_device *counter, 272 + struct counter_count *count, 273 + u64 ceiling) 253 274 { 254 275 struct stm32_lptim_cnt *const priv = counter->priv; 255 - unsigned int ceiling; 256 - int ret; 257 276 258 277 if (stm32_lptim_is_enabled(priv)) 259 278 return -EBUSY; 260 - 261 - ret = kstrtouint(buf, 0, &ceiling); 262 - if (ret) 263 - return ret; 264 279 265 280 if (ceiling > STM32_LPTIM_MAX_ARR) 266 281 return -ERANGE; 267 282 268 283 priv->ceiling = ceiling; 269 284 270 - return len; 285 + return 0; 271 286 } 272 287 273 - static const struct counter_count_ext stm32_lptim_cnt_ext[] = { 274 - { 275 - .name = "enable", 276 - .read = stm32_lptim_cnt_enable_read, 277 - .write = stm32_lptim_cnt_enable_write 278 - }, 279 - { 280 - .name = "ceiling", 281 - .read = stm32_lptim_cnt_ceiling_read, 282 - .write = stm32_lptim_cnt_ceiling_write 283 - }, 288 + static struct counter_comp stm32_lptim_cnt_ext[] = { 289 + COUNTER_COMP_ENABLE(stm32_lptim_cnt_enable_read, 290 + stm32_lptim_cnt_enable_write), 291 + COUNTER_COMP_CEILING(stm32_lptim_cnt_ceiling_read, 292 + stm32_lptim_cnt_ceiling_write), 284 293 }; 285 294 286 - static int stm32_lptim_cnt_action_get(struct counter_device *counter, 287 - struct counter_count *count, 288 - struct counter_synapse *synapse, 289 - size_t *action) 295 + static int stm32_lptim_cnt_action_read(struct counter_device *counter, 296 + struct counter_count *count, 297 + struct counter_synapse *synapse, 298 + enum counter_synapse_action *action) 290 299 { 291 300 struct stm32_lptim_cnt *const priv = counter->priv; 292 - size_t function; 301 + enum counter_function function; 293 302 int err; 294 303 295 - err = stm32_lptim_cnt_function_get(counter, count, &function); 304 + err = stm32_lptim_cnt_function_read(counter, count, &function); 296 305 if (err) 297 306 return err; 298 307 299 308 switch (function) { 300 - case STM32_LPTIM_COUNTER_INCREASE: 309 + case COUNTER_FUNCTION_INCREASE: 301 310 /* LP Timer acts as up-counter on input 1 */ 302 - if (synapse->signal->id == count->synapses[0].signal->id) 303 - *action = priv->polarity; 304 - else 305 - *action = STM32_LPTIM_SYNAPSE_ACTION_NONE; 306 - return 0; 307 - case STM32_LPTIM_ENCODER_BOTH_EDGE: 308 - *action = priv->polarity; 311 + if (synapse->signal->id != count->synapses[0].signal->id) { 312 + *action = COUNTER_SYNAPSE_ACTION_NONE; 313 + return 0; 314 + } 315 + 316 + switch (priv->polarity) { 317 + case STM32_LPTIM_CKPOL_RISING_EDGE: 318 + *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; 319 + return 0; 320 + case STM32_LPTIM_CKPOL_FALLING_EDGE: 321 + *action = COUNTER_SYNAPSE_ACTION_FALLING_EDGE; 322 + return 0; 323 + case STM32_LPTIM_CKPOL_BOTH_EDGES: 324 + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; 325 + return 0; 326 + default: 327 + /* should never reach this path */ 328 + return -EINVAL; 329 + } 330 + case COUNTER_FUNCTION_QUADRATURE_X4: 331 + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; 309 332 return 0; 310 333 default: 311 334 /* should never reach this path */ ··· 316 333 } 317 334 } 318 335 319 - static int stm32_lptim_cnt_action_set(struct counter_device *counter, 320 - struct counter_count *count, 321 - struct counter_synapse *synapse, 322 - size_t action) 336 + static int stm32_lptim_cnt_action_write(struct counter_device *counter, 337 + struct counter_count *count, 338 + struct counter_synapse *synapse, 339 + enum counter_synapse_action action) 323 340 { 324 341 struct stm32_lptim_cnt *const priv = counter->priv; 325 - size_t function; 342 + enum counter_function function; 326 343 int err; 327 344 328 345 if (stm32_lptim_is_enabled(priv)) 329 346 return -EBUSY; 330 347 331 - err = stm32_lptim_cnt_function_get(counter, count, &function); 348 + err = stm32_lptim_cnt_function_read(counter, count, &function); 332 349 if (err) 333 350 return err; 334 351 335 352 /* only set polarity when in counter mode (on input 1) */ 336 - if (function == STM32_LPTIM_COUNTER_INCREASE 337 - && synapse->signal->id == count->synapses[0].signal->id) { 338 - switch (action) { 339 - case STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE: 340 - case STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE: 341 - case STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES: 342 - priv->polarity = action; 343 - return 0; 344 - } 345 - } 353 + if (function != COUNTER_FUNCTION_INCREASE 354 + || synapse->signal->id != count->synapses[0].signal->id) 355 + return -EINVAL; 346 356 347 - return -EINVAL; 357 + switch (action) { 358 + case COUNTER_SYNAPSE_ACTION_RISING_EDGE: 359 + priv->polarity = STM32_LPTIM_CKPOL_RISING_EDGE; 360 + return 0; 361 + case COUNTER_SYNAPSE_ACTION_FALLING_EDGE: 362 + priv->polarity = STM32_LPTIM_CKPOL_FALLING_EDGE; 363 + return 0; 364 + case COUNTER_SYNAPSE_ACTION_BOTH_EDGES: 365 + priv->polarity = STM32_LPTIM_CKPOL_BOTH_EDGES; 366 + return 0; 367 + default: 368 + return -EINVAL; 369 + } 348 370 } 349 371 350 372 static const struct counter_ops stm32_lptim_cnt_ops = { 351 373 .count_read = stm32_lptim_cnt_read, 352 - .function_get = stm32_lptim_cnt_function_get, 353 - .function_set = stm32_lptim_cnt_function_set, 354 - .action_get = stm32_lptim_cnt_action_get, 355 - .action_set = stm32_lptim_cnt_action_set, 374 + .function_read = stm32_lptim_cnt_function_read, 375 + .function_write = stm32_lptim_cnt_function_write, 376 + .action_read = stm32_lptim_cnt_action_read, 377 + .action_write = stm32_lptim_cnt_action_write, 356 378 }; 357 379 358 380 static struct counter_signal stm32_lptim_cnt_signals[] = {
+68 -111
drivers/counter/stm32-timer-cnt.c
··· 13 13 #include <linux/module.h> 14 14 #include <linux/pinctrl/consumer.h> 15 15 #include <linux/platform_device.h> 16 + #include <linux/types.h> 16 17 17 18 #define TIM_CCMR_CCXS (BIT(8) | BIT(0)) 18 19 #define TIM_CCMR_MASK (TIM_CCMR_CC1S | TIM_CCMR_CC2S | \ ··· 37 36 struct stm32_timer_regs bak; 38 37 }; 39 38 40 - /** 41 - * enum stm32_count_function - enumerates stm32 timer counter encoder modes 42 - * @STM32_COUNT_SLAVE_MODE_DISABLED: counts on internal clock when CEN=1 43 - * @STM32_COUNT_ENCODER_MODE_1: counts TI1FP1 edges, depending on TI2FP2 level 44 - * @STM32_COUNT_ENCODER_MODE_2: counts TI2FP2 edges, depending on TI1FP1 level 45 - * @STM32_COUNT_ENCODER_MODE_3: counts on both TI1FP1 and TI2FP2 edges 46 - */ 47 - enum stm32_count_function { 48 - STM32_COUNT_SLAVE_MODE_DISABLED, 49 - STM32_COUNT_ENCODER_MODE_1, 50 - STM32_COUNT_ENCODER_MODE_2, 51 - STM32_COUNT_ENCODER_MODE_3, 52 - }; 53 - 54 39 static const enum counter_function stm32_count_functions[] = { 55 - [STM32_COUNT_SLAVE_MODE_DISABLED] = COUNTER_FUNCTION_INCREASE, 56 - [STM32_COUNT_ENCODER_MODE_1] = COUNTER_FUNCTION_QUADRATURE_X2_A, 57 - [STM32_COUNT_ENCODER_MODE_2] = COUNTER_FUNCTION_QUADRATURE_X2_B, 58 - [STM32_COUNT_ENCODER_MODE_3] = COUNTER_FUNCTION_QUADRATURE_X4, 40 + COUNTER_FUNCTION_INCREASE, 41 + COUNTER_FUNCTION_QUADRATURE_X2_A, 42 + COUNTER_FUNCTION_QUADRATURE_X2_B, 43 + COUNTER_FUNCTION_QUADRATURE_X4, 59 44 }; 60 45 61 46 static int stm32_count_read(struct counter_device *counter, 62 - struct counter_count *count, unsigned long *val) 47 + struct counter_count *count, u64 *val) 63 48 { 64 49 struct stm32_timer_cnt *const priv = counter->priv; 65 50 u32 cnt; ··· 57 70 } 58 71 59 72 static int stm32_count_write(struct counter_device *counter, 60 - struct counter_count *count, 61 - const unsigned long val) 73 + struct counter_count *count, const u64 val) 62 74 { 63 75 struct stm32_timer_cnt *const priv = counter->priv; 64 76 u32 ceiling; ··· 69 83 return regmap_write(priv->regmap, TIM_CNT, val); 70 84 } 71 85 72 - static int stm32_count_function_get(struct counter_device *counter, 73 - struct counter_count *count, 74 - size_t *function) 86 + static int stm32_count_function_read(struct counter_device *counter, 87 + struct counter_count *count, 88 + enum counter_function *function) 75 89 { 76 90 struct stm32_timer_cnt *const priv = counter->priv; 77 91 u32 smcr; ··· 80 94 81 95 switch (smcr & TIM_SMCR_SMS) { 82 96 case TIM_SMCR_SMS_SLAVE_MODE_DISABLED: 83 - *function = STM32_COUNT_SLAVE_MODE_DISABLED; 97 + *function = COUNTER_FUNCTION_INCREASE; 84 98 return 0; 85 99 case TIM_SMCR_SMS_ENCODER_MODE_1: 86 - *function = STM32_COUNT_ENCODER_MODE_1; 100 + *function = COUNTER_FUNCTION_QUADRATURE_X2_A; 87 101 return 0; 88 102 case TIM_SMCR_SMS_ENCODER_MODE_2: 89 - *function = STM32_COUNT_ENCODER_MODE_2; 103 + *function = COUNTER_FUNCTION_QUADRATURE_X2_B; 90 104 return 0; 91 105 case TIM_SMCR_SMS_ENCODER_MODE_3: 92 - *function = STM32_COUNT_ENCODER_MODE_3; 106 + *function = COUNTER_FUNCTION_QUADRATURE_X4; 93 107 return 0; 94 108 default: 95 109 return -EINVAL; 96 110 } 97 111 } 98 112 99 - static int stm32_count_function_set(struct counter_device *counter, 100 - struct counter_count *count, 101 - size_t function) 113 + static int stm32_count_function_write(struct counter_device *counter, 114 + struct counter_count *count, 115 + enum counter_function function) 102 116 { 103 117 struct stm32_timer_cnt *const priv = counter->priv; 104 118 u32 cr1, sms; 105 119 106 120 switch (function) { 107 - case STM32_COUNT_SLAVE_MODE_DISABLED: 121 + case COUNTER_FUNCTION_INCREASE: 108 122 sms = TIM_SMCR_SMS_SLAVE_MODE_DISABLED; 109 123 break; 110 - case STM32_COUNT_ENCODER_MODE_1: 124 + case COUNTER_FUNCTION_QUADRATURE_X2_A: 111 125 sms = TIM_SMCR_SMS_ENCODER_MODE_1; 112 126 break; 113 - case STM32_COUNT_ENCODER_MODE_2: 127 + case COUNTER_FUNCTION_QUADRATURE_X2_B: 114 128 sms = TIM_SMCR_SMS_ENCODER_MODE_2; 115 129 break; 116 - case STM32_COUNT_ENCODER_MODE_3: 130 + case COUNTER_FUNCTION_QUADRATURE_X4: 117 131 sms = TIM_SMCR_SMS_ENCODER_MODE_3; 118 132 break; 119 133 default: ··· 136 150 return 0; 137 151 } 138 152 139 - static ssize_t stm32_count_direction_read(struct counter_device *counter, 153 + static int stm32_count_direction_read(struct counter_device *counter, 140 154 struct counter_count *count, 141 - void *private, char *buf) 155 + enum counter_count_direction *direction) 142 156 { 143 157 struct stm32_timer_cnt *const priv = counter->priv; 144 - const char *direction; 145 158 u32 cr1; 146 159 147 160 regmap_read(priv->regmap, TIM_CR1, &cr1); 148 - direction = (cr1 & TIM_CR1_DIR) ? "backward" : "forward"; 161 + *direction = (cr1 & TIM_CR1_DIR) ? COUNTER_COUNT_DIRECTION_BACKWARD : 162 + COUNTER_COUNT_DIRECTION_FORWARD; 149 163 150 - return scnprintf(buf, PAGE_SIZE, "%s\n", direction); 164 + return 0; 151 165 } 152 166 153 - static ssize_t stm32_count_ceiling_read(struct counter_device *counter, 154 - struct counter_count *count, 155 - void *private, char *buf) 167 + static int stm32_count_ceiling_read(struct counter_device *counter, 168 + struct counter_count *count, u64 *ceiling) 156 169 { 157 170 struct stm32_timer_cnt *const priv = counter->priv; 158 171 u32 arr; 159 172 160 173 regmap_read(priv->regmap, TIM_ARR, &arr); 161 174 162 - return snprintf(buf, PAGE_SIZE, "%u\n", arr); 175 + *ceiling = arr; 176 + 177 + return 0; 163 178 } 164 179 165 - static ssize_t stm32_count_ceiling_write(struct counter_device *counter, 166 - struct counter_count *count, 167 - void *private, 168 - const char *buf, size_t len) 180 + static int stm32_count_ceiling_write(struct counter_device *counter, 181 + struct counter_count *count, u64 ceiling) 169 182 { 170 183 struct stm32_timer_cnt *const priv = counter->priv; 171 - unsigned int ceiling; 172 - int ret; 173 - 174 - ret = kstrtouint(buf, 0, &ceiling); 175 - if (ret) 176 - return ret; 177 184 178 185 if (ceiling > priv->max_arr) 179 186 return -ERANGE; ··· 175 196 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); 176 197 regmap_write(priv->regmap, TIM_ARR, ceiling); 177 198 178 - return len; 199 + return 0; 179 200 } 180 201 181 - static ssize_t stm32_count_enable_read(struct counter_device *counter, 182 - struct counter_count *count, 183 - void *private, char *buf) 202 + static int stm32_count_enable_read(struct counter_device *counter, 203 + struct counter_count *count, u8 *enable) 184 204 { 185 205 struct stm32_timer_cnt *const priv = counter->priv; 186 206 u32 cr1; 187 207 188 208 regmap_read(priv->regmap, TIM_CR1, &cr1); 189 209 190 - return scnprintf(buf, PAGE_SIZE, "%d\n", (bool)(cr1 & TIM_CR1_CEN)); 210 + *enable = cr1 & TIM_CR1_CEN; 211 + 212 + return 0; 191 213 } 192 214 193 - static ssize_t stm32_count_enable_write(struct counter_device *counter, 194 - struct counter_count *count, 195 - void *private, 196 - const char *buf, size_t len) 215 + static int stm32_count_enable_write(struct counter_device *counter, 216 + struct counter_count *count, u8 enable) 197 217 { 198 218 struct stm32_timer_cnt *const priv = counter->priv; 199 - int err; 200 219 u32 cr1; 201 - bool enable; 202 - 203 - err = kstrtobool(buf, &enable); 204 - if (err) 205 - return err; 206 220 207 221 if (enable) { 208 222 regmap_read(priv->regmap, TIM_CR1, &cr1); ··· 214 242 /* Keep enabled state to properly handle low power states */ 215 243 priv->enabled = enable; 216 244 217 - return len; 245 + return 0; 218 246 } 219 247 220 - static const struct counter_count_ext stm32_count_ext[] = { 221 - { 222 - .name = "direction", 223 - .read = stm32_count_direction_read, 224 - }, 225 - { 226 - .name = "enable", 227 - .read = stm32_count_enable_read, 228 - .write = stm32_count_enable_write 229 - }, 230 - { 231 - .name = "ceiling", 232 - .read = stm32_count_ceiling_read, 233 - .write = stm32_count_ceiling_write 234 - }, 235 - }; 236 - 237 - enum stm32_synapse_action { 238 - STM32_SYNAPSE_ACTION_NONE, 239 - STM32_SYNAPSE_ACTION_BOTH_EDGES 248 + static struct counter_comp stm32_count_ext[] = { 249 + COUNTER_COMP_DIRECTION(stm32_count_direction_read), 250 + COUNTER_COMP_ENABLE(stm32_count_enable_read, stm32_count_enable_write), 251 + COUNTER_COMP_CEILING(stm32_count_ceiling_read, 252 + stm32_count_ceiling_write), 240 253 }; 241 254 242 255 static const enum counter_synapse_action stm32_synapse_actions[] = { 243 - [STM32_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, 244 - [STM32_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES 256 + COUNTER_SYNAPSE_ACTION_NONE, 257 + COUNTER_SYNAPSE_ACTION_BOTH_EDGES 245 258 }; 246 259 247 - static int stm32_action_get(struct counter_device *counter, 248 - struct counter_count *count, 249 - struct counter_synapse *synapse, 250 - size_t *action) 260 + static int stm32_action_read(struct counter_device *counter, 261 + struct counter_count *count, 262 + struct counter_synapse *synapse, 263 + enum counter_synapse_action *action) 251 264 { 252 - size_t function; 265 + enum counter_function function; 253 266 int err; 254 267 255 - err = stm32_count_function_get(counter, count, &function); 268 + err = stm32_count_function_read(counter, count, &function); 256 269 if (err) 257 270 return err; 258 271 259 272 switch (function) { 260 - case STM32_COUNT_SLAVE_MODE_DISABLED: 273 + case COUNTER_FUNCTION_INCREASE: 261 274 /* counts on internal clock when CEN=1 */ 262 - *action = STM32_SYNAPSE_ACTION_NONE; 275 + *action = COUNTER_SYNAPSE_ACTION_NONE; 263 276 return 0; 264 - case STM32_COUNT_ENCODER_MODE_1: 277 + case COUNTER_FUNCTION_QUADRATURE_X2_A: 265 278 /* counts up/down on TI1FP1 edge depending on TI2FP2 level */ 266 279 if (synapse->signal->id == count->synapses[0].signal->id) 267 - *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; 280 + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; 268 281 else 269 - *action = STM32_SYNAPSE_ACTION_NONE; 282 + *action = COUNTER_SYNAPSE_ACTION_NONE; 270 283 return 0; 271 - case STM32_COUNT_ENCODER_MODE_2: 284 + case COUNTER_FUNCTION_QUADRATURE_X2_B: 272 285 /* counts up/down on TI2FP2 edge depending on TI1FP1 level */ 273 286 if (synapse->signal->id == count->synapses[1].signal->id) 274 - *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; 287 + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; 275 288 else 276 - *action = STM32_SYNAPSE_ACTION_NONE; 289 + *action = COUNTER_SYNAPSE_ACTION_NONE; 277 290 return 0; 278 - case STM32_COUNT_ENCODER_MODE_3: 291 + case COUNTER_FUNCTION_QUADRATURE_X4: 279 292 /* counts up/down on both TI1FP1 and TI2FP2 edges */ 280 - *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; 293 + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; 281 294 return 0; 282 295 default: 283 296 return -EINVAL; ··· 272 315 static const struct counter_ops stm32_timer_cnt_ops = { 273 316 .count_read = stm32_count_read, 274 317 .count_write = stm32_count_write, 275 - .function_get = stm32_count_function_get, 276 - .function_set = stm32_count_function_set, 277 - .action_get = stm32_action_get, 318 + .function_read = stm32_count_function_read, 319 + .function_write = stm32_count_function_write, 320 + .action_read = stm32_action_read, 278 321 }; 279 322 280 323 static struct counter_signal stm32_signals[] = {
+98 -82
drivers/counter/ti-eqep.c
··· 13 13 #include <linux/platform_device.h> 14 14 #include <linux/pm_runtime.h> 15 15 #include <linux/regmap.h> 16 + #include <linux/types.h> 16 17 17 18 /* 32-bit registers */ 18 19 #define QPOSCNT 0x0 ··· 74 73 }; 75 74 76 75 /* Position Counter Input Modes */ 77 - enum { 76 + enum ti_eqep_count_func { 78 77 TI_EQEP_COUNT_FUNC_QUAD_COUNT, 79 78 TI_EQEP_COUNT_FUNC_DIR_COUNT, 80 79 TI_EQEP_COUNT_FUNC_UP_COUNT, 81 80 TI_EQEP_COUNT_FUNC_DOWN_COUNT, 82 - }; 83 - 84 - enum { 85 - TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES, 86 - TI_EQEP_SYNAPSE_ACTION_RISING_EDGE, 87 - TI_EQEP_SYNAPSE_ACTION_NONE, 88 81 }; 89 82 90 83 struct ti_eqep_cnt { ··· 88 93 }; 89 94 90 95 static int ti_eqep_count_read(struct counter_device *counter, 91 - struct counter_count *count, unsigned long *val) 96 + struct counter_count *count, u64 *val) 92 97 { 93 98 struct ti_eqep_cnt *priv = counter->priv; 94 99 u32 cnt; ··· 100 105 } 101 106 102 107 static int ti_eqep_count_write(struct counter_device *counter, 103 - struct counter_count *count, unsigned long val) 108 + struct counter_count *count, u64 val) 104 109 { 105 110 struct ti_eqep_cnt *priv = counter->priv; 106 111 u32 max; ··· 112 117 return regmap_write(priv->regmap32, QPOSCNT, val); 113 118 } 114 119 115 - static int ti_eqep_function_get(struct counter_device *counter, 116 - struct counter_count *count, size_t *function) 120 + static int ti_eqep_function_read(struct counter_device *counter, 121 + struct counter_count *count, 122 + enum counter_function *function) 117 123 { 118 124 struct ti_eqep_cnt *priv = counter->priv; 119 125 u32 qdecctl; 120 126 121 127 regmap_read(priv->regmap16, QDECCTL, &qdecctl); 122 - *function = (qdecctl & QDECCTL_QSRC) >> QDECCTL_QSRC_SHIFT; 128 + 129 + switch ((qdecctl & QDECCTL_QSRC) >> QDECCTL_QSRC_SHIFT) { 130 + case TI_EQEP_COUNT_FUNC_QUAD_COUNT: 131 + *function = COUNTER_FUNCTION_QUADRATURE_X4; 132 + break; 133 + case TI_EQEP_COUNT_FUNC_DIR_COUNT: 134 + *function = COUNTER_FUNCTION_PULSE_DIRECTION; 135 + break; 136 + case TI_EQEP_COUNT_FUNC_UP_COUNT: 137 + *function = COUNTER_FUNCTION_INCREASE; 138 + break; 139 + case TI_EQEP_COUNT_FUNC_DOWN_COUNT: 140 + *function = COUNTER_FUNCTION_DECREASE; 141 + break; 142 + } 123 143 124 144 return 0; 125 145 } 126 146 127 - static int ti_eqep_function_set(struct counter_device *counter, 128 - struct counter_count *count, size_t function) 147 + static int ti_eqep_function_write(struct counter_device *counter, 148 + struct counter_count *count, 149 + enum counter_function function) 129 150 { 130 151 struct ti_eqep_cnt *priv = counter->priv; 152 + enum ti_eqep_count_func qsrc; 153 + 154 + switch (function) { 155 + case COUNTER_FUNCTION_QUADRATURE_X4: 156 + qsrc = TI_EQEP_COUNT_FUNC_QUAD_COUNT; 157 + break; 158 + case COUNTER_FUNCTION_PULSE_DIRECTION: 159 + qsrc = TI_EQEP_COUNT_FUNC_DIR_COUNT; 160 + break; 161 + case COUNTER_FUNCTION_INCREASE: 162 + qsrc = TI_EQEP_COUNT_FUNC_UP_COUNT; 163 + break; 164 + case COUNTER_FUNCTION_DECREASE: 165 + qsrc = TI_EQEP_COUNT_FUNC_DOWN_COUNT; 166 + break; 167 + default: 168 + /* should never reach this path */ 169 + return -EINVAL; 170 + } 131 171 132 172 return regmap_write_bits(priv->regmap16, QDECCTL, QDECCTL_QSRC, 133 - function << QDECCTL_QSRC_SHIFT); 173 + qsrc << QDECCTL_QSRC_SHIFT); 134 174 } 135 175 136 - static int ti_eqep_action_get(struct counter_device *counter, 137 - struct counter_count *count, 138 - struct counter_synapse *synapse, size_t *action) 176 + static int ti_eqep_action_read(struct counter_device *counter, 177 + struct counter_count *count, 178 + struct counter_synapse *synapse, 179 + enum counter_synapse_action *action) 139 180 { 140 181 struct ti_eqep_cnt *priv = counter->priv; 141 - size_t function; 182 + enum counter_function function; 142 183 u32 qdecctl; 143 184 int err; 144 185 145 - err = ti_eqep_function_get(counter, count, &function); 186 + err = ti_eqep_function_read(counter, count, &function); 146 187 if (err) 147 188 return err; 148 189 149 190 switch (function) { 150 - case TI_EQEP_COUNT_FUNC_QUAD_COUNT: 191 + case COUNTER_FUNCTION_QUADRATURE_X4: 151 192 /* In quadrature mode, the rising and falling edge of both 152 193 * QEPA and QEPB trigger QCLK. 153 194 */ 154 - *action = TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES; 195 + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; 155 196 return 0; 156 - case TI_EQEP_COUNT_FUNC_DIR_COUNT: 197 + case COUNTER_FUNCTION_PULSE_DIRECTION: 157 198 /* In direction-count mode only rising edge of QEPA is counted 158 199 * and QEPB gives direction. 159 200 */ 160 201 switch (synapse->signal->id) { 161 202 case TI_EQEP_SIGNAL_QEPA: 162 - *action = TI_EQEP_SYNAPSE_ACTION_RISING_EDGE; 203 + *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; 163 204 return 0; 164 205 case TI_EQEP_SIGNAL_QEPB: 165 - *action = TI_EQEP_SYNAPSE_ACTION_NONE; 206 + *action = COUNTER_SYNAPSE_ACTION_NONE; 166 207 return 0; 167 208 default: 168 209 /* should never reach this path */ 169 210 return -EINVAL; 170 211 } 171 - case TI_EQEP_COUNT_FUNC_UP_COUNT: 172 - case TI_EQEP_COUNT_FUNC_DOWN_COUNT: 212 + case COUNTER_FUNCTION_INCREASE: 213 + case COUNTER_FUNCTION_DECREASE: 173 214 /* In up/down-count modes only QEPA is counted and QEPB is not 174 215 * used. 175 216 */ ··· 216 185 return err; 217 186 218 187 if (qdecctl & QDECCTL_XCR) 219 - *action = TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES; 188 + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; 220 189 else 221 - *action = TI_EQEP_SYNAPSE_ACTION_RISING_EDGE; 190 + *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; 222 191 return 0; 223 192 case TI_EQEP_SIGNAL_QEPB: 224 - *action = TI_EQEP_SYNAPSE_ACTION_NONE; 193 + *action = COUNTER_SYNAPSE_ACTION_NONE; 225 194 return 0; 226 195 default: 227 196 /* should never reach this path */ ··· 236 205 static const struct counter_ops ti_eqep_counter_ops = { 237 206 .count_read = ti_eqep_count_read, 238 207 .count_write = ti_eqep_count_write, 239 - .function_get = ti_eqep_function_get, 240 - .function_set = ti_eqep_function_set, 241 - .action_get = ti_eqep_action_get, 208 + .function_read = ti_eqep_function_read, 209 + .function_write = ti_eqep_function_write, 210 + .action_read = ti_eqep_action_read, 242 211 }; 243 212 244 - static ssize_t ti_eqep_position_ceiling_read(struct counter_device *counter, 245 - struct counter_count *count, 246 - void *ext_priv, char *buf) 213 + static int ti_eqep_position_ceiling_read(struct counter_device *counter, 214 + struct counter_count *count, 215 + u64 *ceiling) 247 216 { 248 217 struct ti_eqep_cnt *priv = counter->priv; 249 218 u32 qposmax; 250 219 251 220 regmap_read(priv->regmap32, QPOSMAX, &qposmax); 252 221 253 - return sprintf(buf, "%u\n", qposmax); 222 + *ceiling = qposmax; 223 + 224 + return 0; 254 225 } 255 226 256 - static ssize_t ti_eqep_position_ceiling_write(struct counter_device *counter, 257 - struct counter_count *count, 258 - void *ext_priv, const char *buf, 259 - size_t len) 227 + static int ti_eqep_position_ceiling_write(struct counter_device *counter, 228 + struct counter_count *count, 229 + u64 ceiling) 260 230 { 261 231 struct ti_eqep_cnt *priv = counter->priv; 262 - int err; 263 - u32 res; 264 232 265 - err = kstrtouint(buf, 0, &res); 266 - if (err < 0) 267 - return err; 233 + if (ceiling != (u32)ceiling) 234 + return -ERANGE; 268 235 269 - regmap_write(priv->regmap32, QPOSMAX, res); 236 + regmap_write(priv->regmap32, QPOSMAX, ceiling); 270 237 271 - return len; 238 + return 0; 272 239 } 273 240 274 - static ssize_t ti_eqep_position_enable_read(struct counter_device *counter, 275 - struct counter_count *count, 276 - void *ext_priv, char *buf) 241 + static int ti_eqep_position_enable_read(struct counter_device *counter, 242 + struct counter_count *count, u8 *enable) 277 243 { 278 244 struct ti_eqep_cnt *priv = counter->priv; 279 245 u32 qepctl; 280 246 281 247 regmap_read(priv->regmap16, QEPCTL, &qepctl); 282 248 283 - return sprintf(buf, "%u\n", !!(qepctl & QEPCTL_PHEN)); 249 + *enable = !!(qepctl & QEPCTL_PHEN); 250 + 251 + return 0; 284 252 } 285 253 286 - static ssize_t ti_eqep_position_enable_write(struct counter_device *counter, 287 - struct counter_count *count, 288 - void *ext_priv, const char *buf, 289 - size_t len) 254 + static int ti_eqep_position_enable_write(struct counter_device *counter, 255 + struct counter_count *count, u8 enable) 290 256 { 291 257 struct ti_eqep_cnt *priv = counter->priv; 292 - int err; 293 - bool res; 294 258 295 - err = kstrtobool(buf, &res); 296 - if (err < 0) 297 - return err; 259 + regmap_write_bits(priv->regmap16, QEPCTL, QEPCTL_PHEN, enable ? -1 : 0); 298 260 299 - regmap_write_bits(priv->regmap16, QEPCTL, QEPCTL_PHEN, res ? -1 : 0); 300 - 301 - return len; 261 + return 0; 302 262 } 303 263 304 - static struct counter_count_ext ti_eqep_position_ext[] = { 305 - { 306 - .name = "ceiling", 307 - .read = ti_eqep_position_ceiling_read, 308 - .write = ti_eqep_position_ceiling_write, 309 - }, 310 - { 311 - .name = "enable", 312 - .read = ti_eqep_position_enable_read, 313 - .write = ti_eqep_position_enable_write, 314 - }, 264 + static struct counter_comp ti_eqep_position_ext[] = { 265 + COUNTER_COMP_CEILING(ti_eqep_position_ceiling_read, 266 + ti_eqep_position_ceiling_write), 267 + COUNTER_COMP_ENABLE(ti_eqep_position_enable_read, 268 + ti_eqep_position_enable_write), 315 269 }; 316 270 317 271 static struct counter_signal ti_eqep_signals[] = { ··· 311 295 }; 312 296 313 297 static const enum counter_function ti_eqep_position_functions[] = { 314 - [TI_EQEP_COUNT_FUNC_QUAD_COUNT] = COUNTER_FUNCTION_QUADRATURE_X4, 315 - [TI_EQEP_COUNT_FUNC_DIR_COUNT] = COUNTER_FUNCTION_PULSE_DIRECTION, 316 - [TI_EQEP_COUNT_FUNC_UP_COUNT] = COUNTER_FUNCTION_INCREASE, 317 - [TI_EQEP_COUNT_FUNC_DOWN_COUNT] = COUNTER_FUNCTION_DECREASE, 298 + COUNTER_FUNCTION_QUADRATURE_X4, 299 + COUNTER_FUNCTION_PULSE_DIRECTION, 300 + COUNTER_FUNCTION_INCREASE, 301 + COUNTER_FUNCTION_DECREASE, 318 302 }; 319 303 320 304 static const enum counter_synapse_action ti_eqep_position_synapse_actions[] = { 321 - [TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES, 322 - [TI_EQEP_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE, 323 - [TI_EQEP_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, 305 + COUNTER_SYNAPSE_ACTION_BOTH_EDGES, 306 + COUNTER_SYNAPSE_ACTION_RISING_EDGE, 307 + COUNTER_SYNAPSE_ACTION_NONE, 324 308 }; 325 309 326 310 static struct counter_synapse ti_eqep_position_synapses[] = {
+344 -326
include/linux/counter.h
··· 6 6 #ifndef _COUNTER_H_ 7 7 #define _COUNTER_H_ 8 8 9 - #include <linux/counter_enum.h> 10 9 #include <linux/device.h> 10 + #include <linux/kernel.h> 11 11 #include <linux/types.h> 12 12 13 - enum counter_count_direction { 14 - COUNTER_COUNT_DIRECTION_FORWARD = 0, 15 - COUNTER_COUNT_DIRECTION_BACKWARD 16 - }; 17 - extern const char *const counter_count_direction_str[2]; 18 - 19 - enum counter_count_mode { 20 - COUNTER_COUNT_MODE_NORMAL = 0, 21 - COUNTER_COUNT_MODE_RANGE_LIMIT, 22 - COUNTER_COUNT_MODE_NON_RECYCLE, 23 - COUNTER_COUNT_MODE_MODULO_N 24 - }; 25 - extern const char *const counter_count_mode_str[4]; 26 - 27 13 struct counter_device; 14 + struct counter_count; 15 + struct counter_synapse; 28 16 struct counter_signal; 29 17 18 + enum counter_comp_type { 19 + COUNTER_COMP_U8, 20 + COUNTER_COMP_U64, 21 + COUNTER_COMP_BOOL, 22 + COUNTER_COMP_SIGNAL_LEVEL, 23 + COUNTER_COMP_FUNCTION, 24 + COUNTER_COMP_SYNAPSE_ACTION, 25 + COUNTER_COMP_ENUM, 26 + COUNTER_COMP_COUNT_DIRECTION, 27 + COUNTER_COMP_COUNT_MODE, 28 + }; 29 + 30 + enum counter_scope { 31 + COUNTER_SCOPE_DEVICE, 32 + COUNTER_SCOPE_SIGNAL, 33 + COUNTER_SCOPE_COUNT, 34 + }; 35 + 36 + enum counter_count_direction { 37 + COUNTER_COUNT_DIRECTION_FORWARD, 38 + COUNTER_COUNT_DIRECTION_BACKWARD, 39 + }; 40 + 41 + enum counter_count_mode { 42 + COUNTER_COUNT_MODE_NORMAL, 43 + COUNTER_COUNT_MODE_RANGE_LIMIT, 44 + COUNTER_COUNT_MODE_NON_RECYCLE, 45 + COUNTER_COUNT_MODE_MODULO_N, 46 + }; 47 + 48 + enum counter_function { 49 + COUNTER_FUNCTION_INCREASE, 50 + COUNTER_FUNCTION_DECREASE, 51 + COUNTER_FUNCTION_PULSE_DIRECTION, 52 + COUNTER_FUNCTION_QUADRATURE_X1_A, 53 + COUNTER_FUNCTION_QUADRATURE_X1_B, 54 + COUNTER_FUNCTION_QUADRATURE_X2_A, 55 + COUNTER_FUNCTION_QUADRATURE_X2_B, 56 + COUNTER_FUNCTION_QUADRATURE_X4, 57 + }; 58 + 59 + enum counter_signal_level { 60 + COUNTER_SIGNAL_LEVEL_LOW, 61 + COUNTER_SIGNAL_LEVEL_HIGH, 62 + }; 63 + 64 + enum counter_synapse_action { 65 + COUNTER_SYNAPSE_ACTION_NONE, 66 + COUNTER_SYNAPSE_ACTION_RISING_EDGE, 67 + COUNTER_SYNAPSE_ACTION_FALLING_EDGE, 68 + COUNTER_SYNAPSE_ACTION_BOTH_EDGES, 69 + }; 70 + 30 71 /** 31 - * struct counter_signal_ext - Counter Signal extensions 32 - * @name: attribute name 33 - * @read: read callback for this attribute; may be NULL 34 - * @write: write callback for this attribute; may be NULL 35 - * @priv: data private to the driver 72 + * struct counter_comp - Counter component node 73 + * @type: Counter component data type 74 + * @name: device-specific component name 75 + * @priv: component-relevant data 76 + * @action_read Synapse action mode read callback. The read value of the 77 + * respective Synapse action mode should be passed back via 78 + * the action parameter. 79 + * @device_u8_read Device u8 component read callback. The read value of the 80 + * respective Device u8 component should be passed back via 81 + * the val parameter. 82 + * @count_u8_read Count u8 component read callback. The read value of the 83 + * respective Count u8 component should be passed back via 84 + * the val parameter. 85 + * @signal_u8_read Signal u8 component read callback. The read value of the 86 + * respective Signal u8 component should be passed back via 87 + * the val parameter. 88 + * @device_u32_read Device u32 component read callback. The read value of 89 + * the respective Device u32 component should be passed 90 + * back via the val parameter. 91 + * @count_u32_read Count u32 component read callback. The read value of the 92 + * respective Count u32 component should be passed back via 93 + * the val parameter. 94 + * @signal_u32_read Signal u32 component read callback. The read value of 95 + * the respective Signal u32 component should be passed 96 + * back via the val parameter. 97 + * @device_u64_read Device u64 component read callback. The read value of 98 + * the respective Device u64 component should be passed 99 + * back via the val parameter. 100 + * @count_u64_read Count u64 component read callback. The read value of the 101 + * respective Count u64 component should be passed back via 102 + * the val parameter. 103 + * @signal_u64_read Signal u64 component read callback. The read value of 104 + * the respective Signal u64 component should be passed 105 + * back via the val parameter. 106 + * @action_write Synapse action mode write callback. The write value of 107 + * the respective Synapse action mode is passed via the 108 + * action parameter. 109 + * @device_u8_write Device u8 component write callback. The write value of 110 + * the respective Device u8 component is passed via the val 111 + * parameter. 112 + * @count_u8_write Count u8 component write callback. The write value of 113 + * the respective Count u8 component is passed via the val 114 + * parameter. 115 + * @signal_u8_write Signal u8 component write callback. The write value of 116 + * the respective Signal u8 component is passed via the val 117 + * parameter. 118 + * @device_u32_write Device u32 component write callback. The write value of 119 + * the respective Device u32 component is passed via the 120 + * val parameter. 121 + * @count_u32_write Count u32 component write callback. The write value of 122 + * the respective Count u32 component is passed via the val 123 + * parameter. 124 + * @signal_u32_write Signal u32 component write callback. The write value of 125 + * the respective Signal u32 component is passed via the 126 + * val parameter. 127 + * @device_u64_write Device u64 component write callback. The write value of 128 + * the respective Device u64 component is passed via the 129 + * val parameter. 130 + * @count_u64_write Count u64 component write callback. The write value of 131 + * the respective Count u64 component is passed via the val 132 + * parameter. 133 + * @signal_u64_write Signal u64 component write callback. The write value of 134 + * the respective Signal u64 component is passed via the 135 + * val parameter. 36 136 */ 37 - struct counter_signal_ext { 137 + struct counter_comp { 138 + enum counter_comp_type type; 38 139 const char *name; 39 - ssize_t (*read)(struct counter_device *counter, 40 - struct counter_signal *signal, void *priv, char *buf); 41 - ssize_t (*write)(struct counter_device *counter, 42 - struct counter_signal *signal, void *priv, 43 - const char *buf, size_t len); 44 140 void *priv; 141 + union { 142 + int (*action_read)(struct counter_device *counter, 143 + struct counter_count *count, 144 + struct counter_synapse *synapse, 145 + enum counter_synapse_action *action); 146 + int (*device_u8_read)(struct counter_device *counter, u8 *val); 147 + int (*count_u8_read)(struct counter_device *counter, 148 + struct counter_count *count, u8 *val); 149 + int (*signal_u8_read)(struct counter_device *counter, 150 + struct counter_signal *signal, u8 *val); 151 + int (*device_u32_read)(struct counter_device *counter, 152 + u32 *val); 153 + int (*count_u32_read)(struct counter_device *counter, 154 + struct counter_count *count, u32 *val); 155 + int (*signal_u32_read)(struct counter_device *counter, 156 + struct counter_signal *signal, u32 *val); 157 + int (*device_u64_read)(struct counter_device *counter, 158 + u64 *val); 159 + int (*count_u64_read)(struct counter_device *counter, 160 + struct counter_count *count, u64 *val); 161 + int (*signal_u64_read)(struct counter_device *counter, 162 + struct counter_signal *signal, u64 *val); 163 + }; 164 + union { 165 + int (*action_write)(struct counter_device *counter, 166 + struct counter_count *count, 167 + struct counter_synapse *synapse, 168 + enum counter_synapse_action action); 169 + int (*device_u8_write)(struct counter_device *counter, u8 val); 170 + int (*count_u8_write)(struct counter_device *counter, 171 + struct counter_count *count, u8 val); 172 + int (*signal_u8_write)(struct counter_device *counter, 173 + struct counter_signal *signal, u8 val); 174 + int (*device_u32_write)(struct counter_device *counter, 175 + u32 val); 176 + int (*count_u32_write)(struct counter_device *counter, 177 + struct counter_count *count, u32 val); 178 + int (*signal_u32_write)(struct counter_device *counter, 179 + struct counter_signal *signal, u32 val); 180 + int (*device_u64_write)(struct counter_device *counter, 181 + u64 val); 182 + int (*count_u64_write)(struct counter_device *counter, 183 + struct counter_count *count, u64 val); 184 + int (*signal_u64_write)(struct counter_device *counter, 185 + struct counter_signal *signal, u64 val); 186 + }; 45 187 }; 46 188 47 189 /** ··· 193 51 * as it appears in the datasheet documentation 194 52 * @ext: optional array of Counter Signal extensions 195 53 * @num_ext: number of Counter Signal extensions specified in @ext 196 - * @priv: optional private data supplied by driver 197 54 */ 198 55 struct counter_signal { 199 56 int id; 200 57 const char *name; 201 58 202 - const struct counter_signal_ext *ext; 59 + struct counter_comp *ext; 203 60 size_t num_ext; 204 - 205 - void *priv; 206 - }; 207 - 208 - /** 209 - * struct counter_signal_enum_ext - Signal enum extension attribute 210 - * @items: Array of strings 211 - * @num_items: Number of items specified in @items 212 - * @set: Set callback function; may be NULL 213 - * @get: Get callback function; may be NULL 214 - * 215 - * The counter_signal_enum_ext structure can be used to implement enum style 216 - * Signal extension attributes. Enum style attributes are those which have a set 217 - * of strings that map to unsigned integer values. The Generic Counter Signal 218 - * enum extension helper code takes care of mapping between value and string, as 219 - * well as generating a "_available" file which contains a list of all available 220 - * items. The get callback is used to query the currently active item; the index 221 - * of the item within the respective items array is returned via the 'item' 222 - * parameter. The set callback is called when the attribute is updated; the 223 - * 'item' parameter contains the index of the newly activated item within the 224 - * respective items array. 225 - */ 226 - struct counter_signal_enum_ext { 227 - const char * const *items; 228 - size_t num_items; 229 - int (*get)(struct counter_device *counter, 230 - struct counter_signal *signal, size_t *item); 231 - int (*set)(struct counter_device *counter, 232 - struct counter_signal *signal, size_t item); 233 - }; 234 - 235 - /** 236 - * COUNTER_SIGNAL_ENUM() - Initialize Signal enum extension 237 - * @_name: Attribute name 238 - * @_e: Pointer to a counter_signal_enum_ext structure 239 - * 240 - * This should usually be used together with COUNTER_SIGNAL_ENUM_AVAILABLE() 241 - */ 242 - #define COUNTER_SIGNAL_ENUM(_name, _e) \ 243 - { \ 244 - .name = (_name), \ 245 - .read = counter_signal_enum_read, \ 246 - .write = counter_signal_enum_write, \ 247 - .priv = (_e) \ 248 - } 249 - 250 - /** 251 - * COUNTER_SIGNAL_ENUM_AVAILABLE() - Initialize Signal enum available extension 252 - * @_name: Attribute name ("_available" will be appended to the name) 253 - * @_e: Pointer to a counter_signal_enum_ext structure 254 - * 255 - * Creates a read only attribute that lists all the available enum items in a 256 - * newline separated list. This should usually be used together with 257 - * COUNTER_SIGNAL_ENUM() 258 - */ 259 - #define COUNTER_SIGNAL_ENUM_AVAILABLE(_name, _e) \ 260 - { \ 261 - .name = (_name "_available"), \ 262 - .read = counter_signal_enum_available_read, \ 263 - .priv = (_e) \ 264 - } 265 - 266 - enum counter_synapse_action { 267 - COUNTER_SYNAPSE_ACTION_NONE = 0, 268 - COUNTER_SYNAPSE_ACTION_RISING_EDGE, 269 - COUNTER_SYNAPSE_ACTION_FALLING_EDGE, 270 - COUNTER_SYNAPSE_ACTION_BOTH_EDGES 271 61 }; 272 62 273 63 /** 274 64 * struct counter_synapse - Counter Synapse node 275 - * @action: index of current action mode 276 65 * @actions_list: array of available action modes 277 66 * @num_actions: number of action modes specified in @actions_list 278 67 * @signal: pointer to associated signal 279 68 */ 280 69 struct counter_synapse { 281 - size_t action; 282 70 const enum counter_synapse_action *actions_list; 283 71 size_t num_actions; 284 72 285 73 struct counter_signal *signal; 286 - }; 287 - 288 - struct counter_count; 289 - 290 - /** 291 - * struct counter_count_ext - Counter Count extension 292 - * @name: attribute name 293 - * @read: read callback for this attribute; may be NULL 294 - * @write: write callback for this attribute; may be NULL 295 - * @priv: data private to the driver 296 - */ 297 - struct counter_count_ext { 298 - const char *name; 299 - ssize_t (*read)(struct counter_device *counter, 300 - struct counter_count *count, void *priv, char *buf); 301 - ssize_t (*write)(struct counter_device *counter, 302 - struct counter_count *count, void *priv, 303 - const char *buf, size_t len); 304 - void *priv; 305 - }; 306 - 307 - enum counter_function { 308 - COUNTER_FUNCTION_INCREASE = 0, 309 - COUNTER_FUNCTION_DECREASE, 310 - COUNTER_FUNCTION_PULSE_DIRECTION, 311 - COUNTER_FUNCTION_QUADRATURE_X1_A, 312 - COUNTER_FUNCTION_QUADRATURE_X1_B, 313 - COUNTER_FUNCTION_QUADRATURE_X2_A, 314 - COUNTER_FUNCTION_QUADRATURE_X2_B, 315 - COUNTER_FUNCTION_QUADRATURE_X4 316 74 }; 317 75 318 76 /** ··· 220 178 * @id: unique ID used to identify Count 221 179 * @name: device-specific Count name; ideally, this should match 222 180 * the name as it appears in the datasheet documentation 223 - * @function: index of current function mode 224 181 * @functions_list: array available function modes 225 182 * @num_functions: number of function modes specified in @functions_list 226 183 * @synapses: array of synapses for initialization 227 184 * @num_synapses: number of synapses specified in @synapses 228 185 * @ext: optional array of Counter Count extensions 229 186 * @num_ext: number of Counter Count extensions specified in @ext 230 - * @priv: optional private data supplied by driver 231 187 */ 232 188 struct counter_count { 233 189 int id; 234 190 const char *name; 235 191 236 - size_t function; 237 192 const enum counter_function *functions_list; 238 193 size_t num_functions; 239 194 240 195 struct counter_synapse *synapses; 241 196 size_t num_synapses; 242 197 243 - const struct counter_count_ext *ext; 198 + struct counter_comp *ext; 244 199 size_t num_ext; 245 - 246 - void *priv; 247 - }; 248 - 249 - /** 250 - * struct counter_count_enum_ext - Count enum extension attribute 251 - * @items: Array of strings 252 - * @num_items: Number of items specified in @items 253 - * @set: Set callback function; may be NULL 254 - * @get: Get callback function; may be NULL 255 - * 256 - * The counter_count_enum_ext structure can be used to implement enum style 257 - * Count extension attributes. Enum style attributes are those which have a set 258 - * of strings that map to unsigned integer values. The Generic Counter Count 259 - * enum extension helper code takes care of mapping between value and string, as 260 - * well as generating a "_available" file which contains a list of all available 261 - * items. The get callback is used to query the currently active item; the index 262 - * of the item within the respective items array is returned via the 'item' 263 - * parameter. The set callback is called when the attribute is updated; the 264 - * 'item' parameter contains the index of the newly activated item within the 265 - * respective items array. 266 - */ 267 - struct counter_count_enum_ext { 268 - const char * const *items; 269 - size_t num_items; 270 - int (*get)(struct counter_device *counter, struct counter_count *count, 271 - size_t *item); 272 - int (*set)(struct counter_device *counter, struct counter_count *count, 273 - size_t item); 274 - }; 275 - 276 - /** 277 - * COUNTER_COUNT_ENUM() - Initialize Count enum extension 278 - * @_name: Attribute name 279 - * @_e: Pointer to a counter_count_enum_ext structure 280 - * 281 - * This should usually be used together with COUNTER_COUNT_ENUM_AVAILABLE() 282 - */ 283 - #define COUNTER_COUNT_ENUM(_name, _e) \ 284 - { \ 285 - .name = (_name), \ 286 - .read = counter_count_enum_read, \ 287 - .write = counter_count_enum_write, \ 288 - .priv = (_e) \ 289 - } 290 - 291 - /** 292 - * COUNTER_COUNT_ENUM_AVAILABLE() - Initialize Count enum available extension 293 - * @_name: Attribute name ("_available" will be appended to the name) 294 - * @_e: Pointer to a counter_count_enum_ext structure 295 - * 296 - * Creates a read only attribute that lists all the available enum items in a 297 - * newline separated list. This should usually be used together with 298 - * COUNTER_COUNT_ENUM() 299 - */ 300 - #define COUNTER_COUNT_ENUM_AVAILABLE(_name, _e) \ 301 - { \ 302 - .name = (_name "_available"), \ 303 - .read = counter_count_enum_available_read, \ 304 - .priv = (_e) \ 305 - } 306 - 307 - /** 308 - * struct counter_device_attr_group - internal container for attribute group 309 - * @attr_group: Counter sysfs attributes group 310 - * @attr_list: list to keep track of created Counter sysfs attributes 311 - * @num_attr: number of Counter sysfs attributes 312 - */ 313 - struct counter_device_attr_group { 314 - struct attribute_group attr_group; 315 - struct list_head attr_list; 316 - size_t num_attr; 317 - }; 318 - 319 - /** 320 - * struct counter_device_state - internal state container for a Counter device 321 - * @id: unique ID used to identify the Counter 322 - * @dev: internal device structure 323 - * @groups_list: attribute groups list (for Signals, Counts, and ext) 324 - * @num_groups: number of attribute groups containers 325 - * @groups: Counter sysfs attribute groups (to populate @dev.groups) 326 - */ 327 - struct counter_device_state { 328 - int id; 329 - struct device dev; 330 - struct counter_device_attr_group *groups_list; 331 - size_t num_groups; 332 - const struct attribute_group **groups; 333 - }; 334 - 335 - enum counter_signal_level { 336 - COUNTER_SIGNAL_LEVEL_LOW, 337 - COUNTER_SIGNAL_LEVEL_HIGH, 338 200 }; 339 201 340 202 /** ··· 252 306 * @count_write: optional write callback for Count attribute. The write 253 307 * value for the respective Count is passed in via the val 254 308 * parameter. 255 - * @function_get: function to get the current count function mode. Returns 256 - * 0 on success and negative error code on error. The index 257 - * of the respective Count's returned function mode should 258 - * be passed back via the function parameter. 259 - * @function_set: function to set the count function mode. function is the 260 - * index of the requested function mode from the respective 261 - * Count's functions_list array. 262 - * @action_get: function to get the current action mode. Returns 0 on 263 - * success and negative error code on error. The index of 264 - * the respective Synapse's returned action mode should be 265 - * passed back via the action parameter. 266 - * @action_set: function to set the action mode. action is the index of 267 - * the requested action mode from the respective Synapse's 268 - * actions_list array. 309 + * @function_read: read callback the Count function modes. The read 310 + * function mode of the respective Count should be passed 311 + * back via the function parameter. 312 + * @function_write: write callback for Count function modes. The function 313 + * mode to write for the respective Count is passed in via 314 + * the function parameter. 315 + * @action_read: read callback the Synapse action modes. The read action 316 + * mode of the respective Synapse should be passed back via 317 + * the action parameter. 318 + * @action_write: write callback for Synapse action modes. The action mode 319 + * to write for the respective Synapse is passed in via the 320 + * action parameter. 269 321 */ 270 322 struct counter_ops { 271 323 int (*signal_read)(struct counter_device *counter, 272 324 struct counter_signal *signal, 273 325 enum counter_signal_level *level); 274 326 int (*count_read)(struct counter_device *counter, 275 - struct counter_count *count, unsigned long *val); 327 + struct counter_count *count, u64 *value); 276 328 int (*count_write)(struct counter_device *counter, 277 - struct counter_count *count, unsigned long val); 278 - int (*function_get)(struct counter_device *counter, 279 - struct counter_count *count, size_t *function); 280 - int (*function_set)(struct counter_device *counter, 281 - struct counter_count *count, size_t function); 282 - int (*action_get)(struct counter_device *counter, 283 - struct counter_count *count, 284 - struct counter_synapse *synapse, size_t *action); 285 - int (*action_set)(struct counter_device *counter, 286 - struct counter_count *count, 287 - struct counter_synapse *synapse, size_t action); 329 + struct counter_count *count, u64 value); 330 + int (*function_read)(struct counter_device *counter, 331 + struct counter_count *count, 332 + enum counter_function *function); 333 + int (*function_write)(struct counter_device *counter, 334 + struct counter_count *count, 335 + enum counter_function function); 336 + int (*action_read)(struct counter_device *counter, 337 + struct counter_count *count, 338 + struct counter_synapse *synapse, 339 + enum counter_synapse_action *action); 340 + int (*action_write)(struct counter_device *counter, 341 + struct counter_count *count, 342 + struct counter_synapse *synapse, 343 + enum counter_synapse_action action); 288 344 }; 289 - 290 - /** 291 - * struct counter_device_ext - Counter device extension 292 - * @name: attribute name 293 - * @read: read callback for this attribute; may be NULL 294 - * @write: write callback for this attribute; may be NULL 295 - * @priv: data private to the driver 296 - */ 297 - struct counter_device_ext { 298 - const char *name; 299 - ssize_t (*read)(struct counter_device *counter, void *priv, char *buf); 300 - ssize_t (*write)(struct counter_device *counter, void *priv, 301 - const char *buf, size_t len); 302 - void *priv; 303 - }; 304 - 305 - /** 306 - * struct counter_device_enum_ext - Counter enum extension attribute 307 - * @items: Array of strings 308 - * @num_items: Number of items specified in @items 309 - * @set: Set callback function; may be NULL 310 - * @get: Get callback function; may be NULL 311 - * 312 - * The counter_device_enum_ext structure can be used to implement enum style 313 - * Counter extension attributes. Enum style attributes are those which have a 314 - * set of strings that map to unsigned integer values. The Generic Counter enum 315 - * extension helper code takes care of mapping between value and string, as well 316 - * as generating a "_available" file which contains a list of all available 317 - * items. The get callback is used to query the currently active item; the index 318 - * of the item within the respective items array is returned via the 'item' 319 - * parameter. The set callback is called when the attribute is updated; the 320 - * 'item' parameter contains the index of the newly activated item within the 321 - * respective items array. 322 - */ 323 - struct counter_device_enum_ext { 324 - const char * const *items; 325 - size_t num_items; 326 - int (*get)(struct counter_device *counter, size_t *item); 327 - int (*set)(struct counter_device *counter, size_t item); 328 - }; 329 - 330 - /** 331 - * COUNTER_DEVICE_ENUM() - Initialize Counter enum extension 332 - * @_name: Attribute name 333 - * @_e: Pointer to a counter_device_enum_ext structure 334 - * 335 - * This should usually be used together with COUNTER_DEVICE_ENUM_AVAILABLE() 336 - */ 337 - #define COUNTER_DEVICE_ENUM(_name, _e) \ 338 - { \ 339 - .name = (_name), \ 340 - .read = counter_device_enum_read, \ 341 - .write = counter_device_enum_write, \ 342 - .priv = (_e) \ 343 - } 344 - 345 - /** 346 - * COUNTER_DEVICE_ENUM_AVAILABLE() - Initialize Counter enum available extension 347 - * @_name: Attribute name ("_available" will be appended to the name) 348 - * @_e: Pointer to a counter_device_enum_ext structure 349 - * 350 - * Creates a read only attribute that lists all the available enum items in a 351 - * newline separated list. This should usually be used together with 352 - * COUNTER_DEVICE_ENUM() 353 - */ 354 - #define COUNTER_DEVICE_ENUM_AVAILABLE(_name, _e) \ 355 - { \ 356 - .name = (_name "_available"), \ 357 - .read = counter_device_enum_available_read, \ 358 - .priv = (_e) \ 359 - } 360 345 361 346 /** 362 347 * struct counter_device - Counter data structure 363 348 * @name: name of the device as it appears in the datasheet 364 349 * @parent: optional parent device providing the counters 365 - * @device_state: internal device state container 366 350 * @ops: callbacks from driver 367 351 * @signals: array of Signals 368 352 * @num_signals: number of Signals specified in @signals ··· 301 425 * @ext: optional array of Counter device extensions 302 426 * @num_ext: number of Counter device extensions specified in @ext 303 427 * @priv: optional private data supplied by driver 428 + * @dev: internal device structure 304 429 */ 305 430 struct counter_device { 306 431 const char *name; 307 432 struct device *parent; 308 - struct counter_device_state *device_state; 309 433 310 434 const struct counter_ops *ops; 311 435 ··· 314 438 struct counter_count *counts; 315 439 size_t num_counts; 316 440 317 - const struct counter_device_ext *ext; 441 + struct counter_comp *ext; 318 442 size_t num_ext; 319 443 320 444 void *priv; 445 + 446 + struct device dev; 321 447 }; 322 448 323 449 int counter_register(struct counter_device *const counter); 324 450 void counter_unregister(struct counter_device *const counter); 325 451 int devm_counter_register(struct device *dev, 326 452 struct counter_device *const counter); 327 - void devm_counter_unregister(struct device *dev, 328 - struct counter_device *const counter); 453 + 454 + #define COUNTER_COMP_DEVICE_U8(_name, _read, _write) \ 455 + { \ 456 + .type = COUNTER_COMP_U8, \ 457 + .name = (_name), \ 458 + .device_u8_read = (_read), \ 459 + .device_u8_write = (_write), \ 460 + } 461 + #define COUNTER_COMP_COUNT_U8(_name, _read, _write) \ 462 + { \ 463 + .type = COUNTER_COMP_U8, \ 464 + .name = (_name), \ 465 + .count_u8_read = (_read), \ 466 + .count_u8_write = (_write), \ 467 + } 468 + #define COUNTER_COMP_SIGNAL_U8(_name, _read, _write) \ 469 + { \ 470 + .type = COUNTER_COMP_U8, \ 471 + .name = (_name), \ 472 + .signal_u8_read = (_read), \ 473 + .signal_u8_write = (_write), \ 474 + } 475 + 476 + #define COUNTER_COMP_DEVICE_U64(_name, _read, _write) \ 477 + { \ 478 + .type = COUNTER_COMP_U64, \ 479 + .name = (_name), \ 480 + .device_u64_read = (_read), \ 481 + .device_u64_write = (_write), \ 482 + } 483 + #define COUNTER_COMP_COUNT_U64(_name, _read, _write) \ 484 + { \ 485 + .type = COUNTER_COMP_U64, \ 486 + .name = (_name), \ 487 + .count_u64_read = (_read), \ 488 + .count_u64_write = (_write), \ 489 + } 490 + #define COUNTER_COMP_SIGNAL_U64(_name, _read, _write) \ 491 + { \ 492 + .type = COUNTER_COMP_U64, \ 493 + .name = (_name), \ 494 + .signal_u64_read = (_read), \ 495 + .signal_u64_write = (_write), \ 496 + } 497 + 498 + #define COUNTER_COMP_DEVICE_BOOL(_name, _read, _write) \ 499 + { \ 500 + .type = COUNTER_COMP_BOOL, \ 501 + .name = (_name), \ 502 + .device_u8_read = (_read), \ 503 + .device_u8_write = (_write), \ 504 + } 505 + #define COUNTER_COMP_COUNT_BOOL(_name, _read, _write) \ 506 + { \ 507 + .type = COUNTER_COMP_BOOL, \ 508 + .name = (_name), \ 509 + .count_u8_read = (_read), \ 510 + .count_u8_write = (_write), \ 511 + } 512 + #define COUNTER_COMP_SIGNAL_BOOL(_name, _read, _write) \ 513 + { \ 514 + .type = COUNTER_COMP_BOOL, \ 515 + .name = (_name), \ 516 + .signal_u8_read = (_read), \ 517 + .signal_u8_write = (_write), \ 518 + } 519 + 520 + struct counter_available { 521 + union { 522 + const u32 *enums; 523 + const char *const *strs; 524 + }; 525 + size_t num_items; 526 + }; 527 + 528 + #define DEFINE_COUNTER_AVAILABLE(_name, _enums) \ 529 + struct counter_available _name = { \ 530 + .enums = (_enums), \ 531 + .num_items = ARRAY_SIZE(_enums), \ 532 + } 533 + 534 + #define DEFINE_COUNTER_ENUM(_name, _strs) \ 535 + struct counter_available _name = { \ 536 + .strs = (_strs), \ 537 + .num_items = ARRAY_SIZE(_strs), \ 538 + } 539 + 540 + #define COUNTER_COMP_DEVICE_ENUM(_name, _get, _set, _available) \ 541 + { \ 542 + .type = COUNTER_COMP_ENUM, \ 543 + .name = (_name), \ 544 + .device_u32_read = (_get), \ 545 + .device_u32_write = (_set), \ 546 + .priv = &(_available), \ 547 + } 548 + #define COUNTER_COMP_COUNT_ENUM(_name, _get, _set, _available) \ 549 + { \ 550 + .type = COUNTER_COMP_ENUM, \ 551 + .name = (_name), \ 552 + .count_u32_read = (_get), \ 553 + .count_u32_write = (_set), \ 554 + .priv = &(_available), \ 555 + } 556 + #define COUNTER_COMP_SIGNAL_ENUM(_name, _get, _set, _available) \ 557 + { \ 558 + .type = COUNTER_COMP_ENUM, \ 559 + .name = (_name), \ 560 + .signal_u32_read = (_get), \ 561 + .signal_u32_write = (_set), \ 562 + .priv = &(_available), \ 563 + } 564 + 565 + #define COUNTER_COMP_CEILING(_read, _write) \ 566 + COUNTER_COMP_COUNT_U64("ceiling", _read, _write) 567 + 568 + #define COUNTER_COMP_COUNT_MODE(_read, _write, _available) \ 569 + { \ 570 + .type = COUNTER_COMP_COUNT_MODE, \ 571 + .name = "count_mode", \ 572 + .count_u32_read = (_read), \ 573 + .count_u32_write = (_write), \ 574 + .priv = &(_available), \ 575 + } 576 + 577 + #define COUNTER_COMP_DIRECTION(_read) \ 578 + { \ 579 + .type = COUNTER_COMP_COUNT_DIRECTION, \ 580 + .name = "direction", \ 581 + .count_u32_read = (_read), \ 582 + } 583 + 584 + #define COUNTER_COMP_ENABLE(_read, _write) \ 585 + COUNTER_COMP_COUNT_BOOL("enable", _read, _write) 586 + 587 + #define COUNTER_COMP_FLOOR(_read, _write) \ 588 + COUNTER_COMP_COUNT_U64("floor", _read, _write) 589 + 590 + #define COUNTER_COMP_PRESET(_read, _write) \ 591 + COUNTER_COMP_COUNT_U64("preset", _read, _write) 592 + 593 + #define COUNTER_COMP_PRESET_ENABLE(_read, _write) \ 594 + COUNTER_COMP_COUNT_BOOL("preset_enable", _read, _write) 329 595 330 596 #endif /* _COUNTER_H_ */
-45
include/linux/counter_enum.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - /* 3 - * Counter interface enum functions 4 - * Copyright (C) 2018 William Breathitt Gray 5 - */ 6 - #ifndef _COUNTER_ENUM_H_ 7 - #define _COUNTER_ENUM_H_ 8 - 9 - #include <linux/types.h> 10 - 11 - struct counter_device; 12 - struct counter_signal; 13 - struct counter_count; 14 - 15 - ssize_t counter_signal_enum_read(struct counter_device *counter, 16 - struct counter_signal *signal, void *priv, 17 - char *buf); 18 - ssize_t counter_signal_enum_write(struct counter_device *counter, 19 - struct counter_signal *signal, void *priv, 20 - const char *buf, size_t len); 21 - 22 - ssize_t counter_signal_enum_available_read(struct counter_device *counter, 23 - struct counter_signal *signal, 24 - void *priv, char *buf); 25 - 26 - ssize_t counter_count_enum_read(struct counter_device *counter, 27 - struct counter_count *count, void *priv, 28 - char *buf); 29 - ssize_t counter_count_enum_write(struct counter_device *counter, 30 - struct counter_count *count, void *priv, 31 - const char *buf, size_t len); 32 - 33 - ssize_t counter_count_enum_available_read(struct counter_device *counter, 34 - struct counter_count *count, 35 - void *priv, char *buf); 36 - 37 - ssize_t counter_device_enum_read(struct counter_device *counter, void *priv, 38 - char *buf); 39 - ssize_t counter_device_enum_write(struct counter_device *counter, void *priv, 40 - const char *buf, size_t len); 41 - 42 - ssize_t counter_device_enum_available_read(struct counter_device *counter, 43 - void *priv, char *buf); 44 - 45 - #endif /* _COUNTER_ENUM_H_ */