aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/mach-msm/Makefile1
-rw-r--r--arch/arm/mach-msm/clock-debug.c123
-rw-r--r--arch/arm/mach-msm/clock-pcom.c118
-rw-r--r--arch/arm/mach-msm/clock-pcom.h30
-rw-r--r--arch/arm/mach-msm/clock.c146
-rw-r--r--arch/arm/mach-msm/clock.h46
-rw-r--r--arch/arm/mach-msm/devices-msm7x00.c2
-rw-r--r--arch/arm/mach-msm/devices-msm7x30.c2
-rw-r--r--arch/arm/mach-msm/devices-qsd8x50.c2
10 files changed, 108 insertions, 364 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d423d58f938d..af88c834a7c2 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -622,8 +622,8 @@ config ARCH_MSM
622 bool "Qualcomm MSM" 622 bool "Qualcomm MSM"
623 select ARCH_REQUIRE_GPIOLIB 623 select ARCH_REQUIRE_GPIOLIB
624 select CLKDEV_LOOKUP 624 select CLKDEV_LOOKUP
625 select COMMON_CLK
625 select GENERIC_CLOCKEVENTS 626 select GENERIC_CLOCKEVENTS
626 select HAVE_CLK
627 help 627 help
628 Support for Qualcomm MSM/QSD based systems. This runs on the 628 Support for Qualcomm MSM/QSD based systems. This runs on the
629 apps processor of the MSM/QSD and depends on a shared memory 629 apps processor of the MSM/QSD and depends on a shared memory
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 3dbae7406e0f..700d77b7eb1a 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -1,6 +1,5 @@
1obj-y += io.o timer.o 1obj-y += io.o timer.o
2obj-y += clock.o 2obj-y += clock.o
3obj-$(CONFIG_DEBUG_FS) += clock-debug.o
4 3
5obj-$(CONFIG_MSM_VIC) += irq-vic.o 4obj-$(CONFIG_MSM_VIC) += irq-vic.o
6obj-$(CONFIG_MSM_IOMMU) += devices-iommu.o 5obj-$(CONFIG_MSM_IOMMU) += devices-iommu.o
diff --git a/arch/arm/mach-msm/clock-debug.c b/arch/arm/mach-msm/clock-debug.c
deleted file mode 100644
index c4b34d7d26fb..000000000000
--- a/arch/arm/mach-msm/clock-debug.c
+++ /dev/null
@@ -1,123 +0,0 @@
1/*
2 * Copyright (C) 2007 Google, Inc.
3 * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/ctype.h>
19#include <linux/debugfs.h>
20#include <linux/clk.h>
21#include "clock.h"
22
23static int clock_debug_rate_set(void *data, u64 val)
24{
25 struct clk *clock = data;
26 int ret;
27
28 ret = clk_set_rate(clock, val);
29 if (ret != 0)
30 printk(KERN_ERR "clk_set%s_rate failed (%d)\n",
31 (clock->flags & CLK_MIN) ? "_min" : "", ret);
32 return ret;
33}
34
35static int clock_debug_rate_get(void *data, u64 *val)
36{
37 struct clk *clock = data;
38 *val = clk_get_rate(clock);
39 return 0;
40}
41
42DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_debug_rate_get,
43 clock_debug_rate_set, "%llu\n");
44
45static int clock_debug_enable_set(void *data, u64 val)
46{
47 struct clk *clock = data;
48 int rc = 0;
49
50 if (val)
51 rc = clock->ops->enable(clock->id);
52 else
53 clock->ops->disable(clock->id);
54
55 return rc;
56}
57
58static int clock_debug_enable_get(void *data, u64 *val)
59{
60 struct clk *clock = data;
61
62 *val = clock->ops->is_enabled(clock->id);
63
64 return 0;
65}
66
67DEFINE_SIMPLE_ATTRIBUTE(clock_enable_fops, clock_debug_enable_get,
68 clock_debug_enable_set, "%llu\n");
69
70static int clock_debug_local_get(void *data, u64 *val)
71{
72 struct clk *clock = data;
73
74 *val = clock->ops->is_local(clock->id);
75
76 return 0;
77}
78
79DEFINE_SIMPLE_ATTRIBUTE(clock_local_fops, clock_debug_local_get,
80 NULL, "%llu\n");
81
82static struct dentry *debugfs_base;
83
84int __init clock_debug_init(void)
85{
86 debugfs_base = debugfs_create_dir("clk", NULL);
87 if (!debugfs_base)
88 return -ENOMEM;
89 return 0;
90}
91
92int __init clock_debug_add(struct clk *clock)
93{
94 char temp[50], *ptr;
95 struct dentry *clk_dir;
96
97 if (!debugfs_base)
98 return -ENOMEM;
99
100 strncpy(temp, clock->dbg_name, ARRAY_SIZE(temp)-1);
101 for (ptr = temp; *ptr; ptr++)
102 *ptr = tolower(*ptr);
103
104 clk_dir = debugfs_create_dir(temp, debugfs_base);
105 if (!clk_dir)
106 return -ENOMEM;
107
108 if (!debugfs_create_file("rate", S_IRUGO | S_IWUSR, clk_dir,
109 clock, &clock_rate_fops))
110 goto error;
111
112 if (!debugfs_create_file("enable", S_IRUGO | S_IWUSR, clk_dir,
113 clock, &clock_enable_fops))
114 goto error;
115
116 if (!debugfs_create_file("is_local", S_IRUGO, clk_dir, clock,
117 &clock_local_fops))
118 goto error;
119 return 0;
120error:
121 debugfs_remove_recursive(clk_dir);
122 return -ENOMEM;
123}
diff --git a/arch/arm/mach-msm/clock-pcom.c b/arch/arm/mach-msm/clock-pcom.c
index 632173186a69..9a80449518e6 100644
--- a/arch/arm/mach-msm/clock-pcom.c
+++ b/arch/arm/mach-msm/clock-pcom.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2007 Google, Inc. 2 * Copyright (C) 2007 Google, Inc.
3 * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved. 3 * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
4 * 4 *
5 * This software is licensed under the terms of the GNU General Public 5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and 6 * License version 2, as published by the Free Software Foundation, and
@@ -13,9 +13,12 @@
13 * 13 *
14 */ 14 */
15 15
16#include <linux/kernel.h>
16#include <linux/err.h> 17#include <linux/err.h>
17#include <linux/platform_device.h> 18#include <linux/platform_device.h>
18#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/clk-provider.h>
21#include <linux/clkdev.h>
19 22
20#include <mach/clk.h> 23#include <mach/clk.h>
21 24
@@ -23,11 +26,20 @@
23#include "clock.h" 26#include "clock.h"
24#include "clock-pcom.h" 27#include "clock-pcom.h"
25 28
26/* 29struct clk_pcom {
27 * glue for the proc_comm interface 30 unsigned id;
28 */ 31 unsigned long flags;
29static int pc_clk_enable(unsigned id) 32 struct msm_clk msm_clk;
33};
34
35static inline struct clk_pcom *to_clk_pcom(struct clk_hw *hw)
30{ 36{
37 return container_of(to_msm_clk(hw), struct clk_pcom, msm_clk);
38}
39
40static int pc_clk_enable(struct clk_hw *hw)
41{
42 unsigned id = to_clk_pcom(hw)->id;
31 int rc = msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL); 43 int rc = msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
32 if (rc < 0) 44 if (rc < 0)
33 return rc; 45 return rc;
@@ -35,14 +47,16 @@ static int pc_clk_enable(unsigned id)
35 return (int)id < 0 ? -EINVAL : 0; 47 return (int)id < 0 ? -EINVAL : 0;
36} 48}
37 49
38static void pc_clk_disable(unsigned id) 50static void pc_clk_disable(struct clk_hw *hw)
39{ 51{
52 unsigned id = to_clk_pcom(hw)->id;
40 msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL); 53 msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
41} 54}
42 55
43int pc_clk_reset(unsigned id, enum clk_reset_action action) 56static int pc_clk_reset(struct clk_hw *hw, enum clk_reset_action action)
44{ 57{
45 int rc; 58 int rc;
59 unsigned id = to_clk_pcom(hw)->id;
46 60
47 if (action == CLK_RESET_ASSERT) 61 if (action == CLK_RESET_ASSERT)
48 rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_ASSERT, &id, NULL); 62 rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_ASSERT, &id, NULL);
@@ -55,83 +69,99 @@ int pc_clk_reset(unsigned id, enum clk_reset_action action)
55 return (int)id < 0 ? -EINVAL : 0; 69 return (int)id < 0 ? -EINVAL : 0;
56} 70}
57 71
58static int pc_clk_set_rate(unsigned id, unsigned rate) 72static int pc_clk_set_rate(struct clk_hw *hw, unsigned long new_rate,
73 unsigned long p_rate)
59{ 74{
60 /* The rate _might_ be rounded off to the nearest KHz value by the 75 struct clk_pcom *p = to_clk_pcom(hw);
76 unsigned id = p->id, rate = new_rate;
77 int rc;
78
79 /*
80 * The rate _might_ be rounded off to the nearest KHz value by the
61 * remote function. So a return value of 0 doesn't necessarily mean 81 * remote function. So a return value of 0 doesn't necessarily mean
62 * that the exact rate was set successfully. 82 * that the exact rate was set successfully.
63 */ 83 */
64 int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate); 84 if (p->flags & CLKFLAG_MIN)
65 if (rc < 0) 85 rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
66 return rc;
67 else
68 return (int)id < 0 ? -EINVAL : 0;
69}
70
71static int pc_clk_set_min_rate(unsigned id, unsigned rate)
72{
73 int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
74 if (rc < 0)
75 return rc;
76 else 86 else
77 return (int)id < 0 ? -EINVAL : 0; 87 rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
78}
79
80static int pc_clk_set_max_rate(unsigned id, unsigned rate)
81{
82 int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
83 if (rc < 0) 88 if (rc < 0)
84 return rc; 89 return rc;
85 else 90 else
86 return (int)id < 0 ? -EINVAL : 0; 91 return (int)id < 0 ? -EINVAL : 0;
87} 92}
88 93
89static unsigned pc_clk_get_rate(unsigned id) 94static unsigned long pc_clk_recalc_rate(struct clk_hw *hw, unsigned long p_rate)
90{ 95{
96 unsigned id = to_clk_pcom(hw)->id;
91 if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL)) 97 if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
92 return 0; 98 return 0;
93 else 99 else
94 return id; 100 return id;
95} 101}
96 102
97static unsigned pc_clk_is_enabled(unsigned id) 103static int pc_clk_is_enabled(struct clk_hw *hw)
98{ 104{
105 unsigned id = to_clk_pcom(hw)->id;
99 if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL)) 106 if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
100 return 0; 107 return 0;
101 else 108 else
102 return id; 109 return id;
103} 110}
104 111
105static long pc_clk_round_rate(unsigned id, unsigned rate) 112static long pc_clk_round_rate(struct clk_hw *hw, unsigned long rate,
113 unsigned long *p_rate)
106{ 114{
107
108 /* Not really supported; pc_clk_set_rate() does rounding on it's own. */ 115 /* Not really supported; pc_clk_set_rate() does rounding on it's own. */
109 return rate; 116 return rate;
110} 117}
111 118
112static bool pc_clk_is_local(unsigned id) 119static struct clk_ops clk_ops_pcom = {
113{
114 return false;
115}
116
117struct clk_ops clk_ops_pcom = {
118 .enable = pc_clk_enable, 120 .enable = pc_clk_enable,
119 .disable = pc_clk_disable, 121 .disable = pc_clk_disable,
120 .auto_off = pc_clk_disable,
121 .reset = pc_clk_reset,
122 .set_rate = pc_clk_set_rate, 122 .set_rate = pc_clk_set_rate,
123 .set_min_rate = pc_clk_set_min_rate, 123 .recalc_rate = pc_clk_recalc_rate,
124 .set_max_rate = pc_clk_set_max_rate,
125 .get_rate = pc_clk_get_rate,
126 .is_enabled = pc_clk_is_enabled, 124 .is_enabled = pc_clk_is_enabled,
127 .round_rate = pc_clk_round_rate, 125 .round_rate = pc_clk_round_rate,
128 .is_local = pc_clk_is_local,
129}; 126};
130 127
131static int msm_clock_pcom_probe(struct platform_device *pdev) 128static int msm_clock_pcom_probe(struct platform_device *pdev)
132{ 129{
133 const struct pcom_clk_pdata *pdata = pdev->dev.platform_data; 130 const struct pcom_clk_pdata *pdata = pdev->dev.platform_data;
134 msm_clock_init(pdata->lookup, pdata->num_lookups); 131 int i, ret;
132
133 for (i = 0; i < pdata->num_lookups; i++) {
134 const struct clk_pcom_desc *desc = &pdata->lookup[i];
135 struct clk *c;
136 struct clk_pcom *p;
137 struct clk_hw *hw;
138 struct clk_init_data init;
139
140 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
141 if (!p)
142 return -ENOMEM;
143
144 p->id = desc->id;
145 p->flags = desc->flags;
146 p->msm_clk.reset = pc_clk_reset;
147
148 hw = &p->msm_clk.hw;
149 hw->init = &init;
150
151 init.name = desc->name;
152 init.ops = &clk_ops_pcom;
153 init.num_parents = 0;
154 init.flags = CLK_IS_ROOT;
155
156 if (!(p->flags & CLKFLAG_AUTO_OFF))
157 init.flags |= CLK_IGNORE_UNUSED;
158
159 c = devm_clk_register(&pdev->dev, hw);
160 ret = clk_register_clkdev(c, desc->con, desc->dev);
161 if (ret)
162 return ret;
163 }
164
135 return 0; 165 return 0;
136} 166}
137 167
diff --git a/arch/arm/mach-msm/clock-pcom.h b/arch/arm/mach-msm/clock-pcom.h
index 87406a373d2b..5bb164fd46a8 100644
--- a/arch/arm/mach-msm/clock-pcom.h
+++ b/arch/arm/mach-msm/clock-pcom.h
@@ -1,4 +1,5 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved. 1/*
2 * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
2 * 3 *
3 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and 5 * it under the terms of the GNU General Public License version 2 and
@@ -120,26 +121,25 @@
120 121
121#define P_NR_CLKS 102 122#define P_NR_CLKS 102
122 123
123struct clk_ops; 124struct clk_pcom_desc {
124extern struct clk_ops clk_ops_pcom; 125 unsigned id;
126 const char *name;
127 const char *con;
128 const char *dev;
129 unsigned long flags;
130};
125 131
126struct pcom_clk_pdata { 132struct pcom_clk_pdata {
127 struct clk_lookup *lookup; 133 struct clk_pcom_desc *lookup;
128 u32 num_lookups; 134 u32 num_lookups;
129}; 135};
130 136
131int pc_clk_reset(unsigned id, enum clk_reset_action action);
132
133#define CLK_PCOM(clk_name, clk_id, clk_dev, clk_flags) { \ 137#define CLK_PCOM(clk_name, clk_id, clk_dev, clk_flags) { \
134 .con_id = clk_name, \ 138 .id = P_##clk_id, \
135 .dev_id = clk_dev, \ 139 .name = #clk_id, \
136 .clk = &(struct clk){ \ 140 .con = clk_name, \
137 .id = P_##clk_id, \ 141 .dev = clk_dev, \
138 .remote_id = P_##clk_id, \ 142 .flags = clk_flags, \
139 .ops = &clk_ops_pcom, \
140 .flags = clk_flags, \
141 .dbg_name = #clk_id, \
142 }, \
143 } 143 }
144 144
145#endif 145#endif
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index d72dd3770298..35ea02b52483 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -1,7 +1,7 @@
1/* arch/arm/mach-msm/clock.c 1/* arch/arm/mach-msm/clock.c
2 * 2 *
3 * Copyright (C) 2007 Google, Inc. 3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved. 4 * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
5 * 5 *
6 * This software is licensed under the terms of the GNU General Public 6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and 7 * License version 2, as published by the Free Software Foundation, and
@@ -14,151 +14,15 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/kernel.h> 17#include <linux/clk-provider.h>
18#include <linux/list.h>
19#include <linux/err.h>
20#include <linux/spinlock.h>
21#include <linux/pm_qos.h>
22#include <linux/mutex.h>
23#include <linux/clk.h>
24#include <linux/string.h>
25#include <linux/module.h> 18#include <linux/module.h>
26#include <linux/clkdev.h>
27 19
28#include "clock.h" 20#include "clock.h"
29 21
30static DEFINE_MUTEX(clocks_mutex);
31static DEFINE_SPINLOCK(clocks_lock);
32static LIST_HEAD(clocks);
33
34/*
35 * Standard clock functions defined in include/linux/clk.h
36 */
37int clk_enable(struct clk *clk)
38{
39 unsigned long flags;
40 spin_lock_irqsave(&clocks_lock, flags);
41 clk->count++;
42 if (clk->count == 1)
43 clk->ops->enable(clk->id);
44 spin_unlock_irqrestore(&clocks_lock, flags);
45 return 0;
46}
47EXPORT_SYMBOL(clk_enable);
48
49void clk_disable(struct clk *clk)
50{
51 unsigned long flags;
52 spin_lock_irqsave(&clocks_lock, flags);
53 BUG_ON(clk->count == 0);
54 clk->count--;
55 if (clk->count == 0)
56 clk->ops->disable(clk->id);
57 spin_unlock_irqrestore(&clocks_lock, flags);
58}
59EXPORT_SYMBOL(clk_disable);
60
61int clk_reset(struct clk *clk, enum clk_reset_action action) 22int clk_reset(struct clk *clk, enum clk_reset_action action)
62{ 23{
63 return clk->ops->reset(clk->remote_id, action); 24 struct clk_hw *hw = __clk_get_hw(clk);
25 struct msm_clk *m = to_msm_clk(hw);
26 return m->reset(hw, action);
64} 27}
65EXPORT_SYMBOL(clk_reset); 28EXPORT_SYMBOL(clk_reset);
66
67unsigned long clk_get_rate(struct clk *clk)
68{
69 return clk->ops->get_rate(clk->id);
70}
71EXPORT_SYMBOL(clk_get_rate);
72
73int clk_set_rate(struct clk *clk, unsigned long rate)
74{
75 int ret;
76 if (clk->flags & CLKFLAG_MAX) {
77 ret = clk->ops->set_max_rate(clk->id, rate);
78 if (ret)
79 return ret;
80 }
81 if (clk->flags & CLKFLAG_MIN) {
82 ret = clk->ops->set_min_rate(clk->id, rate);
83 if (ret)
84 return ret;
85 }
86
87 if (clk->flags & CLKFLAG_MAX || clk->flags & CLKFLAG_MIN)
88 return ret;
89
90 return clk->ops->set_rate(clk->id, rate);
91}
92EXPORT_SYMBOL(clk_set_rate);
93
94long clk_round_rate(struct clk *clk, unsigned long rate)
95{
96 return clk->ops->round_rate(clk->id, rate);
97}
98EXPORT_SYMBOL(clk_round_rate);
99
100int clk_set_parent(struct clk *clk, struct clk *parent)
101{
102 return -ENOSYS;
103}
104EXPORT_SYMBOL(clk_set_parent);
105
106struct clk *clk_get_parent(struct clk *clk)
107{
108 return ERR_PTR(-ENOSYS);
109}
110EXPORT_SYMBOL(clk_get_parent);
111
112/* EBI1 is the only shared clock that several clients want to vote on as of
113 * this commit. If this changes in the future, then it might be better to
114 * make clk_min_rate handle the voting or make ebi1_clk_set_min_rate more
115 * generic to support different clocks.
116 */
117static struct clk *ebi1_clk;
118
119void msm_clock_init(struct clk_lookup *clock_tbl, size_t num_clocks)
120{
121 unsigned n;
122
123 mutex_lock(&clocks_mutex);
124 for (n = 0; n < num_clocks; n++) {
125 clkdev_add(&clock_tbl[n]);
126 list_add_tail(&clock_tbl[n].clk->list, &clocks);
127 }
128 mutex_unlock(&clocks_mutex);
129
130 ebi1_clk = clk_get(NULL, "ebi1_clk");
131 BUG_ON(ebi1_clk == NULL);
132
133}
134
135/* The bootloader and/or AMSS may have left various clocks enabled.
136 * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have
137 * not been explicitly enabled by a clk_enable() call.
138 */
139static int __init clock_late_init(void)
140{
141 unsigned long flags;
142 struct clk *clk;
143 unsigned count = 0;
144
145 clock_debug_init();
146 mutex_lock(&clocks_mutex);
147 list_for_each_entry(clk, &clocks, list) {
148 clock_debug_add(clk);
149 if (clk->flags & CLKFLAG_AUTO_OFF) {
150 spin_lock_irqsave(&clocks_lock, flags);
151 if (!clk->count) {
152 count++;
153 clk->ops->auto_off(clk->id);
154 }
155 spin_unlock_irqrestore(&clocks_lock, flags);
156 }
157 }
158 mutex_unlock(&clocks_mutex);
159 pr_info("clock_late_init() disabled %d unused clocks\n", count);
160 return 0;
161}
162
163late_initcall(clock_late_init);
164
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index cc76bfe9ba46..42d29dd7aafc 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -1,7 +1,7 @@
1/* arch/arm/mach-msm/clock.h 1/* arch/arm/mach-msm/clock.h
2 * 2 *
3 * Copyright (C) 2007 Google, Inc. 3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved. 4 * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
5 * 5 *
6 * This software is licensed under the terms of the GNU General Public 6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and 7 * License version 2, as published by the Free Software Foundation, and
@@ -17,8 +17,7 @@
17#ifndef __ARCH_ARM_MACH_MSM_CLOCK_H 17#ifndef __ARCH_ARM_MACH_MSM_CLOCK_H
18#define __ARCH_ARM_MACH_MSM_CLOCK_H 18#define __ARCH_ARM_MACH_MSM_CLOCK_H
19 19
20#include <linux/init.h> 20#include <linux/clk-provider.h>
21#include <linux/list.h>
22#include <mach/clk.h> 21#include <mach/clk.h>
23 22
24#define CLK_FIRST_AVAILABLE_FLAG 0x00000100 23#define CLK_FIRST_AVAILABLE_FLAG 0x00000100
@@ -26,44 +25,19 @@
26#define CLKFLAG_MIN 0x00000400 25#define CLKFLAG_MIN 0x00000400
27#define CLKFLAG_MAX 0x00000800 26#define CLKFLAG_MAX 0x00000800
28 27
29struct clk_ops {
30 int (*enable)(unsigned id);
31 void (*disable)(unsigned id);
32 void (*auto_off)(unsigned id);
33 int (*reset)(unsigned id, enum clk_reset_action action);
34 int (*set_rate)(unsigned id, unsigned rate);
35 int (*set_min_rate)(unsigned id, unsigned rate);
36 int (*set_max_rate)(unsigned id, unsigned rate);
37 unsigned (*get_rate)(unsigned id);
38 unsigned (*is_enabled)(unsigned id);
39 long (*round_rate)(unsigned id, unsigned rate);
40 bool (*is_local)(unsigned id);
41};
42
43struct clk {
44 uint32_t id;
45 uint32_t remote_id;
46 uint32_t count;
47 uint32_t flags;
48 struct clk_ops *ops;
49 const char *dbg_name;
50 struct list_head list;
51};
52
53#define OFF CLKFLAG_AUTO_OFF 28#define OFF CLKFLAG_AUTO_OFF
54#define CLK_MIN CLKFLAG_MIN 29#define CLK_MIN CLKFLAG_MIN
55#define CLK_MAX CLKFLAG_MAX 30#define CLK_MAX CLKFLAG_MAX
56#define CLK_MINMAX (CLK_MIN | CLK_MAX) 31#define CLK_MINMAX (CLK_MIN | CLK_MAX)
57 32
58#ifdef CONFIG_DEBUG_FS 33struct msm_clk {
59int __init clock_debug_init(void); 34 int (*reset)(struct clk_hw *hw, enum clk_reset_action action);
60int __init clock_debug_add(struct clk *clock); 35 struct clk_hw hw;
61#else 36};
62static inline int __init clock_debug_init(void) { return 0; }
63static inline int __init clock_debug_add(struct clk *clock) { return 0; }
64#endif
65 37
66struct clk_lookup; 38static inline struct msm_clk *to_msm_clk(struct clk_hw *hw)
67void msm_clock_init(struct clk_lookup *clock_tbl, size_t num_clocks); 39{
40 return container_of(hw, struct msm_clk, hw);
41}
68 42
69#endif 43#endif
diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c
index 9edfe68e9fe9..6d50fb964863 100644
--- a/arch/arm/mach-msm/devices-msm7x00.c
+++ b/arch/arm/mach-msm/devices-msm7x00.c
@@ -425,7 +425,7 @@ struct platform_device msm_device_mdp = {
425 .resource = resources_mdp, 425 .resource = resources_mdp,
426}; 426};
427 427
428static struct clk_lookup msm_clocks_7x01a[] = { 428static struct clk_pcom_desc msm_clocks_7x01a[] = {
429 CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), 429 CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
430 CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0), 430 CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0),
431 CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, 0), 431 CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, 0),
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index 6444f0e618f6..d4db75acff56 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -161,7 +161,7 @@ struct platform_device msm_device_hsusb_host = {
161 }, 161 },
162}; 162};
163 163
164static struct clk_lookup msm_clocks_7x30[] = { 164static struct clk_pcom_desc msm_clocks_7x30[] = {
165 CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), 165 CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
166 CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0), 166 CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0),
167 CLK_PCOM("cam_m_clk", CAM_M_CLK, NULL, 0), 167 CLK_PCOM("cam_m_clk", CAM_M_CLK, NULL, 0),
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c
index caa9a1f0bcbd..f5518112284b 100644
--- a/arch/arm/mach-msm/devices-qsd8x50.c
+++ b/arch/arm/mach-msm/devices-qsd8x50.c
@@ -323,7 +323,7 @@ int __init msm_add_sdcc(unsigned int controller,
323 return platform_device_register(pdev); 323 return platform_device_register(pdev);
324} 324}
325 325
326static struct clk_lookup msm_clocks_8x50[] = { 326static struct clk_pcom_desc msm_clocks_8x50[] = {
327 CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), 327 CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
328 CLK_PCOM("ce_clk", CE_CLK, NULL, 0), 328 CLK_PCOM("ce_clk", CE_CLK, NULL, 0),
329 CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN), 329 CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN),