/*
 * Copyright 2015 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 */
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include "eventmgr.h"
#include "hwmgr.h"
#include "eventinit.h"
#include "eventmanagement.h"

static int pem_init(struct pp_eventmgr *eventmgr)
{
	int result = 0;
	struct pem_event_data event_data = { {0} };

	/* Initialize PowerPlay feature info */
	pem_init_feature_info(eventmgr);

	/* Initialize event action chains */
	pem_init_event_action_chains(eventmgr);

	/* Call initialization event */
	result = pem_handle_event(eventmgr, AMD_PP_EVENT_INITIALIZE, &event_data);

	if (0 != result)
		return result;

	/* Register interrupt callback functions */
	result = pem_register_interrupts(eventmgr);
	return 0;
}

static void pem_fini(struct pp_eventmgr *eventmgr)
{
	struct pem_event_data event_data = { {0} };

	pem_uninit_featureInfo(eventmgr);
	pem_unregister_interrupts(eventmgr);

	pem_handle_event(eventmgr, AMD_PP_EVENT_UNINITIALIZE, &event_data);
}

int eventmgr_init(struct pp_instance *handle)
{
	int result = 0;
	struct pp_eventmgr *eventmgr;

	if (handle == NULL)
		return -EINVAL;

	eventmgr = kzalloc(sizeof(struct pp_eventmgr), GFP_KERNEL);
	if (eventmgr == NULL)
		return -ENOMEM;

	eventmgr->hwmgr = handle->hwmgr;
	handle->eventmgr = eventmgr;

	eventmgr->platform_descriptor = &(eventmgr->hwmgr->platform_descriptor);
	eventmgr->pp_eventmgr_init = pem_init;
	eventmgr->pp_eventmgr_fini = pem_fini;

	return result;
}

int eventmgr_fini(struct pp_eventmgr *eventmgr)
{
	kfree(eventmgr);
	return 0;
}

static int pem_handle_event_unlocked(struct pp_eventmgr *eventmgr, enum amd_pp_event event, struct pem_event_data *data)
{
	if (eventmgr == NULL || event >= AMD_PP_EVENT_MAX || data == NULL)
		return -EINVAL;

	return pem_excute_event_chain(eventmgr, eventmgr->event_chain[event], data);
}

int pem_handle_event(struct pp_eventmgr *eventmgr, enum amd_pp_event event, struct pem_event_data *event_data)
{
	int r = 0;

	r = pem_handle_event_unlocked(eventmgr, event, event_data);

	return r;
}

bool pem_is_hw_access_blocked(struct pp_eventmgr *eventmgr)
{
	return (eventmgr->block_adjust_power_state || phm_is_hw_access_blocked(eventmgr->hwmgr));
}
