Skip to content

Commit 087a1b5

Browse files
anderssonbroonie
authored andcommitted
regulator: qcom: Rework to single platform device
Modeling the individual RPM resources as platform devices consumes at least 12-15kb of RAM, just to hold the platform_device structs. Rework this to instead have one device per pmic exposed by the RPM. With this representation we can more accurately define the input pins on the pmic and have the supply description match the data sheet. Suggested-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com> Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 469a951 commit 087a1b5

1 file changed

Lines changed: 161 additions & 83 deletions

File tree

drivers/regulator/qcom_rpm-regulator.c

Lines changed: 161 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -607,31 +607,6 @@ static const struct qcom_rpm_reg smb208_smps = {
607607
.supports_force_mode_bypass = false,
608608
};
609609

610-
static const struct of_device_id rpm_of_match[] = {
611-
{ .compatible = "qcom,rpm-pm8058-pldo", .data = &pm8058_pldo },
612-
{ .compatible = "qcom,rpm-pm8058-nldo", .data = &pm8058_nldo },
613-
{ .compatible = "qcom,rpm-pm8058-smps", .data = &pm8058_smps },
614-
{ .compatible = "qcom,rpm-pm8058-ncp", .data = &pm8058_ncp },
615-
{ .compatible = "qcom,rpm-pm8058-switch", .data = &pm8058_switch },
616-
617-
{ .compatible = "qcom,rpm-pm8901-pldo", .data = &pm8901_pldo },
618-
{ .compatible = "qcom,rpm-pm8901-nldo", .data = &pm8901_nldo },
619-
{ .compatible = "qcom,rpm-pm8901-ftsmps", .data = &pm8901_ftsmps },
620-
{ .compatible = "qcom,rpm-pm8901-switch", .data = &pm8901_switch },
621-
622-
{ .compatible = "qcom,rpm-pm8921-pldo", .data = &pm8921_pldo },
623-
{ .compatible = "qcom,rpm-pm8921-nldo", .data = &pm8921_nldo },
624-
{ .compatible = "qcom,rpm-pm8921-nldo1200", .data = &pm8921_nldo1200 },
625-
{ .compatible = "qcom,rpm-pm8921-smps", .data = &pm8921_smps },
626-
{ .compatible = "qcom,rpm-pm8921-ftsmps", .data = &pm8921_ftsmps },
627-
{ .compatible = "qcom,rpm-pm8921-ncp", .data = &pm8921_ncp },
628-
{ .compatible = "qcom,rpm-pm8921-switch", .data = &pm8921_switch },
629-
630-
{ .compatible = "qcom,rpm-smb208", .data = &smb208_smps },
631-
{ }
632-
};
633-
MODULE_DEVICE_TABLE(of, rpm_of_match);
634-
635610
static int rpm_reg_set(struct qcom_rpm_reg *vreg,
636611
const struct request_member *req,
637612
const int value)
@@ -773,74 +748,177 @@ static int rpm_reg_of_parse(struct device_node *node,
773748
return 0;
774749
}
775750

