1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __LINUX_GPIO_CONSUMER_H 3 #define __LINUX_GPIO_CONSUMER_H 4 5 #include <linux/bits.h> 6 #include <linux/err.h> 7 #include <linux/types.h> 8 9 struct acpi_device; 10 struct device; 11 struct fwnode_handle; 12 13 struct gpio_array; 14 struct gpio_desc; 15 16 /** 17 * struct gpio_descs - Struct containing an array of descriptors that can be 18 * obtained using gpiod_get_array() 19 * 20 * @info: Pointer to the opaque gpio_array structure 21 * @ndescs: Number of held descriptors 22 * @desc: Array of pointers to GPIO descriptors 23 */ 24 struct gpio_descs { 25 struct gpio_array *info; 26 unsigned int ndescs; 27 struct gpio_desc *desc[]; 28 }; 29 30 #define GPIOD_FLAGS_BIT_DIR_SET BIT(0) 31 #define GPIOD_FLAGS_BIT_DIR_OUT BIT(1) 32 #define GPIOD_FLAGS_BIT_DIR_VAL BIT(2) 33 #define GPIOD_FLAGS_BIT_OPEN_DRAIN BIT(3) 34 /* GPIOD_FLAGS_BIT_NONEXCLUSIVE is DEPRECATED, don't use in new code. */ 35 #define GPIOD_FLAGS_BIT_NONEXCLUSIVE BIT(4) 36 37 /** 38 * enum gpiod_flags - Optional flags that can be passed to one of gpiod_* to 39 * configure direction and output value. These values 40 * cannot be OR'd. 41 * 42 * @GPIOD_ASIS: Don't change anything 43 * @GPIOD_IN: Set lines to input mode 44 * @GPIOD_OUT_LOW: Set lines to output and drive them low 45 * @GPIOD_OUT_HIGH: Set lines to output and drive them high 46 * @GPIOD_OUT_LOW_OPEN_DRAIN: Set lines to open-drain output and drive them low 47 * @GPIOD_OUT_HIGH_OPEN_DRAIN: Set lines to open-drain output and drive them high 48 */ 49 enum gpiod_flags { 50 GPIOD_ASIS = 0, 51 GPIOD_IN = GPIOD_FLAGS_BIT_DIR_SET, 52 GPIOD_OUT_LOW = GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT, 53 GPIOD_OUT_HIGH = GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT | 54 GPIOD_FLAGS_BIT_DIR_VAL, 55 GPIOD_OUT_LOW_OPEN_DRAIN = GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_OPEN_DRAIN, 56 GPIOD_OUT_HIGH_OPEN_DRAIN = GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_OPEN_DRAIN, 57 }; 58 59 #ifdef CONFIG_GPIOLIB 60 61 /* Return the number of GPIOs associated with a device / function */ 62 int gpiod_count(struct device *dev, const char *con_id); 63 64 /* Acquire and dispose GPIOs */ 65 struct gpio_desc *__must_check gpiod_get(struct device *dev, 66 const char *con_id, 67 enum gpiod_flags flags); 68 struct gpio_desc *__must_check gpiod_get_index(struct device *dev, 69 const char *con_id, 70 unsigned int idx, 71 enum gpiod_flags flags); 72 struct gpio_desc *__must_check gpiod_get_optional(struct device *dev, 73 const char *con_id, 74 enum gpiod_flags flags); 75 struct gpio_desc *__must_check gpiod_get_index_optional(struct device *dev, 76 const char *con_id, 77 unsigned int index, 78 enum gpiod_flags flags); 79 struct gpio_descs *__must_check gpiod_get_array(struct device *dev, 80 const char *con_id, 81 enum gpiod_flags flags); 82 struct gpio_descs *__must_check gpiod_get_array_optional(struct device *dev, 83 const char *con_id, 84 enum gpiod_flags flags); 85 void gpiod_put(struct gpio_desc *desc); 86 void gpiod_put_array(struct gpio_descs *descs); 87 88 struct gpio_desc *__must_check devm_gpiod_get(struct device *dev, 89 const char *con_id, 90 enum gpiod_flags flags); 91 struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev, 92 const char *con_id, 93 unsigned int idx, 94 enum gpiod_flags flags); 95 struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev, 96 const char *con_id, 97 enum gpiod_flags flags); 98 struct gpio_desc *__must_check 99 devm_gpiod_get_index_optional(struct device *dev, const char *con_id, 100 unsigned int index, enum gpiod_flags flags); 101 struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev, 102 const char *con_id, 103 enum gpiod_flags flags); 104 struct gpio_descs *__must_check 105 devm_gpiod_get_array_optional(struct device *dev, const char *con_id, 106 enum gpiod_flags flags); 107 void devm_gpiod_put(struct device *dev, struct gpio_desc *desc); 108 void devm_gpiod_unhinge(struct device *dev, struct gpio_desc *desc); 109 void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs); 110 111 int gpiod_get_direction(struct gpio_desc *desc); 112 int gpiod_direction_input(struct gpio_desc *desc); 113 int gpiod_direction_output(struct gpio_desc *desc, int value); 114 int gpiod_direction_output_raw(struct gpio_desc *desc, int value); 115 116 /* Value get/set from non-sleeping context */ 117 int gpiod_get_value(const struct gpio_desc *desc); 118 int gpiod_get_array_value(unsigned int array_size, 119 struct gpio_desc **desc_array, 120 struct gpio_array *array_info, 121 unsigned long *value_bitmap); 122 int gpiod_set_value(struct gpio_desc *desc, int value); 123 int gpiod_set_array_value(unsigned int array_size, 124 struct gpio_desc **desc_array, 125 struct gpio_array *array_info, 126 unsigned long *value_bitmap); 127 int gpiod_get_raw_value(const struct gpio_desc *desc); 128 int gpiod_get_raw_array_value(unsigned int array_size, 129 struct gpio_desc **desc_array, 130 struct gpio_array *array_info, 131 unsigned long *value_bitmap); 132 int gpiod_set_raw_value(struct gpio_desc *desc, int value); 133 int gpiod_set_raw_array_value(unsigned int array_size, 134 struct gpio_desc **desc_array, 135 struct gpio_array *array_info, 136 unsigned long *value_bitmap); 137 138 /* Value get/set from sleeping context */ 139 int gpiod_get_value_cansleep(const struct gpio_desc *desc); 140 int gpiod_get_array_value_cansleep(unsigned int array_size, 141 struct gpio_desc **desc_array, 142 struct gpio_array *array_info, 143 unsigned long *value_bitmap); 144 int gpiod_set_value_cansleep(struct gpio_desc *desc, int value); 145 int gpiod_set_array_value_cansleep(unsigned int array_size, 146 struct gpio_desc **desc_array, 147 struct gpio_array *array_info, 148 unsigned long *value_bitmap); 149 int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc); 150 int gpiod_get_raw_array_value_cansleep(unsigned int array_size, 151 struct gpio_desc **desc_array, 152 struct gpio_array *array_info, 153 unsigned long *value_bitmap); 154 int gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value); 155 int gpiod_set_raw_array_value_cansleep(unsigned int array_size, 156 struct gpio_desc **desc_array, 157 struct gpio_array *array_info, 158 unsigned long *value_bitmap); 159 160 int gpiod_set_config(struct gpio_desc *desc, unsigned long config); 161 int gpiod_set_debounce(struct gpio_desc *desc, unsigned int debounce); 162 void gpiod_toggle_active_low(struct gpio_desc *desc); 163 164 int gpiod_is_active_low(const struct gpio_desc *desc); 165 int gpiod_cansleep(const struct gpio_desc *desc); 166 167 int gpiod_to_irq(const struct gpio_desc *desc); 168 int gpiod_set_consumer_name(struct gpio_desc *desc, const char *name); 169 170 /* Convert between the old gpio_ and new gpiod_ interfaces */ 171 struct gpio_desc *gpio_to_desc(unsigned gpio); 172 int desc_to_gpio(const struct gpio_desc *desc); 173 174 struct gpio_desc *fwnode_gpiod_get_index(struct fwnode_handle *fwnode, 175 const char *con_id, int index, 176 enum gpiod_flags flags, 177 const char *label); 178 struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev, 179 struct fwnode_handle *child, 180 const char *con_id, int index, 181 enum gpiod_flags flags, 182 const char *label); 183 184 #else /* CONFIG_GPIOLIB */ 185 186 #include <linux/bug.h> 187 #include <linux/kernel.h> 188 189 static inline int gpiod_count(struct device *dev, const char *con_id) 190 { 191 return 0; 192 } 193 194 static inline struct gpio_desc *__must_check gpiod_get(struct device *dev, 195 const char *con_id, 196 enum gpiod_flags flags) 197 { 198 return ERR_PTR(-ENOSYS); 199 } 200 static inline struct gpio_desc *__must_check 201 gpiod_get_index(struct device *dev, 202 const char *con_id, 203 unsigned int idx, 204 enum gpiod_flags flags) 205 { 206 return ERR_PTR(-ENOSYS); 207 } 208 209 static inline struct gpio_desc *__must_check 210 gpiod_get_optional(struct device *dev, const char *con_id, 211 enum gpiod_flags flags) 212 { 213 return NULL; 214 } 215 216 static inline struct gpio_desc *__must_check 217 gpiod_get_index_optional(struct device *dev, const char *con_id, 218 unsigned int index, enum gpiod_flags flags) 219 { 220 return NULL; 221 } 222 223 static inline struct gpio_descs *__must_check 224 gpiod_get_array(struct device *dev, const char *con_id, 225 enum gpiod_flags flags) 226 { 227 return ERR_PTR(-ENOSYS); 228 } 229 230 static inline struct gpio_descs *__must_check 231 gpiod_get_array_optional(struct device *dev, const char *con_id, 232 enum gpiod_flags flags) 233 { 234 return NULL; 235 } 236 237 static inline void gpiod_put(struct gpio_desc *desc) 238 { 239 might_sleep(); 240 241 /* GPIO can never have been requested */ 242 WARN_ON(desc); 243 } 244 245 static inline void devm_gpiod_unhinge(struct device *dev, 246 struct gpio_desc *desc) 247 { 248 might_sleep(); 249 250 /* GPIO can never have been requested */ 251 WARN_ON(desc); 252 } 253 254 static inline void gpiod_put_array(struct gpio_descs *descs) 255 { 256 might_sleep(); 257 258 /* GPIO can never have been requested */ 259 WARN_ON(descs); 260 } 261 262 static inline struct gpio_desc *__must_check 263 devm_gpiod_get(struct device *dev, 264 const char *con_id, 265 enum gpiod_flags flags) 266 { 267 return ERR_PTR(-ENOSYS); 268 } 269 static inline 270 struct gpio_desc *__must_check 271 devm_gpiod_get_index(struct device *dev, 272 const char *con_id, 273 unsigned int idx, 274 enum gpiod_flags flags) 275 { 276 return ERR_PTR(-ENOSYS); 277 } 278 279 static inline struct gpio_desc *__must_check 280 devm_gpiod_get_optional(struct device *dev, const char *con_id, 281 enum gpiod_flags flags) 282 { 283 return NULL; 284 } 285 286 static inline struct gpio_desc *__must_check 287 devm_gpiod_get_index_optional(struct device *dev, const char *con_id, 288 unsigned int index, enum gpiod_flags flags) 289 { 290 return NULL; 291 } 292 293 static inline struct gpio_descs *__must_check 294 devm_gpiod_get_array(struct device *dev, const char *con_id, 295 enum gpiod_flags flags) 296 { 297 return ERR_PTR(-ENOSYS); 298 } 299 300 static inline struct gpio_descs *__must_check 301 devm_gpiod_get_array_optional(struct device *dev, const char *con_id, 302 enum gpiod_flags flags) 303 { 304 return NULL; 305 } 306 307 static inline void devm_gpiod_put(struct device *dev, struct gpio_desc *desc) 308 { 309 might_sleep(); 310 311 /* GPIO can never have been requested */ 312 WARN_ON(desc); 313 } 314 315 static inline void devm_gpiod_put_array(struct device *dev, 316 struct gpio_descs *descs) 317 { 318 might_sleep(); 319 320 /* GPIO can never have been requested */ 321 WARN_ON(descs); 322 } 323 324 325 static inline int gpiod_get_direction(const struct gpio_desc *desc) 326 { 327 /* GPIO can never have been requested */ 328 WARN_ON(desc); 329 return -ENOSYS; 330 } 331 static inline int gpiod_direction_input(struct gpio_desc *desc) 332 { 333 /* GPIO can never have been requested */ 334 WARN_ON(desc); 335 return -ENOSYS; 336 } 337 static inline int gpiod_direction_output(struct gpio_desc *desc, int value) 338 { 339 /* GPIO can never have been requested */ 340 WARN_ON(desc); 341 return -ENOSYS; 342 } 343 static inline int gpiod_direction_output_raw(struct gpio_desc *desc, int value) 344 { 345 /* GPIO can never have been requested */ 346 WARN_ON(desc); 347 return -ENOSYS; 348 } 349 static inline int gpiod_get_value(const struct gpio_desc *desc) 350 { 351 /* GPIO can never have been requested */ 352 WARN_ON(desc); 353 return 0; 354 } 355 static inline int gpiod_get_array_value(unsigned int array_size, 356 struct gpio_desc **desc_array, 357 struct gpio_array *array_info, 358 unsigned long *value_bitmap) 359 { 360 /* GPIO can never have been requested */ 361 WARN_ON(desc_array); 362 return 0; 363 } 364 static inline int gpiod_set_value(struct gpio_desc *desc, int value) 365 { 366 /* GPIO can never have been requested */ 367 WARN_ON(desc); 368 return 0; 369 } 370 static inline int gpiod_set_array_value(unsigned int array_size, 371 struct gpio_desc **desc_array, 372 struct gpio_array *array_info, 373 unsigned long *value_bitmap) 374 { 375 /* GPIO can never have been requested */ 376 WARN_ON(desc_array); 377 return 0; 378 } 379 static inline int gpiod_get_raw_value(const struct gpio_desc *desc) 380 { 381 /* GPIO can never have been requested */ 382 WARN_ON(desc); 383 return 0; 384 } 385 static inline int gpiod_get_raw_array_value(unsigned int array_size, 386 struct gpio_desc **desc_array, 387 struct gpio_array *array_info, 388 unsigned long *value_bitmap) 389 { 390 /* GPIO can never have been requested */ 391 WARN_ON(desc_array); 392 return 0; 393 } 394 static inline int gpiod_set_raw_value(struct gpio_desc *desc, int value) 395 { 396 /* GPIO can never have been requested */ 397 WARN_ON(desc); 398 return 0; 399 } 400 static inline int gpiod_set_raw_array_value(unsigned int array_size, 401 struct gpio_desc **desc_array, 402 struct gpio_array *array_info, 403 unsigned long *value_bitmap) 404 { 405 /* GPIO can never have been requested */ 406 WARN_ON(desc_array); 407 return 0; 408 } 409 410 static inline int gpiod_get_value_cansleep(const struct gpio_desc *desc) 411 { 412 /* GPIO can never have been requested */ 413 WARN_ON(desc); 414 return 0; 415 } 416 static inline int gpiod_get_array_value_cansleep(unsigned int array_size, 417 struct gpio_desc **desc_array, 418 struct gpio_array *array_info, 419 unsigned long *value_bitmap) 420 { 421 /* GPIO can never have been requested */ 422 WARN_ON(desc_array); 423 return 0; 424 } 425 static inline int gpiod_set_value_cansleep(struct gpio_desc *desc, int value) 426 { 427 /* GPIO can never have been requested */ 428 WARN_ON(desc); 429 return 0; 430 } 431 static inline int gpiod_set_array_value_cansleep(unsigned int array_size, 432 struct gpio_desc **desc_array, 433 struct gpio_array *array_info, 434 unsigned long *value_bitmap) 435 { 436 /* GPIO can never have been requested */ 437 WARN_ON(desc_array); 438 return 0; 439 } 440 static inline int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc) 441 { 442 /* GPIO can never have been requested */ 443 WARN_ON(desc); 444 return 0; 445 } 446 static inline int gpiod_get_raw_array_value_cansleep(unsigned int array_size, 447 struct gpio_desc **desc_array, 448 struct gpio_array *array_info, 449 unsigned long *value_bitmap) 450 { 451 /* GPIO can never have been requested */ 452 WARN_ON(desc_array); 453 return 0; 454 } 455 static inline int gpiod_set_raw_value_cansleep(struct gpio_desc *desc, 456 int value) 457 { 458 /* GPIO can never have been requested */ 459 WARN_ON(desc); 460 return 0; 461 } 462 static inline int gpiod_set_raw_array_value_cansleep(unsigned int array_size, 463 struct gpio_desc **desc_array, 464 struct gpio_array *array_info, 465 unsigned long *value_bitmap) 466 { 467 /* GPIO can never have been requested */ 468 WARN_ON(desc_array); 469 return 0; 470 } 471 472 static inline int gpiod_set_config(struct gpio_desc *desc, unsigned long config) 473 { 474 /* GPIO can never have been requested */ 475 WARN_ON(desc); 476 return -ENOSYS; 477 } 478 479 static inline int gpiod_set_debounce(struct gpio_desc *desc, unsigned int debounce) 480 { 481 /* GPIO can never have been requested */ 482 WARN_ON(desc); 483 return -ENOSYS; 484 } 485 486 static inline void gpiod_toggle_active_low(struct gpio_desc *desc) 487 { 488 /* GPIO can never have been requested */ 489 WARN_ON(desc); 490 } 491 492 static inline int gpiod_is_active_low(const struct gpio_desc *desc) 493 { 494 /* GPIO can never have been requested */ 495 WARN_ON(desc); 496 return 0; 497 } 498 static inline int gpiod_cansleep(const struct gpio_desc *desc) 499 { 500 /* GPIO can never have been requested */ 501 WARN_ON(desc); 502 return 0; 503 } 504 505 static inline int gpiod_to_irq(const struct gpio_desc *desc) 506 { 507 /* GPIO can never have been requested */ 508 WARN_ON(desc); 509 return -EINVAL; 510 } 511 512 static inline int gpiod_set_consumer_name(struct gpio_desc *desc, 513 const char *name) 514 { 515 /* GPIO can never have been requested */ 516 WARN_ON(desc); 517 return -EINVAL; 518 } 519 520 static inline struct gpio_desc *gpio_to_desc(unsigned gpio) 521 { 522 return NULL; 523 } 524 525 static inline int desc_to_gpio(const struct gpio_desc *desc) 526 { 527 /* GPIO can never have been requested */ 528 WARN_ON(desc); 529 return -EINVAL; 530 } 531 532 static inline 533 struct gpio_desc *fwnode_gpiod_get_index(struct fwnode_handle *fwnode, 534 const char *con_id, int index, 535 enum gpiod_flags flags, 536 const char *label) 537 { 538 return ERR_PTR(-ENOSYS); 539 } 540 541 static inline 542 struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev, 543 struct fwnode_handle *fwnode, 544 const char *con_id, int index, 545 enum gpiod_flags flags, 546 const char *label) 547 { 548 return ERR_PTR(-ENOSYS); 549 } 550 551 #endif /* CONFIG_GPIOLIB */ 552 553 #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_HTE) 554 int gpiod_enable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags); 555 int gpiod_disable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags); 556 #else 557 558 #include <linux/bug.h> 559 560 static inline int gpiod_enable_hw_timestamp_ns(struct gpio_desc *desc, 561 unsigned long flags) 562 { 563 if (!IS_ENABLED(CONFIG_GPIOLIB)) 564 WARN_ON(desc); 565 566 return -ENOSYS; 567 } 568 static inline int gpiod_disable_hw_timestamp_ns(struct gpio_desc *desc, 569 unsigned long flags) 570 { 571 if (!IS_ENABLED(CONFIG_GPIOLIB)) 572 WARN_ON(desc); 573 574 return -ENOSYS; 575 } 576 #endif /* CONFIG_GPIOLIB && CONFIG_HTE */ 577 578 static inline 579 struct gpio_desc *devm_fwnode_gpiod_get(struct device *dev, 580 struct fwnode_handle *fwnode, 581 const char *con_id, 582 enum gpiod_flags flags, 583 const char *label) 584 { 585 return devm_fwnode_gpiod_get_index(dev, fwnode, con_id, 0, 586 flags, label); 587 } 588 589 struct acpi_gpio_params { 590 unsigned int crs_entry_index; 591 unsigned int line_index; 592 bool active_low; 593 }; 594 595 struct acpi_gpio_mapping { 596 const char *name; 597 const struct acpi_gpio_params *data; 598 unsigned int size; 599 600 /* Ignore IoRestriction field */ 601 #define ACPI_GPIO_QUIRK_NO_IO_RESTRICTION BIT(0) 602 /* 603 * When ACPI GPIO mapping table is in use the index parameter inside it 604 * refers to the GPIO resource in _CRS method. That index has no 605 * distinction of actual type of the resource. When consumer wants to 606 * get GpioIo type explicitly, this quirk may be used. 607 */ 608 #define ACPI_GPIO_QUIRK_ONLY_GPIOIO BIT(1) 609 /* Use given pin as an absolute GPIO number in the system */ 610 #define ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER BIT(2) 611 612 unsigned int quirks; 613 }; 614 615 #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_ACPI) 616 617 int acpi_dev_add_driver_gpios(struct acpi_device *adev, 618 const struct acpi_gpio_mapping *gpios); 619 void acpi_dev_remove_driver_gpios(struct acpi_device *adev); 620 621 int devm_acpi_dev_add_driver_gpios(struct device *dev, 622 const struct acpi_gpio_mapping *gpios); 623 624 #else /* CONFIG_GPIOLIB && CONFIG_ACPI */ 625 626 static inline int acpi_dev_add_driver_gpios(struct acpi_device *adev, 627 const struct acpi_gpio_mapping *gpios) 628 { 629 return -ENXIO; 630 } 631 static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev) {} 632 633 static inline int devm_acpi_dev_add_driver_gpios(struct device *dev, 634 const struct acpi_gpio_mapping *gpios) 635 { 636 return -ENXIO; 637 } 638 639 #endif /* CONFIG_GPIOLIB && CONFIG_ACPI */ 640 641 642 #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS) 643 644 int gpiod_export(struct gpio_desc *desc, bool direction_may_change); 645 int gpiod_export_link(struct device *dev, const char *name, 646 struct gpio_desc *desc); 647 void gpiod_unexport(struct gpio_desc *desc); 648 649 #else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */ 650 651 static inline int gpiod_export(struct gpio_desc *desc, 652 bool direction_may_change) 653 { 654 return -ENOSYS; 655 } 656 657 static inline int gpiod_export_link(struct device *dev, const char *name, 658 struct gpio_desc *desc) 659 { 660 return -ENOSYS; 661 } 662 663 static inline void gpiod_unexport(struct gpio_desc *desc) 664 { 665 } 666 667 #endif /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */ 668 669 static inline int gpiod_multi_set_value_cansleep(struct gpio_descs *descs, 670 unsigned long *value_bitmap) 671 { 672 if (IS_ERR_OR_NULL(descs)) 673 return PTR_ERR_OR_ZERO(descs); 674 675 return gpiod_set_array_value_cansleep(descs->ndescs, descs->desc, 676 descs->info, value_bitmap); 677 } 678 679 #endif 680