From: David Brownell <[EMAIL PROTECTED]>
Update the DaVinci clock framework to handle clk_get(dev, name)
better, adding davinci_clk_associate() method letting logical
names be associated with devices. This lets drivers move away
from using "physical" clock names, which are changed in new chip
versions and by adding more controller instances.
Plus a few unrelated fixes to the DM355 clock tree: it doesn't
have IDE or EMAC, or their clocks, so don't list them. But it
does have two more SPI controllers ... list them instead.
Signed-off-by: David Brownell <[EMAIL PROTECTED]>
---
arch/arm/mach-davinci/clock.c | 93 +++++++++++++++++++++++++----
arch/arm/mach-davinci/clock.h | 3
arch/arm/mach-davinci/include/mach/psc.h | 4 +
3 files changed, 89 insertions(+), 11 deletions(-)
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
+#include <linux/clk.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
@@ -43,6 +44,63 @@ static unsigned int fixedrate = 27000000
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.
*/
@@ -50,6 +108,7 @@ struct clk *clk_get(struct device *dev,
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
int idno;
+ struct clk_mapping *mapping;
if (dev == NULL || dev->bus != &platform_bus_type)
idno = -1;
@@ -58,6 +117,18 @@ struct clk *clk_get(struct device *dev,
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 (p->id == idno &&
strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
@@ -65,7 +136,7 @@ struct clk *clk_get(struct device *dev,
goto found;
}
}
-
+
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
@@ -323,21 +394,11 @@ static struct clk davinci_dm355_clks[] =
.usecount = 1,
},
{
- .name = "EMACCLK",
- .rate = &commonrate,
- .lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
- },
- {
.name = "I2CCLK",
.rate = &fixedrate,
.lpsc = DAVINCI_LPSC_I2C,
},
{
- .name = "IDECLK",
- .rate = &commonrate,
- .lpsc = DAVINCI_LPSC_ATA,
- },
- {
.name = "McBSPCLK0",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_McBSP,
@@ -363,6 +424,16 @@ static struct clk davinci_dm355_clks[] =
.lpsc = DAVINCI_LPSC_SPI,
},
{
+ .name = "SPICLK1",
+ .rate = &commonrate,
+ .lpsc = DM355_LPSC_SPI1,
+ },
+ {
+ .name = "SPICLK2",
+ .rate = &commonrate,
+ .lpsc = DM355_LPSC_SPI2,
+ },
+ {
.name = "gpio",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_GPIO,
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -36,4 +36,7 @@ struct clk {
#define DM646X_CLOCK_TICK_RATE 148500000
#define DM355_CLOCK_TICK_RATE 24000000
+int davinci_clk_associate(struct device *dev, const char *logical_clockname,
+ const char *physical_clockname);
+
#endif
--- a/arch/arm/mach-davinci/include/mach/psc.h
+++ b/arch/arm/mach-davinci/include/mach/psc.h
@@ -73,9 +73,13 @@
#define DAVINCI_LPSC_GEM 39
#define DAVINCI_LPSC_IMCOP 40
+#define DM355_LPSC_TIMER3 5
+#define DM355_LPSC_SPI1 6
#define DM355_LPSC_MMC_SD1 7
#define DM355_LPSC_McBSP1 8
#define DM355_LPSC_PWM3 10
+#define DM355_LPSC_SPI2 11
+#define DM355_LPSC_RTO 12
/*
* LPSC Assignments
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source