esoc: Call the PON and POFF hooks with bit-masked flags

Currently, the esoc driver calls the client's power-on and power-off
hooks with a boolean flag indicating if the external modem is in
error-fatal or not. However, this information itself isn't sufficient
for the clients. The clients also may rely on the actions such as, if
the driver would be shutting down the modem in the sequence or not.
Hence, convert the boolean flag to an integer based flag that carries
the bitmask of all such information.

Convert the esoc callbacks for the MHI driver as it's affected by this
API change.

Change-Id: I376e85ba499574a4c9e8cf3e845ab6311afe52d2
Signed-off-by: Raghavendra Rao Ananta <rananta@codeaurora.org>
This commit is contained in:
Raghavendra Rao Ananta 2019-04-05 10:24:53 -07:00 committed by Rishabh Bhatnagar
parent 0ed7b350a9
commit 71e8e64193
3 changed files with 33 additions and 24 deletions

View file

@ -142,7 +142,7 @@ static void mhi_arch_pci_link_state_cb(struct msm_pcie_notify *notify)
}
}
static int mhi_arch_esoc_ops_power_on(void *priv, bool mdm_state)
static int mhi_arch_esoc_ops_power_on(void *priv, unsigned int flags)
{
struct mhi_controller *mhi_cntrl = priv;
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
@ -196,12 +196,13 @@ static void mhi_arch_link_off(struct mhi_controller *mhi_cntrl)
MHI_LOG("Exited\n");
}
void mhi_arch_esoc_ops_power_off(void *priv, bool mdm_state)
static void mhi_arch_esoc_ops_power_off(void *priv, unsigned int flags)
{
struct mhi_controller *mhi_cntrl = priv;
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct arch_info *arch_info = mhi_dev->arch_info;
struct pci_dev *pci_dev = mhi_dev->pci_dev;
bool mdm_state = (flags & ESOC_HOOK_MDM_CRASH);
MHI_LOG("Enter: mdm_crashed:%d\n", mdm_state);

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2013-2015, 2017-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2015, 2017-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/delay.h>
@ -66,7 +66,7 @@ struct mdm_drv {
#define to_mdm_drv(d) container_of(d, struct mdm_drv, cmd_eng)
static void esoc_client_link_power_off(struct esoc_clink *esoc_clink,
bool mdm_crashed);
unsigned int flags);
static int esoc_msm_restart_handler(struct notifier_block *nb,
unsigned long action, void *data)
@ -86,7 +86,7 @@ static int esoc_msm_restart_handler(struct notifier_block *nb,
mutex_unlock(&mdm_drv->poff_lock);
return NOTIFY_OK;
}
esoc_client_link_power_off(esoc_clink, false);
esoc_client_link_power_off(esoc_clink, ESOC_HOOK_MDM_DOWN);
esoc_mdm_log(
"Reboot notifier: Notifying esoc of cold reboot\n");
dev_dbg(&esoc_clink->dev, "Notifying esoc of cold reboot\n");
@ -172,38 +172,38 @@ static void mdm_ssr_fn(struct work_struct *work)
}
static void esoc_client_link_power_on(struct esoc_clink *esoc_clink,
bool mdm_crashed)
unsigned int flags)
{
int i;
struct esoc_client_hook *client_hook;
dev_dbg(&esoc_clink->dev, "Calling power_on hooks\n");
esoc_mdm_log(
"Calling power_on hooks with crash state: %d\n", mdm_crashed);
"Calling power_on hooks with flags: 0x%x\n", flags);
for (i = 0; i < ESOC_MAX_HOOKS; i++) {
client_hook = esoc_clink->client_hook[i];
if (client_hook && client_hook->esoc_link_power_on)
client_hook->esoc_link_power_on(client_hook->priv,
mdm_crashed);
flags);
}
}
static void esoc_client_link_power_off(struct esoc_clink *esoc_clink,
bool mdm_crashed)
unsigned int flags)
{
int i;
struct esoc_client_hook *client_hook;
dev_dbg(&esoc_clink->dev, "Calling power_off hooks\n");
esoc_mdm_log(
"Calling power_off hooks with crash state: %d\n", mdm_crashed);
"Calling power_off hooks with flags: 0x%x\n", flags);
for (i = 0; i < ESOC_MAX_HOOKS; i++) {
client_hook = esoc_clink->client_hook[i];
if (client_hook && client_hook->esoc_link_power_off) {
client_hook->esoc_link_power_off(client_hook->priv,
mdm_crashed);
flags);
}
}
}
@ -244,7 +244,7 @@ static int mdm_subsys_shutdown(const struct subsys_desc *crashed_subsys,
return 0;
esoc_clink_queue_request(ESOC_REQ_CRASH_SHUTDOWN, esoc_clink);
esoc_client_link_power_off(esoc_clink, true);
esoc_client_link_power_off(esoc_clink, ESOC_HOOK_MDM_CRASH);
esoc_mdm_log("Executing the ESOC_PREPARE_DEBUG command\n");
ret = clink_ops->cmd_exe(ESOC_PREPARE_DEBUG,
@ -288,7 +288,7 @@ static int mdm_subsys_shutdown(const struct subsys_desc *crashed_subsys,
mutex_unlock(&mdm_drv->poff_lock);
return ret;
}
esoc_client_link_power_off(esoc_clink, false);
esoc_client_link_power_off(esoc_clink, ESOC_HOOK_MDM_DOWN);
/* Pull the reset line low to turn off the device */
clink_ops->cmd_exe(ESOC_FORCE_PWR_OFF, esoc_clink);
mdm_drv->mode = PWR_OFF;
@ -298,14 +298,15 @@ static int mdm_subsys_shutdown(const struct subsys_desc *crashed_subsys,
return 0;
}
static void mdm_subsys_retry_powerup_cleanup(struct esoc_clink *esoc_clink)
static void mdm_subsys_retry_powerup_cleanup(struct esoc_clink *esoc_clink,
unsigned int poff_flags)
{
struct mdm_ctrl *mdm = get_esoc_clink_data(esoc_clink);
struct mdm_drv *mdm_drv = esoc_get_drv_data(esoc_clink);
esoc_mdm_log("Doing cleanup\n");
esoc_client_link_power_off(esoc_clink, false);
esoc_client_link_power_off(esoc_clink, poff_flags);
mdm_disable_irqs(mdm);
mdm_drv->pon_state = PON_INIT;
reinit_completion(&mdm_drv->pon_done);
@ -319,7 +320,7 @@ static int mdm_handle_boot_fail(struct esoc_clink *esoc_clink, u8 *pon_trial)
switch (boot_fail_action) {
case BOOT_FAIL_ACTION_RETRY:
mdm_subsys_retry_powerup_cleanup(esoc_clink);
mdm_subsys_retry_powerup_cleanup(esoc_clink, 0);
esoc_mdm_log("Request to retry a warm reset\n");
(*pon_trial)++;
break;
@ -329,7 +330,8 @@ static int mdm_handle_boot_fail(struct esoc_clink *esoc_clink, u8 *pon_trial)
* issuing a cold reset & a warm reset back to back.
*/
case BOOT_FAIL_ACTION_COLD_RESET:
mdm_subsys_retry_powerup_cleanup(esoc_clink);
mdm_subsys_retry_powerup_cleanup(esoc_clink,
ESOC_HOOK_MDM_DOWN);
esoc_mdm_log("Doing cold reset by power-down and warm reset\n");
(*pon_trial)++;
mdm_power_down(mdm);
@ -343,7 +345,8 @@ static int mdm_handle_boot_fail(struct esoc_clink *esoc_clink, u8 *pon_trial)
return -EIO;
case BOOT_FAIL_ACTION_SHUTDOWN:
default:
mdm_subsys_retry_powerup_cleanup(esoc_clink);
mdm_subsys_retry_powerup_cleanup(esoc_clink,
ESOC_HOOK_MDM_DOWN);
esoc_mdm_log("Shutdown the modem and quit\n");
mdm_power_down(mdm);
return -EIO;
@ -386,7 +389,7 @@ static int mdm_subsys_powerup(const struct subsys_desc *crashed_subsys)
dev_err(&esoc_clink->dev, "pwr on fail\n");
return ret;
}
esoc_client_link_power_on(esoc_clink, false);
esoc_client_link_power_on(esoc_clink, 0);
} else if (mdm_drv->mode == IN_DEBUG) {
esoc_mdm_log("In SSR power-on mode\n");
esoc_mdm_log("Executing the ESOC_EXIT_DEBUG command\n");
@ -405,7 +408,8 @@ static int mdm_subsys_powerup(const struct subsys_desc *crashed_subsys)
dev_err(&esoc_clink->dev, "pwr on fail\n");
return ret;
}
esoc_client_link_power_on(esoc_clink, true);
esoc_client_link_power_on(esoc_clink,
ESOC_HOOK_MDM_CRASH);
}
/*
@ -430,7 +434,7 @@ static int mdm_subsys_powerup(const struct subsys_desc *crashed_subsys)
esoc_mdm_log(
"Boot failed. Doing cleanup and attempting to retry\n");
pon_trial++;
mdm_subsys_retry_powerup_cleanup(esoc_clink);
mdm_subsys_retry_powerup_cleanup(esoc_clink, 0);
} else if (mdm_drv->pon_state == PON_SUCCESS) {
break;
}

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2014, 2017-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2014, 2017-2019, The Linux Foundation. All rights reserved.
*/
#ifndef __ESOC_CLIENT_H_
#define __ESOC_CLIENT_H_
@ -9,12 +9,16 @@
#include <linux/esoc_ctrl.h>
#include <linux/notifier.h>
/* Flag values used with the power_on and power_off hooks */
#define ESOC_HOOK_MDM_CRASH 0x0001 /* In crash handling path */
#define ESOC_HOOK_MDM_DOWN 0x0002 /* MDM about to go down */
struct esoc_client_hook {
char *name;
void *priv;
enum esoc_client_hook_prio prio;
int (*esoc_link_power_on)(void *priv, bool mdm_crashed);
void (*esoc_link_power_off)(void *priv, bool mdm_crashed);
int (*esoc_link_power_on)(void *priv, unsigned int flags);
void (*esoc_link_power_off)(void *priv, unsigned int flags);
u64 (*esoc_link_get_id)(void *priv);
};