776-
static int rpm_reg_probe(struct platform_device *pdev)
777-
{
778-
struct regulator_init_data *initdata;
751+
struct rpm_regulator_data {
752+
const char *name;
753+
int resource;
779754
const struct qcom_rpm_reg *template;
780-
const struct of_device_id *match;
781-
struct regulator_config config = { };
782-
struct regulator_dev *rdev;
783-
struct qcom_rpm_reg *vreg;
784-
const char *key;
785-
u32 val;
786-
int ret;
755+
const char *supply;
756+
};
757+
758+
static const struct rpm_regulator_data rpm_pm8058_regulators[] = {
759+
{ "l0", QCOM_RPM_PM8058_LDO0, &pm8058_nldo, "vdd_l0_l1_lvs" },
760+
{ "l1", QCOM_RPM_PM8058_LDO1, &pm8058_nldo, "vdd_l0_l1_lvs" },
761+
{ "l2", QCOM_RPM_PM8058_LDO2, &pm8058_pldo, "vdd_l2_l11_l12" },
762+
{ "l3", QCOM_RPM_PM8058_LDO3, &pm8058_pldo, "vdd_l3_l4_l5" },
763+
{ "l4", QCOM_RPM_PM8058_LDO4, &pm8058_pldo, "vdd_l3_l4_l5" },
764+
{ "l5", QCOM_RPM_PM8058_LDO5, &pm8058_pldo, "vdd_l3_l4_l5" },
765+
{ "l6", QCOM_RPM_PM8058_LDO6, &pm8058_pldo, "vdd_l6_l7" },
766+
{ "l7", QCOM_RPM_PM8058_LDO7, &pm8058_pldo, "vdd_l6_l7" },
767+
{ "l8", QCOM_RPM_PM8058_LDO8, &pm8058_pldo, "vdd_l8" },
768+
{ "l9", QCOM_RPM_PM8058_LDO9, &pm8058_pldo, "vdd_l9" },
769+
{ "l10", QCOM_RPM_PM8058_LDO10, &pm8058_pldo, "vdd_l10" },
770+
{ "l11", QCOM_RPM_PM8058_LDO11, &pm8058_pldo, "vdd_l2_l11_l12" },
771+
{ "l12", QCOM_RPM_PM8058_LDO12, &pm8058_pldo, "vdd_l2_l11_l12" },
772+
{ "l13", QCOM_RPM_PM8058_LDO13, &pm8058_pldo, "vdd_l13_l16" },
773+
{ "l14", QCOM_RPM_PM8058_LDO14, &pm8058_pldo, "vdd_l14_l15" },
774+
{ "l15", QCOM_RPM_PM8058_LDO15, &pm8058_pldo, "vdd_l14_l15" },
775+
{ "l16", QCOM_RPM_PM8058_LDO16, &pm8058_pldo, "vdd_l13_l16" },
776+
{ "l17", QCOM_RPM_PM8058_LDO17, &pm8058_pldo, "vdd_l17_l18" },
777+
{ "l18", QCOM_RPM_PM8058_LDO18, &pm8058_pldo, "vdd_l17_l18" },
778+
{ "l19", QCOM_RPM_PM8058_LDO19, &pm8058_pldo, "vdd_l19_l20" },
779+
{ "l20", QCOM_RPM_PM8058_LDO20, &pm8058_pldo, "vdd_l19_l20" },
780+
{ "l21", QCOM_RPM_PM8058_LDO21, &pm8058_nldo, "vdd_l21" },
781+
{ "l22", QCOM_RPM_PM8058_LDO22, &pm8058_nldo, "vdd_l22" },
782+
{ "l23", QCOM_RPM_PM8058_LDO23, &pm8058_nldo, "vdd_l23_l24_l25" },
783+
{ "l24", QCOM_RPM_PM8058_LDO24, &pm8058_nldo, "vdd_l23_l24_l25" },
784+
{ "l25", QCOM_RPM_PM8058_LDO25, &pm8058_nldo, "vdd_l23_l24_l25" },
785+
786+
{ "s0", QCOM_RPM_PM8058_SMPS0, &pm8058_smps, "vdd_s0" },
787+
{ "s1", QCOM_RPM_PM8058_SMPS1, &pm8058_smps, "vdd_s1" },
788+
{ "s2", QCOM_RPM_PM8058_SMPS2, &pm8058_smps, "vdd_s2" },
789+
{ "s3", QCOM_RPM_PM8058_SMPS3, &pm8058_smps, "vdd_s3" },
790+
{ "s4", QCOM_RPM_PM8058_SMPS4, &pm8058_smps, "vdd_s4" },
791+
792+
{ "lvs0", QCOM_RPM_PM8058_LVS0, &pm8058_switch, "vdd_l0_l1_lvs" },
793+
{ "lvs1", QCOM_RPM_PM8058_LVS1, &pm8058_switch, "vdd_l0_l1_lvs" },
794+
795+
{ "ncp", QCOM_RPM_PM8058_NCP, &pm8058_ncp, "vdd_ncp" },
796+
{ }
797+
};
787798

788-
match = of_match_device(rpm_of_match, &pdev->dev);
789-
template = match->data;
799+
static const struct rpm_regulator_data rpm_pm8901_regulators[] = {
800+
{ "l0", QCOM_RPM_PM8901_LDO0, &pm8901_nldo, "vdd_l0" },
801+
{ "l1", QCOM_RPM_PM8901_LDO1, &pm8901_pldo, "vdd_l1" },
802+
{ "l2", QCOM_RPM_PM8901_LDO2, &pm8901_pldo, "vdd_l2" },
803+
{ "l3", QCOM_RPM_PM8901_LDO3, &pm8901_pldo, "vdd_l3" },
804+
{ "l4", QCOM_RPM_PM8901_LDO4, &pm8901_pldo, "vdd_l4" },
805+
{ "l5", QCOM_RPM_PM8901_LDO5, &pm8901_pldo, "vdd_l5" },
806+
{ "l6", QCOM_RPM_PM8901_LDO6, &pm8901_pldo, "vdd_l6" },
790807

791-
vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
792-
if (!vreg) {
793-
dev_err(&pdev->dev, "failed to allocate vreg\n");
794-
return -ENOMEM;
795-
}
796-
memcpy(vreg, template, sizeof(*vreg));
797-
mutex_init(&vreg->lock);
798-
vreg->dev = &pdev->dev;
799-
vreg->desc.id = -1;
800-
vreg->desc.owner = THIS_MODULE;
801-
vreg->desc.type = REGULATOR_VOLTAGE;
802-
vreg->desc.name = pdev->dev.of_node->name;
803-
vreg->desc.supply_name = "vin";
804-
805-
vreg->rpm = dev_get_drvdata(pdev->dev.parent);
806-
if (!vreg->rpm) {
807-
dev_err(&pdev->dev, "unable to retrieve handle to rpm\n");
808-
return -ENODEV;
809-
}
808+
{ "s0", QCOM_RPM_PM8901_SMPS0, &pm8901_ftsmps, "vdd_s0" },
809+
{ "s1", QCOM_RPM_PM8901_SMPS1, &pm8901_ftsmps, "vdd_s1" },
810+
{ "s2", QCOM_RPM_PM8901_SMPS2, &pm8901_ftsmps, "vdd_s2" },
811+
{ "s3", QCOM_RPM_PM8901_SMPS3, &pm8901_ftsmps, "vdd_s3" },
812+
{ "s4", QCOM_RPM_PM8901_SMPS4, &pm8901_ftsmps, "vdd_s4" },
810813

811-
initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
812-
&vreg->desc);
813-
if (!initdata)
814-
return -EINVAL;
814+
{ "lvs0", QCOM_RPM_PM8901_LVS0, &pm8901_switch, "lvs0_in" },
815+
{ "lvs1", QCOM_RPM_PM8901_LVS1, &pm8901_switch, "lvs1_in" },
816+
{ "lvs2", QCOM_RPM_PM8901_LVS2, &pm8901_switch, "lvs2_in" },
817+
{ "lvs3", QCOM_RPM_PM8901_LVS3, &pm8901_switch, "lvs3_in" },
815818

816-
key = "reg";
817-
ret = of_property_read_u32(pdev->dev.of_node, key, &val);
818-
if (ret) {
819-
dev_err(&pdev->dev, "failed to read %s\n", key);
820-
return ret;
821-
}
822-
vreg->resource = val;
819+
{ "mvs", QCOM_RPM_PM8901_MVS, &pm8901_switch, "mvs_in" },
820+
{ }
821+
};
823822

