/*
 * arch/arm/mach-ns9xxx/clock.c
 *
 * Copyright (C) 2007 by Digi International Inc.
 * All rights reserved.
 *
 * 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.
 */
#include <linux/err.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/clk.h>
#include <linux/string.h>
#include <linux/platform_device.h>

#include <asm/semaphore.h>
#include "clock.h"

static LIST_HEAD(clocks);
static DEFINE_SPINLOCK(clk_lock);

struct clk *clk_get(struct device *dev, const char *id)
{
	struct clk *p, *ret = NULL, *retgen = NULL;
	unsigned long flags;
	int idno;

	if (dev == NULL || dev->bus != &platform_bus_type)
		idno = -1;
	else
		idno = to_platform_device(dev)->id;

	spin_lock_irqsave(&clk_lock, flags);
	list_for_each_entry(p, &clocks, node) {
		if (strcmp(id, p->name) == 0) {
			if (p->id == idno) {
				if (!try_module_get(p->owner))
					continue;
				ret = p;
				break;
			} else if (p->id == -1)
				/* remember match with id == -1 in case there is
				 * no clock for idno */
				retgen = p;
		}
	}

	if (!ret && retgen && try_module_get(retgen->owner))
		ret = retgen;

	if (ret)
		++ret->refcount;

	spin_unlock_irqrestore(&clk_lock, flags);

	return ret ? ret : ERR_PTR(-ENOENT);
}
EXPORT_SYMBOL(clk_get);

void clk_put(struct clk *clk)
{
	module_put(clk->owner);
	--clk->refcount;
}
EXPORT_SYMBOL(clk_put);

static int clk_enable_unlocked(struct clk *clk)
{
	int ret = 0;
	if (clk->parent) {
		ret = clk_enable_unlocked(clk->parent);
		if (ret)
			return ret;
	}

	if (clk->usage++ == 0 && clk->endisable)
		ret = clk->endisable(clk, 1);

	return ret;
}

int clk_enable(struct clk *clk)
{
	int ret;
	unsigned long flags;

	spin_lock_irqsave(&clk_lock, flags);

	ret = clk_enable_unlocked(clk);

	spin_unlock_irqrestore(&clk_lock, flags);

	return ret;
}
EXPORT_SYMBOL(clk_enable);

static void clk_disable_unlocked(struct clk *clk)
{
	if (--clk->usage == 0 && clk->endisable)
		clk->endisable(clk, 0);

	if (clk->parent)
		clk_disable_unlocked(clk->parent);
}

void clk_disable(struct clk *clk)
{
	unsigned long flags;

	spin_lock_irqsave(&clk_lock, flags);

	clk_disable_unlocked(clk);

	spin_unlock_irqrestore(&clk_lock, flags);
}
EXPORT_SYMBOL(clk_disable);

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

	if (clk->rate)
		return clk->rate;

	if (clk->parent)
		return clk_get_rate(clk->parent);

	return 0;
}
EXPORT_SYMBOL(clk_get_rate);

int clk_register(struct clk *clk)
{
	unsigned long flags;

	spin_lock_irqsave(&clk_lock, flags);

	list_add(&clk->node, &clocks);

	if (clk->parent)
		++clk->parent->refcount;

	spin_unlock_irqrestore(&clk_lock, flags);

	return 0;
}

int clk_unregister(struct clk *clk)
{
	int ret = 0;
	unsigned long flags;

	spin_lock_irqsave(&clk_lock, flags);

	if (clk->usage || clk->refcount)
		ret = -EBUSY;
	else
		list_del(&clk->node);

	if (clk->parent)
		--clk->parent->refcount;

	spin_unlock_irqrestore(&clk_lock, flags);

	return ret;
}

#if defined CONFIG_DEBUG_FS

#include <linux/debugfs.h>
#include <linux/seq_file.h>

static int clk_debugfs_show(struct seq_file *s, void *null)
{
	unsigned long flags;
	struct clk *p;

	spin_lock_irqsave(&clk_lock, flags);

	list_for_each_entry(p, &clocks, node)
		seq_printf(s, "%s.%d: usage=%lu refcount=%lu rate=%lu\n",
				p->name, p->id, p->usage, p->refcount,
				p->usage ? clk_get_rate(p) : 0);

	spin_unlock_irqrestore(&clk_lock, flags);

	return 0;
}

static int clk_debugfs_open(struct inode *inode, struct file *file)
{
	return single_open(file, clk_debugfs_show, NULL);
}

static struct file_operations clk_debugfs_operations = {
	.open = clk_debugfs_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

static int __init clk_debugfs_init(void)
{
	struct dentry *dentry;

	dentry = debugfs_create_file("clk", S_IFREG | S_IRUGO, NULL, NULL,
			&clk_debugfs_operations);
	return IS_ERR(dentry) ? PTR_ERR(dentry) : 0;
}
subsys_initcall(clk_debugfs_init);

#endif /* if defined CONFIG_DEBUG_FS */
