/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright 2019 Google, LLC
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include "linux/slab.h"
#include <misc/gvotable.h>
#include "pmic-voter.h"

#define V2EL(x) ((struct gvotable_election *)(v))

struct votable_data {
	const char *name;
	void *callback_data;   /* data passed to create_votable */
	int (*callback)(struct votable *votable,
			void *data,
			int effective_result,
			const char *effective_client);
};


bool is_client_vote_enabled_locked(struct votable *v, const char *client_str)
{
	int ret;
	bool enabled = false;

	ret = gvotable_is_enabled(V2EL(v), client_str, &enabled);
	if (ret)
		pr_err("Error gvotable_is_enabled returned %d\n", ret);

	return enabled;
}

bool is_client_vote_enabled(struct votable *votable, const char *client_str)
{
	return is_client_vote_enabled_locked(votable, client_str);
}

int get_client_vote_locked(struct votable *v, const char *client_str)
{
	void *ptr;
	int ret;

	ret = gvotable_get_vote(V2EL(votable), client_str, &ptr);
	return ret ? : (uintptr_t)ptr;
}

int get_client_vote(struct votable *votable, const char *client_str)
{
	return get_client_vote_locked(votable, client_str);
}
EXPORT_SYMBOL_GPL(get_client_vote);

int get_effective_result_locked(struct votable *v)
{
	const void *ptr;
	int ret;

	ret = gvotable_get_current_vote(V2EL(v), &ptr);
	return ret ? : (uintptr_t)ptr;
}
EXPORT_SYMBOL_GPL(get_effective_result_locked);

int get_effective_result(struct votable *votable)
{
	return get_effective_result_locked(votable);
}
EXPORT_SYMBOL_GPL(get_effective_result);

int vote(struct votable *v, const char *client_str, bool state, int val)
{
	return gvotable_cast_vote(V2EL(v), client_str, (void *)(long)val,
				  state);
}
EXPORT_SYMBOL_GPL(vote);

/* It needs to work for new and instances so we can mix the code
 */
struct votable *find_votable(const char *name)
{
	return (struct votable *)gvotable_election_get_handle(name);
}
EXPORT_SYMBOL_GPL(find_votable);

static void pmic_voter_compat_cb(struct gvotable_election *el,
				 const char *cb_reason, void *cb_result)
{
	struct votable_data *vd = (struct votable_data *)gvotable_get_data(el);
	char reason[GVOTABLE_MAX_REASON_LEN] = { 0 };
	char *effective_reason = NULL;
	int effective_result = -EINVAL;
	const void *ptr;
	int ret;

	if (!vd->callback)
		return;

	ret = gvotable_get_current_vote(el, &ptr);
	if (ret == 0)
		effective_result = (uintptr_t)ptr;

	ret = gvotable_get_current_reason(el, reason, sizeof(reason));
	if (ret == 0)
		effective_reason = reason;

	/* for SET_ANY voter, the value is always same as enabled. */
	pr_debug("%s: name=%s result=%d reason=%s\n", __func__, vd->name,
		 effective_result, effective_reason ? effective_reason : "<>");

	/* call with NULL reason and -EINVAL if votes no enabled */
	vd->callback((struct votable *)el, vd->callback_data,
			effective_result, effective_reason);
}

/* Allow redefining the allocator: required for testing */
#ifndef kzalloc_votable
#define kzalloc_votable(p, f) kzalloc(sizeof(*p), f)
#endif

struct votable *create_votable(const char *name,
		int votable_type,
		int (*callback)(struct votable *votable,
				void *data,
				int effective_result,
				const char *effective_client),
		void *callback_data)
{
	int (*comp_fn)(void * , void *) = NULL;
	struct gvotable_election *el;
	struct votable_data *vd;
	int ret;

	if (!name)
		return ERR_PTR(-EINVAL);

	/* create extra votable data */
	vd = kzalloc_votable(vd, GFP_KERNEL);
	if (!vd)
		return ERR_PTR(-ENOMEM);
	vd->callback_data = callback_data;
	vd->callback = callback;
	vd->name = name;

	switch (votable_type) {
		case VOTE_MIN:
			comp_fn = gvotable_comparator_int_min;
		break;
		case VOTE_MAX:
			comp_fn = gvotable_comparator_int_max;
		break;
		case VOTE_SET_ANY:
		break;
		default:
			kfree(vd);
			return ERR_PTR(-EINVAL);
		break;
	}

	if (votable_type == VOTE_SET_ANY) {
		el = gvotable_create_bool_election(NULL, pmic_voter_compat_cb,
						   vd);
	} else {
		el = gvotable_create_int_election(NULL, comp_fn,
						  pmic_voter_compat_cb,
						  vd);
	}

	if (IS_ERR_OR_NULL(el)) {
		kfree(vd);
		return ERR_PTR(-ENOMEM);
	}

	gvotable_set_vote2str(el, gvotable_v2s_int);
	/* votables of type ANY have a default but they don't use it */
	if (votable_type == VOTE_SET_ANY) {
		gvotable_set_default(el, 0);
		gvotable_use_default(el, false);
	}

	ret = gvotable_election_set_name(el, vd->name);
	if (ret < 0) {
		gvotable_destroy_election(el);
		kfree(vd);
		return ERR_PTR(-EEXIST);
	}


	return (struct votable *)el;
}
EXPORT_SYMBOL_GPL(create_votable);

void destroy_votable(struct votable *v)
{
	if (!v)
		return;

	kfree(gvotable_get_data(V2EL(v)));
	gvotable_destroy_election(V2EL(v));
}
EXPORT_SYMBOL_GPL(destroy_votable);

MODULE_AUTHOR("Jim Wylder <jwylder@google.com>");
MODULE_AUTHOR("AleX Pelosi <apelosi@google.com>");
MODULE_DESCRIPTION("QC PMIC Votable compatibility");
MODULE_LICENSE("GPL");