// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
 *
 * (C) COPYRIGHT 2018-2023 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.
 *
 */

/*
 * Implementation of hardware counter context and accumulator APIs.
 */

#include "hwcnt/mali_kbase_hwcnt_context.h"
#include "hwcnt/mali_kbase_hwcnt_accumulator.h"
#include "hwcnt/backend/mali_kbase_hwcnt_backend.h"
#include "hwcnt/mali_kbase_hwcnt_types.h"

#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/slab.h>

/**
 * enum kbase_hwcnt_accum_state - Hardware counter accumulator states.
 * @ACCUM_STATE_ERROR:    Error state, where all accumulator operations fail.
 * @ACCUM_STATE_DISABLED: Disabled state, where dumping is always disabled.
 * @ACCUM_STATE_ENABLED:  Enabled state, where dumping is enabled if there are
 *                        any enabled counters.
 */
enum kbase_hwcnt_accum_state { ACCUM_STATE_ERROR, ACCUM_STATE_DISABLED, ACCUM_STATE_ENABLED };

/**
 * struct kbase_hwcnt_accumulator - Hardware counter accumulator structure.
 * @metadata:               Pointer to immutable hwcnt metadata.
 * @backend:                Pointer to created counter backend.
 * @state:                  The current state of the accumulator.
 *                           - State transition from disabled->enabled or
 *                             disabled->error requires state_lock.
 *                           - State transition from enabled->disabled or
 *                             enabled->error requires both accum_lock and
 *                             state_lock.
 *                           - Error state persists until next disable.
 * @enable_map:             The current set of enabled counters.
 *                           - Must only be modified while holding both
 *                             accum_lock and state_lock.
 *                           - Can be read while holding either lock.
 *                           - Must stay in sync with enable_map_any_enabled.
 * @enable_map_any_enabled: True if any counters in the map are enabled, else
 *                          false. If true, and state is ACCUM_STATE_ENABLED,
 *                          then the counter backend will be enabled.
 *                           - Must only be modified while holding both
 *                             accum_lock and state_lock.
 *                           - Can be read while holding either lock.
 *                           - Must stay in sync with enable_map.
 * @scratch_map:            Scratch enable map, used as temporary enable map
 *                          storage during dumps.
 *                           - Must only be read or modified while holding
 *                             accum_lock.
 * @accum_buf:              Accumulation buffer, where dumps will be accumulated
 *                          into on transition to a disable state.
 *                           - Must only be read or modified while holding
 *                             accum_lock.
 * @accumulated:            True if the accumulation buffer has been accumulated
 *                          into and not subsequently read from yet, else false.
 *                           - Must only be read or modified while holding
 *                             accum_lock.
 * @ts_last_dump_ns:        Timestamp (ns) of the end time of the most recent
 *                          dump that was requested by the user.
 *                           - Must only be read or modified while holding
 *                             accum_lock.
 */
struct kbase_hwcnt_accumulator {
	const struct kbase_hwcnt_metadata *metadata;
	struct kbase_hwcnt_backend *backend;
	enum kbase_hwcnt_accum_state state;
	struct kbase_hwcnt_enable_map enable_map;
	bool enable_map_any_enabled;
	struct kbase_hwcnt_enable_map scratch_map;
	struct kbase_hwcnt_dump_buffer accum_buf;
	bool accumulated;
	u64 ts_last_dump_ns;
};

/**
 * struct kbase_hwcnt_context - Hardware counter context structure.
 * @iface:         Pointer to hardware counter backend interface.
 * @state_lock:    Spinlock protecting state.
 * @disable_count: Disable count of the context. Initialised to 1.
 *                 Decremented when the accumulator is acquired, and incremented
 *                 on release. Incremented on calls to
 *                 kbase_hwcnt_context_disable[_atomic], and decremented on
 *                 calls to kbase_hwcnt_context_enable.
 *                  - Must only be read or modified while holding state_lock.
 * @accum_lock:    Mutex protecting accumulator.
 * @accum_inited:  Flag to prevent concurrent accumulator initialisation and/or
 *                 termination. Set to true before accumulator initialisation,
 *                 and false after accumulator termination.
 *                  - Must only be modified while holding both accum_lock and
 *                    state_lock.
 *                  - Can be read while holding either lock.
 * @accum:         Hardware counter accumulator structure.
 * @wq:            Centralized workqueue for users of hardware counters to
 *                 submit async hardware counter related work. Never directly
 *                 called, but it's expected that a lot of the functions in this
 *                 API will end up called from the enqueued async work.
 */
