|
9 | 9 | #include <linux/of_device.h>
|
10 | 10 | #include <linux/platform_device.h>
|
11 | 11 | #include <linux/regulator/driver.h>
|
| 12 | +#include <linux/regulator/of_regulator.h> |
12 | 13 | #include <linux/soc/qcom/smd-rpm.h>
|
13 | 14 |
|
14 | 15 | struct qcom_rpm_reg {
|
@@ -1239,52 +1240,91 @@ static const struct of_device_id rpm_of_match[] = {
|
1239 | 1240 | };
|
1240 | 1241 | MODULE_DEVICE_TABLE(of, rpm_of_match);
|
1241 | 1242 |
|
1242 |
| -static int rpm_reg_probe(struct platform_device *pdev) |
| 1243 | +/** |
| 1244 | + * rpm_regulator_init_vreg() - initialize all attributes of a qcom_smd-regulator |
| 1245 | + * @vreg: Pointer to the individual qcom_smd-regulator resource |
| 1246 | + * @dev: Pointer to the top level qcom_smd-regulator PMIC device |
| 1247 | + * @node: Pointer to the individual qcom_smd-regulator resource |
| 1248 | + * device node |
| 1249 | + * @rpm: Pointer to the rpm bus node |
| 1250 | + * @pmic_rpm_data: Pointer to a null-terminated array of qcom_smd-regulator |
| 1251 | + * resources defined for the top level PMIC device |
| 1252 | + * |
| 1253 | + * Return: 0 on success, errno on failure |
| 1254 | + */ |
| 1255 | +static int rpm_regulator_init_vreg(struct qcom_rpm_reg *vreg, struct device *dev, |
| 1256 | + struct device_node *node, struct qcom_smd_rpm *rpm, |
| 1257 | + const struct rpm_regulator_data *pmic_rpm_data) |
1243 | 1258 | {
|
1244 |
| - const struct rpm_regulator_data *reg; |
1245 |
| - const struct of_device_id *match; |
1246 |
| - struct regulator_config config = { }; |
| 1259 | + struct regulator_config config = {}; |
| 1260 | + const struct rpm_regulator_data *rpm_data; |
1247 | 1261 | struct regulator_dev *rdev;
|
| 1262 | + int ret; |
| 1263 | + |
| 1264 | + for (rpm_data = pmic_rpm_data; rpm_data->name; rpm_data++) |
| 1265 | + if (of_node_name_eq(node, rpm_data->name)) |
| 1266 | + break; |
| 1267 | + |
| 1268 | + if (!rpm_data->name) { |
| 1269 | + dev_err(dev, "Unknown regulator %pOFn\n", node); |
| 1270 | + return -EINVAL; |
| 1271 | + } |
| 1272 | + |
| 1273 | + vreg->dev = dev; |
| 1274 | + vreg->rpm = rpm; |
| 1275 | + vreg->type = rpm_data->type; |
| 1276 | + vreg->id = rpm_data->id; |
| 1277 | + |
| 1278 | + memcpy(&vreg->desc, rpm_data->desc, sizeof(vreg->desc)); |
| 1279 | + vreg->desc.name = rpm_data->name; |
| 1280 | + vreg->desc.supply_name = rpm_data->supply; |
| 1281 | + vreg->desc.owner = THIS_MODULE; |
| 1282 | + vreg->desc.type = REGULATOR_VOLTAGE; |
| 1283 | + vreg->desc.of_match = rpm_data->name; |
| 1284 | + |
| 1285 | + config.dev = dev; |
| 1286 | + config.of_node = node; |
| 1287 | + config.driver_data = vreg; |
| 1288 | + |
| 1289 | + rdev = devm_regulator_register(dev, &vreg->desc, &config); |
| 1290 | + if (IS_ERR(rdev)) { |
| 1291 | + ret = PTR_ERR(rdev); |
| 1292 | + dev_err(dev, "%pOFn: devm_regulator_register() failed, ret=%d\n", node, ret); |
| 1293 | + return ret; |
| 1294 | + } |
| 1295 | + |
| 1296 | + return 0; |
| 1297 | +} |
| 1298 | + |
| 1299 | +static int rpm_reg_probe(struct platform_device *pdev) |
| 1300 | +{ |
| 1301 | + struct device *dev = &pdev->dev; |
| 1302 | + const struct rpm_regulator_data *vreg_data; |
| 1303 | + struct device_node *node; |
1248 | 1304 | struct qcom_rpm_reg *vreg;
|
1249 | 1305 | struct qcom_smd_rpm *rpm;
|
| 1306 | + int ret; |
1250 | 1307 |
|
1251 | 1308 | rpm = dev_get_drvdata(pdev->dev.parent);
|
1252 | 1309 | if (!rpm) {
|
1253 |
| - dev_err(&pdev->dev, "unable to retrieve handle to rpm\n"); |
| 1310 | + dev_err(&pdev->dev, "Unable to retrieve handle to rpm\n"); |
1254 | 1311 | return -ENODEV;
|
1255 | 1312 | }
|
1256 | 1313 |
|
1257 |
| - match = of_match_device(rpm_of_match, &pdev->dev); |
1258 |
| - if (!match) { |
1259 |
| - dev_err(&pdev->dev, "failed to match device\n"); |
| 1314 | + vreg_data = of_device_get_match_data(dev); |
| 1315 | + if (!vreg_data) |
1260 | 1316 | return -ENODEV;
|
1261 |
| - } |
1262 | 1317 |
|
1263 |
| - for (reg = match->data; reg->name; reg++) { |
| 1318 | + for_each_available_child_of_node(dev->of_node, node) { |
1264 | 1319 | vreg = devm_kzalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
|
1265 | 1320 | if (!vreg)
|
1266 | 1321 | return -ENOMEM;
|
1267 | 1322 |
|
1268 |
| - vreg->dev = &pdev->dev; |
1269 |
| - vreg->type = reg->type; |
1270 |
| - vreg->id = reg->id; |
1271 |
| - vreg->rpm = rpm; |
1272 |
| - |
1273 |
| - memcpy(&vreg->desc, reg->desc, sizeof(vreg->desc)); |
1274 |
| - |
1275 |
| - vreg->desc.id = -1; |
1276 |
| - vreg->desc.owner = THIS_MODULE; |
1277 |
| - vreg->desc.type = REGULATOR_VOLTAGE; |
1278 |
| - vreg->desc.name = reg->name; |
1279 |
| - vreg->desc.supply_name = reg->supply; |
1280 |
| - vreg->desc.of_match = reg->name; |
1281 |
| - |
1282 |
| - config.dev = &pdev->dev; |
1283 |
| - config.driver_data = vreg; |
1284 |
| - rdev = devm_regulator_register(&pdev->dev, &vreg->desc, &config); |
1285 |
| - if (IS_ERR(rdev)) { |
1286 |
| - dev_err(&pdev->dev, "failed to register %s\n", reg->name); |
1287 |
| - return PTR_ERR(rdev); |
| 1323 | + ret = rpm_regulator_init_vreg(vreg, dev, node, rpm, vreg_data); |
| 1324 | + |
| 1325 | + if (ret < 0) { |
| 1326 | + of_node_put(node); |
| 1327 | + return ret; |
1288 | 1328 | }
|
1289 | 1329 | }
|
1290 | 1330 |
|
|
0 commit comments