/*
 * Google LWIS Clock Interface
 *
 * Copyright (c) 2018 Google, LLC
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#define pr_fmt(fmt) KBUILD_MODNAME "-clock: " fmt

#include <linux/kernel.h>
#include <linux/slab.h>

#include "lwis_clock.h"

struct lwis_clock_list *lwis_clock_list_alloc(int num_clks)
{
	struct lwis_clock_list *list;

	/* No need to allocate if num_clks is invalid */
	if (num_clks <= 0) {
		return ERR_PTR(-EINVAL);
	}

	list = kmalloc(sizeof(struct lwis_clock_list), GFP_KERNEL);
	if (!list) {
		return ERR_PTR(-ENOMEM);
	}

	list->clk = kzalloc(num_clks * sizeof(struct lwis_clock), GFP_KERNEL);
	if (!list->clk) {
		kfree(list);
		return ERR_PTR(-ENOMEM);
	}

	list->count = num_clks;

	return list;
}

void lwis_clock_list_free(struct lwis_clock_list *list)
{
	if (!list) {
		return;
	}

	if (list->clk) {
		kfree(list->clk);
	}

	kfree(list);
}

int lwis_clock_get(struct lwis_clock_list *list, char *name, struct device *dev, uint32_t rate)
{
	struct clk *clk;
	int i;
	int index = -1;

	if (!dev || !list) {
		return -EINVAL;
	}

	/* Look for empty slot and duplicate entries */
	for (i = 0; i < list->count; ++i) {
		if (list->clk[i].clk == NULL) {
			index = i;
			break;
		} else if (!strcmp(list->clk[i].name, name)) {
			pr_info("Clock %s already allocated\n", name);
			return i;
		}
	}

	/* No empty slot */
	if (index < 0) {
		pr_err("No empty slots in the lwis_clock struct\n");
		return -ENOMEM;
	}

	/* Make sure clock exists */
	clk = devm_clk_get(dev, name);
	if (IS_ERR(clk)) {
		pr_err("Clock %s not found\n", name);
		return PTR_ERR(clk);
	}

	list->clk[index].clk = clk;
	list->clk[index].name = name;
	list->clk[index].rate = rate;

	return index;
}

int lwis_clock_put_by_idx(struct lwis_clock_list *list, int index, struct device *dev)
{
	if (!dev || !list || index < 0 || index >= list->count) {
		return -EINVAL;
	}

	if (IS_ERR_OR_NULL(list->clk[index].clk)) {
		return -EINVAL;
	}

	devm_clk_put(dev, list->clk[index].clk);
	memset(list->clk + index, 0, sizeof(struct lwis_clock));

	return 0;
}

int lwis_clock_put_by_name(struct lwis_clock_list *list, char *name, struct device *dev)
{
	int i;

	if (!dev || !list) {
		return -EINVAL;
	}

	/* Find entry by name */
	for (i = 0; i < list->count; ++i) {
		if (!strcmp(list->clk[i].name, name)) {
			if (IS_ERR_OR_NULL(list->clk[i].clk)) {
				return -EINVAL;
			}
			devm_clk_put(dev, list->clk[i].clk);
			memset(list->clk + i, 0, sizeof(struct lwis_clock));
			return 0;
		}
	}

	pr_err("Clock %s not found\n", name);
	return -EINVAL;
}

int lwis_clock_enable_by_idx(struct lwis_clock_list *list, int index)
{
	int ret = 0;

	if (!list || index < 0 || index >= list->count) {
		return -EINVAL;
	}

	ret = clk_prepare_enable(list->clk[index].clk);
	if (ret) {
		return ret;
	}

	if (list->clk[index].rate > 0) {
		ret = clk_set_rate(list->clk[index].clk, list->clk[index].rate);
	}

	return ret;
}

int lwis_clock_enable_by_name(struct lwis_clock_list *list, char *name)
{
	int i;

	if (!list) {
		return -EINVAL;
	}

	for (i = 0; i < list->count; ++i) {
		if (!strcmp(list->clk[i].name, name)) {
			return lwis_clock_enable_by_idx(list, i);
		}
	}

	pr_err("Clock %s not found\n", name);
	return -ENOENT;
}

int lwis_clock_enable_all(struct lwis_clock_list *list)
{
	int i;
	int ret;

	if (!list) {
		return -EINVAL;
	}

	for (i = 0; i < list->count; ++i) {
		ret = lwis_clock_enable_by_idx(list, i);
		if (ret) {
			pr_err("Error enabling clock %s\n", list->clk[i].name);
			return ret;
		}
	}

	return 0;
}

void lwis_clock_disable_by_idx(struct lwis_clock_list *list, int index)
{
	if (!list || index < 0 || index >= list->count) {
		return;
	}

	clk_disable_unprepare(list->clk[index].clk);
}

void lwis_clock_disable_by_name(struct lwis_clock_list *list, char *name)
{
	int i;

	if (!list) {
		return;
	}

	for (i = 0; i < list->count; ++i) {
		if (!strcmp(list->clk[i].name, name)) {
			lwis_clock_disable_by_idx(list, i);
			return;
		}
	}

	pr_err("Clock %s not found\n", name);
}

void lwis_clock_disable_all(struct lwis_clock_list *list)
{
	int i;

	if (!list) {
		return;
	}

	for (i = 0; i < list->count; ++i) {
		lwis_clock_disable_by_idx(list, i);
	}
}

void lwis_clock_print(struct lwis_clock_list *list)
{
	int i;
	for (i = 0; i < list->count; ++i) {
		pr_info("%s: %s: rate: %d\n", __func__, list->clk[i].name, list->clk[i].rate);
	}
}