struct kbase_hwcnt_context {
	const struct kbase_hwcnt_backend_interface *iface;
	spinlock_t state_lock;
	size_t disable_count;
	struct mutex accum_lock;
	bool accum_inited;
	struct kbase_hwcnt_accumulator accum;
	struct workqueue_struct *wq;
};

int kbase_hwcnt_context_init(const struct kbase_hwcnt_backend_interface *iface,
			     struct kbase_hwcnt_context **out_hctx)
{
	struct kbase_hwcnt_context *hctx = NULL;

	if (!iface || !out_hctx)
		return -EINVAL;

	hctx = kzalloc(sizeof(*hctx), GFP_KERNEL);
	if (!hctx)
		goto err_alloc_hctx;

	hctx->iface = iface;
	spin_lock_init(&hctx->state_lock);
	hctx->disable_count = 1;
	mutex_init(&hctx->accum_lock);
	hctx->accum_inited = false;

	hctx->wq = alloc_workqueue("mali_kbase_hwcnt", WQ_HIGHPRI | WQ_UNBOUND, 0);
	if (!hctx->wq)
		goto err_alloc_workqueue;

	*out_hctx = hctx;

	return 0;

err_alloc_workqueue:
	kfree(hctx);
err_alloc_hctx:
	return -ENOMEM;
}

void kbase_hwcnt_context_term(struct kbase_hwcnt_context *hctx)
{
	if (!hctx)
		return;

	/* Make sure we didn't leak the accumulator */
	WARN_ON(hctx->accum_inited);

	/* We don't expect any work to be pending on this workqueue.
	 * Regardless, this will safely drain and complete the work.
	 */
	destroy_workqueue(hctx->wq);
	kfree(hctx);
}

/**
 * kbasep_hwcnt_accumulator_term() - Terminate the accumulator for the context.
 * @hctx: Non-NULL pointer to hardware counter context.
 */
static void kbasep_hwcnt_accumulator_term(struct kbase_hwcnt_context *hctx)
{
	WARN_ON(!hctx);
	WARN_ON(!hctx->accum_inited);

	kbase_hwcnt_enable_map_free(&hctx->accum.scratch_map);
	kbase_hwcnt_dump_buffer_free(&hctx->accum.accum_buf);
	kbase_hwcnt_enable_map_free(&hctx->accum.enable_map);
	hctx->iface->term(hctx->accum.backend);
	memset(&hctx->accum, 0, sizeof(hctx->accum));
}

/**
 * kbasep_hwcnt_accumulator_init() - Initialise the accumulator for the context.
 * @hctx: Non-NULL pointer to hardware counter context.
 *
 * Return: 0 on success, else error code.
 */
static int kbasep_hwcnt_accumulator_init(struct kbase_hwcnt_context *hctx)
{
	int errcode;

	WARN_ON(!hctx);
	WARN_ON(!hctx->accum_inited);

	errcode = hctx->iface->init(hctx->iface->info, &hctx->accum.backend);
	if (errcode)
		goto error;

	hctx->accum.metadata = hctx->iface->metadata(hctx->iface->info);
	hctx->accum.state = ACCUM_STATE_ERROR;

	errcode = kbase_hwcnt_enable_map_alloc(hctx->accum.metadata, &hctx->accum.enable_map);
	if (errcode)
		goto error;

	hctx->accum.enable_map_any_enabled = false;

	errcode = kbase_hwcnt_dump_buffer_alloc(hctx->accum.metadata, &hctx->accum.accum_buf);
	if (errcode)
		goto error;

	errcode = kbase_hwcnt_enable_map_alloc(hctx->accum.metadata, &hctx->accum.scratch_map);
	if (errcode)
		goto error;

	hctx->accum.accumulated = false;

	hctx->accum.ts_last_dump_ns = hctx->iface->timestamp_ns(hctx->accum.backend);

	return 0;

error:
	kbasep_hwcnt_accumulator_term(hctx);
	return errcode;
}

/**
 * kbasep_hwcnt_accumulator_disable() - Transition the accumulator into the
 *                                      disabled state, from the enabled or
 *                                      error states.
 * @hctx:       Non-NULL pointer to hardware counter context.
 * @accumulate: True if we should accumulate before disabling, else false.
 */
