diff options
| -rw-r--r-- | drivers/base/regmap/regmap.c | 143 |
1 files changed, 50 insertions, 93 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index e4e567e82b84..01ae4b829360 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
| @@ -449,100 +449,64 @@ int regmap_attach_dev(struct device *dev, struct regmap *map, | |||
| 449 | } | 449 | } |
| 450 | EXPORT_SYMBOL_GPL(regmap_attach_dev); | 450 | EXPORT_SYMBOL_GPL(regmap_attach_dev); |
| 451 | 451 | ||
| 452 | enum regmap_endian_type { | 452 | static enum regmap_endian regmap_get_reg_endian(const struct regmap_bus *bus, |
| 453 | REGMAP_ENDIAN_REG, | 453 | const struct regmap_config *config) |
| 454 | REGMAP_ENDIAN_VAL, | 454 | { |
| 455 | }; | 455 | enum regmap_endian endian; |
| 456 | 456 | ||
| 457 | static int of_regmap_get_endian(struct device *dev, | 457 | /* Retrieve the endianness specification from the regmap config */ |
| 458 | const struct regmap_bus *bus, | 458 | endian = config->reg_format_endian; |
| 459 | const struct regmap_config *config, | 459 | |
| 460 | enum regmap_endian_type type, | 460 | /* If the regmap config specified a non-default value, use that */ |
| 461 | enum regmap_endian *endian) | 461 | if (endian != REGMAP_ENDIAN_DEFAULT) |
| 462 | return endian; | ||
| 463 | |||
| 464 | /* Retrieve the endianness specification from the bus config */ | ||
| 465 | if (bus && bus->reg_format_endian_default) | ||
| 466 | endian = bus->reg_format_endian_default; | ||
| 467 | |||
| 468 | /* If the bus specified a non-default value, use that */ | ||
| 469 | if (endian != REGMAP_ENDIAN_DEFAULT) | ||
| 470 | return endian; | ||
| 471 | |||
| 472 | /* Use this if no other value was found */ | ||
| 473 | return REGMAP_ENDIAN_BIG; | ||
| 474 | } | ||
| 475 | |||
| 476 | static enum regmap_endian regmap_get_val_endian(struct device *dev, | ||
| 477 | const struct regmap_bus *bus, | ||
| 478 | const struct regmap_config *config) | ||
| 462 | { | 479 | { |
| 463 | struct device_node *np = dev->of_node; | 480 | struct device_node *np = dev->of_node; |
| 481 | enum regmap_endian endian; | ||
| 464 | 482 | ||
| 465 | if (!endian || !config) | 483 | /* Retrieve the endianness specification from the regmap config */ |
| 466 | return -EINVAL; | 484 | endian = config->val_format_endian; |
| 467 | 485 | ||
| 468 | /* | 486 | /* If the regmap config specified a non-default value, use that */ |
| 469 | * Firstly, try to parse the endianness from driver's config, | 487 | if (endian != REGMAP_ENDIAN_DEFAULT) |
| 470 | * this is to be compatible with the none DT or the old drivers. | 488 | return endian; |
| 471 | * From the driver's config the endianness value maybe: | ||
| 472 | * REGMAP_ENDIAN_BIG, | ||
| 473 | * REGMAP_ENDIAN_LITTLE, | ||
| 474 | * REGMAP_ENDIAN_NATIVE, | ||
| 475 | * REGMAP_ENDIAN_DEFAULT. | ||
| 476 | */ | ||
| 477 | switch (type) { | ||
| 478 | case REGMAP_ENDIAN_REG: | ||
| 479 | *endian = config->reg_format_endian; | ||
| 480 | break; | ||
| 481 | case REGMAP_ENDIAN_VAL: | ||
| 482 | *endian = config->val_format_endian; | ||
| 483 | break; | ||
| 484 | default: | ||
| 485 | return -EINVAL; | ||
| 486 | } | ||
| 487 | 489 | ||
| 488 | /* | 490 | /* Parse the device's DT node for an endianness specification */ |
| 489 | * If the endianness parsed from driver config is | 491 | if (of_property_read_bool(np, "big-endian")) |
| 490 | * REGMAP_ENDIAN_DEFAULT, that means maybe we are using the DT | 492 | endian = REGMAP_ENDIAN_BIG; |
| 491 | * node to specify the endianness information. | 493 | else if (of_property_read_bool(np, "little-endian")) |
| 492 | */ | 494 | endian = REGMAP_ENDIAN_LITTLE; |
| 493 | if (*endian != REGMAP_ENDIAN_DEFAULT) | ||
| 494 | return 0; | ||
| 495 | 495 | ||
| 496 | /* | 496 | /* If the endianness was specified in DT, use that */ |
| 497 | * Secondly, try to parse the endianness from DT node if the | 497 | if (endian != REGMAP_ENDIAN_DEFAULT) |
| 498 | * driver config does not specify it. | 498 | return endian; |
| 499 | * From the DT node the endianness value maybe: | ||
| 500 | * REGMAP_ENDIAN_BIG, | ||
| 501 | * REGMAP_ENDIAN_LITTLE, | ||
| 502 | * REGMAP_ENDIAN_NATIVE, | ||
| 503 | */ | ||
| 504 | switch (type) { | ||
| 505 | case REGMAP_ENDIAN_VAL: | ||
| 506 | if (of_property_read_bool(np, "big-endian")) | ||
| 507 | *endian = REGMAP_ENDIAN_BIG; | ||
| 508 | else if (of_property_read_bool(np, "little-endian")) | ||
| 509 | *endian = REGMAP_ENDIAN_LITTLE; | ||
| 510 | else | ||
| 511 | *endian = REGMAP_ENDIAN_NATIVE; | ||
| 512 | break; | ||
| 513 | case REGMAP_ENDIAN_REG: | ||
| 514 | break; | ||
| 515 | default: | ||
| 516 | return -EINVAL; | ||
| 517 | } | ||
| 518 | 499 | ||
| 519 | /* | 500 | /* Retrieve the endianness specification from the bus config */ |
| 520 | * If the endianness parsed from DT node is REGMAP_ENDIAN_NATIVE, that | 501 | if (bus && bus->val_format_endian_default) |
| 521 | * maybe means the DT does not care the endianness or it should use | 502 | endian = bus->val_format_endian_default; |
| 522 | * the regmap bus's default endianness, then we should try to check | ||
| 523 | * whether the regmap bus has specified the default endianness. | ||
| 524 | */ | ||
| 525 | if (*endian != REGMAP_ENDIAN_NATIVE) | ||
| 526 | return 0; | ||
| 527 | 503 | ||
| 528 | /* | 504 | /* If the bus specified a non-default value, use that */ |
| 529 | * Finally, try to parse the endianness from regmap bus config | 505 | if (endian != REGMAP_ENDIAN_DEFAULT) |
| 530 | * if in device's DT node the endianness property is absent. | 506 | return endian; |
| 531 | */ | ||
| 532 | switch (type) { | ||
| 533 | case REGMAP_ENDIAN_REG: | ||
| 534 | if (bus && bus->reg_format_endian_default) | ||
| 535 | *endian = bus->reg_format_endian_default; | ||
| 536 | break; | ||
| 537 | case REGMAP_ENDIAN_VAL: | ||
| 538 | if (bus && bus->val_format_endian_default) | ||
| 539 | *endian = bus->val_format_endian_default; | ||
| 540 | break; | ||
| 541 | default: | ||
| 542 | return -EINVAL; | ||
| 543 | } | ||
| 544 | 507 | ||
| 545 | return 0; | 508 | /* Use this if no other value was found */ |
| 509 | return REGMAP_ENDIAN_BIG; | ||
| 546 | } | 510 | } |
| 547 | 511 | ||
| 548 | /** | 512 | /** |
| @@ -648,15 +612,8 @@ struct regmap *regmap_init(struct device *dev, | |||
| 648 | map->reg_read = _regmap_bus_read; | 612 | map->reg_read = _regmap_bus_read; |
| 649 | } | 613 | } |
| 650 | 614 | ||
| 651 | ret = of_regmap_get_endian(dev, bus, config, REGMAP_ENDIAN_REG, | 615 | reg_endian = regmap_get_reg_endian(bus, config); |
| 652 | ®_endian); | 616 | val_endian = regmap_get_val_endian(dev, bus, config); |
| 653 | if (ret) | ||
| 654 | return ERR_PTR(ret); | ||
| 655 | |||
| 656 | ret = of_regmap_get_endian(dev, bus, config, REGMAP_ENDIAN_VAL, | ||
| 657 | &val_endian); | ||
| 658 | if (ret) | ||
| 659 | return ERR_PTR(ret); | ||
| 660 | 617 | ||
| 661 | switch (config->reg_bits + map->reg_shift) { | 618 | switch (config->reg_bits + map->reg_shift) { |
| 662 | case 2: | 619 | case 2: |
