Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1039ef61 authored by Amir Samuelov's avatar Amir Samuelov
Browse files

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: default avatarAmir Samuelov <amirs@codeaurora.org>
parent b1cb986a
Loading
Loading
Loading
Loading
+53 −11
Original line number Diff line number Diff line
/*
 * 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.
 */