static void kbasep_hwcnt_accumulator_disable(struct kbase_hwcnt_context *hctx, bool accumulate)
{
	int errcode = 0;
	bool backend_enabled = false;
	struct kbase_hwcnt_accumulator *accum;
	unsigned long flags;
	u64 dump_time_ns;

	WARN_ON(!hctx);
	lockdep_assert_held(&hctx->accum_lock);
	WARN_ON(!hctx->accum_inited);

	accum = &hctx->accum;

	spin_lock_irqsave(&hctx->state_lock, flags);

	WARN_ON(hctx->disable_count != 0);
	WARN_ON(hctx->accum.state == ACCUM_STATE_DISABLED);

	if ((hctx->accum.state == ACCUM_STATE_ENABLED) && (accum->enable_map_any_enabled))
		backend_enabled = true;

	if (!backend_enabled)
		hctx->accum.state = ACCUM_STATE_DISABLED;

	spin_unlock_irqrestore(&hctx->state_lock, flags);

	/* Early out if the backend is not already enabled */
	if (!backend_enabled)
		return;

	if (!accumulate)
		goto disable;

	/* Try and accumulate before disabling */
	errcode = hctx->iface->dump_request(accum->backend, &dump_time_ns);
	if (errcode)
		goto disable;

	errcode = hctx->iface->dump_wait(accum->backend);
	if (errcode)
		goto disable;

	errcode = hctx->iface->dump_get(accum->backend, &accum->accum_buf, &accum->enable_map,
					accum->accumulated);
	if (errcode)
		goto disable;

	accum->accumulated = true;

disable:
	hctx->iface->dump_disable(accum->backend);

	/* Regardless of any errors during the accumulate, put the accumulator
	 * in the disabled state.
	 */
	spin_lock_irqsave(&hctx->state_lock, flags);

	hctx->accum.state = ACCUM_STATE_DISABLED;

	spin_unlock_irqrestore(&hctx->state_lock, flags);
}

/**
 * kbasep_hwcnt_accumulator_enable() - Transition the accumulator into the
 *                                     enabled state, from the disabled state.
 * @hctx: Non-NULL pointer to hardware counter context.
 */
static void kbasep_hwcnt_accumulator_enable(struct kbase_hwcnt_context *hctx)
{
	int errcode = 0;
	struct kbase_hwcnt_accumulator *accum;

	WARN_ON(!hctx);
	lockdep_assert_held(&hctx->state_lock);
	WARN_ON(!hctx->accum_inited);
	WARN_ON(hctx->accum.state != ACCUM_STATE_DISABLED);

	accum = &hctx->accum;

	/* The backend only needs enabling if any counters are enabled */
	if (accum->enable_map_any_enabled)
		errcode = hctx->iface->dump_enable_nolock(accum->backend, &accum->enable_map);

	if (!errcode)
		accum->state = ACCUM_STATE_ENABLED;
	else
		accum->state = ACCUM_STATE_ERROR;
}

/**
 * kbasep_hwcnt_accumulator_dump() - Perform a dump with the most up-to-date
 *                                   values of enabled counters possible, and
 *                                   optionally update the set of enabled
 *                                   counters.
 * @hctx:        Non-NULL pointer to the hardware counter context
 * @ts_start_ns: Non-NULL pointer where the start timestamp of the dump will
 *               be written out to on success
 * @ts_end_ns:   Non-NULL pointer where the end timestamp of the dump will
 *               be written out to on success
 * @dump_buf:    Pointer to the buffer where the dump will be written out to on
 *               success. If non-NULL, must have the same metadata as the
 *               accumulator. If NULL, the dump will be discarded.
 * @new_map:     Pointer to the new counter enable map. If non-NULL, must have
 *               the same metadata as the accumulator. If NULL, the set of
 *               enabled counters will be unchanged.
 *
 * Return:       0 on success, else error code.
 */
