/*
 * SPDX-FileCopyrightText: Copyright 2022-2023 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 "ethosu_cancel_inference.h"

#include "ethosu_core_rpmsg.h"
#include "ethosu_device.h"
#include "ethosu_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_CORE_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;
	}

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);
}
