Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d72fbdf0 authored by Russell King's avatar Russell King Committed by Russell King
Browse files

[ARM] integrator: convert to clkdev and lookup clocks by device name



People often point to the Integrator/Versatile/Realview
implementations to justify using the consumer name as the sole
selector for clocks.

Eliminate this excuse by changing the Integrator implementation, so
it provides a better example of how it should be done.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent cf30fb4a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -210,6 +210,7 @@ config ARCH_INTEGRATOR
	bool "ARM Ltd. Integrator family"
	select ARM_AMBA
	select HAVE_CLK
	select COMMON_CLKDEV
	select ICST525
	help
	  Support for ARM's Integrator platform.
+4 −76
Original line number Diff line number Diff line
@@ -10,42 +10,12 @@
 */
#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/mutex.h>

#include <asm/hardware/icst525.h>

#include "clock.h"

static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);

struct clk *clk_get(struct device *dev, const char *id)
{
	struct clk *p, *clk = ERR_PTR(-ENOENT);

	mutex_lock(&clocks_mutex);
	list_for_each_entry(p, &clocks, node) {
		if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
			clk = p;
			break;
		}
	}
	mutex_unlock(&clocks_mutex);

	return clk;
}
EXPORT_SYMBOL(clk_get);

void clk_put(struct clk *clk)
{
	module_put(clk->owner);
}
EXPORT_SYMBOL(clk_put);
#include <asm/clkdev.h>
#include <mach/clkdev.h>

int clk_enable(struct clk *clk)
{
@@ -67,7 +37,6 @@ EXPORT_SYMBOL(clk_get_rate);
long clk_round_rate(struct clk *clk, unsigned long rate)
{
	struct icst525_vco vco;

	vco = icst525_khz_to_vco(clk->params, rate / 1000);
	return icst525_khz(clk->params, vco) * 1000;
}
@@ -76,56 +45,15 @@ EXPORT_SYMBOL(clk_round_rate);
int clk_set_rate(struct clk *clk, unsigned long rate)
{
	int ret = -EIO;

	if (clk->setvco) {
		struct icst525_vco vco;

		vco = icst525_khz_to_vco(clk->params, rate / 1000);
		clk->rate = icst525_khz(clk->params, vco) * 1000;

		printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n",
			clk->name, vco.s, vco.r, vco.v);

		clk->setvco(clk, vco);
		ret = 0;
	}
	return 0;
	return ret;
}
EXPORT_SYMBOL(clk_set_rate);

/*
 * These are fixed clocks.
 */
static struct clk kmi_clk = {
	.name	= "KMIREFCLK",
	.rate	= 24000000,
};

static struct clk uart_clk = {
	.name	= "UARTCLK",
	.rate	= 14745600,
};

int clk_register(struct clk *clk)
{
	mutex_lock(&clocks_mutex);
	list_add(&clk->node, &clocks);
	mutex_unlock(&clocks_mutex);
	return 0;
}
EXPORT_SYMBOL(clk_register);

void clk_unregister(struct clk *clk)
{
	mutex_lock(&clocks_mutex);
	list_del(&clk->node);
	mutex_unlock(&clocks_mutex);
}
EXPORT_SYMBOL(clk_unregister);

static int __init clk_init(void)
{
	clk_register(&kmi_clk);
	clk_register(&uart_clk);
	return 0;
}
arch_initcall(clk_init);
+0 −25
Original line number Diff line number Diff line
/*
 *  linux/arch/arm/mach-integrator/clock.h
 *
 *  Copyright (C) 2004 ARM Limited.
 *  Written by Deep Blue Solutions Limited.
 *
 * 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.
 */
struct module;
struct icst525_params;

struct clk {
	struct list_head	node;
	unsigned long		rate;
	struct module		*owner;
	const char		*name;
	const struct icst525_params *params;
	void			*data;
	void			(*setvco)(struct clk *, struct icst525_vco vco);
};

int clk_register(struct clk *clk);
void clk_unregister(struct clk *clk);
+35 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@
#include <linux/amba/serial.h>
#include <linux/io.h>

#include <asm/clkdev.h>
#include <mach/clkdev.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/hardware/arm_timer.h>
@@ -108,10 +110,43 @@ static struct amba_device *amba_devs[] __initdata = {
	&kmi1_device,
};

/*
 * These are fixed clocks.
 */
static struct clk clk24mhz = {
	.rate	= 24000000,
};

static struct clk uartclk = {
	.rate	= 14745600,
};

static struct clk_lookup lookups[] __initdata = {
	{	/* UART0 */
		.dev_id		= "mb:16",
		.clk		= &uartclk,
	}, {	/* UART1 */
		.dev_id		= "mb:17",
		.clk		= &uartclk,
	}, {	/* KMI0 */
		.dev_id		= "mb:18",
		.clk		= &clk24mhz,
	}, {	/* KMI1 */
		.dev_id		= "mb:19",
		.clk		= &clk24mhz,
	}, {	/* MMCI - IntegratorCP */
		.dev_id		= "mb:1c",
		.clk		= &uartclk,
	}
};

static int __init integrator_init(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(lookups); i++)
		clkdev_add(&lookups[i]);

	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
		struct amba_device *d = amba_devs[i];
		amba_device_register(d, &iomem_resource);
+16 −10
Original line number Diff line number Diff line
@@ -22,13 +22,13 @@
#include <linux/amba/clcd.h>
#include <linux/io.h>

#include <asm/clkdev.h>
#include <mach/clkdev.h>
#include <asm/hardware/icst525.h>
#include <mach/lm.h>
#include <mach/impd1.h>
#include <asm/sizes.h>

#include "clock.h"

static int module_id;

module_param_named(lmid, module_id, int, 0444);
@@ -37,6 +37,7 @@ MODULE_PARM_DESC(lmid, "logic module stack position");
struct impd1_module {
	void __iomem	*base;
	struct clk	vcos[2];
	struct clk_lookup *clks[3];
};

static const struct icst525_params impd1_vco_params = {
@@ -339,9 +340,8 @@ static struct impd1_device impd1_devs[] = {
	}
};

static const char *impd1_vconames[2] = {
	"CLCDCLK",
	"AUXVCO2",
static struct clk fixed_14745600 = {
	.rate = 14745600,
};

static int impd1_probe(struct lm_device *dev)
@@ -374,14 +374,20 @@ static int impd1_probe(struct lm_device *dev)

	for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) {
		impd1->vcos[i].owner = THIS_MODULE,
		impd1->vcos[i].name = impd1_vconames[i],
		impd1->vcos[i].params = &impd1_vco_params,
		impd1->vcos[i].data = impd1,
		impd1->vcos[i].setvco = impd1_setvco;

		clk_register(&impd1->vcos[i]);
	}

	impd1->clks[0] = clkdev_alloc(&impd1->vcos[0], NULL, "lm%x:01000",
					dev->id);
	impd1->clks[1] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00100",
					dev->id);
	impd1->clks[2] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00200",
					dev->id);
	for (i = 0; i < ARRAY_SIZE(impd1->clks); i++)
		clkdev_add(impd1->clks[i]);

	for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) {
		struct impd1_device *idev = impd1_devs + i;
		struct amba_device *d;
@@ -434,8 +440,8 @@ static void impd1_remove(struct lm_device *dev)

	device_for_each_child(&dev->dev, NULL, impd1_remove_one);

	for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++)
		clk_unregister(&impd1->vcos[i]);
	for (i = 0; i < ARRAY_SIZE(impd1->clks); i++)
		clkdev_drop(impd1->clks[i]);

	lm_set_drvdata(dev, NULL);

Loading