static int kbasep_hwcnt_accumulator_dump(struct kbase_hwcnt_context *hctx, u64 *ts_start_ns,
					 u64 *ts_end_ns, struct kbase_hwcnt_dump_buffer *dump_buf,
					 const struct kbase_hwcnt_enable_map *new_map)
{
	int errcode = 0;
	unsigned long flags;
	enum kbase_hwcnt_accum_state state;
	bool dump_requested = false;
	bool dump_written = false;
	bool cur_map_any_enabled;
	struct kbase_hwcnt_enable_map *cur_map;
	bool new_map_any_enabled = false;
	u64 dump_time_ns = 0;
	struct kbase_hwcnt_accumulator *accum;

	WARN_ON(!hctx);
	WARN_ON(!ts_start_ns);
	WARN_ON(!ts_end_ns);
	WARN_ON(dump_buf && (dump_buf->metadata != hctx->accum.metadata));
	WARN_ON(new_map && (new_map->metadata != hctx->accum.metadata));
	WARN_ON(!hctx->accum_inited);
	lockdep_assert_held(&hctx->accum_lock);

	accum = &hctx->accum;
	cur_map = &accum->scratch_map;

	/* Save out info about the current enable map */
	cur_map_any_enabled = accum->enable_map_any_enabled;
	kbase_hwcnt_enable_map_copy(cur_map, &accum->enable_map);

	if (new_map)
		new_map_any_enabled = kbase_hwcnt_enable_map_any_enabled(new_map);

	/*
	 * We're holding accum_lock, so the accumulator state might transition
	 * from disabled to enabled during this function (as enabling is lock
	 * free), but it will never disable (as disabling needs to hold the
	 * accum_lock), nor will it ever transition from enabled to error (as
	 * an enable while we're already enabled is impossible).
	 *
	 * If we're already disabled, we'll only look at the accumulation buffer
	 * rather than do a real dump, so a concurrent enable does not affect
	 * us.
	 *
	 * If a concurrent enable fails, we might transition to the error
	 * state, but again, as we're only looking at the accumulation buffer,
	 * it's not an issue.
	 */
	spin_lock_irqsave(&hctx->state_lock, flags);

	state = accum->state;

	/*
	 * Update the new map now, such that if an enable occurs during this
	 * dump then that enable will set the new map. If we're already enabled,
	 * then we'll do it ourselves after the dump.
	 */
	if (new_map) {
		kbase_hwcnt_enable_map_copy(&accum->enable_map, new_map);
		accum->enable_map_any_enabled = new_map_any_enabled;
	}

	spin_unlock_irqrestore(&hctx->state_lock, flags);

	/* Error state, so early out. No need to roll back any map updates */
	if (state == ACCUM_STATE_ERROR)
		return -EIO;

	/* Initiate the dump if the backend is enabled. */
	if ((state == ACCUM_STATE_ENABLED) && cur_map_any_enabled) {
		if (dump_buf) {
			errcode = hctx->iface->dump_request(accum->backend, &dump_time_ns);
			dump_requested = true;
		} else {
			dump_time_ns = hctx->iface->timestamp_ns(accum->backend);
			errcode = hctx->iface->dump_clear(accum->backend);
		}

		if (errcode)
			goto error;
	} else {
		dump_time_ns = hctx->iface->timestamp_ns(accum->backend);
	}

	/* Copy any accumulation into the dest buffer */
	if (accum->accumulated && dump_buf) {
		kbase_hwcnt_dump_buffer_copy(dump_buf, &accum->accum_buf, cur_map);
		dump_written = true;
	}

	/* Wait for any requested dumps to complete */
	if (dump_requested) {
		WARN_ON(state != ACCUM_STATE_ENABLED);
		errcode = hctx->iface->dump_wait(accum->backend);
		if (errcode)
			goto error;
	}

	/* If we're enabled and there's a new enable map, change the enabled set
	 * as soon after the dump has completed as possible.
	 */
	if ((state == ACCUM_STATE_ENABLED) && new_map) {
		/* Backend is only enabled if there were any enabled counters */
		if (cur_map_any_enabled)
			hctx->iface->dump_disable(accum->backend);

		/* (Re-)enable the backend if the new map has enabled counters.
		 * No need to acquire the spinlock, as concurrent enable while
		 * we're already enabled and holding accum_lock is impossible.
		 */
		if (new_map_any_enabled) {
			errcode = hctx->iface->dump_enable(accum->backend, new_map);
			if (errcode)
				goto error;
		}
	}

	/* Copy, accumulate, or zero into the dest buffer to finish */
	if (dump_buf) {
		/* If we dumped, copy or accumulate it into the destination */
		if (dump_requested) {
			WARN_ON(state != ACCUM_STATE_ENABLED);
			errcode = hctx->iface->dump_get(accum->backend, dump_buf, cur_map,
							dump_written);
			if (errcode)
				goto error;
			dump_written = true;
		}

		/* If we've not written anything into the dump buffer so far, it
		 * means there was nothing to write. Zero any enabled counters.
		 */
		if (!dump_written)
			kbase_hwcnt_dump_buffer_zero(dump_buf, cur_map);
	}

	/* Write out timestamps */
	*ts_start_ns = accum->ts_last_dump_ns;
	*ts_end_ns = dump_time_ns;

	accum->accumulated = false;
	accum->ts_last_dump_ns = dump_time_ns;

	return 0;
error:
	/* An error was only physically possible if the backend was enabled */
	WARN_ON(state != ACCUM_STATE_ENABLED);

	/* Disable the backend, and transition to the error state */
	hctx->iface->dump_disable(accum->backend);
	spin_lock_irqsave(&hctx->state_lock, flags);

	accum->state = ACCUM_STATE_ERROR;

	spin_unlock_irqrestore(&hctx->state_lock, flags);

	return errcode;
}

