mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 11:37:06 +02:00
power: supply: qti_battery_charger: add SSR support
Add subsystem restart (SSR) support to battery charger driver so that it can stop read/write properties when subsystem goes down. Also, send message to enable notification again once subsystem comes up. Change-Id: I64f3abfa1d12c4e6a65fd01d7f66155c8741e68a Signed-off-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
This commit is contained in:
parent
d48bfa7036
commit
4e207a47ef
|
|
@ -148,6 +148,8 @@ struct battery_chg_dev {
|
|||
u32 *thermal_levels;
|
||||
int curr_thermal_level;
|
||||
int num_thermal_levels;
|
||||
atomic_t state;
|
||||
struct work_struct subsys_up_work;
|
||||
};
|
||||
|
||||
static const int battery_prop_map[BATT_PROP_MAX] = {
|
||||
|
|
@ -198,6 +200,16 @@ static int battery_chg_write(struct battery_chg_dev *bcdev, void *data,
|
|||
{
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* When the subsystem goes down, it's better to return the last
|
||||
* known values until it comes back up. Hence, return 0 so that
|
||||
* pmic_glink_write() is not attempted until pmic glink is up.
|
||||
*/
|
||||
if (atomic_read(&bcdev->state) == PMIC_GLINK_STATE_DOWN) {
|
||||
pr_debug("glink state is down\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_lock(&bcdev->rw_lock);
|
||||
reinit_completion(&bcdev->ack);
|
||||
rc = pmic_glink_write(bcdev->client, data, len);
|
||||
|
|
@ -268,6 +280,40 @@ static int get_property_id(struct psy_state *pst,
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
static void battery_chg_notify_enable(struct battery_chg_dev *bcdev)
|
||||
{
|
||||
struct battery_charger_set_notify_msg req_msg = { { 0 } };
|
||||
int rc;
|
||||
|
||||
/* Send request to enable notification */
|
||||
req_msg.hdr.owner = MSG_OWNER_BC;
|
||||
req_msg.hdr.type = MSG_TYPE_NOTIFY;
|
||||
req_msg.hdr.opcode = BC_SET_NOTIFY_REQ;
|
||||
|
||||
rc = battery_chg_write(bcdev, &req_msg, sizeof(req_msg));
|
||||
if (rc < 0)
|
||||
pr_err("Failed to enable notification rc=%d\n", rc);
|
||||
}
|
||||
|
||||
static void battery_chg_subsys_up_work(struct work_struct *work)
|
||||
{
|
||||
struct battery_chg_dev *bcdev = container_of(work,
|
||||
struct battery_chg_dev, subsys_up_work);
|
||||
|
||||
battery_chg_notify_enable(bcdev);
|
||||
}
|
||||
|
||||
static void battery_chg_state_cb(void *priv, enum pmic_glink_state state)
|
||||
{
|
||||
struct battery_chg_dev *bcdev = priv;
|
||||
|
||||
pr_debug("state: %d\n", state);
|
||||
|
||||
atomic_set(&bcdev->state, state);
|
||||
if (state == PMIC_GLINK_STATE_UP)
|
||||
schedule_work(&bcdev->subsys_up_work);
|
||||
}
|
||||
|
||||
/**
|
||||
* qti_battery_charger_get_prop() - Gets the property being requested
|
||||
*
|
||||
|
|
@ -977,7 +1023,6 @@ static int battery_chg_probe(struct platform_device *pdev)
|
|||
struct battery_chg_dev *bcdev;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct pmic_glink_client_data client_data = { };
|
||||
struct battery_charger_set_notify_msg req_msg = { { 0 } };
|
||||
int rc, i;
|
||||
|
||||
bcdev = devm_kzalloc(&pdev->dev, sizeof(*bcdev), GFP_KERNEL);
|
||||
|
|
@ -1012,12 +1057,15 @@ static int battery_chg_probe(struct platform_device *pdev)
|
|||
|
||||
mutex_init(&bcdev->rw_lock);
|
||||
init_completion(&bcdev->ack);
|
||||
INIT_WORK(&bcdev->subsys_up_work, battery_chg_subsys_up_work);
|
||||
atomic_set(&bcdev->state, PMIC_GLINK_STATE_UP);
|
||||
bcdev->dev = dev;
|
||||
|
||||
client_data.id = MSG_OWNER_BC;
|
||||
client_data.name = "battery_charger";
|
||||
client_data.msg_cb = battery_chg_callback;
|
||||
client_data.priv = bcdev;
|
||||
client_data.state_cb = battery_chg_state_cb;
|
||||
|
||||
bcdev->client = pmic_glink_register_client(dev, &client_data);
|
||||
if (IS_ERR(bcdev->client)) {
|
||||
|
|
@ -1045,14 +1093,7 @@ static int battery_chg_probe(struct platform_device *pdev)
|
|||
goto error;
|
||||
}
|
||||
|
||||
/* Send request to enable notification */
|
||||
req_msg.hdr.owner = MSG_OWNER_BC;
|
||||
req_msg.hdr.type = MSG_TYPE_NOTIFY;
|
||||
req_msg.hdr.opcode = BC_SET_NOTIFY_REQ;
|
||||
|
||||
rc = battery_chg_write(bcdev, &req_msg, sizeof(req_msg));
|
||||
if (rc < 0)
|
||||
pr_err("Failed to enable notification rc=%d\n", rc);
|
||||
battery_chg_notify_enable(bcdev);
|
||||
|
||||
return 0;
|
||||
error:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user