824-
if ((vreg->parts->uV.mask || vreg->parts->mV.mask) &&
825-
(!initdata->constraints.min_uV || !initdata->constraints.max_uV)) {
826-
dev_err(&pdev->dev, "no voltage specified for regulator\n");
827-
return -EINVAL;
828-
}
823+
static const struct rpm_regulator_data rpm_pm8921_regulators[] = {
824+
{ "s1", QCOM_RPM_PM8921_SMPS1, &pm8921_smps, "vdd_s1" },
825+
{ "s2", QCOM_RPM_PM8921_SMPS2, &pm8921_smps, "vdd_s2" },
826+
{ "s3", QCOM_RPM_PM8921_SMPS3, &pm8921_smps },
827+
{ "s4", QCOM_RPM_PM8921_SMPS4, &pm8921_smps, "vdd_s4" },
828+
{ "s7", QCOM_RPM_PM8921_SMPS7, &pm8921_smps, "vdd_s7" },
829+
{ "s8", QCOM_RPM_PM8921_SMPS8, &pm8921_smps, "vdd_s8" },
830+
831+
{ "l1", QCOM_RPM_PM8921_LDO1, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
832+
{ "l2", QCOM_RPM_PM8921_LDO2, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
833+
{ "l3", QCOM_RPM_PM8921_LDO3, &pm8921_pldo, "vdd_l3_l15_l17" },
834+
{ "l4", QCOM_RPM_PM8921_LDO4, &pm8921_pldo, "vdd_l4_l14" },
835+
{ "l5", QCOM_RPM_PM8921_LDO5, &pm8921_pldo, "vdd_l5_l8_l16" },
836+
{ "l6", QCOM_RPM_PM8921_LDO6, &pm8921_pldo, "vdd_l6_l7" },
837+
{ "l7", QCOM_RPM_PM8921_LDO7, &pm8921_pldo, "vdd_l6_l7" },
838+
{ "l8", QCOM_RPM_PM8921_LDO8, &pm8921_pldo, "vdd_l5_l8_l16" },
839+
{ "l9", QCOM_RPM_PM8921_LDO9, &pm8921_pldo, "vdd_l9_l11" },
840+
{ "l10", QCOM_RPM_PM8921_LDO10, &pm8921_pldo, "vdd_l10_l22" },
841+
{ "l11", QCOM_RPM_PM8921_LDO11, &pm8921_pldo, "vdd_l9_l11" },
842+
{ "l12", QCOM_RPM_PM8921_LDO12, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
843+
{ "l14", QCOM_RPM_PM8921_LDO14, &pm8921_pldo, "vdd_l4_l14" },
844+
{ "l15", QCOM_RPM_PM8921_LDO15, &pm8921_pldo, "vdd_l3_l15_l17" },
845+
{ "l16", QCOM_RPM_PM8921_LDO16, &pm8921_pldo, "vdd_l5_l8_l16" },
846+
{ "l17", QCOM_RPM_PM8921_LDO17, &pm8921_pldo, "vdd_l3_l15_l17" },
847+
{ "l18", QCOM_RPM_PM8921_LDO18, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
848+
{ "l21", QCOM_RPM_PM8921_LDO21, &pm8921_pldo, "vdd_l21_l23_l29" },
849+
{ "l22", QCOM_RPM_PM8921_LDO22, &pm8921_pldo, "vdd_l10_l22" },
850+
{ "l23", QCOM_RPM_PM8921_LDO23, &pm8921_pldo, "vdd_l21_l23_l29" },
851+
{ "l24", QCOM_RPM_PM8921_LDO24, &pm8921_nldo1200, "vdd_l24" },
852+
{ "l25", QCOM_RPM_PM8921_LDO25, &pm8921_nldo1200, "vdd_l25" },
853+
{ "l26", QCOM_RPM_PM8921_LDO26, &pm8921_nldo1200, "vdd_l26" },
854+
{ "l27", QCOM_RPM_PM8921_LDO27, &pm8921_nldo1200, "vdd_l27" },
855+
{ "l28", QCOM_RPM_PM8921_LDO28, &pm8921_nldo1200, "vdd_l28" },
856+
{ "l29", QCOM_RPM_PM8921_LDO29, &pm8921_pldo, "vdd_l21_l23_l29" },
857+
858+
{ "lvs1", QCOM_RPM_PM8921_LVS1, &pm8921_switch, "vin_lvs1_3_6" },
859+
{ "lvs2", QCOM_RPM_PM8921_LVS2, &pm8921_switch, "vin_lvs2" },
860+
{ "lvs3", QCOM_RPM_PM8921_LVS3, &pm8921_switch, "vin_lvs1_3_6" },
861+
{ "lvs4", QCOM_RPM_PM8921_LVS4, &pm8921_switch, "vin_lvs4_5_7" },
862+
{ "lvs5", QCOM_RPM_PM8921_LVS5, &pm8921_switch, "vin_lvs4_5_7" },
863+
{ "lvs6", QCOM_RPM_PM8921_LVS6, &pm8921_switch, "vin_lvs1_3_6" },
864+
{ "lvs7", QCOM_RPM_PM8921_LVS7, &pm8921_switch, "vin_lvs4_5_7" },
865+
866+
{ "usb-switch", QCOM_RPM_USB_OTG_SWITCH, &pm8921_switch, "vin_5vs" },
867+
{ "hdmi-switch", QCOM_RPM_HDMI_SWITCH, &pm8921_switch, "vin_5vs" },
868+
{ "ncp", QCOM_RPM_PM8921_NCP, &pm8921_ncp, "vdd_ncp" },
869+
{ }
870+
};
829871

872+
static const struct of_device_id rpm_of_match[] = {
873+
{ .compatible = "qcom,rpm-pm8058-regulators", .data = &rpm_pm8058_regulators },
874+
{ .compatible = "qcom,rpm-pm8901-regulators", .data = &rpm_pm8901_regulators },
875+
{ .compatible = "qcom,rpm-pm8921-regulators", .data = &rpm_pm8921_regulators },
876+
{ }
877+
};
878+
MODULE_DEVICE_TABLE(of, rpm_of_match);
830879

831-
config.dev = &pdev->dev;
832-
config.init_data = initdata;
833-
config.driver_data = vreg;
834-
config.of_node = pdev->dev.of_node;
880+
static int rpm_reg_probe(struct platform_device *pdev)
881+
{
882+
const struct rpm_regulator_data *reg;
883+
const struct of_device_id *match;
884+
struct regulator_config config = { };
885+
struct regulator_dev *rdev;
886+
struct qcom_rpm_reg *vreg;
835887

836-
ret = rpm_reg_of_parse(pdev->dev.of_node, &vreg->desc, &config);
837-
if (ret)
838-
return ret;
888+
match = of_match_device(rpm_of_match, &pdev->dev);
889+
for (reg = match->data; reg->name; reg++) {
890+
vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
891+
if (!vreg) {
892+
dev_err(&pdev->dev, "failed to allocate vreg\n");
893+
return -ENOMEM;
894+
}
895+
memcpy(vreg, reg->template, sizeof(*vreg));
896+
mutex_init(&vreg->lock);
897+
898+
vreg->dev = &pdev->dev;
899+
vreg->resource = reg->resource;
900+
901+
vreg->desc.id = -1;
902+
vreg->desc.owner = THIS_MODULE;
903+
vreg->desc.type = REGULATOR_VOLTAGE;
904+
vreg->desc.name = reg->name;
905+
vreg->desc.supply_name = reg->supply;
906+
vreg->desc.of_match = reg->name;
907+
vreg->desc.of_parse_cb = rpm_reg_of_parse;
908+
909+
vreg->rpm = dev_get_drvdata(pdev->dev.parent);
910+
if (!vreg->rpm) {
911+
dev_err(&pdev->dev, "unable to retrieve handle to rpm\n");
912+
return -ENODEV;
913+
}
839914

840-
rdev = devm_regulator_register(&pdev->dev, &vreg->desc, &config);
841-
if (IS_ERR(rdev)) {
842-
dev_err(&pdev->dev, "can't register regulator\n");
843-
return PTR_ERR(rdev);
915+
config.dev = &pdev->dev;
916+
config.driver_data = vreg;
917+
rdev = devm_regulator_register(&pdev->dev, &vreg->desc, &config);
918+
if (IS_ERR(rdev)) {
919+
dev_err(&pdev->dev, "can't register regulator\n");
920+
return PTR_ERR(rdev);
921+
}
844922
}
845923

846924
return 0;

0 commit comments

Comments
 (0)