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

Configure Feed

Select the types of activity you want to include in your feed.

regulator: s2mps11: update node parsing (allow -supply properties)

For the upcoming S2MPG10 and S2MPG11 support, we need to be able to
parse -supply properties in the PMIC's DT node.

This currently doesn't work, because the code here currently points the
regulator core at each individual regulator sub-node, and therefore the
regulator core is unable to find the -supply properties.

Update the code to simply let the regulator core handle all the parsing
by adding the ::of_match and ::regulators_node members to all existing
regulator descriptions, by adding ::of_parse_cb() to those
regulators which support the vendor-specific samsung,ext-control-gpios
to parse it (S2MPS14), and by dropping the explicit call to
of_regulator_match().

Configuring the PMIC to respect the external control GPIOs via
s2mps14_pmic_enable_ext_control() is left outside ::of_parse_cb()
because the regulator core ignores errors other than -EPROBE_DEFER from
that callback, while the code currently fails probe on register write
errors and I believe it should stay that way.

The driver can now avoid the devm_gpiod_unhinge() dance due to
simpler error handling of GPIO descriptor acquisition.

This change also has the advantage of reducing runtime memory
consumption by quite a bit as the driver doesn't need to allocate a
'struct of_regulator_match' and a 'struct gpio_desc *' for each
regulator for all PMICs as the regulator core does that. This saves
40+8 bytes on arm64 for each individual regulator on all supported
PMICs (even on non-S2MPS14 due to currently unnecessarily allocating
the extra memory unconditionally). With the upcoming S2MPG10 and
S2MPG11 support, this amounts to 1640+328 and 1120+224 bytes
respectively.

Signed-off-by: André Draszik <andre.draszik@linaro.org>
Link: https://patch.msgid.link/20260122-s2mpg1x-regulators-v7-14-3b1f9831fffd@linaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

André Draszik and committed by
Mark Brown
5b3c9573 223cefd0

