// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
 *
 * (C) COPYRIGHT 2021 ARM Limited. All rights reserved.
 *
 * 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 license.
 *
 * 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.
 *
 */

#include "mali_kbase.h"
#include "mali_kbase_hwcnt_watchdog_if.h"
#include "mali_kbase_hwcnt_watchdog_if_timer.h"

#include <linux/workqueue.h>
#include <linux/slab.h>

/**
 * struct kbase_hwcnt_watchdog_if_timer_info - Timer information for watchdog
 *                                             interface.
 *
 * @workq:          Single threaded work queue in which to execute callbacks.
 * @dwork:          Worker to execute callback function.
 * @timer_enabled:  True if watchdog timer enabled, otherwise false
 * @callback:       Watchdog callback function
 * @user_data:      Pointer to user data passed as argument to the callback
 *                  function
 */
struct kbase_hwcnt_watchdog_if_timer_info {
	struct workqueue_struct *workq;
	struct delayed_work dwork;
	bool timer_enabled;
	kbase_hwcnt_watchdog_callback_fn *callback;
	void *user_data;
};

/**
 * kbasep_hwcnt_watchdog_callback() - Watchdog callback
 *
 * @work: Work structure
 *
 * Function to be called in a work queue after watchdog timer has expired.
 */
static void kbasep_hwcnt_watchdog_callback(struct work_struct *const work)
{
	struct kbase_hwcnt_watchdog_if_timer_info *const info =
		container_of(work, struct kbase_hwcnt_watchdog_if_timer_info, dwork.work);

	if (info->callback)
		info->callback(info->user_data);
}

static int kbasep_hwcnt_watchdog_if_timer_enable(
	const struct kbase_hwcnt_watchdog_info *const timer,
	u32 const period_ms, kbase_hwcnt_watchdog_callback_fn *const callback,
	void *const user_data)
{
	struct kbase_hwcnt_watchdog_if_timer_info *const timer_info =
		(void *)timer;

	if (WARN_ON(!timer) || WARN_ON(!callback) || WARN_ON(timer_info->timer_enabled))
		return -EINVAL;

	timer_info->callback = callback;
	timer_info->user_data = user_data;

	queue_delayed_work(timer_info->workq, &timer_info->dwork, msecs_to_jiffies(period_ms));
	timer_info->timer_enabled = true;

	return 0;
}

static void kbasep_hwcnt_watchdog_if_timer_disable(
	const struct kbase_hwcnt_watchdog_info *const timer)
{
	struct kbase_hwcnt_watchdog_if_timer_info *const timer_info =
		(void *)timer;

	if (WARN_ON(!timer))
		return;

	if (!timer_info->timer_enabled)
		return;

	cancel_delayed_work_sync(&timer_info->dwork);
	timer_info->timer_enabled = false;
}

static void kbasep_hwcnt_watchdog_if_timer_modify(
	const struct kbase_hwcnt_watchdog_info *const timer, u32 const delay_ms)
{
	struct kbase_hwcnt_watchdog_if_timer_info *const timer_info =
		(void *)timer;

	if (WARN_ON(!timer) || WARN_ON(!timer_info->timer_enabled))
		return;

	mod_delayed_work(timer_info->workq, &timer_info->dwork, msecs_to_jiffies(delay_ms));
}

void kbase_hwcnt_watchdog_if_timer_destroy(
	struct kbase_hwcnt_watchdog_interface *const watchdog_if)
{
	struct kbase_hwcnt_watchdog_if_timer_info *timer_info;

	if (WARN_ON(!watchdog_if))
		return;

	timer_info = (void *)watchdog_if->timer;

	if (WARN_ON(!timer_info))
		return;

	destroy_workqueue(timer_info->workq);
	kfree(timer_info);

	*watchdog_if = (struct kbase_hwcnt_watchdog_interface){ NULL };
}

int kbase_hwcnt_watchdog_if_timer_create(
	struct kbase_hwcnt_watchdog_interface *const watchdog_if)
{
	struct kbase_hwcnt_watchdog_if_timer_info *timer_info;

	if (WARN_ON(!watchdog_if))
		return -EINVAL;

	timer_info = kmalloc(sizeof(*timer_info), GFP_KERNEL);
	if (!timer_info)
		return -ENOMEM;

	*timer_info =
		(struct kbase_hwcnt_watchdog_if_timer_info){ .timer_enabled =
								     false };

	INIT_DELAYED_WORK(&timer_info->dwork, kbasep_hwcnt_watchdog_callback);

	*watchdog_if = (struct kbase_hwcnt_watchdog_interface){
		.timer = (void *)timer_info,
		.enable = kbasep_hwcnt_watchdog_if_timer_enable,
		.disable = kbasep_hwcnt_watchdog_if_timer_disable,
		.modify = kbasep_hwcnt_watchdog_if_timer_modify,
	};

	timer_info->workq = alloc_workqueue("mali_hwc_watchdog_wq", WQ_HIGHPRI | WQ_UNBOUND, 1);
	if (timer_info->workq)
		return 0;

	kfree(timer_info);
	return -ENOMEM;
}
