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

power: supply: charger-manager: Update extcon functions

In commit 830ae442202e ("extcon: Remove the deprecated extcon functions")
the function extcon_register_interest became a no-op returning an error,
leading to non-functional behaviour in charger-manager.

Additionally, a translation table is needed between the text representation
of the extcon cable names and their IDs is needed. In order to retain DT
compatibility, TA and CHARGE-DOWNSTREAM are added as they were present up
until commit 11eecf910bd8 ("extcon: Modify the id and name of external
connector")

Signed-off-by: Jonathan Bakker <xc-racer2@live.ca>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>

authored by

Jonathan Bakker and committed by
Sebastian Reichel
c1f73028 9434e453

+64 -25
+61 -23
drivers/power/supply/charger-manager.c
··· 26 26 #include <linux/of.h> 27 27 #include <linux/thermal.h> 28 28 29 + static struct { 30 + const char *name; 31 + u64 extcon_type; 32 + } extcon_mapping[] = { 33 + /* Current textual representations */ 34 + { "USB", EXTCON_USB }, 35 + { "USB-HOST", EXTCON_USB_HOST }, 36 + { "SDP", EXTCON_CHG_USB_SDP }, 37 + { "DCP", EXTCON_CHG_USB_DCP }, 38 + { "CDP", EXTCON_CHG_USB_CDP }, 39 + { "ACA", EXTCON_CHG_USB_ACA }, 40 + { "FAST-CHARGER", EXTCON_CHG_USB_FAST }, 41 + { "SLOW-CHARGER", EXTCON_CHG_USB_SLOW }, 42 + { "WPT", EXTCON_CHG_WPT }, 43 + { "PD", EXTCON_CHG_USB_PD }, 44 + { "DOCK", EXTCON_DOCK }, 45 + { "JIG", EXTCON_JIG }, 46 + { "MECHANICAL", EXTCON_MECHANICAL }, 47 + /* Deprecated textual representations */ 48 + { "TA", EXTCON_CHG_USB_SDP }, 49 + { "CHARGE-DOWNSTREAM", EXTCON_CHG_USB_CDP }, 50 + }; 51 + 29 52 /* 30 53 * Default temperature threshold for charging. 31 54 * Every temperature units are in tenth of centigrade. ··· 973 950 static int charger_extcon_init(struct charger_manager *cm, 974 951 struct charger_cable *cable) 975 952 { 976 - int ret; 953 + int ret, i; 954 + u64 extcon_type = EXTCON_NONE; 977 955 978 956 /* 979 957 * Charger manager use Extcon framework to identify ··· 983 959 */ 984 960 INIT_WORK(&cable->wq, charger_extcon_work); 985 961 cable->nb.notifier_call = charger_extcon_notifier; 986 - ret = extcon_register_interest(&cable->extcon_dev, 987 - cable->extcon_name, cable->name, &cable->nb); 988 - if (ret < 0) { 989 - pr_info("Cannot register extcon_dev for %s(cable: %s)\n", 962 + 963 + cable->extcon_dev = extcon_get_extcon_dev(cable->extcon_name); 964 + if (IS_ERR_OR_NULL(cable->extcon_dev)) { 965 + pr_err("Cannot find extcon_dev for %s (cable: %s)\n", 990 966 cable->extcon_name, cable->name); 967 + if (cable->extcon_dev == NULL) 968 + return -EPROBE_DEFER; 969 + else 970 + return PTR_ERR(cable->extcon_dev); 991 971 } 992 972 993 - return ret; 973 + for (i = 0; i < ARRAY_SIZE(extcon_mapping); i++) { 974 + if (!strcmp(cable->name, extcon_mapping[i].name)) { 975 + extcon_type = extcon_mapping[i].extcon_type; 976 + break; 977 + } 978 + } 979 + if (extcon_type == EXTCON_NONE) { 980 + pr_err("Cannot find cable for type %s", cable->name); 981 + return -EINVAL; 982 + } 983 + 984 + cable->extcon_type = extcon_type; 985 + 986 + ret = devm_extcon_register_notifier(cm->dev, cable->extcon_dev, 987 + cable->extcon_type, &cable->nb); 988 + if (ret < 0) { 989 + pr_err("Cannot register extcon_dev for %s (cable: %s)\n", 990 + cable->extcon_name, cable->name); 991 + return ret; 992 + } 993 + 994 + return 0; 994 995 } 995 996 996 997 /** ··· 1032 983 { 1033 984 struct charger_desc *desc = cm->desc; 1034 985 struct charger_regulator *charger; 986 + unsigned long event; 1035 987 int ret; 1036 988 int i; 1037 989 int j; ··· 1060 1010 } 1061 1011 cable->charger = charger; 1062 1012 cable->cm = cm; 1013 + 1014 + event = extcon_get_state(cable->extcon_dev, 1015 + cable->extcon_type); 1016 + charger_extcon_notifier(&cable->nb, 1017 + event, NULL); 1063 1018 } 1064 1019 } 1065 1020 ··· 1425 1370 struct charger_desc *desc = cm_get_drv_data(pdev); 1426 1371 struct charger_manager *cm; 1427 1372 int ret, i = 0; 1428 - int j = 0; 1429 1373 union power_supply_propval val; 1430 1374 struct power_supply *fuel_gauge; 1431 1375 enum power_supply_property *properties; ··· 1626 1572 struct charger_regulator *charger; 1627 1573 1628 1574 charger = &desc->charger_regulators[i]; 1629 - for (j = 0; j < charger->num_cables; j++) { 1630 - struct charger_cable *cable = &charger->cables[j]; 1631 - /* Remove notifier block if only edev exists */ 1632 - if (cable->extcon_dev.edev) 1633 - extcon_unregister_interest(&cable->extcon_dev); 1634 - } 1635 1575 1636 1576 regulator_put(desc->charger_regulators[i].consumer); 1637 1577 } ··· 1640 1592 struct charger_manager *cm = platform_get_drvdata(pdev); 1641 1593 struct charger_desc *desc = cm->desc; 1642 1594 int i = 0; 1643 - int j = 0; 1644 1595 1645 1596 /* Remove from the list */ 1646 1597 mutex_lock(&cm_list_mtx); ··· 1648 1601 1649 1602 cancel_work_sync(&setup_polling); 1650 1603 cancel_delayed_work_sync(&cm_monitor_work); 1651 - 1652 - for (i = 0 ; i < desc->num_charger_regulators ; i++) { 1653 - struct charger_regulator *charger 1654 - = &desc->charger_regulators[i]; 1655 - for (j = 0 ; j < charger->num_cables ; j++) { 1656 - struct charger_cable *cable = &charger->cables[j]; 1657 - extcon_unregister_interest(&cable->extcon_dev); 1658 - } 1659 - } 1660 1604 1661 1605 for (i = 0 ; i < desc->num_charger_regulators ; i++) 1662 1606 regulator_put(desc->charger_regulators[i].consumer);
+3 -2
include/linux/power/charger-manager.h
··· 40 40 /** 41 41 * struct charger_cable 42 42 * @extcon_name: the name of extcon device. 43 - * @name: the name of charger cable(external connector). 43 + * @name: the name of the cable connector 44 44 * @extcon_dev: the extcon device. 45 45 * @wq: the workqueue to control charger according to the state of 46 46 * charger cable. If charger cable is attached, enable charger. ··· 56 56 struct charger_cable { 57 57 const char *extcon_name; 58 58 const char *name; 59 + struct extcon_dev *extcon_dev; 60 + u64 extcon_type; 59 61 60 62 /* The charger-manager use Extcon framework */ 61 - struct extcon_specific_cable_nb extcon_dev; 62 63 struct work_struct wq; 63 64 struct notifier_block nb; 64 65