summaryrefslogtreecommitdiff
path: root/drivers/regulator/qcom_smd-regulator.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/qcom_smd-regulator.c')
-rw-r--r--drivers/regulator/qcom_smd-regulator.c74
1 files changed, 53 insertions, 21 deletions
diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c
index 9f2b58458841..25ed9f713974 100644
--- a/drivers/regulator/qcom_smd-regulator.c
+++ b/drivers/regulator/qcom_smd-regulator.c
@@ -6,17 +6,15 @@
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/soc/qcom/smd-rpm.h>
+static struct qcom_smd_rpm *smd_vreg_rpm;
+
struct qcom_rpm_reg {
struct device *dev;
-
- struct qcom_smd_rpm *rpm;
-
u32 type;
u32 id;
@@ -71,7 +69,7 @@ static int rpm_reg_write_active(struct qcom_rpm_reg *vreg)
if (!reqlen)
return 0;
- ret = qcom_rpm_smd_write(vreg->rpm, QCOM_SMD_RPM_ACTIVE_STATE,
+ ret = qcom_rpm_smd_write(smd_vreg_rpm, QCOM_SMD_RPM_ACTIVE_STATE,
vreg->type, vreg->id,
req, sizeof(req[0]) * reqlen);
if (!ret) {
@@ -749,7 +747,7 @@ static const struct regulator_desc pms405_pldo600 = {
.ops = &rpm_smps_ldo_ops,
};
-static const struct regulator_desc mp5496_smpa2 = {
+static const struct regulator_desc mp5496_smps = {
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(600000, 0, 127, 12500),
},
@@ -794,8 +792,10 @@ struct rpm_regulator_data {
};
static const struct rpm_regulator_data rpm_mp5496_regulators[] = {
- { "s2", QCOM_SMD_RPM_SMPA, 2, &mp5496_smpa2, "s2" },
+ { "s1", QCOM_SMD_RPM_SMPA, 1, &mp5496_smps, "s1" },
+ { "s2", QCOM_SMD_RPM_SMPA, 2, &mp5496_smps, "s2" },
{ "l2", QCOM_SMD_RPM_LDOA, 2, &mp5496_ldoa2, "l2" },
+ { "l5", QCOM_SMD_RPM_LDOA, 5, &mp5496_ldoa2, "l5" },
{}
};
@@ -1012,6 +1012,39 @@ static const struct rpm_regulator_data rpm_pm8916_regulators[] = {
{}
};
+static const struct rpm_regulator_data rpm_pm8937_regulators[] = {
+ { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8994_hfsmps, "vdd_s1" },
+ { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8994_hfsmps, "vdd_s2" },
+ { "s3", QCOM_SMD_RPM_SMPA, 3, &pm8994_hfsmps, "vdd_s3" },
+ { "s4", QCOM_SMD_RPM_SMPA, 4, &pm8994_hfsmps, "vdd_s4" },
+ /* S5 - S6 are managed by SPMI */
+
+ { "l1", QCOM_SMD_RPM_LDOA, 1, &pm8953_ult_nldo, "vdd_l1_l19" },
+ { "l2", QCOM_SMD_RPM_LDOA, 2, &pm8953_ult_nldo, "vdd_l2_l23" },
+ { "l3", QCOM_SMD_RPM_LDOA, 3, &pm8953_ult_nldo, "vdd_l3" },
+ { "l4", QCOM_SMD_RPM_LDOA, 4, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16" },
+ { "l5", QCOM_SMD_RPM_LDOA, 5, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16" },
+ { "l6", QCOM_SMD_RPM_LDOA, 6, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16" },
+ { "l7", QCOM_SMD_RPM_LDOA, 7, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16" },
+ { "l8", QCOM_SMD_RPM_LDOA, 8, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" },
+ { "l9", QCOM_SMD_RPM_LDOA, 9, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" },
+ { "l10", QCOM_SMD_RPM_LDOA, 10, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18"},
+ { "l11", QCOM_SMD_RPM_LDOA, 11, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" },
+ { "l12", QCOM_SMD_RPM_LDOA, 12, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" },
+ { "l13", QCOM_SMD_RPM_LDOA, 13, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" },
+ { "l14", QCOM_SMD_RPM_LDOA, 14, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" },
+ { "l15", QCOM_SMD_RPM_LDOA, 15, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" },
+ { "l16", QCOM_SMD_RPM_LDOA, 16, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16" },
+ { "l17", QCOM_SMD_RPM_LDOA, 17, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" },
+ { "l18", QCOM_SMD_RPM_LDOA, 18, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" },
+ { "l19", QCOM_SMD_RPM_LDOA, 19, &pm8953_ult_nldo, "vdd_l1_l19" },
+ { "l20", QCOM_SMD_RPM_LDOA, 20, &pm8953_lnldo, "vdd_l20_l21" },
+ { "l21", QCOM_SMD_RPM_LDOA, 21, &pm8953_lnldo, "vdd_l20_l21" },
+ { "l22", QCOM_SMD_RPM_LDOA, 22, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" },
+ { "l23", QCOM_SMD_RPM_LDOA, 23, &pm8994_nldo, "vdd_l2_l23" },
+ {}
+};
+
static const struct rpm_regulator_data rpm_pm8941_regulators[] = {
{ "s1", QCOM_SMD_RPM_SMPA, 1, &pm8x41_hfsmps, "vdd_s1" },
{ "s2", QCOM_SMD_RPM_SMPA, 2, &pm8x41_hfsmps, "vdd_s2" },
@@ -1329,6 +1362,7 @@ static const struct of_device_id rpm_of_match[] = {
{ .compatible = "qcom,rpm-pm8841-regulators", .data = &rpm_pm8841_regulators },
{ .compatible = "qcom,rpm-pm8909-regulators", .data = &rpm_pm8909_regulators },
{ .compatible = "qcom,rpm-pm8916-regulators", .data = &rpm_pm8916_regulators },
+ { .compatible = "qcom,rpm-pm8937-regulators", .data = &rpm_pm8937_regulators },
{ .compatible = "qcom,rpm-pm8941-regulators", .data = &rpm_pm8941_regulators },
{ .compatible = "qcom,rpm-pm8950-regulators", .data = &rpm_pm8950_regulators },
{ .compatible = "qcom,rpm-pm8953-regulators", .data = &rpm_pm8953_regulators },
@@ -1349,14 +1383,13 @@ MODULE_DEVICE_TABLE(of, rpm_of_match);
* @dev: Pointer to the top level qcom_smd-regulator PMIC device
* @node: Pointer to the individual qcom_smd-regulator resource
* device node
- * @rpm: Pointer to the rpm bus node
* @pmic_rpm_data: Pointer to a null-terminated array of qcom_smd-regulator
* resources defined for the top level PMIC device
*
- * Return: 0 on success, errno on failure
+ * Return: 0 on success, or a negative error number on failure
*/
static int rpm_regulator_init_vreg(struct qcom_rpm_reg *vreg, struct device *dev,
- struct device_node *node, struct qcom_smd_rpm *rpm,
+ struct device_node *node,
const struct rpm_regulator_data *pmic_rpm_data)
{
struct regulator_config config = {};
@@ -1374,7 +1407,6 @@ static int rpm_regulator_init_vreg(struct qcom_rpm_reg *vreg, struct device *dev
}
vreg->dev = dev;
- vreg->rpm = rpm;
vreg->type = rpm_data->type;
vreg->id = rpm_data->id;
@@ -1403,7 +1435,6 @@ static int rpm_reg_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct rpm_regulator_data *vreg_data;
- struct device_node *node;
struct qcom_rpm_reg *vreg;
struct qcom_smd_rpm *rpm;
int ret;
@@ -1414,23 +1445,23 @@ static int rpm_reg_probe(struct platform_device *pdev)
return -ENODEV;
}
+ if (smd_vreg_rpm && rpm != smd_vreg_rpm)
+ return dev_err_probe(dev, -EINVAL, "RPM mismatch\n");
+
+ smd_vreg_rpm = rpm;
+
vreg_data = of_device_get_match_data(dev);
if (!vreg_data)
return -ENODEV;
- for_each_available_child_of_node(dev->of_node, node) {
+ for_each_available_child_of_node_scoped(dev->of_node, node) {
vreg = devm_kzalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
- if (!vreg) {
- of_node_put(node);
+ if (!vreg)
return -ENOMEM;
- }
-
- ret = rpm_regulator_init_vreg(vreg, dev, node, rpm, vreg_data);
- if (ret < 0) {
- of_node_put(node);
+ ret = rpm_regulator_init_vreg(vreg, dev, node, vreg_data);
+ if (ret < 0)
return ret;
- }
}
return 0;
@@ -1440,6 +1471,7 @@ static struct platform_driver rpm_reg_driver = {
.probe = rpm_reg_probe,
.driver = {
.name = "qcom_rpm_smd_regulator",
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
.of_match_table = rpm_of_match,
},
};