pmic-voter: disassociate device from votables

Currently the pmic votables need a device to be created.
Votables should be able to work on device less code. Remove
the need for device and instead use a void pointer to be passed
back to the callback.

CRs-Fixed: 1018090
Change-Id: If5dafbcc0d88596332b794ad5b6fdc1f9ff98a45
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
This commit is contained in:
Abhijeet Dharmapurikar 2016-06-06 16:13:14 -07:00 committed by Kyle Yan
parent fc63395132
commit fc630843db
6 changed files with 216 additions and 131 deletions

View file

@ -15,7 +15,8 @@
#include <linux/errno.h>
#include <linux/bitops.h>
#include <linux/printk.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/string.h>
#include "pmic-voter.h"
@ -35,13 +36,14 @@ struct votable {
const char *name;
struct list_head list;
struct client_vote votes[NUM_MAX_CLIENTS];
struct device *dev;
int num_clients;
int type;
int effective_client_id;
int effective_result;
struct mutex vote_lock;
int (*callback)(struct device *dev,
void *data;
int (*callback)(struct votable *votable,
void *data,
int effective_result,
const char *effective_client);
char *client_strs[NUM_MAX_CLIENTS];
@ -152,8 +154,7 @@ static int get_client_id(struct votable *votable, const char *client_str)
for (i = 0; i < votable->num_clients; i++) {
if (!votable->client_strs[i]) {
votable->client_strs[i]
= devm_kstrdup(votable->dev,
client_str, GFP_KERNEL);
= kstrdup(client_str, GFP_KERNEL);
if (!votable->client_strs[i])
return -ENOMEM;
return i;
@ -361,7 +362,8 @@ int vote(struct votable *votable, const char *client_str, bool enabled, int val)
get_client_str(votable, effective_id),
effective_id);
if (votable->callback)
rc = votable->callback(votable->dev, effective_result,
rc = votable->callback(votable, votable->data,
effective_result,
get_client_str(votable, effective_id));
}
@ -377,7 +379,8 @@ int rerun_election(struct votable *votable)
lock_votable(votable);
if (votable->callback)
rc = votable->callback(votable->dev,
rc = votable->callback(votable,
votable->data,
votable->effective_result,
get_client_str(votable, votable->effective_client_id));
unlock_votable(votable);
@ -466,12 +469,13 @@ static const struct file_operations votable_debugfs_ops = {
.release = single_release,
};
struct votable *create_votable(struct device *dev, const char *name,
int votable_type,
int (*callback)(struct device *dev,
int effective_result,
const char *effective_client)
)
struct votable *create_votable(const char *name,
int votable_type,
int (*callback)(struct votable *votable,
void *data,
int effective_result,
const char *effective_client),
void *data)
{
struct votable *votable;
unsigned long flags;
@ -483,25 +487,30 @@ struct votable *create_votable(struct device *dev, const char *name,
if (debug_root == NULL) {
debug_root = debugfs_create_dir("pmic-votable", NULL);
if (!debug_root) {
dev_err(dev, "Couldn't create debug dir\n");
pr_err("Couldn't create debug dir\n");
return ERR_PTR(-ENOMEM);
}
}
if (votable_type >= NUM_VOTABLE_TYPES) {
dev_err(dev, "Invalid votable_type specified for voter\n");
pr_err("Invalid votable_type specified for voter\n");
return ERR_PTR(-EINVAL);
}
votable = devm_kzalloc(dev, sizeof(struct votable), GFP_KERNEL);
votable = kzalloc(sizeof(struct votable), GFP_KERNEL);
if (!votable)
return ERR_PTR(-ENOMEM);
votable->dev = dev;
votable->name = name;
votable->name = kstrdup(name, GFP_KERNEL);
if (!votable->name) {
kfree(votable);
return ERR_PTR(-ENOMEM);
}
votable->num_clients = NUM_MAX_CLIENTS;
votable->callback = callback;
votable->type = votable_type;
votable->data = data;
mutex_init(&votable->vote_lock);
/*
@ -521,22 +530,28 @@ struct votable *create_votable(struct device *dev, const char *name,
debug_root, votable,
&votable_debugfs_ops);
if (!votable->ent) {
dev_err(dev, "Couldn't create %s debug file\n", name);
devm_kfree(dev, votable);
pr_err("Couldn't create %s debug file\n", name);
kfree(votable->name);
kfree(votable);
return ERR_PTR(-EEXIST);
}
return votable;
}
void destroy_votable(struct device *dev, struct votable *votable)
void destroy_votable(struct votable *votable)
{
unsigned long flags;
int i;
/* only disengage from list, mem will be freed with dev release */
spin_lock_irqsave(&votable_list_slock, flags);
list_del(&votable->list);
spin_unlock_irqrestore(&votable_list_slock, flags);
debugfs_remove(votable->ent);
for (i = 0; i < votable->num_clients && votable->client_strs[i]; i++)
kfree(votable->client_strs[i]);
kfree(votable->name);
kfree(votable);
}

View file

@ -33,13 +33,14 @@ const char *get_effective_client_locked(struct votable *votable);
int vote(struct votable *votable, const char *client_str, bool state, int val);
int rerun_election(struct votable *votable);
struct votable *find_votable(const char *name);
struct votable *create_votable(struct device *dev, const char *name,
struct votable *create_votable(const char *name,
int votable_type,
int (*callback)(struct device *dev,
int (*callback)(struct votable *votable,
void *data,
int effective_result,
const char *effective_client)
);
void destroy_votable(struct device *dev, struct votable *votable);
const char *effective_client),
void *data);
void destroy_votable(struct votable *votable);
void lock_votable(struct votable *votable);
void unlock_votable(struct votable *votable);

View file

@ -798,6 +798,7 @@ static int smb2_probe(struct platform_device *pdev)
return rc;
cleanup:
smblib_deinit(chg);
if (chg->usb_psy)
power_supply_unregister(chg->usb_psy);
if (chg->batt_psy)

View file

@ -2335,11 +2335,12 @@ static void smbchg_parallel_usb_check_ok(struct smbchg_chip *chip)
schedule_delayed_work(&chip->parallel_en_work, 0);
}
static int charging_suspend_vote_cb(struct device *dev, int suspend,
static int charging_suspend_vote_cb(struct votable *votable, void *data,
int suspend,
const char *client)
{
int rc;
struct smbchg_chip *chip = dev_get_drvdata(dev);
struct smbchg_chip *chip = data;
if (suspend < 0) {
pr_err("No voters\n");
@ -2356,11 +2357,13 @@ static int charging_suspend_vote_cb(struct device *dev, int suspend,
return rc;
}
static int usb_suspend_vote_cb(struct device *dev, int suspend,
const char *client)
static int usb_suspend_vote_cb(struct votable *votable,
void *data,
int suspend,
const char *client)
{
int rc;
struct smbchg_chip *chip = dev_get_drvdata(dev);
struct smbchg_chip *chip = data;
if (suspend < 0) {
pr_err("No voters\n");
@ -2380,11 +2383,13 @@ static int usb_suspend_vote_cb(struct device *dev, int suspend,
return rc;
}
static int dc_suspend_vote_cb(struct device *dev, int suspend,
static int dc_suspend_vote_cb(struct votable *votable,
void *data,
int suspend,
const char *client)
{
int rc;
struct smbchg_chip *chip = dev_get_drvdata(dev);
struct smbchg_chip *chip = data;
if (suspend < 0) {
pr_err("No voters\n");
@ -2401,11 +2406,12 @@ static int dc_suspend_vote_cb(struct device *dev, int suspend,
return rc;
}
static int set_fastchg_current_vote_cb(struct device *dev,
static int set_fastchg_current_vote_cb(struct votable *votable,
void *data,
int fcc_ma,
const char *client)
{
struct smbchg_chip *chip = dev_get_drvdata(dev);
struct smbchg_chip *chip = data;
int rc;
if (fcc_ma < 0) {
@ -2692,11 +2698,12 @@ DEFINE_SIMPLE_ATTRIBUTE(force_dcin_icl_ops, NULL,
* set the dc charge path's maximum allowed current draw
* that may be limited by the system's thermal level
*/
static int set_dc_current_limit_vote_cb(struct device *dev,
static int set_dc_current_limit_vote_cb(struct votable *votable,
void *data,
int icl_ma,
const char *client)
{
struct smbchg_chip *chip = dev_get_drvdata(dev);
struct smbchg_chip *chip = data;
if (icl_ma < 0) {
pr_err("No voters\n");
@ -2710,11 +2717,12 @@ static int set_dc_current_limit_vote_cb(struct device *dev,
* set the usb charge path's maximum allowed current draw
* that may be limited by the system's thermal level
*/
static int set_usb_current_limit_vote_cb(struct device *dev,
static int set_usb_current_limit_vote_cb(struct votable *votable,
void *data,
int icl_ma,
const char *client)
{
struct smbchg_chip *chip = dev_get_drvdata(dev);
struct smbchg_chip *chip = data;
int rc, aicl_ma;
const char *effective_id;
@ -3302,12 +3310,13 @@ static void smbchg_soc_changed(struct smbchg_chip *chip)
#define AICL_RERUN_ON (BIT(5) | BIT(4))
#define AICL_RERUN_OFF 0
static int smbchg_hw_aicl_rerun_enable_indirect_cb(struct device *dev,
static int smbchg_hw_aicl_rerun_enable_indirect_cb(struct votable *votable,
void *data,
int enable,
const char *client)
{
int rc = 0;
struct smbchg_chip *chip = dev_get_drvdata(dev);
struct smbchg_chip *chip = data;
if (enable < 0) {
pr_err("No voters\n");
@ -3327,11 +3336,12 @@ static int smbchg_hw_aicl_rerun_enable_indirect_cb(struct device *dev,
return rc;
}
static int smbchg_hw_aicl_rerun_disable_cb(struct device *dev, int disable,
static int smbchg_hw_aicl_rerun_disable_cb(struct votable *votable, void *data,
int disable,
const char *client)
{
int rc = 0;
struct smbchg_chip *chip = dev_get_drvdata(dev);
struct smbchg_chip *chip = data;
if (disable < 0) {
pr_err("No voters\n");
@ -3347,11 +3357,12 @@ static int smbchg_hw_aicl_rerun_disable_cb(struct device *dev, int disable,
return rc;
}
static int smbchg_aicl_deglitch_config_cb(struct device *dev, int shorter,
static int smbchg_aicl_deglitch_config_cb(struct votable *votable, void *data,
int shorter,
const char *client)
{
int rc = 0;
struct smbchg_chip *chip = dev_get_drvdata(dev);
struct smbchg_chip *chip = data;
if (shorter < 0) {
pr_err("No voters\n");
@ -7997,68 +8008,79 @@ static int smbchg_probe(struct platform_device *pdev)
return -EINVAL;
}
chip->fcc_votable = create_votable(&pdev->dev,
"BATT_FCC",
chip->fcc_votable = create_votable("BATT_FCC",
VOTE_MIN,
set_fastchg_current_vote_cb);
if (IS_ERR(chip->fcc_votable))
return PTR_ERR(chip->fcc_votable);
set_fastchg_current_vote_cb, chip);
if (IS_ERR(chip->fcc_votable)) {
rc = PTR_ERR(chip->fcc_votable);
goto votables_cleanup;
}
chip->usb_icl_votable = create_votable(&pdev->dev,
"USB_ICL",
chip->usb_icl_votable = create_votable("USB_ICL",
VOTE_MIN,
set_usb_current_limit_vote_cb);
if (IS_ERR(chip->usb_icl_votable))
return PTR_ERR(chip->usb_icl_votable);
set_usb_current_limit_vote_cb, chip);
if (IS_ERR(chip->usb_icl_votable)) {
rc = PTR_ERR(chip->usb_icl_votable);
goto votables_cleanup;
}
chip->dc_icl_votable = create_votable(&pdev->dev,
"DCIN_ICL",
chip->dc_icl_votable = create_votable("DCIN_ICL",
VOTE_MIN,
set_dc_current_limit_vote_cb);
if (IS_ERR(chip->dc_icl_votable))
return PTR_ERR(chip->dc_icl_votable);
set_dc_current_limit_vote_cb, chip);
if (IS_ERR(chip->dc_icl_votable)) {
rc = PTR_ERR(chip->dc_icl_votable);
goto votables_cleanup;
}
chip->usb_suspend_votable = create_votable(&pdev->dev,
"USB_SUSPEND",
chip->usb_suspend_votable = create_votable("USB_SUSPEND",
VOTE_SET_ANY,
usb_suspend_vote_cb);
if (IS_ERR(chip->usb_suspend_votable))
return PTR_ERR(chip->usb_suspend_votable);
usb_suspend_vote_cb, chip);
if (IS_ERR(chip->usb_suspend_votable)) {
rc = PTR_ERR(chip->usb_suspend_votable);
goto votables_cleanup;
}
chip->dc_suspend_votable = create_votable(&pdev->dev,
"DC_SUSPEND",
chip->dc_suspend_votable = create_votable("DC_SUSPEND",
VOTE_SET_ANY,
dc_suspend_vote_cb);
if (IS_ERR(chip->dc_suspend_votable))
return PTR_ERR(chip->dc_suspend_votable);
dc_suspend_vote_cb, chip);
if (IS_ERR(chip->dc_suspend_votable)) {
rc = PTR_ERR(chip->dc_suspend_votable);
goto votables_cleanup;
}
chip->battchg_suspend_votable = create_votable(&pdev->dev,
"BATTCHG_SUSPEND",
chip->battchg_suspend_votable = create_votable("BATTCHG_SUSPEND",
VOTE_SET_ANY,
charging_suspend_vote_cb);
if (IS_ERR(chip->battchg_suspend_votable))
return PTR_ERR(chip->battchg_suspend_votable);
charging_suspend_vote_cb, chip);
if (IS_ERR(chip->battchg_suspend_votable)) {
rc = PTR_ERR(chip->battchg_suspend_votable);
goto votables_cleanup;
}
chip->hw_aicl_rerun_disable_votable = create_votable(&pdev->dev,
"HWAICL_DISABLE",
chip->hw_aicl_rerun_disable_votable = create_votable("HWAICL_DISABLE",
VOTE_SET_ANY,
smbchg_hw_aicl_rerun_disable_cb);
if (IS_ERR(chip->hw_aicl_rerun_disable_votable))
return PTR_ERR(chip->hw_aicl_rerun_disable_votable);
smbchg_hw_aicl_rerun_disable_cb, chip);
if (IS_ERR(chip->hw_aicl_rerun_disable_votable)) {
rc = PTR_ERR(chip->hw_aicl_rerun_disable_votable);
goto votables_cleanup;
}
chip->hw_aicl_rerun_enable_indirect_votable = create_votable(&pdev->dev,
chip->hw_aicl_rerun_enable_indirect_votable = create_votable(
"HWAICL_ENABLE_INDIRECT",
VOTE_SET_ANY,
smbchg_hw_aicl_rerun_enable_indirect_cb);
if (IS_ERR(chip->hw_aicl_rerun_enable_indirect_votable))
return PTR_ERR(chip->hw_aicl_rerun_enable_indirect_votable);
smbchg_hw_aicl_rerun_enable_indirect_cb, chip);
if (IS_ERR(chip->hw_aicl_rerun_enable_indirect_votable)) {
rc = PTR_ERR(chip->hw_aicl_rerun_enable_indirect_votable);
goto votables_cleanup;
}
chip->aicl_deglitch_short_votable = create_votable(&pdev->dev,
chip->aicl_deglitch_short_votable = create_votable(
"HWAICL_SHORT_DEGLITCH",
VOTE_SET_ANY,
smbchg_aicl_deglitch_config_cb);
if (IS_ERR(chip->aicl_deglitch_short_votable))
return PTR_ERR(chip->aicl_deglitch_short_votable);
smbchg_aicl_deglitch_config_cb, chip);
if (IS_ERR(chip->aicl_deglitch_short_votable)) {
rc = PTR_ERR(chip->aicl_deglitch_short_votable);
goto votables_cleanup;
}
INIT_WORK(&chip->usb_set_online_work, smbchg_usb_update_online_work);
INIT_DELAYED_WORK(&chip->parallel_en_work,
@ -8092,38 +8114,39 @@ static int smbchg_probe(struct platform_device *pdev)
rc = smbchg_parse_peripherals(chip);
if (rc) {
dev_err(chip->dev, "Error parsing DT peripherals: %d\n", rc);
return rc;
goto votables_cleanup;
}
rc = smbchg_check_chg_version(chip);
if (rc) {
pr_err("Unable to check schg version rc=%d\n", rc);
return rc;
goto votables_cleanup;
}
rc = smb_parse_dt(chip);
if (rc < 0) {
dev_err(&pdev->dev, "Unable to parse DT nodes: %d\n", rc);
return rc;
goto votables_cleanup;
}
rc = smbchg_regulator_init(chip);
if (rc) {
dev_err(&pdev->dev,
"Couldn't initialize regulator rc=%d\n", rc);
return rc;
goto votables_cleanup;
}
chip->extcon = devm_extcon_dev_allocate(chip->dev, smbchg_extcon_cable);
if (IS_ERR(chip->extcon)) {
dev_err(chip->dev, "failed to allocate extcon device\n");
return PTR_ERR(chip->extcon);
rc = PTR_ERR(chip->extcon);
goto votables_cleanup;
}
rc = devm_extcon_dev_register(chip->dev, chip->extcon);
if (rc) {
dev_err(chip->dev, "failed to register extcon device\n");
return rc;
goto votables_cleanup;
}
chip->usb_psy_d.name = "usb";
@ -8143,13 +8166,16 @@ static int smbchg_probe(struct platform_device *pdev)
if (IS_ERR(chip->usb_psy)) {
dev_err(&pdev->dev, "Unable to register usb_psy rc = %ld\n",
PTR_ERR(chip->usb_psy));
return PTR_ERR(chip->usb_psy);
rc = PTR_ERR(chip->usb_psy);
goto votables_cleanup;
}
if (of_find_property(chip->dev->of_node, "dpdm-supply", NULL)) {
chip->dpdm_reg = devm_regulator_get(chip->dev, "dpdm");
if (IS_ERR(chip->dpdm_reg))
return PTR_ERR(chip->dpdm_reg);
if (IS_ERR(chip->dpdm_reg)) {
rc = PTR_ERR(chip->dpdm_reg);
goto votables_cleanup;
}
}
rc = smbchg_hw_init(chip);
@ -8257,6 +8283,25 @@ unregister_led_class:
led_classdev_unregister(&chip->led_cdev);
out:
handle_usb_removal(chip);
votables_cleanup:
if (chip->aicl_deglitch_short_votable)
destroy_votable(chip->aicl_deglitch_short_votable);
if (chip->hw_aicl_rerun_enable_indirect_votable)
destroy_votable(chip->hw_aicl_rerun_enable_indirect_votable);
if (chip->hw_aicl_rerun_disable_votable)
destroy_votable(chip->hw_aicl_rerun_disable_votable);
if (chip->battchg_suspend_votable)
destroy_votable(chip->battchg_suspend_votable);
if (chip->dc_suspend_votable)
destroy_votable(chip->dc_suspend_votable);
if (chip->usb_suspend_votable)
destroy_votable(chip->usb_suspend_votable);
if (chip->dc_icl_votable)
destroy_votable(chip->dc_icl_votable);
if (chip->usb_icl_votable)
destroy_votable(chip->usb_icl_votable);
if (chip->fcc_votable)
destroy_votable(chip->fcc_votable);
return rc;
}
@ -8266,6 +8311,16 @@ static int smbchg_remove(struct platform_device *pdev)
debugfs_remove_recursive(chip->debug_root);
destroy_votable(chip->aicl_deglitch_short_votable);
destroy_votable(chip->hw_aicl_rerun_enable_indirect_votable);
destroy_votable(chip->hw_aicl_rerun_disable_votable);
destroy_votable(chip->battchg_suspend_votable);
destroy_votable(chip->dc_suspend_votable);
destroy_votable(chip->usb_suspend_votable);
destroy_votable(chip->dc_icl_votable);
destroy_votable(chip->usb_icl_votable);
destroy_votable(chip->fcc_votable);
return 0;
}

View file

@ -299,18 +299,18 @@ static int smblib_detach_usb(struct smb_charger *chg)
* VOTABLE CALLBACKS *
*********************/
static int smblib_usb_suspend_vote_callback(struct device *dev,
static int smblib_usb_suspend_vote_callback(struct votable *votable, void *data,
int suspend, const char *client)
{
struct smb_charger *chg = dev_get_drvdata(dev);
struct smb_charger *chg = data;
return smblib_set_usb_suspend(chg, suspend);
}
static int smblib_dc_suspend_vote_callback(struct device *dev,
static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data,
int suspend, const char *client)
{
struct smb_charger *chg = dev_get_drvdata(dev);
struct smb_charger *chg = data;
if (suspend < 0)
suspend = false;
@ -318,10 +318,10 @@ static int smblib_dc_suspend_vote_callback(struct device *dev,
return smblib_set_dc_suspend(chg, suspend);
}
static int smblib_fcc_vote_callback(struct device *dev,
static int smblib_fcc_vote_callback(struct votable *votable, void *data,
int fcc_ua, const char *client)
{
struct smb_charger *chg = dev_get_drvdata(dev);
struct smb_charger *chg = data;
int rc = 0;
if (fcc_ua < 0) {
@ -333,10 +333,10 @@ static int smblib_fcc_vote_callback(struct device *dev,
return rc;
}
static int smblib_fv_vote_callback(struct device *dev,
static int smblib_fv_vote_callback(struct votable *votable, void *data,
int fv_uv, const char *client)
{
struct smb_charger *chg = dev_get_drvdata(dev);
struct smb_charger *chg = data;
int rc = 0;
if (fv_uv < 0) {
@ -350,10 +350,10 @@ static int smblib_fv_vote_callback(struct device *dev,
#define USBIN_25MA 25000
#define USBIN_100MA 100000
static int smblib_usb_icl_vote_callback(struct device *dev,
static int smblib_usb_icl_vote_callback(struct votable *votable, void *data,
int icl_ua, const char *client)
{
struct smb_charger *chg = dev_get_drvdata(dev);
struct smb_charger *chg = data;
int rc = 0;
bool suspend;
@ -390,10 +390,10 @@ suspend:
return rc;
}
static int smblib_dc_icl_vote_callback(struct device *dev,
static int smblib_dc_icl_vote_callback(struct votable *votable, void *data,
int icl_ua, const char *client)
{
struct smb_charger *chg = dev_get_drvdata(dev);
struct smb_charger *chg = data;
int rc = 0;
bool suspend;
@ -1330,57 +1330,56 @@ int smblib_init(struct smb_charger *chg)
mutex_init(&chg->write_lock);
INIT_DELAYED_WORK(&chg->hvdcp_detect_work, smblib_hvdcp_detect_work);
chg->usb_suspend_votable = create_votable(chg->dev,
"INPUT_SUSPEND", VOTE_SET_ANY,
smblib_usb_suspend_vote_callback);
chg->usb_suspend_votable = create_votable("INPUT_SUSPEND", VOTE_SET_ANY,
smblib_usb_suspend_vote_callback,
chg);
if (IS_ERR(chg->usb_suspend_votable)) {
rc = PTR_ERR(chg->usb_suspend_votable);
return rc;
}
chg->dc_suspend_votable = create_votable(chg->dev,
"DC_SUSPEND", VOTE_SET_ANY,
smblib_dc_suspend_vote_callback);
chg->dc_suspend_votable = create_votable("DC_SUSPEND", VOTE_SET_ANY,
smblib_dc_suspend_vote_callback,
chg);
if (IS_ERR(chg->dc_suspend_votable)) {
rc = PTR_ERR(chg->dc_suspend_votable);
return rc;
}
chg->fcc_votable = create_votable(chg->dev,
"FCC", VOTE_MAX,
smblib_fcc_vote_callback);
chg->fcc_votable = create_votable("FCC", VOTE_MAX,
smblib_fcc_vote_callback,
chg);
if (IS_ERR(chg->fcc_votable)) {
rc = PTR_ERR(chg->fcc_votable);
return rc;
}
chg->fv_votable = create_votable(chg->dev,
"FV", VOTE_MAX,
smblib_fv_vote_callback);
chg->fv_votable = create_votable("FV", VOTE_MAX,
smblib_fv_vote_callback,
chg);
if (IS_ERR(chg->fv_votable)) {
rc = PTR_ERR(chg->fv_votable);
return rc;
}
chg->usb_icl_votable = create_votable(chg->dev,
"USB_ICL", VOTE_MIN,
smblib_usb_icl_vote_callback);
chg->usb_icl_votable = create_votable("USB_ICL", VOTE_MIN,
smblib_usb_icl_vote_callback,
chg);
if (IS_ERR(chg->usb_icl_votable)) {
rc = PTR_ERR(chg->usb_icl_votable);
return rc;
}
chg->dc_icl_votable = create_votable(chg->dev,
"DC_ICL", VOTE_MIN,
smblib_dc_icl_vote_callback);
chg->dc_icl_votable = create_votable("DC_ICL", VOTE_MIN,
smblib_dc_icl_vote_callback,
chg);
if (IS_ERR(chg->dc_icl_votable)) {
rc = PTR_ERR(chg->dc_icl_votable);
return rc;
}
chg->pd_allowed_votable = create_votable(chg->dev,
"PD_ALLOWED", VOTE_SET_ANY,
NULL);
chg->pd_allowed_votable = create_votable("PD_ALLOWED", VOTE_SET_ANY,
NULL, NULL);
if (IS_ERR(chg->pd_allowed_votable)) {
rc = PTR_ERR(chg->pd_allowed_votable);
return rc;
@ -1388,3 +1387,16 @@ int smblib_init(struct smb_charger *chg)
return 0;
}
int smblib_deinit(struct smb_charger *chg)
{
destroy_votable(chg->usb_suspend_votable);
destroy_votable(chg->dc_suspend_votable);
destroy_votable(chg->fcc_votable);
destroy_votable(chg->fv_votable);
destroy_votable(chg->usb_icl_votable);
destroy_votable(chg->dc_icl_votable);
destroy_votable(chg->pd_allowed_votable);
return 0;
}

View file

@ -158,5 +158,6 @@ int smblib_set_prop_pd_active(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_init(struct smb_charger *chg);
int smblib_deinit(struct smb_charger *chg);
#endif /* __SMB2_CHARGER_H */