/*
 * Copyright 2022-2023 Arm Limited and/or its affiliates
 *
 * 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.
 *
 * SPDX-License-Identifier: GPL-2.0-only
 */

/****************************************************************************
 * 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_info(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_info(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);
	if (IS_ERR(msg)) {
		dev_warn(dev,
			 "Id for cancel inference msg not found. id=%ddev",
			 msg_id);

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