/*
 * Copyright 2012 Freescale Semiconductor, Inc.
 * Copyright 2012 Linaro Ltd.
 *
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */

#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/err.h>
#include "clk.h"

static int clk_busy_wait(void __iomem *reg, u8 shift)
{
	unsigned long timeout = jiffies + msecs_to_jiffies(10);

	while (readl_relaxed(reg) & (1 << shift))
		if (time_after(jiffies, timeout))
			return -ETIMEDOUT;

	return 0;
}

struct clk_busy_divider {
	struct clk_divider div;
	const struct clk_ops *div_ops;
	void __iomem *reg;
	u8 shift;
};

static inline struct clk_busy_divider *to_clk_busy_divider(struct clk_hw *hw)
{
	struct clk_divider *div = to_clk_divider(hw);

	return container_of(div, struct clk_busy_divider, div);
}

static unsigned long clk_busy_divider_recalc_rate(struct clk_hw *hw,
						  unsigned long parent_rate)
{
	struct clk_busy_divider *busy = to_clk_busy_divider(hw);

	return busy->div_ops->recalc_rate(&busy->div.hw, parent_rate);
}

static long clk_busy_divider_round_rate(struct clk_hw *hw, unsigned long rate,
					unsigned long *prate)
{
	struct clk_busy_divider *busy = to_clk_busy_divider(hw);

	return busy->div_ops->round_rate(&busy->div.hw, rate, prate);
}

static int clk_busy_divider_set_rate(struct clk_hw *hw, unsigned long rate,
		unsigned long parent_rate)
{
	struct clk_busy_divider *busy = to_clk_busy_divider(hw);
	int ret;

	ret = busy->div_ops->set_rate(&busy->div.hw, rate, parent_rate);
	if (!ret)
		ret = clk_busy_wait(busy->reg, busy->shift);

	return ret;
}

static struct clk_ops clk_busy_divider_ops = {
	.recalc_rate = clk_busy_divider_recalc_rate,
	.round_rate = clk_busy_divider_round_rate,
	.set_rate = clk_busy_divider_set_rate,
};

struct clk *imx_clk_busy_divider(const char *name, const char *parent_name,
				 void __iomem *reg, u8 shift, u8 width,
				 void __iomem *busy_reg, u8 busy_shift)
{
	struct clk_busy_divider *busy;
	struct clk *clk;
	struct clk_init_data init;

	busy = kzalloc(sizeof(*busy), GFP_KERNEL);
	if (!busy)
		return ERR_PTR(-ENOMEM);

	busy->reg = busy_reg;
	busy->shift = busy_shift;

	busy->div.reg = reg;
	busy->div.shift = shift;
	busy->div.width = width;
	busy->div.lock = &imx_ccm_lock;
	busy->div_ops = &clk_divider_ops;

	init.name = name;
	init.ops = &clk_busy_divider_ops;
	init.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE;
	init.parent_names = &parent_name;
	init.num_parents = 1;

	busy->div.hw.init = &init;

	clk = clk_register(NULL, &busy->div.hw);
	if (IS_ERR(clk))
		kfree(busy);

	return clk;
}

struct clk_busy_mux {
	struct clk_mux mux;
	const struct clk_ops *mux_ops;
	void __iomem *reg;
	u8 shift;
};

static inline struct clk_busy_mux *to_clk_busy_mux(struct clk_hw *hw)
{
	struct clk_mux *mux = to_clk_mux(hw);

	return container_of(mux, struct clk_busy_mux, mux);
}

static u8 clk_busy_mux_get_parent(struct clk_hw *hw)
{
	struct clk_busy_mux *busy = to_clk_busy_mux(hw);

	return busy->mux_ops->get_parent(&busy->mux.hw);
}

static int clk_busy_mux_set_parent(struct clk_hw *hw, u8 index)
{
	struct clk_busy_mux *busy = to_clk_busy_mux(hw);
	int ret;

	ret = busy->mux_ops->set_parent(&busy->mux.hw, index);
	if (!ret)
		ret = clk_busy_wait(busy->reg, busy->shift);

	return ret;
}

static struct clk_ops clk_busy_mux_ops = {
	.get_parent = clk_busy_mux_get_parent,
	.set_parent = clk_busy_mux_set_parent,
};

struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
			     u8 width, void __iomem *busy_reg, u8 busy_shift,
			     const char * const *parent_names, int num_parents)
{
	struct clk_busy_mux *busy;
	struct clk *clk;
	struct clk_init_data init;

	busy = kzalloc(sizeof(*busy), GFP_KERNEL);
	if (!busy)
		return ERR_PTR(-ENOMEM);

	busy->reg = busy_reg;
	busy->shift = busy_shift;

	busy->mux.reg = reg;
	busy->mux.shift = shift;
	busy->mux.mask = BIT(width) - 1;
	busy->mux.lock = &imx_ccm_lock;
	busy->mux_ops = &clk_mux_ops;

	init.name = name;
	init.ops = &clk_busy_mux_ops;
	init.flags = 0;
	init.parent_names = parent_names;
	init.num_parents = num_parents;

	busy->mux.hw.init = &init;

	clk = clk_register(NULL, &busy->mux.hw);
	if (IS_ERR(clk))
		kfree(busy);

	return clk;
}
