Commit d895fd24 authored by Kevin Hilman's avatar Kevin Hilman

davinci: clkdev: convert to new clkdev infrastructure

Signed-off-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
parent 61fa7027
......@@ -560,6 +560,7 @@ config ARCH_DAVINCI
select HAVE_CLK
select ZONE_DMA
select HAVE_IDE
select COMMON_CLKDEV
help
Support for TI's DaVinci platform.
......
......@@ -30,114 +30,6 @@ static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
static DEFINE_SPINLOCK(clockfw_lock);
extern void davinci_psc_config(unsigned int domain, unsigned int id, char enable);
/*
* Register a mapping { dev, logical_clockname } --> clock
*
* Device drivers should always use logical clocknames, so they
* don't need to change the physical name when new silicon grows
* another instance of that module or changes the clock tree.
*/
struct clk_mapping {
struct device *dev;
const char *name;
struct clk *clock;
struct clk_mapping *next;
};
static struct clk_mapping *maplist;
int __init davinci_clk_associate(struct device *dev,
const char *logical_clockname,
const char *physical_clockname)
{
int status = -EINVAL;
struct clk *clock;
struct clk_mapping *mapping;
if (!dev)
goto done;
clock = clk_get(dev, physical_clockname);
if (IS_ERR(clock) || !try_module_get(clock->owner))
goto done;
mutex_lock(&clocks_mutex);
for (mapping = maplist; mapping; mapping = mapping->next) {
if (dev != mapping->dev)
continue;
if (strcmp(logical_clockname, mapping->name) != 0)
continue;
goto fail;
}
mapping = kzalloc(sizeof *mapping, GFP_KERNEL);
mapping->dev = dev;
mapping->name = logical_clockname;
mapping->clock = clock;
mapping->next = maplist;
maplist = mapping;
status = 0;
fail:
mutex_unlock(&clocks_mutex);
done:
WARN_ON(status < 0);
return status;
}
/*
* Returns a clock. Note that we first try to use device id on the bus
* and clock name. If this fails, we try to use clock name only.
*/
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
struct clk_mapping *mapping;
if (!id)
return ERR_PTR(-EINVAL);
mutex_lock(&clocks_mutex);
/* always prefer logical clock names */
if (dev) {
for (mapping = maplist; mapping; mapping = mapping->next) {
if (dev != mapping->dev)
continue;
if (strcmp(id, mapping->name) != 0)
continue;
clk = mapping->clock;
goto found;
}
}
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
found:
mutex_unlock(&clocks_mutex);
WARN(IS_ERR(clk), "CLK: can't find %s/%s\n",
dev ? dev_name(dev) : "nodev", id);
return clk;
}
EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
{
if (clk && !IS_ERR(clk))
module_put(clk->owner);
}
EXPORT_SYMBOL(clk_put);
static unsigned psc_domain(struct clk *clk)
{
return (clk->flags & PSC_DSP)
......@@ -372,31 +264,30 @@ static void __init clk_pll_init(struct clk *clk)
pr_debug("] --> %lu MHz output.\n", clk->rate / 1000000);
}
int __init davinci_clk_init(struct clk *clocks[])
{
struct clk *clkp;
int i = 0;
int __init davinci_clk_init(struct davinci_clk *clocks)
{
struct davinci_clk *c;
struct clk *clk;
while ((clkp = clocks[i++])) {
if (clkp->pll_data)
clk_pll_init(clkp);
for (c = clocks; c->lk.clk; c++) {
clk = c->lk.clk;
/* Calculate rates for PLL-derived clocks */
else if (clkp->flags & CLK_PLL)
clk_sysclk_recalc(clkp);
if (clk->pll_data)
clk_pll_init(clk);
if (clkp->lpsc)
clkp->flags |= CLK_PSC;
/* Calculate rates for PLL-derived clocks */
else if (clk->flags & CLK_PLL)
clk_sysclk_recalc(clk);
clk_register(clkp);
if (clk->lpsc)
clk->flags |= CLK_PSC;
/* FIXME: remove equivalent special-cased code from
* davinci_psc_init() once cpus list *all* clocks.
*/
clkdev_add(&c->lk);
clk_register(clk);
/* Turn on clocks that Linux doesn't otherwise manage */
if (clkp->flags & ALWAYS_ENABLED)
clk_enable(clkp);
if (clk->flags & ALWAYS_ENABLED)
clk_enable(clk);
}
return 0;
......
......@@ -12,6 +12,7 @@
#define __ARCH_ARM_DAVINCI_CLOCK_H
#include <linux/list.h>
#include <asm/clkdev.h>
#define DAVINCI_PLL1_BASE 0x01c40800
#define DAVINCI_PLL2_BASE 0x01c40c00
......@@ -76,7 +77,21 @@ struct clk {
#define CLK_PLL BIT(4) /* PLL-derived clock */
#define PRE_PLL BIT(5) /* source is before PLL mult/div */
struct davinci_clk {
struct clk_lookup lk;
};
#define CLK(dev, con, ck) \
{ \
.lk = { \
.dev_id = dev, \
.con_id = con, \
.clk = ck, \
}, \
}
int davinci_clk_associate(struct device *dev, const char *logical_clockname,
const char *physical_clockname);
int davinci_clk_init(struct davinci_clk *clocks);
#endif
......@@ -152,7 +152,6 @@ static struct platform_device davinci_mmcsd1_device = {
void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
{
struct platform_device *pdev = NULL;
const char *clockname;
if (WARN_ON(cpu_is_davinci_dm646x()))
return;
......@@ -179,7 +178,6 @@ void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
davinci_cfg_reg(DM355_SD1_DATA3);
pdev = &davinci_mmcsd1_device;
clockname = "mmcsd1";
break;
case 0:
if (cpu_is_davinci_dm355()) {
......@@ -206,7 +204,6 @@ void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
}
pdev = &davinci_mmcsd0_device;
clockname = cpu_is_davinci_dm355() ? "mmcsd0" : "mmcsd";
break;
}
......@@ -214,7 +211,6 @@ void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
return;
pdev->dev.platform_data = config;
davinci_clk_associate(&pdev->dev, "mmc", clockname);
platform_device_register(pdev);
}
......
......@@ -205,7 +205,7 @@ static struct clk uart2_clk = {
};
static struct clk i2c_clk = {
.name = "I2CCLK",
.name = "i2c",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_I2C,
};
......@@ -304,6 +304,7 @@ static struct clk timer2_clk = {
.name = "timer2",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_TIMER2,
.usecount = 1, /* REVISIT: why cant' this be disabled? */
};
static struct clk timer3_clk = {
......@@ -324,50 +325,50 @@ static struct clk usb_clk = {
.lpsc = DAVINCI_LPSC_USB,
};
static struct clk *dm355_clks[] __initdata = {
&ref_clk,
&pll1_clk,
&pll1_sysclk1,
&pll1_sysclk2,
&pll1_sysclk3,
&pll1_sysclk4,
&pll1_aux_clk,
&pll1_sysclkbp,
&vpss_dac_clk,
&vpss_master_clk,
&vpss_slave_clk,
&clkout1_clk,
&clkout2_clk,
&pll2_clk,
&pll2_sysclk1,
&pll2_sysclkbp,
&clkout3_clk,
&arm_clk,
&mjcp_clk,
&uart0_clk,
&uart1_clk,
&uart2_clk,
&i2c_clk,
&asp0_clk,
&asp1_clk,
&mmcsd0_clk,
&mmcsd1_clk,
&spi0_clk,
&spi1_clk,
&spi2_clk,
&gpio_clk,
&aemif_clk,
&pwm0_clk,
&pwm1_clk,
&pwm2_clk,
&pwm3_clk,
&timer0_clk,
&timer1_clk,
&timer2_clk,
&timer3_clk,
&rto_clk,
&usb_clk,
NULL,
static struct davinci_clk dm355_clks[] = {
CLK(NULL, "ref", &ref_clk),
CLK(NULL, "pll1", &pll1_clk),
CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
CLK(NULL, "pll1_aux", &pll1_aux_clk),
CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
CLK(NULL, "vpss_dac", &vpss_dac_clk),
CLK(NULL, "vpss_master", &vpss_master_clk),
CLK(NULL, "vpss_slave", &vpss_slave_clk),
CLK(NULL, "clkout1", &clkout1_clk),
CLK(NULL, "clkout2", &clkout2_clk),
CLK(NULL, "pll2", &pll2_clk),
CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
CLK(NULL, "clkout3", &clkout3_clk),
CLK(NULL, "arm", &arm_clk),
CLK(NULL, "mjcp", &mjcp_clk),
CLK(NULL, "uart0", &uart0_clk),
CLK(NULL, "uart1", &uart1_clk),
CLK(NULL, "uart2", &uart2_clk),
CLK("i2c_davinci.1", NULL, &i2c_clk),
CLK("soc-audio.0", NULL, &asp0_clk),
CLK("soc-audio.1", NULL, &asp1_clk),
CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
CLK(NULL, "spi0", &spi0_clk),
CLK(NULL, "spi1", &spi1_clk),
CLK(NULL, "spi2", &spi2_clk),
CLK(NULL, "gpio", &gpio_clk),
CLK(NULL, "aemif", &aemif_clk),
CLK(NULL, "pwm0", &pwm0_clk),
CLK(NULL, "pwm1", &pwm1_clk),
CLK(NULL, "pwm2", &pwm2_clk),
CLK(NULL, "pwm3", &pwm3_clk),
CLK(NULL, "timer0", &timer0_clk),
CLK(NULL, "timer1", &timer1_clk),
CLK("watchdog", NULL, &timer2_clk),
CLK(NULL, "timer3", &timer3_clk),
CLK(NULL, "rto", &rto_clk),
CLK(NULL, "usb", &usb_clk),
CLK(NULL, NULL, NULL),
};
/*----------------------------------------------------------------------*/
......@@ -418,7 +419,6 @@ void __init dm355_init_spi0(unsigned chipselect_mask,
spi_register_board_info(info, len);
davinci_clk_associate(&dm355_spi0_device.dev, "spi", "spi0");
platform_device_register(&dm355_spi0_device);
}
......
......@@ -177,13 +177,13 @@ static struct clk emac_clk = {
};
static struct clk i2c_clk = {
.name = "I2CCLK",
.name = "i2c",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_I2C,
};
static struct clk ide_clk = {
.name = "IDECLK",
.name = "ide",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_ATA,
};
......@@ -264,46 +264,48 @@ static struct clk timer2_clk = {
.name = "timer2",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_TIMER2,
};
static struct clk *dm644x_clks[] __initdata = {
&ref_clk,
&pll1_clk,
&pll1_sysclk1,
&pll1_sysclk2,
&pll1_sysclk3,
&pll1_sysclk5,
&pll1_aux_clk,
&pll1_sysclkbp,
&pll2_clk,
&pll2_sysclk1,
&pll2_sysclk2,
&pll2_sysclkbp,
&dsp_clk,
&arm_clk,
&vicp_clk,
&vpss_master_clk,
&vpss_slave_clk,
&uart0_clk,
&uart1_clk,
&uart2_clk,
&emac_clk,
&i2c_clk,
&ide_clk,
&asp_clk,
&mmcsd_clk,
&spi_clk,
&gpio_clk,
&usb_clk,
&vlynq_clk,
&aemif_clk,
&pwm0_clk,
&pwm1_clk,
&pwm2_clk,
&timer0_clk,
&timer1_clk,
&timer2_clk,
NULL,
.usecount = 1, /* REVISIT: why cant' this be disabled? */
};
struct davinci_clk dm644x_clks[] = {
CLK(NULL, "ref", &ref_clk),
CLK(NULL, "pll1", &pll1_clk),
CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
CLK(NULL, "pll1_aux", &pll1_aux_clk),
CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
CLK(NULL, "pll2", &pll2_clk),
CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
CLK(NULL, "dsp", &dsp_clk),
CLK(NULL, "arm", &arm_clk),
CLK(NULL, "vicp", &vicp_clk),
CLK(NULL, "vpss_master", &vpss_master_clk),
CLK(NULL, "vpss_slave", &vpss_slave_clk),
CLK(NULL, "arm", &arm_clk),
CLK(NULL, "uart0", &uart0_clk),
CLK(NULL, "uart1", &uart1_clk),
CLK(NULL, "uart2", &uart2_clk),
CLK("davinci_emac.1", NULL, &emac_clk),
CLK("i2c_davinci.1", NULL, &i2c_clk),
CLK("palm_bk3710", NULL, &ide_clk),
CLK("soc-audio.0", NULL, &asp_clk),
CLK("davinci_mmc.0", NULL, &mmcsd_clk),
CLK(NULL, "spi", &spi_clk),
CLK(NULL, "gpio", &gpio_clk),
CLK(NULL, "usb", &usb_clk),
CLK(NULL, "vlynq", &vlynq_clk),
CLK(NULL, "aemif", &aemif_clk),
CLK(NULL, "pwm0", &pwm0_clk),
CLK(NULL, "pwm1", &pwm1_clk),
CLK(NULL, "pwm2", &pwm2_clk),
CLK(NULL, "timer0", &timer0_clk),
CLK(NULL, "timer1", &timer1_clk),
CLK("watchdog", NULL, &timer2_clk),
CLK(NULL, NULL, NULL),
};
/*
......
......@@ -220,36 +220,43 @@ static struct clk timer1_clk = {
.lpsc = DM646X_LPSC_TIMER1,
};
static struct clk *dm646x_clks[] __initdata = {
&ref_clk,
&aux_clkin,
&pll1_clk,
&pll1_sysclk1,
&pll1_sysclk2,
&pll1_sysclk3,
&pll1_sysclk4,
&pll1_sysclk5,
&pll1_sysclk6,
&pll1_sysclk8,
&pll1_sysclk9,
&pll1_sysclkbp,
&pll1_aux_clk,
&pll2_clk,
&pll2_sysclk1,
&dsp_clk,
&arm_clk,
&uart0_clk,
&uart1_clk,
&uart2_clk,
&i2c_clk,
&gpio_clk,
&aemif_clk,
&emac_clk,
&pwm0_clk,
&pwm1_clk,
&timer0_clk,
&timer1_clk,
NULL,
static struct clk timer2_clk = {
.name = "timer2",
.parent = &pll1_sysclk3,
.flags = ALWAYS_ENABLED, /* no LPSC, always enabled; c.f. spruep9a */
};
struct davinci_clk dm646x_clks[] = {
CLK(NULL, "ref", &ref_clk),
CLK(NULL, "aux", &aux_clkin),
CLK(NULL, "pll1", &pll1_clk),
CLK(NULL, "pll1_sysclk", &pll1_sysclk1),
CLK(NULL, "pll1_sysclk", &pll1_sysclk2),
CLK(NULL, "pll1_sysclk", &pll1_sysclk3),
CLK(NULL, "pll1_sysclk", &pll1_sysclk4),
CLK(NULL, "pll1_sysclk", &pll1_sysclk5),
CLK(NULL, "pll1_sysclk", &pll1_sysclk6),
CLK(NULL, "pll1_sysclk", &pll1_sysclk8),
CLK(NULL, "pll1_sysclk", &pll1_sysclk9),
CLK(NULL, "pll1_sysclk", &pll1_sysclkbp),
CLK(NULL, "pll1_aux", &pll1_aux_clk),
CLK(NULL, "pll2", &pll2_clk),
CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
CLK(NULL, "dsp", &dsp_clk),
CLK(NULL, "arm", &arm_clk),
CLK(NULL, "uart0", &uart0_clk),
CLK(NULL, "uart1", &uart1_clk),
CLK(NULL, "uart2", &uart2_clk),
CLK("i2c_davinci.1", NULL, &i2c_clk),
CLK(NULL, "gpio", &gpio_clk),
CLK(NULL, "aemif", &aemif_clk),
CLK("davinci_emac.1", NULL, &emac_clk),
CLK(NULL, "pwm0", &pwm0_clk),
CLK(NULL, "pwm1", &pwm1_clk),
CLK(NULL, "timer0", &timer0_clk),
CLK(NULL, "timer1", &timer1_clk),
CLK("watchdog", NULL, &timer2_clk),
CLK(NULL, NULL, NULL),
};
/*
......
#ifndef __MACH_CLKDEV_H
#define __MACH_CLKDEV_H
static inline int __clk_get(struct clk *clk)
{
return 1;
}
static inline void __clk_put(struct clk *clk)
{
}
#endif
......@@ -17,6 +17,5 @@ struct clk;
extern int clk_register(struct clk *clk);
extern void clk_unregister(struct clk *clk);
extern int davinci_clk_init(struct clk *clocks[]);
#endif
......@@ -18,6 +18,7 @@
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/device.h>
#include <mach/hardware.h>
#include <asm/system.h>
......@@ -309,7 +310,7 @@ static struct clock_event_device clockevent_davinci = {
static void __init davinci_timer_init(void)
{
struct clk *timer_clk, *wd_clk;
struct clk *timer_clk;
static char err[] __initdata = KERN_ERR
"%s: can't register clocksource!\n";
......@@ -321,12 +322,6 @@ static void __init davinci_timer_init(void)
BUG_ON(IS_ERR(timer_clk));
clk_enable(timer_clk);
if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) {
wd_clk = clk_get(NULL, "timer2");
BUG_ON(IS_ERR(wd_clk));
clk_enable(wd_clk);
}
davinci_clock_tick_rate = clk_get_rate(timer_clk);
clk_put(timer_clk);
......@@ -358,6 +353,14 @@ struct sys_timer davinci_timer = {
void davinci_watchdog_reset(void) {
u32 tgcr, wdtcr;
void __iomem *base = IO_ADDRESS(DAVINCI_WDOG_BASE);
struct device dev;
struct clk *wd_clk;
dev_set_name(&dev, "watchdog");
wd_clk = clk_get(&dev, NULL);
if (WARN_ON(IS_ERR(wd_clk)))
return;
clk_enable(wd_clk);
/* disable, internal clock source */
__raw_writel(0, base + TCR);
......
......@@ -554,7 +554,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
dev->irq = irq->start;
platform_set_drvdata(pdev, dev);
dev->clk = clk_get(&pdev->dev, "I2CCLK");
dev->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(dev->clk)) {
r = -ENODEV;
goto err_free_mem;
......
......@@ -351,7 +351,7 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
int i, rc;
hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
clk = clk_get(&pdev->dev, "IDECLK");
clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(clk))
return -ENODEV;
......
......@@ -1133,7 +1133,7 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
goto out;
ret = -ENXIO;
host->clk = clk_get(&pdev->dev, "mmc");
host->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(host->clk)) {
ret = PTR_ERR(host->clk);
goto out;
......
......@@ -2605,7 +2605,7 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
unsigned long size;
/* obtain emac clock from kernel */
emac_clk = clk_get(&pdev->dev, "emac");
emac_clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(emac_clk)) {
printk(KERN_ERR "DaVinci EMAC: Failed to get EMAC clock\n");
return -EBUSY;
......
......@@ -205,7 +205,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
struct resource *res;
struct device *dev = &pdev->dev;
wdt_clk = clk_get(dev, "timer2");
wdt_clk = clk_get(dev, NULL);
if (WARN_ON(!wdt_clk))
return -ENODEV;
clk_enable(wdt_clk);
......
......@@ -446,10 +446,6 @@ static int davinci_i2s_probe(struct platform_device *pdev,
struct resource *mem, *ioarea;
struct evm_snd_platform_data *pdata;
int ret;
static const char *clocks[] = { "asp0", "asp1", };
if (pdev->id < 0 || pdev->id > ARRAY_SIZE(clocks))
return -EINVAL;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
......@@ -472,7 +468,7 @@ static int davinci_i2s_probe(struct platform_device *pdev,
cpu_dai->private_data = dev;
dev->clk = clk_get(&pdev->dev, clocks[pdev->id]);
dev->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(dev->clk)) {
ret = -ENODEV;
goto err_free_mem;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment