/*
 * Copyright (c) 2012, 2014-2015, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of The Linux Foundation nor
 *     the names of its contributors may be used to endorse or promote
 *     products derived from this software without specific prior written
 *     permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdint.h>
#include <debug.h>
#include <reg.h>
#include <err.h>
#include <limits.h>
#include <bits.h>
#include <clock.h>
#include <string.h>

static struct clk_list msm_clk_list;

int clk_set_parent(struct clk *clk, struct clk *parent)
{
	if (!clk->ops->set_parent)
		return 0;

	return clk->ops->set_parent(clk, parent);
}

struct clk *clk_get_parent(struct clk *clk)
{
	if (!clk->ops->get_parent)
		return NULL;

	return clk->ops->get_parent(clk);
}

int clk_reset(struct clk *clk, enum clk_reset_action action)
{
	if (!clk)
		return 0;

	if (!clk->ops->reset)
		return 0;

	return clk->ops->reset(clk, action);
}

/*
 * Standard clock functions defined in include/clk.h
 */
int clk_enable(struct clk *clk)
{
	int ret = 0;
	struct clk *parent;

	if (!clk)
		return 0;

	if (clk->count == 0) {
		parent = clk_get_parent(clk);
		ret = clk_enable(parent);
		if (ret)
			goto out;

		if (clk->ops->enable)
			ret = clk->ops->enable(clk);
		if (ret) {
			clk_disable(parent);
			goto out;
		}
	}
	clk->count++;
out:
	return ret;
}

void clk_disable(struct clk *clk)
{
	struct clk *parent;

	if (!clk)
		return;

	if (clk->count == 0)
		goto out;
	if (clk->count == 1) {
		if (clk->ops->disable)
			clk->ops->disable(clk);
		parent = clk_get_parent(clk);
		clk_disable(parent);
	}
	clk->count--;
out:
	return;
}

unsigned long clk_get_rate(struct clk *clk)
{
	if (!clk->ops->get_rate)
		return 0;

	return clk->ops->get_rate(clk);
}

int clk_set_rate(struct clk *clk, unsigned long rate)
{
	if (!clk->ops->set_rate)
		return ERR_NOT_VALID;

	return clk->ops->set_rate(clk, rate);
}

void clk_init(struct clk_lookup *clist, unsigned num)
{
	if(clist && num)
	{
		msm_clk_list.clist = (struct clk_lookup *)clist;
		msm_clk_list.num = num;
	}
}

struct clk *clk_get (const char * cid)
{
	unsigned i;
	struct clk_lookup *cl= msm_clk_list.clist;
	unsigned num = msm_clk_list.num;

	if(!cl || !num)
	{
		dprintf (CRITICAL, "Alert!! clock list not defined!\n");
		return NULL;
	}
	for(i=0; i < num; i++, cl++)
	{
		if(!strcmp(cl->con_id, cid))
		{
			return cl->clk;
		}
	}

	dprintf(CRITICAL, "Alert!! Requested clock \"%s\" is not supported!\n", cid);
	return NULL;
}

int clk_get_set_enable(char *id, unsigned long rate, bool enable)
{
	int ret = NO_ERROR;
	struct clk *cp;

	/* Get clk */
	cp = clk_get(id);
	if(!cp)
	{
		dprintf(CRITICAL, "Can't find clock with id: %s\n", id);
		ret = ERR_NOT_VALID;
		goto get_set_enable_error;
	}

	/* Set rate */
	if(rate)
	{
		ret = clk_set_rate(cp, rate);
		if(ret)
		{
			dprintf(CRITICAL, "Clock set rate failed.\n");
			goto get_set_enable_error;
		}
	}

	/* Enable clock */
	if(enable)
	{
		ret = clk_enable(cp);
		if(ret)
		{
			dprintf(CRITICAL, "Clock enable failed.\n");
		}
	}

get_set_enable_error:
	return ret;
}

#ifdef DEBUG_CLOCK
struct clk_list *clk_get_list()
{
	return &msm_clk_list;
}
#endif