+105 -87
+105 -87
drivers/regulator/s2mps11.c
··· 40 40 * the suspend mode was enabled. 41 41 */ 42 42 DECLARE_BITMAP(suspend_state, S2MPS_REGULATOR_MAX); 43 - 44 - /* 45 - * Array (size: number of regulators) with GPIO-s for external 46 - * sleep control. 47 - */ 48 - struct gpio_desc **ext_control_gpiod; 49 43 }; 50 44 51 45 static int get_ramp_delay(int ramp_delay) ··· 238 244 case S2MPS14X: 239 245 if (test_bit(rdev_id, s2mps11->suspend_state)) 240 246 val = S2MPS14_ENABLE_SUSPEND; 241 - else if (s2mps11->ext_control_gpiod[rdev_id]) 247 + else if (rdev->ena_pin) 242 248 val = S2MPS14_ENABLE_EXT_CONTROL; 243 249 else 244 250 val = rdev->desc->enable_mask; ··· 328 334 rdev->desc->enable_mask, state); 329 335 } 330 336 337 + static int s2mps11_of_parse_cb(struct device_node *np, 338 + const struct regulator_desc *desc, 339 + struct regulator_config *config) 340 + { 341 + const struct s2mps11_info *s2mps11 = config->driver_data; 342 + struct gpio_desc *ena_gpiod; 343 + int ret; 344 + 345 + if (s2mps11->dev_type == S2MPS14X) 346 + switch (desc->id) { 347 + case S2MPS14_LDO10: 348 + case S2MPS14_LDO11: 349 + case S2MPS14_LDO12: 350 + break; 351 + 352 + default: 353 + return 0; 354 + } 355 + else 356 + return 0; 357 + 358 + ena_gpiod = fwnode_gpiod_get_index(of_fwnode_handle(np), 359 + "samsung,ext-control", 0, 360 + GPIOD_OUT_HIGH | 361 + GPIOD_FLAGS_BIT_NONEXCLUSIVE, 362 + "s2mps11-regulator"); 363 + if (IS_ERR(ena_gpiod)) { 364 + ret = PTR_ERR(ena_gpiod); 365 + 366 + /* Ignore all errors except probe defer. */ 367 + if (ret == -EPROBE_DEFER) 368 + return ret; 369 + 370 + if (ret == -ENOENT) 371 + dev_info(config->dev, 372 + "No entry for control GPIO for %d/%s in node %pOF\n", 373 + desc->id, desc->name, np); 374 + else 375 + dev_warn_probe(config->dev, ret, 376 + "Failed to get control GPIO for %d/%s in node %pOF\n", 377 + desc->id, desc->name, np); 378 + return 0; 379 + } 380 + 381 + dev_info(config->dev, "Using GPIO for ext-control over %d/%s\n", 382 + desc->id, desc->name); 383 + 384 + config->ena_gpiod = ena_gpiod; 385 + 386 + return 0; 387 + } 388 + 331 389 static const struct regulator_ops s2mps11_ldo_ops = { 332 390 .list_voltage = regulator_list_voltage_linear, 333 391 .map_voltage = regulator_map_voltage_linear, ··· 408 362 #define regulator_desc_s2mps11_ldo(num, step) { \ 409 363 .name = "LDO"#num, \ 410 364 .id = S2MPS11_LDO##num, \ 365 + .of_match = of_match_ptr("LDO"#num), \ 366 + .regulators_node = of_match_ptr("regulators"), \ 411 367 .ops = &s2mps11_ldo_ops, \ 412 368 .type = REGULATOR_VOLTAGE, \ 413 369 .owner = THIS_MODULE, \ ··· 426 378 #define regulator_desc_s2mps11_buck1_4(num) { \ 427 379 .name = "BUCK"#num, \ 428 380 .id = S2MPS11_BUCK##num, \ 381 + .of_match = of_match_ptr("BUCK"#num), \ 382 + .regulators_node = of_match_ptr("regulators"), \ 429 383 .ops = &s2mps11_buck_ops, \ 430 384 .type = REGULATOR_VOLTAGE, \ 431 385 .owner = THIS_MODULE, \ ··· 445 395 #define regulator_desc_s2mps11_buck5 { \ 446 396 .name = "BUCK5", \ 447 397 .id = S2MPS11_BUCK5, \ 398 + .of_match = of_match_ptr("BUCK5"), \ 399 + .regulators_node = of_match_ptr("regulators"), \ 448 400 .ops = &s2mps11_buck_ops, \ 449 401 .type = REGULATOR_VOLTAGE, \ 450 402 .owner = THIS_MODULE, \ ··· 464 412 #define regulator_desc_s2mps11_buck67810(num, min, step, min_sel, voltages) { \ 465 413 .name = "BUCK"#num, \ 466 414 .id = S2MPS11_BUCK##num, \ 415 + .of_match = of_match_ptr("BUCK"#num), \ 416 + .regulators_node = of_match_ptr("regulators"), \ 467 417 .ops = &s2mps11_buck_ops, \ 468 418 .type = REGULATOR_VOLTAGE, \ 469 419 .owner = THIS_MODULE, \ ··· 483 429 #define regulator_desc_s2mps11_buck9 { \ 484 430 .name = "BUCK9", \ 485 431 .id = S2MPS11_BUCK9, \ 432 + .of_match = of_match_ptr("BUCK9"), \ 433 + .regulators_node = of_match_ptr("regulators"), \ 486 434 .ops = &s2mps11_buck_ops, \ 487 435 .type = REGULATOR_VOLTAGE, \ 488 436 .owner = THIS_MODULE, \ ··· 558 502 #define regulator_desc_s2mps13_ldo(num, min, step, min_sel) { \ 559 503 .name = "LDO"#num, \ 560 504 .id = S2MPS13_LDO##num, \ 505 + .of_match = of_match_ptr("LDO"#num), \ 506 + .regulators_node = of_match_ptr("regulators"), \ 561 507 .ops = &s2mps14_reg_ops, \ 562 508 .type = REGULATOR_VOLTAGE, \ 563 509 .owner = THIS_MODULE, \ ··· 576 518 #define regulator_desc_s2mps13_buck(num, min, step, min_sel) { \ 577 519 .name = "BUCK"#num, \ 578 520 .id = S2MPS13_BUCK##num, \ 521 + .of_match = of_match_ptr("BUCK"#num), \ 522 + .regulators_node = of_match_ptr("regulators"), \ 579 523 .ops = &s2mps14_reg_ops, \ 580 524 .type = REGULATOR_VOLTAGE, \ 581 525 .owner = THIS_MODULE, \ ··· 595 535 #define regulator_desc_s2mps13_buck7(num, min, step, min_sel) { \ 596 536 .name = "BUCK"#num, \ 597 537 .id = S2MPS13_BUCK##num, \ 538 + .of_match = of_match_ptr("BUCK"#num), \ 539 + .regulators_node = of_match_ptr("regulators"), \ 598 540 .ops = &s2mps14_reg_ops, \ 599 541 .type = REGULATOR_VOLTAGE, \ 600 542 .owner = THIS_MODULE, \ ··· 614 552 #define regulator_desc_s2mps13_buck8_10(num, min, step, min_sel) { \ 615 553 .name = "BUCK"#num, \ 616 554 .id = S2MPS13_BUCK##num, \ 555 + .of_match = of_match_ptr("BUCK"#num), \ 556 + .regulators_node = of_match_ptr("regulators"), \ 617 557 .ops = &s2mps14_reg_ops, \ 618 558 .type = REGULATOR_VOLTAGE, \ 619 559 .owner = THIS_MODULE, \ ··· 698 634 #define regulator_desc_s2mps14_ldo(num, min, step) { \ 699 635 .name = "LDO"#num, \ 700 636 .id = S2MPS14_LDO##num, \ 637 + .of_match = of_match_ptr("LDO"#num), \ 638 + .regulators_node = of_match_ptr("regulators"), \ 639 + .of_parse_cb = s2mps11_of_parse_cb, \ 701 640 .ops = &s2mps14_reg_ops, \ 702 641 .type = REGULATOR_VOLTAGE, \ 703 642 .owner = THIS_MODULE, \ ··· 716 649 #define regulator_desc_s2mps14_buck(num, min, step, min_sel) { \ 717 650 .name = "BUCK"#num, \ 718 651 .id = S2MPS14_BUCK##num, \ 652 + .of_match = of_match_ptr("BUCK"#num), \ 653 + .regulators_node = of_match_ptr("regulators"), \ 654 + .of_parse_cb = s2mps11_of_parse_cb, \ 719 655 .ops = &s2mps14_reg_ops, \ 720 656 .type = REGULATOR_VOLTAGE, \ 721 657 .owner = THIS_MODULE, \ ··· 795 725 #define regulator_desc_s2mps15_ldo(num, range) { \ 796 726 .name = "LDO"#num, \ 797 727 .id = S2MPS15_LDO##num, \ 728 + .of_match = of_match_ptr("LDO"#num), \ 729 + .regulators_node = of_match_ptr("regulators"), \ 798 730 .ops = &s2mps15_reg_ldo_ops, \ 799 731 .type = REGULATOR_VOLTAGE, \ 800 732 .owner = THIS_MODULE, \ ··· 812 740 #define regulator_desc_s2mps15_buck(num, range) { \ 813 741 .name = "BUCK"#num, \ 814 742 .id = S2MPS15_BUCK##num, \ 743 + .of_match = of_match_ptr("BUCK"#num), \ 744 + .regulators_node = of_match_ptr("regulators"), \ 815 745 .ops = &s2mps15_reg_buck_ops, \ 816 746 .type = REGULATOR_VOLTAGE, \ 817 747 .owner = THIS_MODULE, \ ··· 909 835 rdev->desc->enable_mask, S2MPS14_ENABLE_EXT_CONTROL); 910 836 } 911 837 912 - static void s2mps14_pmic_dt_parse_ext_control_gpio(struct platform_device *pdev, 913 - struct of_regulator_match *rdata, struct s2mps11_info *s2mps11) 914 - { 915 - struct gpio_desc **gpio = s2mps11->ext_control_gpiod; 916 - unsigned int i; 917 - unsigned int valid_regulators[3] = { S2MPS14_LDO10, S2MPS14_LDO11, 918 - S2MPS14_LDO12 }; 919 - 920 - for (i = 0; i < ARRAY_SIZE(valid_regulators); i++) { 921 - unsigned int reg = valid_regulators[i]; 922 - 923 - if (!rdata[reg].init_data || !rdata[reg].of_node) 924 - continue; 925 - 926 - gpio[reg] = devm_fwnode_gpiod_get(&pdev->dev, 927 - of_fwnode_handle(rdata[reg].of_node), 928 - "samsung,ext-control", 929 - GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE, 930 - "s2mps11-regulator"); 931 - if (PTR_ERR(gpio[reg]) == -ENOENT) 932 - gpio[reg] = NULL; 933 - else if (IS_ERR(gpio[reg])) { 934 - dev_err(&pdev->dev, "Failed to get control GPIO for %d/%s\n", 935 - reg, rdata[reg].name); 936 - gpio[reg] = NULL; 937 - continue; 938 - } 939 - if (gpio[reg]) 940 - dev_dbg(&pdev->dev, "Using GPIO for ext-control over %d/%s\n", 941 - reg, rdata[reg].name); 942 - } 943 - } 944 - 945 - static int s2mps11_pmic_dt_parse(struct platform_device *pdev, 946 - struct of_regulator_match *rdata, struct s2mps11_info *s2mps11, 947 - unsigned int rdev_num) 948 - { 949 - struct device_node *reg_np; 950 - 951 - reg_np = of_get_child_by_name(pdev->dev.parent->of_node, "regulators"); 952 - if (!reg_np) { 953 - dev_err(&pdev->dev, "could not find regulators sub-node\n"); 954 - return -EINVAL; 955 - } 956 - 957 - of_regulator_match(&pdev->dev, reg_np, rdata, rdev_num); 958 - if (s2mps11->dev_type == S2MPS14X) 959 - s2mps14_pmic_dt_parse_ext_control_gpio(pdev, rdata, s2mps11); 960 - 961 - of_node_put(reg_np); 962 - 963 - return 0; 964 - } 965 - 966 838 static int s2mpu02_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) 967 839 { 968 840 unsigned int ramp_val, ramp_shift, ramp_reg; ··· 966 946 #define regulator_desc_s2mpu02_ldo1(num) { \ 967 947 .name = "LDO"#num, \ 968 948 .id = S2MPU02_LDO##num, \ 949 + .of_match = of_match_ptr("LDO"#num), \ 950 + .regulators_node = of_match_ptr("regulators"), \ 969 951 .ops = &s2mpu02_ldo_ops, \ 970 952 .type = REGULATOR_VOLTAGE, \ 971 953 .owner = THIS_MODULE, \ ··· 983 961 #define regulator_desc_s2mpu02_ldo2(num) { \ 984 962 .name = "LDO"#num, \ 985 963 .id = S2MPU02_LDO##num, \ 964 + .of_match = of_match_ptr("LDO"#num), \ 965 + .regulators_node = of_match_ptr("regulators"), \ 986 966 .ops = &s2mpu02_ldo_ops, \ 987 967 .type = REGULATOR_VOLTAGE, \ 988 968 .owner = THIS_MODULE, \ ··· 1000 976 #define regulator_desc_s2mpu02_ldo3(num) { \ 1001 977 .name = "LDO"#num, \ 1002 978 .id = S2MPU02_LDO##num, \ 979 + .of_match = of_match_ptr("LDO"#num), \ 980 + .regulators_node = of_match_ptr("regulators"), \ 1003 981 .ops = &s2mpu02_ldo_ops, \ 1004 982 .type = REGULATOR_VOLTAGE, \ 1005 983 .owner = THIS_MODULE, \ ··· 1017 991 #define regulator_desc_s2mpu02_ldo4(num) { \ 1018 992 .name = "LDO"#num, \ 1019 993 .id = S2MPU02_LDO##num, \ 994 + .of_match = of_match_ptr("LDO"#num), \ 995 + .regulators_node = of_match_ptr("regulators"), \ 1020 996 .ops = &s2mpu02_ldo_ops, \ 1021 997 .type = REGULATOR_VOLTAGE, \ 1022 998 .owner = THIS_MODULE, \ ··· 1034 1006 #define regulator_desc_s2mpu02_ldo5(num) { \ 1035 1007 .name = "LDO"#num, \ 1036 1008 .id = S2MPU02_LDO##num, \ 1009 + .of_match = of_match_ptr("LDO"#num), \ 1010 + .regulators_node = of_match_ptr("regulators"), \ 1037 1011 .ops = &s2mpu02_ldo_ops, \ 1038 1012 .type = REGULATOR_VOLTAGE, \ 1039 1013 .owner = THIS_MODULE, \ ··· 1052 1022 #define regulator_desc_s2mpu02_buck1234(num) { \ 1053 1023 .name = "BUCK"#num, \ 1054 1024 .id = S2MPU02_BUCK##num, \ 1025 + .of_match = of_match_ptr("BUCK"#num), \ 1026 + .regulators_node = of_match_ptr("regulators"), \ 1055 1027 .ops = &s2mpu02_buck_ops, \ 1056 1028 .type = REGULATOR_VOLTAGE, \ 1057 1029 .owner = THIS_MODULE, \ ··· 1070 1038 #define regulator_desc_s2mpu02_buck5(num) { \ 1071 1039 .name = "BUCK"#num, \ 1072 1040 .id = S2MPU02_BUCK##num, \ 1041 + .of_match = of_match_ptr("BUCK"#num), \ 1042 + .regulators_node = of_match_ptr("regulators"), \ 1073 1043 .ops = &s2mpu02_ldo_ops, \ 1074 1044 .type = REGULATOR_VOLTAGE, \ 1075 1045 .owner = THIS_MODULE, \ ··· 1088 1054 #define regulator_desc_s2mpu02_buck6(num) { \ 1089 1055 .name = "BUCK"#num, \ 1090 1056 .id = S2MPU02_BUCK##num, \ 1057 + .of_match = of_match_ptr("BUCK"#num), \ 1058 + .regulators_node = of_match_ptr("regulators"), \ 1091 1059 .ops = &s2mpu02_ldo_ops, \ 1092 1060 .type = REGULATOR_VOLTAGE, \ 1093 1061 .owner = THIS_MODULE, \ ··· 1106 1070 #define regulator_desc_s2mpu02_buck7(num) { \ 1107 1071 .name = "BUCK"#num, \ 1108 1072 .id = S2MPU02_BUCK##num, \ 1073 + .of_match = of_match_ptr("BUCK"#num), \ 1074 + .regulators_node = of_match_ptr("regulators"), \ 1109 1075 .ops = &s2mpu02_ldo_ops, \ 1110 1076 .type = REGULATOR_VOLTAGE, \ 1111 1077 .owner = THIS_MODULE, \ ··· 1163 1125 #define regulator_desc_s2mpu05_ldo_reg(num, min, step, reg) { \ 1164 1126 .name = "ldo"#num, \ 1165 1127 .id = S2MPU05_LDO##num, \ 1128 + .of_match = of_match_ptr("ldo"#num), \ 1129 + .regulators_node = of_match_ptr("regulators"), \ 1166 1130 .ops = &s2mpu02_ldo_ops, \ 1167 1131 .type = REGULATOR_VOLTAGE, \ 1168 1132 .owner = THIS_MODULE, \ ··· 1196 1156 #define regulator_desc_s2mpu05_buck(num, which) { \ 1197 1157 .name = "buck"#num, \ 1198 1158 .id = S2MPU05_BUCK##num, \ 1159 + .of_match = of_match_ptr("buck"#num), \ 1160 + .regulators_node = of_match_ptr("regulators"), \ 1199 1161 .ops = &s2mpu02_buck_ops, \ 1200 1162 .type = REGULATOR_VOLTAGE, \ 1201 1163 .owner = THIS_MODULE, \ ··· 1296 1254 s2mps11->dev_type); 1297 1255 } 1298 1256 1299 - s2mps11->ext_control_gpiod = devm_kcalloc(&pdev->dev, rdev_num, 1300 - sizeof(*s2mps11->ext_control_gpiod), GFP_KERNEL); 1301 - if (!s2mps11->ext_control_gpiod) 1302 - return -ENOMEM; 1303 - 1304 - struct of_regulator_match *rdata __free(kfree) = 1305 - kcalloc(rdev_num, sizeof(*rdata), GFP_KERNEL); 1306 - if (!rdata) 1307 - return -ENOMEM; 1308 - 1309 - for (i = 0; i < rdev_num; i++) 1310 - rdata[i].name = regulators[i].name; 1311 - 1312 - ret = s2mps11_pmic_dt_parse(pdev, rdata, s2mps11, rdev_num); 1313 - if (ret) 1314 - return ret; 1257 + device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent); 1315 1258 1316 1259 platform_set_drvdata(pdev, s2mps11); 1317 1260 ··· 1306 1279 for (i = 0; i < rdev_num; i++) { 1307 1280 struct regulator_dev *regulator; 1308 1281 1309 - config.init_data = rdata[i].init_data; 1310 - config.of_node = rdata[i].of_node; 1311 - config.ena_gpiod = s2mps11->ext_control_gpiod[i]; 1312 - /* 1313 - * Hand the GPIO descriptor management over to the regulator 1314 - * core, remove it from devres management. 1315 - */ 1316 - if (config.ena_gpiod) 1317 - devm_gpiod_unhinge(&pdev->dev, config.ena_gpiod); 1318 1282 regulator = devm_regulator_register(&pdev->dev, 1319 1283 &regulators[i], &config); 1320 1284 if (IS_ERR(regulator)) ··· 1314 1296 regulators[i].id, 1315 1297 regulators[i].name); 1316 1298 1317 - if (config.ena_gpiod) { 1299 + if (regulator->ena_pin) { 1318 1300 ret = s2mps14_pmic_enable_ext_control(s2mps11, 1319 1301 regulator); 1320 1302 if (ret < 0)