/* 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/logbuffer.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) (typeof(p))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");
