soc: qcom: spss_utils: handle ssr after fota
After SPU's firmware was updated, prevent SSR from happening until getting a message from userspace that update is finished. Need to Avoid SSR because PIL would load old images from /firmware_mnt. Change-Id: I4b07e2e886e26a928faeae0c6f4f790dd01c645f Signed-off-by: Dan Bar-On <dbaron@codeaurora.org>
This commit is contained in:
@@ -259,6 +259,9 @@ static struct spcom_channel *spcom_find_channel_by_name(const char *name);
|
|||||||
static int spcom_register_rpmsg_drv(struct spcom_channel *ch);
|
static int spcom_register_rpmsg_drv(struct spcom_channel *ch);
|
||||||
static int spcom_unregister_rpmsg_drv(struct spcom_channel *ch);
|
static int spcom_unregister_rpmsg_drv(struct spcom_channel *ch);
|
||||||
|
|
||||||
|
/* PIL's original SSR function*/
|
||||||
|
int (*desc_powerup)(const struct subsys_desc *) = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* spcom_is_channel_open() - channel is open on this side.
|
* spcom_is_channel_open() - channel is open on this side.
|
||||||
*
|
*
|
||||||
@@ -604,6 +607,24 @@ static int spcom_local_powerup(const struct subsys_desc *subsys)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* spcom_local_powerup_after_fota() - SSR is not allowed after FOTA -
|
||||||
|
* might cause cryptographic erase. Reset the device
|
||||||
|
*
|
||||||
|
* @subsys: subsystem descriptor.
|
||||||
|
*
|
||||||
|
* Return: 0 on successful operation, negative value otherwise.
|
||||||
|
*/
|
||||||
|
static int spcom_local_powerup_after_fota(const struct subsys_desc *subsys)
|
||||||
|
{
|
||||||
|
(void)subsys;
|
||||||
|
|
||||||
|
pr_err("SSR after firmware update before calling IAR update - panic\n");
|
||||||
|
panic("SSR after SPU firmware update\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* spcom_handle_restart_sp_command() - Handle Restart SP command from
|
* spcom_handle_restart_sp_command() - Handle Restart SP command from
|
||||||
* user space.
|
* user space.
|
||||||
@@ -618,7 +639,6 @@ static int spcom_handle_restart_sp_command(void *cmd_buf, int cmd_size)
|
|||||||
void *subsystem_get_retval = NULL;
|
void *subsystem_get_retval = NULL;
|
||||||
struct spcom_user_restart_sp_command *cmd = cmd_buf;
|
struct spcom_user_restart_sp_command *cmd = cmd_buf;
|
||||||
struct subsys_desc *desc_p = NULL;
|
struct subsys_desc *desc_p = NULL;
|
||||||
int (*desc_powerup)(const struct subsys_desc *) = NULL;
|
|
||||||
|
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
pr_err("NULL cmd_buf\n");
|
pr_err("NULL cmd_buf\n");
|
||||||
@@ -672,8 +692,14 @@ static int spcom_handle_restart_sp_command(void *cmd_buf, int cmd_size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cmd->arg) {
|
if (cmd->arg) {
|
||||||
/* Reset the PIL subsystem power up function */
|
|
||||||
desc_p->powerup = desc_powerup;
|
/* SPU got firmware update. Don't allow SSR*/
|
||||||
|
if (cmd->is_updated) {
|
||||||
|
desc_p->powerup = spcom_local_powerup_after_fota;
|
||||||
|
} else {
|
||||||
|
/* Reset the PIL subsystem power up function */
|
||||||
|
desc_p->powerup = desc_powerup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pr_debug("restart - PIL FW loading process is complete\n");
|
pr_debug("restart - PIL FW loading process is complete\n");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1146,6 +1172,41 @@ static int spcom_handle_unlock_ion_buf_command(struct spcom_channel *ch,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* spcom_handle_enable_ssr_command() - Handle user space request to enable ssr
|
||||||
|
*
|
||||||
|
* After FOTA SSR is disabled until IAR update occurs.
|
||||||
|
* Then - enable SSR again
|
||||||
|
*
|
||||||
|
* Return: size in bytes on success, negative value on failure.
|
||||||
|
*/
|
||||||
|
static int spcom_handle_enable_ssr_command(void)
|
||||||
|
{
|
||||||
|
struct subsys_desc *desc_p = NULL;
|
||||||
|
void *subsystem_get_retval = find_subsys_device("spss");
|
||||||
|
|
||||||
|
if (!subsystem_get_retval) {
|
||||||
|
pr_err("restart - no device\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
desc_p = *(struct subsys_desc **)subsystem_get_retval;
|
||||||
|
if (!desc_p) {
|
||||||
|
pr_err("restart - no device\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!desc_powerup) {
|
||||||
|
pr_err("no original SSR function\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
desc_p->powerup = desc_powerup;
|
||||||
|
pr_info("SSR is enabled after FOTA\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* spcom_handle_write() - Handle user space write commands.
|
* spcom_handle_write() - Handle user space write commands.
|
||||||
*
|
*
|
||||||
@@ -1174,7 +1235,8 @@ static int spcom_handle_write(struct spcom_channel *ch,
|
|||||||
pr_debug("cmd_id [0x%x]\n", cmd_id);
|
pr_debug("cmd_id [0x%x]\n", cmd_id);
|
||||||
|
|
||||||
if (!ch && cmd_id != SPCOM_CMD_CREATE_CHANNEL
|
if (!ch && cmd_id != SPCOM_CMD_CREATE_CHANNEL
|
||||||
&& cmd_id != SPCOM_CMD_RESTART_SP) {
|
&& cmd_id != SPCOM_CMD_RESTART_SP
|
||||||
|
&& cmd_id != SPCOM_CMD_ENABLE_SSR) {
|
||||||
pr_err("channel context is null\n");
|
pr_err("channel context is null\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -1210,6 +1272,9 @@ static int spcom_handle_write(struct spcom_channel *ch,
|
|||||||
case SPCOM_CMD_RESTART_SP:
|
case SPCOM_CMD_RESTART_SP:
|
||||||
ret = spcom_handle_restart_sp_command(buf, buf_size);
|
ret = spcom_handle_restart_sp_command(buf, buf_size);
|
||||||
break;
|
break;
|
||||||
|
case SPCOM_CMD_ENABLE_SSR:
|
||||||
|
ret = spcom_handle_enable_ssr_command();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("Invalid Command Id [0x%x]\n", (int) cmd->cmd_id);
|
pr_err("Invalid Command Id [0x%x]\n", (int) cmd->cmd_id);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
@@ -1964,7 +2029,7 @@ static int spcom_create_channel_chardev(const char *name, bool is_sharable)
|
|||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
pr_err("can't unregister rpmsg drv %d\n", ret);
|
pr_err("can't unregister rpmsg drv %d\n", ret);
|
||||||
exit_destroy_channel:
|
exit_destroy_channel:
|
||||||
// empty channel leaves free slot for next time
|
/* empty channel leaves free slot for next time*/
|
||||||
mutex_lock(&ch->lock);
|
mutex_lock(&ch->lock);
|
||||||
memset(ch->name, 0, SPCOM_CHANNEL_NAME_SIZE);
|
memset(ch->name, 0, SPCOM_CHANNEL_NAME_SIZE);
|
||||||
mutex_unlock(&ch->lock);
|
mutex_unlock(&ch->lock);
|
||||||
@@ -2293,7 +2358,7 @@ static void spcom_rpdev_remove(struct rpmsg_device *rpdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&ch->lock);
|
mutex_lock(&ch->lock);
|
||||||
// unlock all ion buffers of sp_kernel channel
|
/* unlock all ion buffers of sp_kernel channel*/
|
||||||
if (strcmp(ch->name, "sp_kernel") == 0) {
|
if (strcmp(ch->name, "sp_kernel") == 0) {
|
||||||
for (i = 0; i < ARRAY_SIZE(ch->dmabuf_handle_table); i++) {
|
for (i = 0; i < ARRAY_SIZE(ch->dmabuf_handle_table); i++) {
|
||||||
if (ch->dmabuf_handle_table[i] != NULL) {
|
if (ch->dmabuf_handle_table[i] != NULL) {
|
||||||
|
|||||||
@@ -50,9 +50,14 @@ enum spcom_cmd_id {
|
|||||||
SPCOM_CMD_UNLOCK_ION_BUF = 0x554C434B, /* "ULCK" = 0x4C4F434B */
|
SPCOM_CMD_UNLOCK_ION_BUF = 0x554C434B, /* "ULCK" = 0x4C4F434B */
|
||||||
SPCOM_CMD_FSSR = 0x46535352, /* "FSSR" = 0x46535352 */
|
SPCOM_CMD_FSSR = 0x46535352, /* "FSSR" = 0x46535352 */
|
||||||
SPCOM_CMD_CREATE_CHANNEL = 0x43524554, /* "CRET" = 0x43524554 */
|
SPCOM_CMD_CREATE_CHANNEL = 0x43524554, /* "CRET" = 0x43524554 */
|
||||||
|
|
||||||
|
#define SPCOM_CMD_ENABLE_SSR \
|
||||||
|
SPCOM_CMD_ENABLE_SSR
|
||||||
|
SPCOM_CMD_ENABLE_SSR = 0x45535352, /* "ESSR" =0x45535352*/
|
||||||
|
|
||||||
#define SPCOM_CMD_RESTART_SP \
|
#define SPCOM_CMD_RESTART_SP \
|
||||||
SPCOM_CMD_RESTART_SP
|
SPCOM_CMD_RESTART_SP
|
||||||
SPCOM_CMD_RESTART_SP = 0x52535452, /* "RSTR" = 0x52535452 */
|
SPCOM_CMD_RESTART_SP = 0x52535452, /* "RSTR" = 0x52535452 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -94,6 +99,8 @@ struct spcom_user_create_channel_command {
|
|||||||
struct spcom_user_restart_sp_command {
|
struct spcom_user_restart_sp_command {
|
||||||
enum spcom_cmd_id cmd_id;
|
enum spcom_cmd_id cmd_id;
|
||||||
uint32_t arg;
|
uint32_t arg;
|
||||||
|
#define SPCOM_IS_UPDATED_SUPPORETED
|
||||||
|
uint32_t is_updated;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/* maximum ION buf for send-modfied-command */
|
/* maximum ION buf for send-modfied-command */
|
||||||
|
|||||||
Reference in New Issue
Block a user