/**
 * kbasep_hwcnt_context_disable() - Increment the disable count of the context.
 * @hctx:       Non-NULL pointer to hardware counter context.
 * @accumulate: True if we should accumulate before disabling, else false.
 */
static void kbasep_hwcnt_context_disable(struct kbase_hwcnt_context *hctx, bool accumulate)
{
	unsigned long flags;

	WARN_ON(!hctx);
	lockdep_assert_held(&hctx->accum_lock);

	if (!kbase_hwcnt_context_disable_atomic(hctx)) {
		kbasep_hwcnt_accumulator_disable(hctx, accumulate);

		spin_lock_irqsave(&hctx->state_lock, flags);

		/* Atomic disable failed and we're holding the mutex, so current
		 * disable count must be 0.
		 */
		WARN_ON(hctx->disable_count != 0);
		hctx->disable_count++;

		spin_unlock_irqrestore(&hctx->state_lock, flags);
	}
}

int kbase_hwcnt_accumulator_acquire(struct kbase_hwcnt_context *hctx,
				    struct kbase_hwcnt_accumulator **accum)
{
	int errcode = 0;
	unsigned long flags;

	if (!hctx || !accum)
		return -EINVAL;

	mutex_lock(&hctx->accum_lock);
	spin_lock_irqsave(&hctx->state_lock, flags);

	if (!hctx->accum_inited)
		/* Set accum initing now to prevent concurrent init */
		hctx->accum_inited = true;
	else
		/* Already have an accum, or already being inited */
		errcode = -EBUSY;

	spin_unlock_irqrestore(&hctx->state_lock, flags);
	mutex_unlock(&hctx->accum_lock);

	if (errcode)
		return errcode;

	errcode = kbasep_hwcnt_accumulator_init(hctx);

	if (errcode) {
		mutex_lock(&hctx->accum_lock);
		spin_lock_irqsave(&hctx->state_lock, flags);

		hctx->accum_inited = false;

		spin_unlock_irqrestore(&hctx->state_lock, flags);
		mutex_unlock(&hctx->accum_lock);

		return errcode;
	}

	spin_lock_irqsave(&hctx->state_lock, flags);

	WARN_ON(hctx->disable_count == 0);
	WARN_ON(hctx->accum.enable_map_any_enabled);

	/* Decrement the disable count to allow the accumulator to be accessible
	 * now that it's fully constructed.
	 */
	hctx->disable_count--;

	/*
	 * Make sure the accumulator is initialised to the correct state.
	 * Regardless of initial state, counters don't need to be enabled via
	 * the backend, as the initial enable map has no enabled counters.
	 */
	hctx->accum.state = (hctx->disable_count == 0) ? ACCUM_STATE_ENABLED : ACCUM_STATE_DISABLED;

	spin_unlock_irqrestore(&hctx->state_lock, flags);

	*accum = &hctx->accum;

	return 0;
}

void kbase_hwcnt_accumulator_release(struct kbase_hwcnt_accumulator *accum)
{
	unsigned long flags;
	struct kbase_hwcnt_context *hctx;

	if (!accum)
		return;

	hctx = container_of(accum, struct kbase_hwcnt_context, accum);

	mutex_lock(&hctx->accum_lock);

	/* Double release is a programming error */
	WARN_ON(!hctx->accum_inited);

	/* Disable the context to ensure the accumulator is inaccesible while
	 * we're destroying it. This performs the corresponding disable count
	 * increment to the decrement done during acquisition.
	 */
	kbasep_hwcnt_context_disable(hctx, false);

	mutex_unlock(&hctx->accum_lock);

	kbasep_hwcnt_accumulator_term(hctx);

	mutex_lock(&hctx->accum_lock);
	spin_lock_irqsave(&hctx->state_lock, flags);

	hctx->accum_inited = false;

	spin_unlock_irqrestore(&hctx->state_lock, flags);
	mutex_unlock(&hctx->accum_lock);
}

