/* 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");