diff options
author | Chanwoo Choi <cw00.choi@samsung.com> | 2012-11-22 02:54:26 -0500 |
---|---|---|
committer | Anton Vorontsov <anton.vorontsov@linaro.org> | 2013-01-05 17:00:09 -0500 |
commit | 41468a11199212f092cb4c071626785db6a32393 (patch) | |
tree | 17316fec71046352f67a5bc596efc6a7ffb7236f /drivers/power/charger-manager.c | |
parent | d1c3ed669a2d452cacfb48c2d171a1f364dae2ed (diff) |
charger-manager: Split _probe funtion to make the code more clean
This patch split _probe function for readability because _probe function
is longer than 400 line.
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
Diffstat (limited to 'drivers/power/charger-manager.c')
-rw-r--r-- | drivers/power/charger-manager.c | 279 |
1 files changed, 168 insertions, 111 deletions
diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c index 6ba047f5ac2c..029732d83090 100644 --- a/drivers/power/charger-manager.c +++ b/drivers/power/charger-manager.c | |||
@@ -1215,6 +1215,55 @@ static int charger_extcon_init(struct charger_manager *cm, | |||
1215 | return ret; | 1215 | return ret; |
1216 | } | 1216 | } |
1217 | 1217 | ||
1218 | /** | ||
1219 | * charger_manager_register_extcon - Register extcon device to recevie state | ||
1220 | * of charger cable. | ||
1221 | * @cm: the Charger Manager representing the battery. | ||
1222 | * | ||
1223 | * This function support EXTCON(External Connector) subsystem to detect the | ||
1224 | * state of charger cables for enabling or disabling charger(regulator) and | ||
1225 | * select the charger cable for charging among a number of external cable | ||
1226 | * according to policy of H/W board. | ||
1227 | */ | ||
1228 | static int charger_manager_register_extcon(struct charger_manager *cm) | ||
1229 | { | ||
1230 | struct charger_desc *desc = cm->desc; | ||
1231 | struct charger_regulator *charger; | ||
1232 | int ret = 0; | ||
1233 | int i; | ||
1234 | int j; | ||
1235 | |||
1236 | for (i = 0; i < desc->num_charger_regulators; i++) { | ||
1237 | charger = &desc->charger_regulators[i]; | ||
1238 | |||
1239 | charger->consumer = regulator_get(cm->dev, | ||
1240 | charger->regulator_name); | ||
1241 | if (charger->consumer == NULL) { | ||
1242 | dev_err(cm->dev, "Cannot find charger(%s)n", | ||
1243 | charger->regulator_name); | ||
1244 | ret = -EINVAL; | ||
1245 | goto err; | ||
1246 | } | ||
1247 | charger->cm = cm; | ||
1248 | |||
1249 | for (j = 0; j < charger->num_cables; j++) { | ||
1250 | struct charger_cable *cable = &charger->cables[j]; | ||
1251 | |||
1252 | ret = charger_extcon_init(cm, cable); | ||
1253 | if (ret < 0) { | ||
1254 | dev_err(cm->dev, "Cannot initialize charger(%s)n", | ||
1255 | charger->regulator_name); | ||
1256 | goto err; | ||
1257 | } | ||
1258 | cable->charger = charger; | ||
1259 | cable->cm = cm; | ||
1260 | } | ||
1261 | } | ||
1262 | |||
1263 | err: | ||
1264 | return ret; | ||
1265 | } | ||
1266 | |||
1218 | /* help function of sysfs node to control charger(regulator) */ | 1267 | /* help function of sysfs node to control charger(regulator) */ |
1219 | static ssize_t charger_name_show(struct device *dev, | 1268 | static ssize_t charger_name_show(struct device *dev, |
1220 | struct device_attribute *attr, char *buf) | 1269 | struct device_attribute *attr, char *buf) |
@@ -1274,7 +1323,7 @@ static ssize_t charger_externally_control_store(struct device *dev, | |||
1274 | 1323 | ||
1275 | for (i = 0; i < desc->num_charger_regulators; i++) { | 1324 | for (i = 0; i < desc->num_charger_regulators; i++) { |
1276 | if (&desc->charger_regulators[i] != charger && | 1325 | if (&desc->charger_regulators[i] != charger && |
1277 | !desc->charger_regulators[i].externally_control) { | 1326 | !desc->charger_regulators[i].externally_control) { |
1278 | /* | 1327 | /* |
1279 | * At least, one charger is controlled by | 1328 | * At least, one charger is controlled by |
1280 | * charger-manager | 1329 | * charger-manager |
@@ -1303,13 +1352,107 @@ static ssize_t charger_externally_control_store(struct device *dev, | |||
1303 | return count; | 1352 | return count; |
1304 | } | 1353 | } |
1305 | 1354 | ||
1355 | /** | ||
1356 | * charger_manager_register_sysfs - Register sysfs entry for each charger | ||
1357 | * @cm: the Charger Manager representing the battery. | ||
1358 | * | ||
1359 | * This function add sysfs entry for charger(regulator) to control charger from | ||
1360 | * user-space. If some development board use one more chargers for charging | ||
1361 | * but only need one charger on specific case which is dependent on user | ||
1362 | * scenario or hardware restrictions, the user enter 1 or 0(zero) to '/sys/ | ||
1363 | * class/power_supply/battery/charger.[index]/externally_control'. For example, | ||
1364 | * if user enter 1 to 'sys/class/power_supply/battery/charger.[index]/ | ||
1365 | * externally_control, this charger isn't controlled from charger-manager and | ||
1366 | * always stay off state of regulator. | ||
1367 | */ | ||
1368 | static int charger_manager_register_sysfs(struct charger_manager *cm) | ||
1369 | { | ||
1370 | struct charger_desc *desc = cm->desc; | ||
1371 | struct charger_regulator *charger; | ||
1372 | int chargers_externally_control = 1; | ||
1373 | char buf[11]; | ||
1374 | char *str; | ||
1375 | int ret = 0; | ||
1376 | int i; | ||
1377 | |||
1378 | /* Create sysfs entry to control charger(regulator) */ | ||
1379 | for (i = 0; i < desc->num_charger_regulators; i++) { | ||
1380 | charger = &desc->charger_regulators[i]; | ||
1381 | |||
1382 | snprintf(buf, 10, "charger.%d", i); | ||
1383 | str = kzalloc(sizeof(char) * (strlen(buf) + 1), GFP_KERNEL); | ||
1384 | if (!str) { | ||
1385 | dev_err(cm->dev, "Cannot allocate memory: %s\n", | ||
1386 | charger->regulator_name); | ||
1387 | ret = -ENOMEM; | ||
1388 | goto err; | ||
1389 | } | ||
1390 | strcpy(str, buf); | ||
1391 | |||
1392 | charger->attrs[0] = &charger->attr_name.attr; | ||
1393 | charger->attrs[1] = &charger->attr_state.attr; | ||
1394 | charger->attrs[2] = &charger->attr_externally_control.attr; | ||
1395 | charger->attrs[3] = NULL; | ||
1396 | charger->attr_g.name = str; | ||
1397 | charger->attr_g.attrs = charger->attrs; | ||
1398 | |||
1399 | sysfs_attr_init(&charger->attr_name.attr); | ||
1400 | charger->attr_name.attr.name = "name"; | ||
1401 | charger->attr_name.attr.mode = 0444; | ||
1402 | charger->attr_name.show = charger_name_show; | ||
1403 | |||
1404 | sysfs_attr_init(&charger->attr_state.attr); | ||
1405 | charger->attr_state.attr.name = "state"; | ||
1406 | charger->attr_state.attr.mode = 0444; | ||
1407 | charger->attr_state.show = charger_state_show; | ||
1408 | |||
1409 | sysfs_attr_init(&charger->attr_externally_control.attr); | ||
1410 | charger->attr_externally_control.attr.name | ||
1411 | = "externally_control"; | ||
1412 | charger->attr_externally_control.attr.mode = 0644; | ||
1413 | charger->attr_externally_control.show | ||
1414 | = charger_externally_control_show; | ||
1415 | charger->attr_externally_control.store | ||
1416 | = charger_externally_control_store; | ||
1417 | |||
1418 | if (!desc->charger_regulators[i].externally_control || | ||
1419 | !chargers_externally_control) | ||
1420 | chargers_externally_control = 0; | ||
1421 | |||
1422 | dev_info(cm->dev, "'%s' regulator's externally_control" | ||
1423 | "is %d\n", charger->regulator_name, | ||
1424 | charger->externally_control); | ||
1425 | |||
1426 | ret = sysfs_create_group(&cm->charger_psy.dev->kobj, | ||
1427 | &charger->attr_g); | ||
1428 | if (ret < 0) { | ||
1429 | dev_err(cm->dev, "Cannot create sysfs entry" | ||
1430 | "of %s regulator\n", | ||
1431 | charger->regulator_name); | ||
1432 | ret = -EINVAL; | ||
1433 | goto err; | ||
1434 | } | ||
1435 | } | ||
1436 | |||
1437 | if (chargers_externally_control) { | ||
1438 | dev_err(cm->dev, "Cannot register regulator because " | ||
1439 | "charger-manager must need at least " | ||
1440 | "one charger for charging battery\n"); | ||
1441 | |||
1442 | ret = -EINVAL; | ||
1443 | goto err; | ||
1444 | } | ||
1445 | |||
1446 | err: | ||
1447 | return ret; | ||
1448 | } | ||
1449 | |||
1306 | static int charger_manager_probe(struct platform_device *pdev) | 1450 | static int charger_manager_probe(struct platform_device *pdev) |
1307 | { | 1451 | { |
1308 | struct charger_desc *desc = dev_get_platdata(&pdev->dev); | 1452 | struct charger_desc *desc = dev_get_platdata(&pdev->dev); |
1309 | struct charger_manager *cm; | 1453 | struct charger_manager *cm; |
1310 | int ret = 0, i = 0; | 1454 | int ret = 0, i = 0; |
1311 | int j = 0; | 1455 | int j = 0; |
1312 | int chargers_externally_control = 1; | ||
1313 | union power_supply_propval val; | 1456 | union power_supply_propval val; |
1314 | 1457 | ||
1315 | if (g_desc && !rtc_dev && g_desc->rtc_name) { | 1458 | if (g_desc && !rtc_dev && g_desc->rtc_name) { |
@@ -1440,11 +1583,10 @@ static int charger_manager_probe(struct platform_device *pdev) | |||
1440 | 1583 | ||
1441 | memcpy(&cm->charger_psy, &psy_default, sizeof(psy_default)); | 1584 | memcpy(&cm->charger_psy, &psy_default, sizeof(psy_default)); |
1442 | 1585 | ||
1443 | if (!desc->psy_name) { | 1586 | if (!desc->psy_name) |
1444 | strncpy(cm->psy_name_buf, psy_default.name, PSY_NAME_MAX); | 1587 | strncpy(cm->psy_name_buf, psy_default.name, PSY_NAME_MAX); |
1445 | } else { | 1588 | else |
1446 | strncpy(cm->psy_name_buf, desc->psy_name, PSY_NAME_MAX); | 1589 | strncpy(cm->psy_name_buf, desc->psy_name, PSY_NAME_MAX); |
1447 | } | ||
1448 | cm->charger_psy.name = cm->psy_name_buf; | 1590 | cm->charger_psy.name = cm->psy_name_buf; |
1449 | 1591 | ||
1450 | /* Allocate for psy properties because they may vary */ | 1592 | /* Allocate for psy properties because they may vary */ |
@@ -1496,105 +1638,19 @@ static int charger_manager_probe(struct platform_device *pdev) | |||
1496 | goto err_register; | 1638 | goto err_register; |
1497 | } | 1639 | } |
1498 | 1640 | ||
1499 | for (i = 0 ; i < desc->num_charger_regulators ; i++) { | 1641 | /* Register extcon device for charger cable */ |
1500 | struct charger_regulator *charger | 1642 | ret = charger_manager_register_extcon(cm); |
1501 | = &desc->charger_regulators[i]; | 1643 | if (ret < 0) { |
1502 | char buf[11]; | 1644 | dev_err(&pdev->dev, "Cannot initialize extcon device\n"); |
1503 | char *str; | 1645 | goto err_reg_extcon; |
1504 | |||
1505 | charger->consumer = regulator_get(&pdev->dev, | ||
1506 | charger->regulator_name); | ||
1507 | if (charger->consumer == NULL) { | ||
1508 | dev_err(&pdev->dev, "Cannot find charger(%s)n", | ||
1509 | charger->regulator_name); | ||
1510 | ret = -EINVAL; | ||
1511 | goto err_chg_get; | ||
1512 | } | ||
1513 | charger->cm = cm; | ||
1514 | |||
1515 | for (j = 0 ; j < charger->num_cables ; j++) { | ||
1516 | struct charger_cable *cable = &charger->cables[j]; | ||
1517 | |||
1518 | ret = charger_extcon_init(cm, cable); | ||
1519 | if (ret < 0) { | ||
1520 | dev_err(&pdev->dev, "Cannot find charger(%s)n", | ||
1521 | charger->regulator_name); | ||
1522 | goto err_extcon; | ||
1523 | } | ||
1524 | cable->charger = charger; | ||
1525 | cable->cm = cm; | ||
1526 | } | ||
1527 | |||
1528 | /* Create sysfs entry to control charger(regulator) */ | ||
1529 | snprintf(buf, 10, "charger.%d", i); | ||
1530 | str = kzalloc(sizeof(char) * (strlen(buf) + 1), GFP_KERNEL); | ||
1531 | if (!str) { | ||
1532 | for (i--; i >= 0; i--) { | ||
1533 | charger = &desc->charger_regulators[i]; | ||
1534 | kfree(charger->attr_g.name); | ||
1535 | } | ||
1536 | ret = -ENOMEM; | ||
1537 | |||
1538 | goto err_extcon; | ||
1539 | } | ||
1540 | strcpy(str, buf); | ||
1541 | |||
1542 | charger->attrs[0] = &charger->attr_name.attr; | ||
1543 | charger->attrs[1] = &charger->attr_state.attr; | ||
1544 | charger->attrs[2] = &charger->attr_externally_control.attr; | ||
1545 | charger->attrs[3] = NULL; | ||
1546 | charger->attr_g.name = str; | ||
1547 | charger->attr_g.attrs = charger->attrs; | ||
1548 | |||
1549 | sysfs_attr_init(&charger->attr_name.attr); | ||
1550 | charger->attr_name.attr.name = "name"; | ||
1551 | charger->attr_name.attr.mode = 0444; | ||
1552 | charger->attr_name.show = charger_name_show; | ||
1553 | |||
1554 | sysfs_attr_init(&charger->attr_state.attr); | ||
1555 | charger->attr_state.attr.name = "state"; | ||
1556 | charger->attr_state.attr.mode = 0444; | ||
1557 | charger->attr_state.show = charger_state_show; | ||
1558 | |||
1559 | sysfs_attr_init(&charger->attr_externally_control.attr); | ||
1560 | charger->attr_externally_control.attr.name | ||
1561 | = "externally_control"; | ||
1562 | charger->attr_externally_control.attr.mode = 0644; | ||
1563 | charger->attr_externally_control.show | ||
1564 | = charger_externally_control_show; | ||
1565 | charger->attr_externally_control.store | ||
1566 | = charger_externally_control_store; | ||
1567 | |||
1568 | if (!desc->charger_regulators[i].externally_control || | ||
1569 | !chargers_externally_control) { | ||
1570 | chargers_externally_control = 0; | ||
1571 | } | ||
1572 | dev_info(&pdev->dev, "'%s' regulator's externally_control" | ||
1573 | "is %d\n", charger->regulator_name, | ||
1574 | charger->externally_control); | ||
1575 | |||
1576 | ret = sysfs_create_group(&cm->charger_psy.dev->kobj, | ||
1577 | &charger->attr_g); | ||
1578 | if (ret < 0) { | ||
1579 | dev_info(&pdev->dev, "Cannot create sysfs entry" | ||
1580 | "of %s regulator\n", | ||
1581 | charger->regulator_name); | ||
1582 | } | ||
1583 | } | ||
1584 | |||
1585 | if (chargers_externally_control) { | ||
1586 | dev_err(&pdev->dev, "Cannot register regulator because " | ||
1587 | "charger-manager must need at least " | ||
1588 | "one charger for charging battery\n"); | ||
1589 | |||
1590 | ret = -EINVAL; | ||
1591 | goto err_chg_enable; | ||
1592 | } | 1646 | } |
1593 | 1647 | ||
1594 | ret = try_charger_enable(cm, true); | 1648 | /* Register sysfs entry for charger(regulator) */ |
1595 | if (ret) { | 1649 | ret = charger_manager_register_sysfs(cm); |
1596 | dev_err(&pdev->dev, "Cannot enable charger regulators\n"); | 1650 | if (ret < 0) { |
1597 | goto err_chg_enable; | 1651 | dev_err(&pdev->dev, |
1652 | "Cannot initialize sysfs entry of regulator\n"); | ||
1653 | goto err_reg_sysfs; | ||
1598 | } | 1654 | } |
1599 | 1655 | ||
1600 | /* Add to the list */ | 1656 | /* Add to the list */ |
@@ -1613,27 +1669,28 @@ static int charger_manager_probe(struct platform_device *pdev) | |||
1613 | 1669 | ||
1614 | return 0; | 1670 | return 0; |
1615 | 1671 | ||
1616 | err_chg_enable: | 1672 | err_reg_sysfs: |
1617 | for (i = 0; i < desc->num_charger_regulators; i++) { | 1673 | for (i = 0; i < desc->num_charger_regulators; i++) { |
1618 | struct charger_regulator *charger; | 1674 | struct charger_regulator *charger; |
1619 | 1675 | ||
1620 | charger = &desc->charger_regulators[i]; | 1676 | charger = &desc->charger_regulators[i]; |
1621 | sysfs_remove_group(&cm->charger_psy.dev->kobj, | 1677 | sysfs_remove_group(&cm->charger_psy.dev->kobj, |
1622 | &charger->attr_g); | 1678 | &charger->attr_g); |
1679 | |||
1623 | kfree(charger->attr_g.name); | 1680 | kfree(charger->attr_g.name); |
1624 | } | 1681 | } |
1625 | err_extcon: | 1682 | err_reg_extcon: |
1626 | for (i = 0 ; i < desc->num_charger_regulators ; i++) { | 1683 | for (i = 0; i < desc->num_charger_regulators; i++) { |
1627 | struct charger_regulator *charger | 1684 | struct charger_regulator *charger; |
1628 | = &desc->charger_regulators[i]; | 1685 | |
1629 | for (j = 0 ; j < charger->num_cables ; j++) { | 1686 | charger = &desc->charger_regulators[i]; |
1687 | for (j = 0; j < charger->num_cables; j++) { | ||
1630 | struct charger_cable *cable = &charger->cables[j]; | 1688 | struct charger_cable *cable = &charger->cables[j]; |
1631 | extcon_unregister_interest(&cable->extcon_dev); | 1689 | extcon_unregister_interest(&cable->extcon_dev); |
1632 | } | 1690 | } |
1633 | } | 1691 | |
1634 | err_chg_get: | ||
1635 | for (i = 0 ; i < desc->num_charger_regulators ; i++) | ||
1636 | regulator_put(desc->charger_regulators[i].consumer); | 1692 | regulator_put(desc->charger_regulators[i].consumer); |
1693 | } | ||
1637 | 1694 | ||
1638 | power_supply_unregister(&cm->charger_psy); | 1695 | power_supply_unregister(&cm->charger_psy); |
1639 | err_register: | 1696 | err_register: |