aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-msm/Makefile2
-rw-r--r--arch/arm/mach-msm/board-halibut.c2
-rw-r--r--arch/arm/mach-msm/board-trout.c2
-rw-r--r--arch/arm/mach-msm/clock-7x01a.c126
-rw-r--r--arch/arm/mach-msm/clock-pcom.c131
-rw-r--r--arch/arm/mach-msm/clock-pcom.h153
-rw-r--r--arch/arm/mach-msm/clock.c257
-rw-r--r--arch/arm/mach-msm/clock.h70
-rw-r--r--arch/arm/mach-msm/devices-msm7x00.c47
-rw-r--r--arch/arm/mach-msm/devices.h5
-rw-r--r--arch/arm/mach-msm/include/mach/board.h5
-rw-r--r--arch/arm/mach-msm/include/mach/clk.h57
12 files changed, 651 insertions, 206 deletions
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 435d83cd52c2..70fa9703f437 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -2,7 +2,7 @@ obj-y += io.o idle.o irq.o timer.o dma.o
2obj-y += proc_comm.o 2obj-y += proc_comm.o
3obj-y += vreg.o 3obj-y += vreg.o
4obj-y += acpuclock-arm11.o 4obj-y += acpuclock-arm11.o
5obj-y += clock.o clock-7x01a.o 5obj-y += clock.o clock-pcom.o
6 6
7obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o 7obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
8obj-$(CONFIG_MSM_SMD) += last_radio_log.o 8obj-$(CONFIG_MSM_SMD) += last_radio_log.o
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c
index acc22886e340..7bd72e8f127e 100644
--- a/arch/arm/mach-msm/board-halibut.c
+++ b/arch/arm/mach-msm/board-halibut.c
@@ -90,7 +90,7 @@ static void __init halibut_fixup(struct machine_desc *desc, struct tag *tags,
90static void __init halibut_map_io(void) 90static void __init halibut_map_io(void)
91{ 91{
92 msm_map_common_io(); 92 msm_map_common_io();
93 msm_clock_init(); 93 msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
94} 94}
95 95
96MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") 96MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c
index b88aec269df5..dca5a5f062dc 100644
--- a/arch/arm/mach-msm/board-trout.c
+++ b/arch/arm/mach-msm/board-trout.c
@@ -78,7 +78,7 @@ static void __init trout_map_io(void)
78 writeb(0x80, TROUT_CPLD_BASE + 0x00); 78 writeb(0x80, TROUT_CPLD_BASE + 0x00);
79#endif 79#endif
80 80
81 msm_clock_init(); 81 msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
82} 82}
83 83
84MACHINE_START(TROUT, "HTC Dream") 84MACHINE_START(TROUT, "HTC Dream")
diff --git a/arch/arm/mach-msm/clock-7x01a.c b/arch/arm/mach-msm/clock-7x01a.c
deleted file mode 100644
index 62230a3428ee..000000000000
--- a/arch/arm/mach-msm/clock-7x01a.c
+++ /dev/null
@@ -1,126 +0,0 @@
1/* arch/arm/mach-msm/clock-7x01a.c
2 *
3 * Clock tables for MSM7X01A
4 *
5 * Copyright (C) 2007 Google, Inc.
6 * Copyright (c) 2007 QUALCOMM Incorporated
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/kernel.h>
20#include <linux/platform_device.h>
21
22#include "clock.h"
23#include "devices.h"
24
25/* clock IDs used by the modem processor */
26
27#define ACPU_CLK 0 /* Applications processor clock */
28#define ADM_CLK 1 /* Applications data mover clock */
29#define ADSP_CLK 2 /* ADSP clock */
30#define EBI1_CLK 3 /* External bus interface 1 clock */
31#define EBI2_CLK 4 /* External bus interface 2 clock */
32#define ECODEC_CLK 5 /* External CODEC clock */
33#define EMDH_CLK 6 /* External MDDI host clock */
34#define GP_CLK 7 /* General purpose clock */
35#define GRP_CLK 8 /* Graphics clock */
36#define I2C_CLK 9 /* I2C clock */
37#define ICODEC_RX_CLK 10 /* Internal CODEX RX clock */
38#define ICODEC_TX_CLK 11 /* Internal CODEX TX clock */
39#define IMEM_CLK 12 /* Internal graphics memory clock */
40#define MDC_CLK 13 /* MDDI client clock */
41#define MDP_CLK 14 /* Mobile display processor clock */
42#define PBUS_CLK 15 /* Peripheral bus clock */
43#define PCM_CLK 16 /* PCM clock */
44#define PMDH_CLK 17 /* Primary MDDI host clock */
45#define SDAC_CLK 18 /* Stereo DAC clock */
46#define SDC1_CLK 19 /* Secure Digital Card clocks */
47#define SDC1_PCLK 20
48#define SDC2_CLK 21
49#define SDC2_PCLK 22
50#define SDC3_CLK 23
51#define SDC3_PCLK 24
52#define SDC4_CLK 25
53#define SDC4_PCLK 26
54#define TSIF_CLK 27 /* Transport Stream Interface clocks */
55#define TSIF_REF_CLK 28
56#define TV_DAC_CLK 29 /* TV clocks */
57#define TV_ENC_CLK 30
58#define UART1_CLK 31 /* UART clocks */
59#define UART2_CLK 32
60#define UART3_CLK 33
61#define UART1DM_CLK 34
62#define UART2DM_CLK 35
63#define USB_HS_CLK 36 /* High speed USB core clock */
64#define USB_HS_PCLK 37 /* High speed USB pbus clock */
65#define USB_OTG_CLK 38 /* Full speed USB clock */
66#define VDC_CLK 39 /* Video controller clock */
67#define VFE_CLK 40 /* Camera / Video Front End clock */
68#define VFE_MDC_CLK 41 /* VFE MDDI client clock */
69
70#define NR_CLKS 42
71
72#define CLOCK(clk_name, clk_id, clk_dev, clk_flags) { \
73 .name = clk_name, \
74 .id = clk_id, \
75 .flags = clk_flags, \
76 .dev = clk_dev, \
77 }
78
79#define OFF CLKFLAG_AUTO_OFF
80#define MINMAX CLKFLAG_USE_MIN_MAX_TO_SET
81
82struct clk msm_clocks[] = {
83 CLOCK("adm_clk", ADM_CLK, NULL, 0),
84 CLOCK("adsp_clk", ADSP_CLK, NULL, 0),
85 CLOCK("ebi1_clk", EBI1_CLK, NULL, 0),
86 CLOCK("ebi2_clk", EBI2_CLK, NULL, 0),
87 CLOCK("ecodec_clk", ECODEC_CLK, NULL, 0),
88 CLOCK("emdh_clk", EMDH_CLK, NULL, OFF),
89 CLOCK("gp_clk", GP_CLK, NULL, 0),
90 CLOCK("grp_clk", GRP_CLK, NULL, OFF),
91 CLOCK("i2c_clk", I2C_CLK, &msm_device_i2c.dev, 0),
92 CLOCK("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0),
93 CLOCK("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0),
94 CLOCK("imem_clk", IMEM_CLK, NULL, OFF),
95 CLOCK("mdc_clk", MDC_CLK, NULL, 0),
96 CLOCK("mdp_clk", MDP_CLK, NULL, OFF),
97 CLOCK("pbus_clk", PBUS_CLK, NULL, 0),
98 CLOCK("pcm_clk", PCM_CLK, NULL, 0),
99 CLOCK("pmdh_clk", PMDH_CLK, NULL, OFF | MINMAX),
100 CLOCK("sdac_clk", SDAC_CLK, NULL, OFF),
101 CLOCK("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF),
102 CLOCK("sdc_pclk", SDC1_PCLK, &msm_device_sdc1.dev, OFF),
103 CLOCK("sdc_clk", SDC2_CLK, &msm_device_sdc2.dev, OFF),
104 CLOCK("sdc_pclk", SDC2_PCLK, &msm_device_sdc2.dev, OFF),
105 CLOCK("sdc_clk", SDC3_CLK, &msm_device_sdc3.dev, OFF),
106 CLOCK("sdc_pclk", SDC3_PCLK, &msm_device_sdc3.dev, OFF),
107 CLOCK("sdc_clk", SDC4_CLK, &msm_device_sdc4.dev, OFF),
108 CLOCK("sdc_pclk", SDC4_PCLK, &msm_device_sdc4.dev, OFF),
109 CLOCK("tsif_clk", TSIF_CLK, NULL, 0),
110 CLOCK("tsif_ref_clk", TSIF_REF_CLK, NULL, 0),
111 CLOCK("tv_dac_clk", TV_DAC_CLK, NULL, 0),
112 CLOCK("tv_enc_clk", TV_ENC_CLK, NULL, 0),
113 CLOCK("uart_clk", UART1_CLK, &msm_device_uart1.dev, OFF),
114 CLOCK("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0),
115 CLOCK("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF),
116 CLOCK("uart1dm_clk", UART1DM_CLK, NULL, OFF),
117 CLOCK("uart2dm_clk", UART2DM_CLK, NULL, 0),
118 CLOCK("usb_hs_clk", USB_HS_CLK, &msm_device_hsusb.dev, OFF),
119 CLOCK("usb_hs_pclk", USB_HS_PCLK, &msm_device_hsusb.dev, OFF),
120 CLOCK("usb_otg_clk", USB_OTG_CLK, NULL, 0),
121 CLOCK("vdc_clk", VDC_CLK, NULL, OFF | MINMAX),
122 CLOCK("vfe_clk", VFE_CLK, NULL, OFF),
123 CLOCK("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF),
124};
125
126unsigned msm_num_clocks = ARRAY_SIZE(msm_clocks);
diff --git a/arch/arm/mach-msm/clock-pcom.c b/arch/arm/mach-msm/clock-pcom.c
new file mode 100644
index 000000000000..a3b45627eb4a
--- /dev/null
+++ b/arch/arm/mach-msm/clock-pcom.c
@@ -0,0 +1,131 @@
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/err.h>
17#include <linux/ctype.h>
18#include <linux/stddef.h>
19#include <mach/clk.h>
20
21#include "proc_comm.h"
22#include "clock.h"
23
24/*
25 * glue for the proc_comm interface
26 */
27int pc_clk_enable(unsigned id)
28{
29 int rc = msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
30 if (rc < 0)
31 return rc;
32 else
33 return (int)id < 0 ? -EINVAL : 0;
34}
35
36void pc_clk_disable(unsigned id)
37{
38 msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
39}
40
41int pc_clk_reset(unsigned id, enum clk_reset_action action)
42{
43 int rc;
44
45 if (action == CLK_RESET_ASSERT)
46 rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_ASSERT, &id, NULL);
47 else
48 rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_DEASSERT, &id, NULL);
49
50 if (rc < 0)
51 return rc;
52 else
53 return (int)id < 0 ? -EINVAL : 0;
54}
55
56int pc_clk_set_rate(unsigned id, unsigned rate)
57{
58 /* The rate _might_ be rounded off to the nearest KHz value by the
59 * remote function. So a return value of 0 doesn't necessarily mean
60 * that the exact rate was set successfully.
61 */
62 int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
63 if (rc < 0)
64 return rc;
65 else
66 return (int)id < 0 ? -EINVAL : 0;
67}
68
69int pc_clk_set_min_rate(unsigned id, unsigned rate)
70{
71 int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
72 if (rc < 0)
73 return rc;
74 else
75 return (int)id < 0 ? -EINVAL : 0;
76}
77
78int pc_clk_set_max_rate(unsigned id, unsigned rate)
79{
80 int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
81 if (rc < 0)
82 return rc;
83 else
84 return (int)id < 0 ? -EINVAL : 0;
85}
86
87int pc_clk_set_flags(unsigned id, unsigned flags)
88{
89 int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags);
90 if (rc < 0)
91 return rc;
92 else
93 return (int)id < 0 ? -EINVAL : 0;
94}
95
96unsigned pc_clk_get_rate(unsigned id)
97{
98 if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
99 return 0;
100 else
101 return id;
102}
103
104unsigned pc_clk_is_enabled(unsigned id)
105{
106 if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
107 return 0;
108 else
109 return id;
110}
111
112long pc_clk_round_rate(unsigned id, unsigned rate)
113{
114
115 /* Not really supported; pc_clk_set_rate() does rounding on it's own. */
116 return rate;
117}
118
119struct clk_ops clk_ops_pcom = {
120 .enable = pc_clk_enable,
121 .disable = pc_clk_disable,
122 .auto_off = pc_clk_disable,
123 .reset = pc_clk_reset,
124 .set_rate = pc_clk_set_rate,
125 .set_min_rate = pc_clk_set_min_rate,
126 .set_max_rate = pc_clk_set_max_rate,
127 .set_flags = pc_clk_set_flags,
128 .get_rate = pc_clk_get_rate,
129 .is_enabled = pc_clk_is_enabled,
130 .round_rate = pc_clk_round_rate,
131};
diff --git a/arch/arm/mach-msm/clock-pcom.h b/arch/arm/mach-msm/clock-pcom.h
new file mode 100644
index 000000000000..17d027b23501
--- /dev/null
+++ b/arch/arm/mach-msm/clock-pcom.h
@@ -0,0 +1,153 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of Code Aurora Forum, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#ifndef __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H
31#define __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H
32
33/* clock IDs used by the modem processor */
34
35#define P_ACPU_CLK 0 /* Applications processor clock */
36#define P_ADM_CLK 1 /* Applications data mover clock */
37#define P_ADSP_CLK 2 /* ADSP clock */
38#define P_EBI1_CLK 3 /* External bus interface 1 clock */
39#define P_EBI2_CLK 4 /* External bus interface 2 clock */
40#define P_ECODEC_CLK 5 /* External CODEC clock */
41#define P_EMDH_CLK 6 /* External MDDI host clock */
42#define P_GP_CLK 7 /* General purpose clock */
43#define P_GRP_3D_CLK 8 /* Graphics clock */
44#define P_I2C_CLK 9 /* I2C clock */
45#define P_ICODEC_RX_CLK 10 /* Internal CODEX RX clock */
46#define P_ICODEC_TX_CLK 11 /* Internal CODEX TX clock */
47#define P_IMEM_CLK 12 /* Internal graphics memory clock */
48#define P_MDC_CLK 13 /* MDDI client clock */
49#define P_MDP_CLK 14 /* Mobile display processor clock */
50#define P_PBUS_CLK 15 /* Peripheral bus clock */
51#define P_PCM_CLK 16 /* PCM clock */
52#define P_PMDH_CLK 17 /* Primary MDDI host clock */
53#define P_SDAC_CLK 18 /* Stereo DAC clock */
54#define P_SDC1_CLK 19 /* Secure Digital Card clocks */
55#define P_SDC1_P_CLK 20
56#define P_SDC2_CLK 21
57#define P_SDC2_P_CLK 22
58#define P_SDC3_CLK 23
59#define P_SDC3_P_CLK 24
60#define P_SDC4_CLK 25
61#define P_SDC4_P_CLK 26
62#define P_TSIF_CLK 27 /* Transport Stream Interface clocks */
63#define P_TSIF_REF_CLK 28
64#define P_TV_DAC_CLK 29 /* TV clocks */
65#define P_TV_ENC_CLK 30
66#define P_UART1_CLK 31 /* UART clocks */
67#define P_UART2_CLK 32
68#define P_UART3_CLK 33
69#define P_UART1DM_CLK 34
70#define P_UART2DM_CLK 35
71#define P_USB_HS_CLK 36 /* High speed USB core clock */
72#define P_USB_HS_P_CLK 37 /* High speed USB pbus clock */
73#define P_USB_OTG_CLK 38 /* Full speed USB clock */
74#define P_VDC_CLK 39 /* Video controller clock */
75#define P_VFE_MDC_CLK 40 /* Camera / Video Front End clock */
76#define P_VFE_CLK 41 /* VFE MDDI client clock */
77#define P_MDP_LCDC_PCLK_CLK 42
78#define P_MDP_LCDC_PAD_PCLK_CLK 43
79#define P_MDP_VSYNC_CLK 44
80#define P_SPI_CLK 45
81#define P_VFE_AXI_CLK 46
82#define P_USB_HS2_CLK 47 /* High speed USB 2 core clock */
83#define P_USB_HS2_P_CLK 48 /* High speed USB 2 pbus clock */
84#define P_USB_HS3_CLK 49 /* High speed USB 3 core clock */
85#define P_USB_HS3_P_CLK 50 /* High speed USB 3 pbus clock */
86#define P_GRP_3D_P_CLK 51 /* Graphics pbus clock */
87#define P_USB_PHY_CLK 52 /* USB PHY clock */
88#define P_USB_HS_CORE_CLK 53 /* High speed USB 1 core clock */
89#define P_USB_HS2_CORE_CLK 54 /* High speed USB 2 core clock */
90#define P_USB_HS3_CORE_CLK 55 /* High speed USB 3 core clock */
91#define P_CAM_M_CLK 56
92#define P_CAMIF_PAD_P_CLK 57
93#define P_GRP_2D_CLK 58
94#define P_GRP_2D_P_CLK 59
95#define P_I2S_CLK 60
96#define P_JPEG_CLK 61
97#define P_JPEG_P_CLK 62
98#define P_LPA_CODEC_CLK 63
99#define P_LPA_CORE_CLK 64
100#define P_LPA_P_CLK 65
101#define P_MDC_IO_CLK 66
102#define P_MDC_P_CLK 67
103#define P_MFC_CLK 68
104#define P_MFC_DIV2_CLK 69
105#define P_MFC_P_CLK 70
106#define P_QUP_I2C_CLK 71
107#define P_ROTATOR_IMEM_CLK 72
108#define P_ROTATOR_P_CLK 73
109#define P_VFE_CAMIF_CLK 74
110#define P_VFE_P_CLK 75
111#define P_VPE_CLK 76
112#define P_I2C_2_CLK 77
113#define P_MI2S_CODEC_RX_S_CLK 78
114#define P_MI2S_CODEC_RX_M_CLK 79
115#define P_MI2S_CODEC_TX_S_CLK 80
116#define P_MI2S_CODEC_TX_M_CLK 81
117#define P_PMDH_P_CLK 82
118#define P_EMDH_P_CLK 83
119#define P_SPI_P_CLK 84
120#define P_TSIF_P_CLK 85
121#define P_MDP_P_CLK 86
122#define P_SDAC_M_CLK 87
123#define P_MI2S_S_CLK 88
124#define P_MI2S_M_CLK 89
125#define P_AXI_ROTATOR_CLK 90
126#define P_HDMI_CLK 91
127#define P_CSI0_CLK 92
128#define P_CSI0_VFE_CLK 93
129#define P_CSI0_P_CLK 94
130#define P_CSI1_CLK 95
131#define P_CSI1_VFE_CLK 96
132#define P_CSI1_P_CLK 97
133#define P_GSBI_CLK 98
134#define P_GSBI_P_CLK 99
135
136#define P_NR_CLKS 100
137
138struct clk_ops;
139extern struct clk_ops clk_ops_pcom;
140
141int pc_clk_reset(unsigned id, enum clk_reset_action action);
142
143#define CLK_PCOM(clk_name, clk_id, clk_dev, clk_flags) { \
144 .name = clk_name, \
145 .id = P_##clk_id, \
146 .remote_id = P_##clk_id, \
147 .ops = &clk_ops_pcom, \
148 .flags = clk_flags, \
149 .dev = clk_dev, \
150 .dbg_name = #clk_id, \
151 }
152
153#endif
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index 3b1ce36f1032..34c6a52af060 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 QUALCOMM Incorporated 4 * Copyright (c) 2007-2010, Code Aurora Forum. 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
@@ -22,6 +22,10 @@
22#include <linux/err.h> 22#include <linux/err.h>
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/debugfs.h>
26#include <linux/ctype.h>
27#include <linux/pm_qos_params.h>
28#include <mach/clk.h>
25 29
26#include "clock.h" 30#include "clock.h"
27#include "proc_comm.h" 31#include "proc_comm.h"
@@ -29,61 +33,15 @@
29static DEFINE_MUTEX(clocks_mutex); 33static DEFINE_MUTEX(clocks_mutex);
30static DEFINE_SPINLOCK(clocks_lock); 34static DEFINE_SPINLOCK(clocks_lock);
31static LIST_HEAD(clocks); 35static LIST_HEAD(clocks);
36struct clk *msm_clocks;
37unsigned msm_num_clocks;
32 38
33/* 39/*
34 * glue for the proc_comm interface 40 * Bitmap of enabled clocks, excluding ACPU which is always
41 * enabled
35 */ 42 */
36static inline int pc_clk_enable(unsigned id) 43static DECLARE_BITMAP(clock_map_enabled, NR_CLKS);
37{ 44static DEFINE_SPINLOCK(clock_map_lock);
38 return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
39}
40
41static inline void pc_clk_disable(unsigned id)
42{
43 msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
44}
45
46static inline int pc_clk_set_rate(unsigned id, unsigned rate)
47{
48 return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
49}
50
51static inline int pc_clk_set_min_rate(unsigned id, unsigned rate)
52{
53 return msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
54}
55
56static inline int pc_clk_set_max_rate(unsigned id, unsigned rate)
57{
58 return msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
59}
60
61static inline int pc_clk_set_flags(unsigned id, unsigned flags)
62{
63 return msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags);
64}
65
66static inline unsigned pc_clk_get_rate(unsigned id)
67{
68 if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
69 return 0;
70 else
71 return id;
72}
73
74static inline unsigned pc_clk_is_enabled(unsigned id)
75{
76 if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
77 return 0;
78 else
79 return id;
80}
81
82static inline int pc_pll_request(unsigned id, unsigned on)
83{
84 on = !!on;
85 return msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on);
86}
87 45
88/* 46/*
89 * Standard clock functions defined in include/linux/clk.h 47 * Standard clock functions defined in include/linux/clk.h
@@ -119,8 +77,12 @@ int clk_enable(struct clk *clk)
119 unsigned long flags; 77 unsigned long flags;
120 spin_lock_irqsave(&clocks_lock, flags); 78 spin_lock_irqsave(&clocks_lock, flags);
121 clk->count++; 79 clk->count++;
122 if (clk->count == 1) 80 if (clk->count == 1) {
123 pc_clk_enable(clk->id); 81 clk->ops->enable(clk->id);
82 spin_lock(&clock_map_lock);
83 clock_map_enabled[BIT_WORD(clk->id)] |= BIT_MASK(clk->id);
84 spin_unlock(&clock_map_lock);
85 }
124 spin_unlock_irqrestore(&clocks_lock, flags); 86 spin_unlock_irqrestore(&clocks_lock, flags);
125 return 0; 87 return 0;
126} 88}
@@ -132,31 +94,54 @@ void clk_disable(struct clk *clk)
132 spin_lock_irqsave(&clocks_lock, flags); 94 spin_lock_irqsave(&clocks_lock, flags);
133 BUG_ON(clk->count == 0); 95 BUG_ON(clk->count == 0);
134 clk->count--; 96 clk->count--;
135 if (clk->count == 0) 97 if (clk->count == 0) {
136 pc_clk_disable(clk->id); 98 clk->ops->disable(clk->id);
99 spin_lock(&clock_map_lock);
100 clock_map_enabled[BIT_WORD(clk->id)] &= ~BIT_MASK(clk->id);
101 spin_unlock(&clock_map_lock);
102 }
137 spin_unlock_irqrestore(&clocks_lock, flags); 103 spin_unlock_irqrestore(&clocks_lock, flags);
138} 104}
139EXPORT_SYMBOL(clk_disable); 105EXPORT_SYMBOL(clk_disable);
140 106
107int clk_reset(struct clk *clk, enum clk_reset_action action)
108{
109 if (!clk->ops->reset)
110 clk->ops->reset = &pc_clk_reset;
111 return clk->ops->reset(clk->remote_id, action);
112}
113EXPORT_SYMBOL(clk_reset);
114
141unsigned long clk_get_rate(struct clk *clk) 115unsigned long clk_get_rate(struct clk *clk)
142{ 116{
143 return pc_clk_get_rate(clk->id); 117 return clk->ops->get_rate(clk->id);
144} 118}
145EXPORT_SYMBOL(clk_get_rate); 119EXPORT_SYMBOL(clk_get_rate);
146 120
147int clk_set_rate(struct clk *clk, unsigned long rate) 121int clk_set_rate(struct clk *clk, unsigned long rate)
148{ 122{
149 int ret; 123 return clk->ops->set_rate(clk->id, rate);
150 if (clk->flags & CLKFLAG_USE_MIN_MAX_TO_SET) {
151 ret = pc_clk_set_max_rate(clk->id, rate);
152 if (ret)
153 return ret;
154 return pc_clk_set_min_rate(clk->id, rate);
155 }
156 return pc_clk_set_rate(clk->id, rate);
157} 124}
158EXPORT_SYMBOL(clk_set_rate); 125EXPORT_SYMBOL(clk_set_rate);
159 126
127long clk_round_rate(struct clk *clk, unsigned long rate)
128{
129 return clk->ops->round_rate(clk->id, rate);
130}
131EXPORT_SYMBOL(clk_round_rate);
132
133int clk_set_min_rate(struct clk *clk, unsigned long rate)
134{
135 return clk->ops->set_min_rate(clk->id, rate);
136}
137EXPORT_SYMBOL(clk_set_min_rate);
138
139int clk_set_max_rate(struct clk *clk, unsigned long rate)
140{
141 return clk->ops->set_max_rate(clk->id, rate);
142}
143EXPORT_SYMBOL(clk_set_max_rate);
144
160int clk_set_parent(struct clk *clk, struct clk *parent) 145int clk_set_parent(struct clk *clk, struct clk *parent)
161{ 146{
162 return -ENOSYS; 147 return -ENOSYS;
@@ -173,22 +158,153 @@ int clk_set_flags(struct clk *clk, unsigned long flags)
173{ 158{
174 if (clk == NULL || IS_ERR(clk)) 159 if (clk == NULL || IS_ERR(clk))
175 return -EINVAL; 160 return -EINVAL;
176 return pc_clk_set_flags(clk->id, flags); 161 return clk->ops->set_flags(clk->id, flags);
177} 162}
178EXPORT_SYMBOL(clk_set_flags); 163EXPORT_SYMBOL(clk_set_flags);
179 164
165/* EBI1 is the only shared clock that several clients want to vote on as of
166 * this commit. If this changes in the future, then it might be better to
167 * make clk_min_rate handle the voting or make ebi1_clk_set_min_rate more
168 * generic to support different clocks.
169 */
170static struct clk *ebi1_clk;
180 171
181void __init msm_clock_init(void) 172static void __init set_clock_ops(struct clk *clk)
173{
174 if (!clk->ops) {
175 clk->ops = &clk_ops_pcom;
176 clk->id = clk->remote_id;
177 }
178}
179
180void __init msm_clock_init(struct clk *clock_tbl, unsigned num_clocks)
182{ 181{
183 unsigned n; 182 unsigned n;
184 183
185 spin_lock_init(&clocks_lock); 184 spin_lock_init(&clocks_lock);
186 mutex_lock(&clocks_mutex); 185 mutex_lock(&clocks_mutex);
187 for (n = 0; n < msm_num_clocks; n++) 186 msm_clocks = clock_tbl;
187 msm_num_clocks = num_clocks;
188 for (n = 0; n < msm_num_clocks; n++) {
189 set_clock_ops(&msm_clocks[n]);
188 list_add_tail(&msm_clocks[n].list, &clocks); 190 list_add_tail(&msm_clocks[n].list, &clocks);
191 }
189 mutex_unlock(&clocks_mutex); 192 mutex_unlock(&clocks_mutex);
193
194 ebi1_clk = clk_get(NULL, "ebi1_clk");
195 BUG_ON(ebi1_clk == NULL);
196
197}
198
199#if defined(CONFIG_DEBUG_FS)
200static struct clk *msm_clock_get_nth(unsigned index)
201{
202 if (index < msm_num_clocks)
203 return msm_clocks + index;
204 else
205 return 0;
206}
207
208static int clock_debug_rate_set(void *data, u64 val)
209{
210 struct clk *clock = data;
211 int ret;
212
213 /* Only increases to max rate will succeed, but that's actually good
214 * for debugging purposes. So we don't check for error. */
215 if (clock->flags & CLK_MAX)
216 clk_set_max_rate(clock, val);
217 if (clock->flags & CLK_MIN)
218 ret = clk_set_min_rate(clock, val);
219 else
220 ret = clk_set_rate(clock, val);
221 if (ret != 0)
222 printk(KERN_ERR "clk_set%s_rate failed (%d)\n",
223 (clock->flags & CLK_MIN) ? "_min" : "", ret);
224 return ret;
225}
226
227static int clock_debug_rate_get(void *data, u64 *val)
228{
229 struct clk *clock = data;
230 *val = clk_get_rate(clock);
231 return 0;
232}
233
234static int clock_debug_enable_set(void *data, u64 val)
235{
236 struct clk *clock = data;
237 int rc = 0;
238
239 if (val)
240 rc = clock->ops->enable(clock->id);
241 else
242 clock->ops->disable(clock->id);
243
244 return rc;
190} 245}
191 246
247static int clock_debug_enable_get(void *data, u64 *val)
248{
249 struct clk *clock = data;
250
251 *val = clock->ops->is_enabled(clock->id);
252
253 return 0;
254}
255
256static int clock_debug_local_get(void *data, u64 *val)
257{
258 struct clk *clock = data;
259
260 *val = clock->ops != &clk_ops_pcom;
261
262 return 0;
263}
264
265DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_debug_rate_get,
266 clock_debug_rate_set, "%llu\n");
267DEFINE_SIMPLE_ATTRIBUTE(clock_enable_fops, clock_debug_enable_get,
268 clock_debug_enable_set, "%llu\n");
269DEFINE_SIMPLE_ATTRIBUTE(clock_local_fops, clock_debug_local_get,
270 NULL, "%llu\n");
271
272static int __init clock_debug_init(void)
273{
274 struct dentry *dent_rate, *dent_enable, *dent_local;
275 struct clk *clock;
276 unsigned n = 0;
277 char temp[50], *ptr;
278
279 dent_rate = debugfs_create_dir("clk_rate", 0);
280 if (IS_ERR(dent_rate))
281 return PTR_ERR(dent_rate);
282
283 dent_enable = debugfs_create_dir("clk_enable", 0);
284 if (IS_ERR(dent_enable))
285 return PTR_ERR(dent_enable);
286
287 dent_local = debugfs_create_dir("clk_local", NULL);
288 if (IS_ERR(dent_local))
289 return PTR_ERR(dent_local);
290
291 while ((clock = msm_clock_get_nth(n++)) != 0) {
292 strncpy(temp, clock->dbg_name, ARRAY_SIZE(temp)-1);
293 for (ptr = temp; *ptr; ptr++)
294 *ptr = tolower(*ptr);
295 debugfs_create_file(temp, 0644, dent_rate,
296 clock, &clock_rate_fops);
297 debugfs_create_file(temp, 0644, dent_enable,
298 clock, &clock_enable_fops);
299 debugfs_create_file(temp, S_IRUGO, dent_local,
300 clock, &clock_local_fops);
301 }
302 return 0;
303}
304
305device_initcall(clock_debug_init);
306#endif
307
192/* The bootloader and/or AMSS may have left various clocks enabled. 308/* The bootloader and/or AMSS may have left various clocks enabled.
193 * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have 309 * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have
194 * not been explicitly enabled by a clk_enable() call. 310 * not been explicitly enabled by a clk_enable() call.
@@ -205,7 +321,7 @@ static int __init clock_late_init(void)
205 spin_lock_irqsave(&clocks_lock, flags); 321 spin_lock_irqsave(&clocks_lock, flags);
206 if (!clk->count) { 322 if (!clk->count) {
207 count++; 323 count++;
208 pc_clk_disable(clk->id); 324 clk->ops->auto_off(clk->id);
209 } 325 }
210 spin_unlock_irqrestore(&clocks_lock, flags); 326 spin_unlock_irqrestore(&clocks_lock, flags);
211 } 327 }
@@ -216,3 +332,4 @@ static int __init clock_late_init(void)
216} 332}
217 333
218late_initcall(clock_late_init); 334late_initcall(clock_late_init);
335
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index f875e1544e5f..598db9290422 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 QUALCOMM Incorporated 4 * Copyright (c) 2007-2010, Code Aurora Forum. 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
@@ -18,6 +18,9 @@
18#define __ARCH_ARM_MACH_MSM_CLOCK_H 18#define __ARCH_ARM_MACH_MSM_CLOCK_H
19 19
20#include <linux/list.h> 20#include <linux/list.h>
21#include <mach/clk.h>
22
23#include "clock-pcom.h"
21 24
22#define CLKFLAG_INVERT 0x00000001 25#define CLKFLAG_INVERT 0x00000001
23#define CLKFLAG_NOINVERT 0x00000002 26#define CLKFLAG_NOINVERT 0x00000002
@@ -25,14 +28,32 @@
25#define CLKFLAG_NORESET 0x00000008 28#define CLKFLAG_NORESET 0x00000008
26 29
27#define CLK_FIRST_AVAILABLE_FLAG 0x00000100 30#define CLK_FIRST_AVAILABLE_FLAG 0x00000100
28#define CLKFLAG_USE_MIN_MAX_TO_SET 0x00000200 31#define CLKFLAG_AUTO_OFF 0x00000200
29#define CLKFLAG_AUTO_OFF 0x00000400 32#define CLKFLAG_MIN 0x00000400
33#define CLKFLAG_MAX 0x00000800
34
35struct clk_ops {
36 int (*enable)(unsigned id);
37 void (*disable)(unsigned id);
38 void (*auto_off)(unsigned id);
39 int (*reset)(unsigned id, enum clk_reset_action action);
40 int (*set_rate)(unsigned id, unsigned rate);
41 int (*set_min_rate)(unsigned id, unsigned rate);
42 int (*set_max_rate)(unsigned id, unsigned rate);
43 int (*set_flags)(unsigned id, unsigned flags);
44 unsigned (*get_rate)(unsigned id);
45 unsigned (*is_enabled)(unsigned id);
46 long (*round_rate)(unsigned id, unsigned rate);
47};
30 48
31struct clk { 49struct clk {
32 uint32_t id; 50 uint32_t id;
51 uint32_t remote_id;
33 uint32_t count; 52 uint32_t count;
34 uint32_t flags; 53 uint32_t flags;
35 const char *name; 54 const char *name;
55 struct clk_ops *ops;
56 const char *dbg_name;
36 struct list_head list; 57 struct list_head list;
37 struct device *dev; 58 struct device *dev;
38}; 59};
@@ -41,8 +62,47 @@ struct clk {
41#define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104) 62#define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104)
42#define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124) 63#define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124)
43 64
44extern struct clk msm_clocks[]; 65#ifdef CONFIG_DEBUG_FS
45extern unsigned msm_num_clocks; 66#define CLOCK_DBG_NAME(x) .dbg_name = x,
67#else
68#define CLOCK_DBG_NAME(x)
69#endif
70
71#define CLOCK(clk_name, clk_id, clk_dev, clk_flags) { \
72 .name = clk_name, \
73 .id = clk_id, \
74 .flags = clk_flags, \
75 .dev = clk_dev, \
76 CLOCK_DBG_NAME(#clk_id) \
77 }
78
79#define OFF CLKFLAG_AUTO_OFF
80#define CLK_MIN CLKFLAG_MIN
81#define CLK_MAX CLKFLAG_MAX
82#define CLK_MINMAX (CLK_MIN | CLK_MAX)
83#define NR_CLKS P_NR_CLKS
84
85enum {
86 PLL_0 = 0,
87 PLL_1,
88 PLL_2,
89 PLL_3,
90 PLL_4,
91 PLL_5,
92 PLL_6,
93 NUM_PLL
94};
95
96enum clkvote_client {
97 CLKVOTE_ACPUCLK = 0,
98 CLKVOTE_PMQOS,
99 CLKVOTE_MAX,
100};
101
102int msm_clock_require_tcxo(unsigned long *reason, int nbits);
103int msm_clock_get_name(uint32_t id, char *name, uint32_t size);
104int ebi1_clk_set_min_rate(enum clkvote_client client, unsigned long rate);
105unsigned long clk_get_max_axi_khz(void);
46 106
47#endif 107#endif
48 108
diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c
index 982f1da60160..fde9d8f69f10 100644
--- a/arch/arm/mach-msm/devices-msm7x00.c
+++ b/arch/arm/mach-msm/devices-msm7x00.c
@@ -24,6 +24,8 @@
24#include <linux/mtd/nand.h> 24#include <linux/mtd/nand.h>
25#include <linux/mtd/partitions.h> 25#include <linux/mtd/partitions.h>
26 26
27
28#include "clock.h"
27#include <mach/mmc.h> 29#include <mach/mmc.h>
28 30
29static struct resource resources_uart1[] = { 31static struct resource resources_uart1[] = {
@@ -344,3 +346,48 @@ int __init msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat,
344 return platform_device_register(pdev); 346 return platform_device_register(pdev);
345} 347}
346 348
349struct clk msm_clocks_7x01a[] = {
350 CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
351 CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0),
352 CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, 0),
353 CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0),
354 CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0),
355 CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF),
356 CLK_PCOM("gp_clk", GP_CLK, NULL, 0),
357 CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, OFF),
358 CLK_PCOM("i2c_clk", I2C_CLK, &msm_device_i2c.dev, 0),
359 CLK_PCOM("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0),
360 CLK_PCOM("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0),
361 CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF),
362 CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0),
363 CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF),
364 CLK_PCOM("pbus_clk", PBUS_CLK, NULL, 0),
365 CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0),
366 CLK_PCOM("pmdh_clk", PMDH_CLK, NULL, OFF ),
367 CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF),
368 CLK_PCOM("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF),
369 CLK_PCOM("sdc_pclk", SDC1_P_CLK, &msm_device_sdc1.dev, OFF),
370 CLK_PCOM("sdc_clk", SDC2_CLK, &msm_device_sdc2.dev, OFF),
371 CLK_PCOM("sdc_pclk", SDC2_P_CLK, &msm_device_sdc2.dev, OFF),
372 CLK_PCOM("sdc_clk", SDC3_CLK, &msm_device_sdc3.dev, OFF),
373 CLK_PCOM("sdc_pclk", SDC3_P_CLK, &msm_device_sdc3.dev, OFF),
374 CLK_PCOM("sdc_clk", SDC4_CLK, &msm_device_sdc4.dev, OFF),
375 CLK_PCOM("sdc_pclk", SDC4_P_CLK, &msm_device_sdc4.dev, OFF),
376 CLK_PCOM("tsif_clk", TSIF_CLK, NULL, 0),
377 CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0),
378 CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0),
379 CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0),
380 CLK_PCOM("uart_clk", UART1_CLK, &msm_device_uart1.dev, OFF),
381 CLK_PCOM("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0),
382 CLK_PCOM("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF),
383 CLK_PCOM("uart1dm_clk", UART1DM_CLK, NULL, OFF),
384 CLK_PCOM("uart2dm_clk", UART2DM_CLK, NULL, 0),
385 CLK_PCOM("usb_hs_clk", USB_HS_CLK, &msm_device_hsusb.dev, OFF),
386 CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, &msm_device_hsusb.dev, OFF),
387 CLK_PCOM("usb_otg_clk", USB_OTG_CLK, NULL, 0),
388 CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF ),
389 CLK_PCOM("vfe_clk", VFE_CLK, NULL, OFF),
390 CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF),
391};
392
393unsigned msm_num_clocks_7x01a = ARRAY_SIZE(msm_clocks_7x01a);
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 0744c4a27d6a..19c5de99e20c 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -16,6 +16,8 @@
16#ifndef __ARCH_ARM_MACH_MSM_DEVICES_H 16#ifndef __ARCH_ARM_MACH_MSM_DEVICES_H
17#define __ARCH_ARM_MACH_MSM_DEVICES_H 17#define __ARCH_ARM_MACH_MSM_DEVICES_H
18 18
19#include "clock.h"
20
19extern struct platform_device msm_device_uart1; 21extern struct platform_device msm_device_uart1;
20extern struct platform_device msm_device_uart2; 22extern struct platform_device msm_device_uart2;
21extern struct platform_device msm_device_uart3; 23extern struct platform_device msm_device_uart3;
@@ -33,4 +35,7 @@ extern struct platform_device msm_device_smd;
33 35
34extern struct platform_device msm_device_nand; 36extern struct platform_device msm_device_nand;
35 37
38extern struct clk msm_clocks_7x01a[];
39extern unsigned msm_num_clocks_7x01a;
40
36#endif 41#endif
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 7933641c4761..e302fbdc439b 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -30,14 +30,15 @@ struct msm_acpu_clock_platform_data
30 unsigned long wait_for_irq_khz; 30 unsigned long wait_for_irq_khz;
31}; 31};
32 32
33 33struct clk;
34
34/* common init routines for use by arch/arm/mach-msm/board-*.c */ 35/* common init routines for use by arch/arm/mach-msm/board-*.c */
35 36
36void __init msm_add_devices(void); 37void __init msm_add_devices(void);
37void __init msm_map_common_io(void); 38void __init msm_map_common_io(void);
38void __init msm_init_irq(void); 39void __init msm_init_irq(void);
39void __init msm_init_gpio(void); 40void __init msm_init_gpio(void);
40void __init msm_clock_init(void); 41void __init msm_clock_init(struct clk *clock_tbl, unsigned num_clocks);
41void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *); 42void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *);
42 43
43#endif 44#endif
diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h
new file mode 100644
index 000000000000..c05ca40478c7
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/clk.h
@@ -0,0 +1,57 @@
1/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of Code Aurora Forum, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29#ifndef __MACH_CLK_H
30#define __MACH_CLK_H
31
32/* Magic rate value for use with PM QOS to request the board's maximum
33 * supported AXI rate. PM QOS will only pass positive s32 rate values
34 * through to the clock driver, so INT_MAX is used.
35 */
36#define MSM_AXI_MAX_FREQ LONG_MAX
37
38enum clk_reset_action {
39 CLK_RESET_DEASSERT = 0,
40 CLK_RESET_ASSERT = 1
41};
42
43struct clk;
44
45/* Rate is minimum clock rate in Hz */
46int clk_set_min_rate(struct clk *clk, unsigned long rate);
47
48/* Rate is maximum clock rate in Hz */
49int clk_set_max_rate(struct clk *clk, unsigned long rate);
50
51/* Assert/Deassert reset to a hardware block associated with a clock */
52int clk_reset(struct clk *clk, enum clk_reset_action action);
53
54/* Set clock-specific configuration parameters */
55int clk_set_flags(struct clk *clk, unsigned long flags);
56
57#endif