c68ffddabc
clk_add_alias is commonly called for platform devices that are not yet registered in the device tree. Thus the clock alias is associated with NULL device name. Fix this by passing the device name instead of just device pointer. Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> Signed-off-by: Eric Miao <eric.miao@marvell.com>
106 lines
1.8 KiB
C
106 lines
1.8 KiB
C
/*
|
|
* linux/arch/arm/mach-sa1100/clock.c
|
|
*/
|
|
#include <linux/module.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/list.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/err.h>
|
|
#include <linux/string.h>
|
|
#include <linux/clk.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/delay.h>
|
|
|
|
#include <asm/clkdev.h>
|
|
#include <mach/pxa2xx-regs.h>
|
|
#include <mach/hardware.h>
|
|
|
|
#include "devices.h"
|
|
#include "generic.h"
|
|
#include "clock.h"
|
|
|
|
static DEFINE_SPINLOCK(clocks_lock);
|
|
|
|
int clk_enable(struct clk *clk)
|
|
{
|
|
unsigned long flags;
|
|
|
|
spin_lock_irqsave(&clocks_lock, flags);
|
|
if (clk->enabled++ == 0)
|
|
clk->ops->enable(clk);
|
|
spin_unlock_irqrestore(&clocks_lock, flags);
|
|
|
|
if (clk->delay)
|
|
udelay(clk->delay);
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(clk_enable);
|
|
|
|
void clk_disable(struct clk *clk)
|
|
{
|
|
unsigned long flags;
|
|
|
|
WARN_ON(clk->enabled == 0);
|
|
|
|
spin_lock_irqsave(&clocks_lock, flags);
|
|
if (--clk->enabled == 0)
|
|
clk->ops->disable(clk);
|
|
spin_unlock_irqrestore(&clocks_lock, flags);
|
|
}
|
|
EXPORT_SYMBOL(clk_disable);
|
|
|
|
unsigned long clk_get_rate(struct clk *clk)
|
|
{
|
|
unsigned long rate;
|
|
|
|
rate = clk->rate;
|
|
if (clk->ops->getrate)
|
|
rate = clk->ops->getrate(clk);
|
|
|
|
return rate;
|
|
}
|
|
EXPORT_SYMBOL(clk_get_rate);
|
|
|
|
|
|
void clk_cken_enable(struct clk *clk)
|
|
{
|
|
CKEN |= 1 << clk->cken;
|
|
}
|
|
|
|
void clk_cken_disable(struct clk *clk)
|
|
{
|
|
CKEN &= ~(1 << clk->cken);
|
|
}
|
|
|
|
const struct clkops clk_cken_ops = {
|
|
.enable = clk_cken_enable,
|
|
.disable = clk_cken_disable,
|
|
};
|
|
|
|
void clks_register(struct clk_lookup *clks, size_t num)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < num; i++)
|
|
clkdev_add(&clks[i]);
|
|
}
|
|
|
|
int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
|
|
struct device *dev)
|
|
{
|
|
struct clk *r = clk_get(dev, id);
|
|
struct clk_lookup *l;
|
|
|
|
if (!r)
|
|
return -ENODEV;
|
|
|
|
l = clkdev_alloc(r, alias, alias_dev_name);
|
|
clk_put(r);
|
|
if (!l)
|
|
return -ENODEV;
|
|
clkdev_add(l);
|
|
return 0;
|
|
}
|