/*
 * SPDX-FileCopyrightText: Copyright 2022-2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
 * SPDX-License-Identifier: GPL-2.0-only
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 */

/****************************************************************************
 * Includes
 ****************************************************************************/

#include <rpmsg/ethosu_rpmsg_cancel_inference.h>

#include <common/ethosu_device.h>
#include <rpmsg/ethosu_rpmsg.h>
#include <rpmsg/ethosu_rpmsg_inference.h>

#include <linux/remoteproc.h>
#include <linux/wait.h>

/****************************************************************************
 * Defines
 ****************************************************************************/

#define CANCEL_INFERENCE_RESP_TIMEOUT_MS 2000

/****************************************************************************
 * Functions
 ****************************************************************************/

static int ethosu_cancel_inference_send(
	struct ethosu_cancel_inference *cancellation,
	struct ethosu_mailbox *mailbox)
{
	return ethosu_mailbox_cancel_inference(mailbox,
					       &cancellation->msg,
					       cancellation->inf->msg.id);
}

static void ethosu_cancel_inference_fail(struct ethosu_mailbox_msg *msg)
{
	struct ethosu_cancel_inference *cancellation =
		container_of(msg, typeof(*cancellation), msg);

	if (completion_done(&cancellation->done))
		return;

	cancellation->errno = -EFAULT;
	cancellation->uapi->status = ETHOSU_UAPI_STATUS_ERROR;
	complete(&cancellation->done);
}

int ethosu_cancel_inference_request(struct device *dev,
				    struct ethosu_mailbox *mailbox,
				    struct ethosu_inference *inf,
				    struct ethosu_uapi_cancel_inference_status *uapi)
{
	struct ethosu_cancel_inference *cancellation;
	int ret;
	int timeout;

	if (inf->done) {
		uapi->status = ETHOSU_UAPI_STATUS_ERROR;

		return 0;
	}

	cancellation =
		devm_kzalloc(dev,
			     sizeof(struct ethosu_cancel_inference),
			     GFP_KERNEL);
	if (!cancellation)
		return -ENOMEM;

	/* increase ref count on the inference we are refering to */
	ethosu_inference_get(inf);
	/* mark inference ABORTING to avoid resending the inference message */
	inf->status = ETHOSU_UAPI_STATUS_ABORTING;

	cancellation->dev = dev;
	cancellation->inf = inf;
	cancellation->uapi = uapi;
	init_completion(&cancellation->done);
	cancellation->msg.fail = ethosu_cancel_inference_fail;

	ret = ethosu_mailbox_register(mailbox,
				      &cancellation->msg);
	if (ret < 0)
		goto kfree;

	dev_dbg(dev,
		"Inference cancellation create. cancel=0x%pK, msg.id=%ddev",
		cancellation, cancellation->msg.id);

	ret = ethosu_cancel_inference_send(cancellation, mailbox);
	if (0 != ret)
		goto deregister;

	/* Unlock the mutex before going to block on the condition */
	device_unlock(dev);

	/* wait for response to arrive back */
	timeout = wait_for_completion_timeout(&cancellation->done,
					      msecs_to_jiffies(
						      CANCEL_INFERENCE_RESP_TIMEOUT_MS));
	/* take back the mutex before resuming to do anything */
	ret = device_lock_interruptible(dev);
	if (0 != ret)
		goto deregister;

	if (0 == timeout /* timed out*/) {
		dev_warn(dev,
			 "Msg: Cancel Inference response lost - timeoutdev");
		ret = -EIO;

		rproc_report_crash(rproc_get_by_child(dev), RPROC_FATAL_ERROR);
		goto deregister;
	}

	if (cancellation->errno) {
		ret = cancellation->errno;
		rproc_report_crash(rproc_get_by_child(dev), RPROC_FATAL_ERROR);
		goto deregister;
	}

	if (inf->status != ETHOSU_UAPI_STATUS_ABORTED)
		inf->status = ETHOSU_UAPI_STATUS_ABORTED;

deregister:
	ethosu_mailbox_deregister(mailbox,
				  &cancellation->msg);

kfree:
	dev_dbg(dev,
		"Cancel inference destroy. cancel=0x%pK", cancellation);

	/* decrease the reference on the inference we are refering to */
	ethosu_inference_put(cancellation->inf);
	devm_kfree(dev, cancellation);

	return ret;
}

void ethosu_cancel_inference_rsp(struct ethosu_mailbox *mailbox,
				 int msg_id,
				 struct ethosu_core_msg_cancel_inference_rsp *rsp)
{
	struct device *dev = mailbox->dev;
	struct ethosu_mailbox_msg *msg;
	struct ethosu_cancel_inference *cancellation;

	msg = ethosu_mailbox_find(mailbox, msg_id,
				  ETHOSU_CORE_MSG_CANCEL_INFERENCE_REQ);
	if (IS_ERR(msg)) {
		dev_warn(dev,
			 "Id for cancel inference msg not found. Id=0x%x: %ld",
			 msg_id, PTR_ERR(msg));

		return;
	}

	cancellation = container_of(msg, typeof(*cancellation), msg);

	if (completion_done(&cancellation->done))
		return;

	cancellation->errno = 0;
	switch (rsp->status) {
	case ETHOSU_CORE_STATUS_OK:
		cancellation->uapi->status = ETHOSU_UAPI_STATUS_OK;
		break;
	case ETHOSU_CORE_STATUS_ERROR:
		cancellation->uapi->status = ETHOSU_UAPI_STATUS_ERROR;
		break;
	}

	complete(&cancellation->done);
}
