spcom: free all SKP ION buffers on SSR

Free all the SKP ION buffers that were locked for SPSS app swapping,
when remote subsystem reset.

Change-Id: I5230152cc7c3e721b1ebb01b663b9fd14bd2d6c9
Signed-off-by: Amir Samuelov <amirs@codeaurora.org>
This commit is contained in:
Amir Samuelov 2017-01-05 18:40:45 +02:00
parent b1cb986a8f
commit 1039ef6124

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -274,6 +274,8 @@ static int spcom_open(struct spcom_channel *ch, unsigned int timeout_msec);
static int spcom_close(struct spcom_channel *ch);
static void spcom_notify_rx_abort(void *handle, const void *priv,
const void *pkt_priv);
static struct spcom_channel *spcom_find_channel_by_name(const char *name);
static int spcom_unlock_ion_buf(struct spcom_channel *ch, int fd);
/**
* spcom_is_ready() - driver is initialized and ready.
@ -347,6 +349,9 @@ static int spcom_create_predefined_channels_chardev(void)
static void spcom_link_state_notif_cb(struct glink_link_state_cb_info *cb_info,
void *priv)
{
struct spcom_channel *ch = NULL;
const char *ch_name = "sp_kernel";
spcom_dev->link_state = cb_info->link_state;
pr_debug("spcom_link_state_notif_cb called. transport = %s edge = %s\n",
@ -359,6 +364,17 @@ static void spcom_link_state_notif_cb(struct glink_link_state_cb_info *cb_info,
break;
case GLINK_LINK_STATE_DOWN:
pr_err("GLINK_LINK_STATE_DOWN.\n");
/*
* Free all the SKP ION buffers that were locked
* for SPSS app swapping, when remote subsystem reset.
*/
pr_debug("Free all SKP ION buffers on SSR.\n");
ch = spcom_find_channel_by_name(ch_name);
if (!ch)
pr_err("failed to find channel [%s].\n", ch_name);
else
spcom_unlock_ion_buf(ch, SPCOM_ION_FD_UNLOCK_ALL);
break;
default:
pr_err("unknown link_state [%d].\n", cb_info->link_state);
@ -1643,24 +1659,18 @@ static int spcom_handle_lock_ion_buf_command(struct spcom_channel *ch,
}
/**
* spcom_handle_unlock_ion_buf_command() - Unlock an ION buffer.
* spcom_unlock_ion_buf() - Unlock an ION buffer.
*
* Unlock an ION buffer, let it be free, when it is no longer being used by
* the remote subsystem.
*/
static int spcom_handle_unlock_ion_buf_command(struct spcom_channel *ch,
void *cmd_buf, int size)
static int spcom_unlock_ion_buf(struct spcom_channel *ch, int fd)
{
struct spcom_user_command *cmd = cmd_buf;
int fd = cmd->arg;
struct ion_client *ion_client = spcom_dev->ion_client;
int i;
bool found = false;
if (size != sizeof(*cmd)) {
pr_err("cmd size [%d] , expected [%d].\n",
(int) size, (int) sizeof(*cmd));
return -EINVAL;
}
pr_debug("Unlock ion buf ch [%s] fd [%d].\n", ch->name, fd);
/* Check ION client */
if (ion_client == NULL) {
@ -1669,6 +1679,8 @@ static int spcom_handle_unlock_ion_buf_command(struct spcom_channel *ch,
}
if (fd == (int) SPCOM_ION_FD_UNLOCK_ALL) {
pr_debug("unlocked ALL ion buf ch [%s].\n", ch->name);
found = true;
/* unlock all ION buf */
for (i = 0 ; i < ARRAY_SIZE(ch->ion_handle_table) ; i++) {
if (ch->ion_handle_table[i] != NULL) {
@ -1686,14 +1698,44 @@ static int spcom_handle_unlock_ion_buf_command(struct spcom_channel *ch,
ch->ion_handle_table[i] = NULL;
ch->ion_fd_table[i] = -1;
pr_debug("unlocked ion buf#[%d].\n", i);
found = true;
break;
}
}
}
if (!found) {
pr_err("ch [%s] fd [%d] was not found.\n", ch->name, fd);
return -ENODEV;
}
return 0;
}
/**
* spcom_handle_unlock_ion_buf_command() - Unlock an ION buffer.
*
* Unlock an ION buffer, let it be free, when it is no longer being used by
* the remote subsystem.
*/
static int spcom_handle_unlock_ion_buf_command(struct spcom_channel *ch,
void *cmd_buf, int size)
{
int ret;
struct spcom_user_command *cmd = cmd_buf;
int fd = cmd->arg;
if (size != sizeof(*cmd)) {
pr_err("cmd size [%d] , expected [%d].\n",
(int) size, (int) sizeof(*cmd));
return -EINVAL;
}
ret = spcom_unlock_ion_buf(ch, fd);
return ret;
}
/**
* spcom_handle_fake_ssr_command() - Handle fake ssr command from user space.
*/