void kbase_hwcnt_context_disable(struct kbase_hwcnt_context *hctx)
{
	if (WARN_ON(!hctx))
		return;

	/* Try and atomically disable first, so we can avoid locking the mutex
	 * if we don't need to.
	 */
	if (kbase_hwcnt_context_disable_atomic(hctx))
		return;

	mutex_lock(&hctx->accum_lock);

	kbasep_hwcnt_context_disable(hctx, true);

	mutex_unlock(&hctx->accum_lock);
}

bool kbase_hwcnt_context_disable_atomic(struct kbase_hwcnt_context *hctx)
{
	unsigned long flags;
	bool atomic_disabled = false;

	if (WARN_ON(!hctx))
		return false;

	spin_lock_irqsave(&hctx->state_lock, flags);

	if (!WARN_ON(hctx->disable_count == SIZE_MAX)) {
		/*
		 * If disable count is non-zero, we can just bump the disable
		 * count.
		 *
		 * Otherwise, we can't disable in an atomic context.
		 */
		if (hctx->disable_count != 0) {
			hctx->disable_count++;
			atomic_disabled = true;
		}
	}

	spin_unlock_irqrestore(&hctx->state_lock, flags);

	return atomic_disabled;
}

void kbase_hwcnt_context_enable(struct kbase_hwcnt_context *hctx)
{
	unsigned long flags;

	if (WARN_ON(!hctx))
		return;

	spin_lock_irqsave(&hctx->state_lock, flags);

	if (!WARN_ON(hctx->disable_count == 0)) {
		if (hctx->disable_count == 1)
			kbasep_hwcnt_accumulator_enable(hctx);

		hctx->disable_count--;
	}

	spin_unlock_irqrestore(&hctx->state_lock, flags);
}

const struct kbase_hwcnt_metadata *kbase_hwcnt_context_metadata(struct kbase_hwcnt_context *hctx)
{
	if (!hctx)
		return NULL;

	return hctx->iface->metadata(hctx->iface->info);
}

bool kbase_hwcnt_context_queue_work(struct kbase_hwcnt_context *hctx, struct work_struct *work)
{
	if (WARN_ON(!hctx) || WARN_ON(!work))
		return false;

	return queue_work(hctx->wq, work);
}

int kbase_hwcnt_accumulator_set_counters(struct kbase_hwcnt_accumulator *accum,
					 const struct kbase_hwcnt_enable_map *new_map,
					 u64 *ts_start_ns, u64 *ts_end_ns,
					 struct kbase_hwcnt_dump_buffer *dump_buf)
{
	int errcode;
	struct kbase_hwcnt_context *hctx;

	if (!accum || !new_map || !ts_start_ns || !ts_end_ns)
		return -EINVAL;

	hctx = container_of(accum, struct kbase_hwcnt_context, accum);

	if ((new_map->metadata != hctx->accum.metadata) ||
	    (dump_buf && (dump_buf->metadata != hctx->accum.metadata)))
		return -EINVAL;

	mutex_lock(&hctx->accum_lock);

	errcode = kbasep_hwcnt_accumulator_dump(hctx, ts_start_ns, ts_end_ns, dump_buf, new_map);

	mutex_unlock(&hctx->accum_lock);

	return errcode;
}

int kbase_hwcnt_accumulator_dump(struct kbase_hwcnt_accumulator *accum, u64 *ts_start_ns,
				 u64 *ts_end_ns, struct kbase_hwcnt_dump_buffer *dump_buf)
{
	int errcode;
	struct kbase_hwcnt_context *hctx;

	if (!accum || !ts_start_ns || !ts_end_ns)
		return -EINVAL;

	hctx = container_of(accum, struct kbase_hwcnt_context, accum);

	if (dump_buf && (dump_buf->metadata != hctx->accum.metadata))
		return -EINVAL;

	mutex_lock(&hctx->accum_lock);

	errcode = kbasep_hwcnt_accumulator_dump(hctx, ts_start_ns, ts_end_ns, dump_buf, NULL);

	mutex_unlock(&hctx->accum_lock);

	return errcode;
}

u64 kbase_hwcnt_accumulator_timestamp_ns(struct kbase_hwcnt_accumulator *accum)
{
	struct kbase_hwcnt_context *hctx;

	if (WARN_ON(!accum))
		return 0;

	hctx = container_of(accum, struct kbase_hwcnt_context, accum);
	return hctx->iface->timestamp_ns(accum->backend);
}
