Commit 5e96da5d authored by Daniel Walker's avatar Daniel Walker
Browse files

msm: generalize clock support.



The 'PCOM' method of clock control (commands issued to the radio
CPU) is shared across several (but not all) Qualcomm SOCs.
Generalize this clock mechanism so these other SOCs can be added.
Signed-off-by: default avatarGregory Bean <gbean@codeaurora.org>
Signed-off-by: default avatarDavid Brown <davidb@codeaurora.org>
Signed-off-by: default avatarDaniel Walker <dwalker@codeaurora.org>
Signed-off-by: default avatarAbhijeet Dharmapurikar <adharmap@codeaurora.org>
Signed-off-by: default avatarStepan Moskovchenko <stepanm@codeaurora.org>
parent ec4d7925
......@@ -2,7 +2,7 @@ obj-y += io.o idle.o irq.o timer.o dma.o
obj-y += proc_comm.o
obj-y += vreg.o
obj-y += acpuclock-arm11.o
obj-y += clock.o clock-7x01a.o
obj-y += clock.o clock-pcom.o
obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
obj-$(CONFIG_MSM_SMD) += last_radio_log.o
......
......@@ -90,7 +90,7 @@ static void __init halibut_fixup(struct machine_desc *desc, struct tag *tags,
static void __init halibut_map_io(void)
{
msm_map_common_io();
msm_clock_init();
msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
}
MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
......
......@@ -78,7 +78,7 @@ static void __init trout_map_io(void)
writeb(0x80, TROUT_CPLD_BASE + 0x00);
#endif
msm_clock_init();
msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
}
MACHINE_START(TROUT, "HTC Dream")
......
/* arch/arm/mach-msm/clock-7x01a.c
*
* Clock tables for MSM7X01A
*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2007 QUALCOMM Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include "clock.h"
#include "devices.h"
/* clock IDs used by the modem processor */
#define ACPU_CLK 0 /* Applications processor clock */
#define ADM_CLK 1 /* Applications data mover clock */
#define ADSP_CLK 2 /* ADSP clock */
#define EBI1_CLK 3 /* External bus interface 1 clock */
#define EBI2_CLK 4 /* External bus interface 2 clock */
#define ECODEC_CLK 5 /* External CODEC clock */
#define EMDH_CLK 6 /* External MDDI host clock */
#define GP_CLK 7 /* General purpose clock */
#define GRP_CLK 8 /* Graphics clock */
#define I2C_CLK 9 /* I2C clock */
#define ICODEC_RX_CLK 10 /* Internal CODEX RX clock */
#define ICODEC_TX_CLK 11 /* Internal CODEX TX clock */
#define IMEM_CLK 12 /* Internal graphics memory clock */
#define MDC_CLK 13 /* MDDI client clock */
#define MDP_CLK 14 /* Mobile display processor clock */
#define PBUS_CLK 15 /* Peripheral bus clock */
#define PCM_CLK 16 /* PCM clock */
#define PMDH_CLK 17 /* Primary MDDI host clock */
#define SDAC_CLK 18 /* Stereo DAC clock */
#define SDC1_CLK 19 /* Secure Digital Card clocks */
#define SDC1_PCLK 20
#define SDC2_CLK 21
#define SDC2_PCLK 22
#define SDC3_CLK 23
#define SDC3_PCLK 24
#define SDC4_CLK 25
#define SDC4_PCLK 26
#define TSIF_CLK 27 /* Transport Stream Interface clocks */
#define TSIF_REF_CLK 28
#define TV_DAC_CLK 29 /* TV clocks */
#define TV_ENC_CLK 30
#define UART1_CLK 31 /* UART clocks */
#define UART2_CLK 32
#define UART3_CLK 33
#define UART1DM_CLK 34
#define UART2DM_CLK 35
#define USB_HS_CLK 36 /* High speed USB core clock */
#define USB_HS_PCLK 37 /* High speed USB pbus clock */
#define USB_OTG_CLK 38 /* Full speed USB clock */
#define VDC_CLK 39 /* Video controller clock */
#define VFE_CLK 40 /* Camera / Video Front End clock */
#define VFE_MDC_CLK 41 /* VFE MDDI client clock */
#define NR_CLKS 42
#define CLOCK(clk_name, clk_id, clk_dev, clk_flags) { \
.name = clk_name, \
.id = clk_id, \
.flags = clk_flags, \
.dev = clk_dev, \
}
#define OFF CLKFLAG_AUTO_OFF
#define MINMAX CLKFLAG_USE_MIN_MAX_TO_SET
struct clk msm_clocks[] = {
CLOCK("adm_clk", ADM_CLK, NULL, 0),
CLOCK("adsp_clk", ADSP_CLK, NULL, 0),
CLOCK("ebi1_clk", EBI1_CLK, NULL, 0),
CLOCK("ebi2_clk", EBI2_CLK, NULL, 0),
CLOCK("ecodec_clk", ECODEC_CLK, NULL, 0),
CLOCK("emdh_clk", EMDH_CLK, NULL, OFF),
CLOCK("gp_clk", GP_CLK, NULL, 0),
CLOCK("grp_clk", GRP_CLK, NULL, OFF),
CLOCK("i2c_clk", I2C_CLK, &msm_device_i2c.dev, 0),
CLOCK("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0),
CLOCK("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0),
CLOCK("imem_clk", IMEM_CLK, NULL, OFF),
CLOCK("mdc_clk", MDC_CLK, NULL, 0),
CLOCK("mdp_clk", MDP_CLK, NULL, OFF),
CLOCK("pbus_clk", PBUS_CLK, NULL, 0),
CLOCK("pcm_clk", PCM_CLK, NULL, 0),
CLOCK("pmdh_clk", PMDH_CLK, NULL, OFF | MINMAX),
CLOCK("sdac_clk", SDAC_CLK, NULL, OFF),
CLOCK("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF),
CLOCK("sdc_pclk", SDC1_PCLK, &msm_device_sdc1.dev, OFF),
CLOCK("sdc_clk", SDC2_CLK, &msm_device_sdc2.dev, OFF),
CLOCK("sdc_pclk", SDC2_PCLK, &msm_device_sdc2.dev, OFF),
CLOCK("sdc_clk", SDC3_CLK, &msm_device_sdc3.dev, OFF),
CLOCK("sdc_pclk", SDC3_PCLK, &msm_device_sdc3.dev, OFF),
CLOCK("sdc_clk", SDC4_CLK, &msm_device_sdc4.dev, OFF),
CLOCK("sdc_pclk", SDC4_PCLK, &msm_device_sdc4.dev, OFF),
CLOCK("tsif_clk", TSIF_CLK, NULL, 0),
CLOCK("tsif_ref_clk", TSIF_REF_CLK, NULL, 0),
CLOCK("tv_dac_clk", TV_DAC_CLK, NULL, 0),
CLOCK("tv_enc_clk", TV_ENC_CLK, NULL, 0),
CLOCK("uart_clk", UART1_CLK, &msm_device_uart1.dev, OFF),
CLOCK("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0),
CLOCK("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF),
CLOCK("uart1dm_clk", UART1DM_CLK, NULL, OFF),
CLOCK("uart2dm_clk", UART2DM_CLK, NULL, 0),
CLOCK("usb_hs_clk", USB_HS_CLK, &msm_device_hsusb.dev, OFF),
CLOCK("usb_hs_pclk", USB_HS_PCLK, &msm_device_hsusb.dev, OFF),
CLOCK("usb_otg_clk", USB_OTG_CLK, NULL, 0),
CLOCK("vdc_clk", VDC_CLK, NULL, OFF | MINMAX),
CLOCK("vfe_clk", VFE_CLK, NULL, OFF),
CLOCK("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF),
};
unsigned msm_num_clocks = ARRAY_SIZE(msm_clocks);
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/err.h>
#include <linux/ctype.h>
#include <linux/stddef.h>
#include <mach/clk.h>
#include "proc_comm.h"
#include "clock.h"
/*
* glue for the proc_comm interface
*/
int pc_clk_enable(unsigned id)
{
int rc = msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
if (rc < 0)
return rc;
else
return (int)id < 0 ? -EINVAL : 0;
}
void pc_clk_disable(unsigned id)
{
msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
}
int pc_clk_reset(unsigned id, enum clk_reset_action action)
{
int rc;
if (action == CLK_RESET_ASSERT)
rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_ASSERT, &id, NULL);
else
rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_DEASSERT, &id, NULL);
if (rc < 0)
return rc;
else
return (int)id < 0 ? -EINVAL : 0;
}
int pc_clk_set_rate(unsigned id, unsigned rate)
{
/* The rate _might_ be rounded off to the nearest KHz value by the
* remote function. So a return value of 0 doesn't necessarily mean
* that the exact rate was set successfully.
*/
int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
if (rc < 0)
return rc;
else
return (int)id < 0 ? -EINVAL : 0;
}
int pc_clk_set_min_rate(unsigned id, unsigned rate)
{
int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
if (rc < 0)
return rc;
else
return (int)id < 0 ? -EINVAL : 0;
}
int pc_clk_set_max_rate(unsigned id, unsigned rate)
{
int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
if (rc < 0)
return rc;
else
return (int)id < 0 ? -EINVAL : 0;
}
int pc_clk_set_flags(unsigned id, unsigned flags)
{
int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags);
if (rc < 0)
return rc;
else
return (int)id < 0 ? -EINVAL : 0;
}
unsigned pc_clk_get_rate(unsigned id)
{
if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
return 0;
else
return id;
}
unsigned pc_clk_is_enabled(unsigned id)
{
if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
return 0;
else
return id;
}
long pc_clk_round_rate(unsigned id, unsigned rate)
{
/* Not really supported; pc_clk_set_rate() does rounding on it's own. */
return rate;
}
struct clk_ops clk_ops_pcom = {
.enable = pc_clk_enable,
.disable = pc_clk_disable,
.auto_off = pc_clk_disable,
.reset = pc_clk_reset,
.set_rate = pc_clk_set_rate,
.set_min_rate = pc_clk_set_min_rate,
.set_max_rate = pc_clk_set_max_rate,
.set_flags = pc_clk_set_flags,
.get_rate = pc_clk_get_rate,
.is_enabled = pc_clk_is_enabled,
.round_rate = pc_clk_round_rate,
};
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H
#define __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H
/* clock IDs used by the modem processor */
#define P_ACPU_CLK 0 /* Applications processor clock */
#define P_ADM_CLK 1 /* Applications data mover clock */
#define P_ADSP_CLK 2 /* ADSP clock */
#define P_EBI1_CLK 3 /* External bus interface 1 clock */
#define P_EBI2_CLK 4 /* External bus interface 2 clock */
#define P_ECODEC_CLK 5 /* External CODEC clock */
#define P_EMDH_CLK 6 /* External MDDI host clock */
#define P_GP_CLK 7 /* General purpose clock */
#define P_GRP_3D_CLK 8 /* Graphics clock */
#define P_I2C_CLK 9 /* I2C clock */
#define P_ICODEC_RX_CLK 10 /* Internal CODEX RX clock */
#define P_ICODEC_TX_CLK 11 /* Internal CODEX TX clock */
#define P_IMEM_CLK 12 /* Internal graphics memory clock */
#define P_MDC_CLK 13 /* MDDI client clock */
#define P_MDP_CLK 14 /* Mobile display processor clock */
#define P_PBUS_CLK 15 /* Peripheral bus clock */
#define P_PCM_CLK 16 /* PCM clock */
#define P_PMDH_CLK 17 /* Primary MDDI host clock */
#define P_SDAC_CLK 18 /* Stereo DAC clock */
#define P_SDC1_CLK 19 /* Secure Digital Card clocks */
#define P_SDC1_P_CLK 20
#define P_SDC2_CLK 21
#define P_SDC2_P_CLK 22
#define P_SDC3_CLK 23
#define P_SDC3_P_CLK 24
#define P_SDC4_CLK 25
#define P_SDC4_P_CLK 26
#define P_TSIF_CLK 27 /* Transport Stream Interface clocks */
#define P_TSIF_REF_CLK 28
#define P_TV_DAC_CLK 29 /* TV clocks */
#define P_TV_ENC_CLK 30
#define P_UART1_CLK 31 /* UART clocks */
#define P_UART2_CLK 32
#define P_UART3_CLK 33
#define P_UART1DM_CLK 34
#define P_UART2DM_CLK 35
#define P_USB_HS_CLK 36 /* High speed USB core clock */
#define P_USB_HS_P_CLK 37 /* High speed USB pbus clock */
#define P_USB_OTG_CLK 38 /* Full speed USB clock */
#define P_VDC_CLK 39 /* Video controller clock */
#define P_VFE_MDC_CLK 40 /* Camera / Video Front End clock */
#define P_VFE_CLK 41 /* VFE MDDI client clock */
#define P_MDP_LCDC_PCLK_CLK 42
#define P_MDP_LCDC_PAD_PCLK_CLK 43
#define P_MDP_VSYNC_CLK 44
#define P_SPI_CLK 45
#define P_VFE_AXI_CLK 46
#define P_USB_HS2_CLK 47 /* High speed USB 2 core clock */
#define P_USB_HS2_P_CLK 48 /* High speed USB 2 pbus clock */
#define P_USB_HS3_CLK 49 /* High speed USB 3 core clock */
#define P_USB_HS3_P_CLK 50 /* High speed USB 3 pbus clock */
#define P_GRP_3D_P_CLK 51 /* Graphics pbus clock */
#define P_USB_PHY_CLK 52 /* USB PHY clock */
#define P_USB_HS_CORE_CLK 53 /* High speed USB 1 core clock */
#define P_USB_HS2_CORE_CLK 54 /* High speed USB 2 core clock */
#define P_USB_HS3_CORE_CLK 55 /* High speed USB 3 core clock */
#define P_CAM_M_CLK 56
#define P_CAMIF_PAD_P_CLK 57
#define P_GRP_2D_CLK 58
#define P_GRP_2D_P_CLK 59
#define P_I2S_CLK 60
#define P_JPEG_CLK 61
#define P_JPEG_P_CLK 62
#define P_LPA_CODEC_CLK 63
#define P_LPA_CORE_CLK 64
#define P_LPA_P_CLK 65
#define P_MDC_IO_CLK 66
#define P_MDC_P_CLK 67
#define P_MFC_CLK 68
#define P_MFC_DIV2_CLK 69
#define P_MFC_P_CLK 70
#define P_QUP_I2C_CLK 71
#define P_ROTATOR_IMEM_CLK 72
#define P_ROTATOR_P_CLK 73
#define P_VFE_CAMIF_CLK 74
#define P_VFE_P_CLK 75
#define P_VPE_CLK 76
#define P_I2C_2_CLK 77
#define P_MI2S_CODEC_RX_S_CLK 78
#define P_MI2S_CODEC_RX_M_CLK 79
#define P_MI2S_CODEC_TX_S_CLK 80
#define P_MI2S_CODEC_TX_M_CLK 81
#define P_PMDH_P_CLK 82
#define P_EMDH_P_CLK 83
#define P_SPI_P_CLK 84
#define P_TSIF_P_CLK 85
#define P_MDP_P_CLK 86
#define P_SDAC_M_CLK 87
#define P_MI2S_S_CLK 88
#define P_MI2S_M_CLK 89
#define P_AXI_ROTATOR_CLK 90
#define P_HDMI_CLK 91
#define P_CSI0_CLK 92
#define P_CSI0_VFE_CLK 93
#define P_CSI0_P_CLK 94
#define P_CSI1_CLK 95
#define P_CSI1_VFE_CLK 96
#define P_CSI1_P_CLK 97
#define P_GSBI_CLK 98
#define P_GSBI_P_CLK 99
#define P_NR_CLKS 100
struct clk_ops;
extern struct clk_ops clk_ops_pcom;
int pc_clk_reset(unsigned id, enum clk_reset_action action);
#define CLK_PCOM(clk_name, clk_id, clk_dev, clk_flags) { \
.name = clk_name, \
.id = P_##clk_id, \
.remote_id = P_##clk_id, \
.ops = &clk_ops_pcom, \
.flags = clk_flags, \
.dev = clk_dev, \
.dbg_name = #clk_id, \
}
#endif
/* arch/arm/mach-msm/clock.c
*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2007 QUALCOMM Incorporated
* Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
......@@ -22,6 +22,10 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/spinlock.h>
#include <linux/debugfs.h>
#include <linux/ctype.h>
#include <linux/pm_qos_params.h>
#include <mach/clk.h>
#include "clock.h"
#include "proc_comm.h"
......@@ -29,61 +33,15 @@
static DEFINE_MUTEX(clocks_mutex);
static DEFINE_SPINLOCK(clocks_lock);
static LIST_HEAD(clocks);
struct clk *msm_clocks;
unsigned msm_num_clocks;
/*
* glue for the proc_comm interface
* Bitmap of enabled clocks, excluding ACPU which is always
* enabled
*/
static inline int pc_clk_enable(unsigned id)
{
return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
}
static inline void pc_clk_disable(unsigned id)
{
msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
}
static inline int pc_clk_set_rate(unsigned id, unsigned rate)
{
return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
}
static inline int pc_clk_set_min_rate(unsigned id, unsigned rate)
{
return msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
}
static inline int pc_clk_set_max_rate(unsigned id, unsigned rate)
{
return msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
}
static inline int pc_clk_set_flags(unsigned id, unsigned flags)
{
return msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags);
}
static inline unsigned pc_clk_get_rate(unsigned id)
{
if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
return 0;
else
return id;
}
static inline unsigned pc_clk_is_enabled(unsigned id)
{
if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
return 0;
else
return id;
}
static inline int pc_pll_request(unsigned id, unsigned on)
{
on = !!on;
return msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on);
}
static DECLARE_BITMAP(clock_map_enabled, NR_CLKS);
static DEFINE_SPINLOCK(clock_map_lock);
/*
* Standard clock functions defined in include/linux/clk.h
......@@ -119,8 +77,12 @@ int clk_enable(struct clk *clk)
unsigned long flags;
spin_lock_irqsave(&clocks_lock, flags);
clk->count++;
if (clk->count == 1)
pc_clk_enable(clk->id);
if (clk->count == 1) {
clk->ops->enable(clk->id);
spin_lock(&clock_map_lock);
clock_map_enabled[BIT_WORD(clk->id)] |= BIT_MASK(clk->id);
spin_unlock(&clock_map_lock);
}
spin_unlock_irqrestore(&clocks_lock, flags);
return 0;
}
......@@ -132,31 +94,54 @@ void clk_disable(struct clk *clk)
spin_lock_irqsave(&clocks_lock, flags);
BUG_ON(clk->count == 0);
clk->count--;
if (clk->count == 0)
pc_clk_disable(clk->id);
if (clk->count == 0) {
clk->ops->disable(clk->id);
spin_lock(&clock_map_lock);
clock_map_enabled[BIT_WORD(clk->id)] &= ~BIT_MASK(clk->id);
spin_unlock(&clock_map_lock);
}
spin_unlock_irqrestore(&clocks_lock, flags);
}
EXPORT_SYMBOL(clk_disable);
int clk_reset(struct clk *clk, enum clk_reset_action action)
{
if (!clk->ops->reset)
clk->ops->reset = &pc_clk_reset;
return clk->ops->reset(clk->remote_id, action);
}
EXPORT_SYMBOL(clk_reset);
unsigned long clk_get_rate(struct clk *clk)
{
return pc_clk_get_rate(clk->id);
return clk->ops->get_rate(clk->id);
}
EXPORT_SYMBOL(clk_get_rate);
int clk_set_rate(struct clk *clk, unsigned long rate)
{
int ret;
if (clk->flags & CLKFLAG_USE_MIN_MAX_TO_SET) {
ret = pc_clk_set_max_rate(clk->id, rate);
if (ret)
return ret;
return pc_clk_set_min_rate(clk->id, rate);
}
return pc_clk_set_rate(clk->id, rate);
return clk->ops->set_rate(clk->id, rate);
}
EXPORT_SYMBOL(clk_set_rate);
long clk_round_rate(struct clk *clk, unsigned long rate)
{
return clk->ops->round_rate(clk->id, rate);
}
EXPORT_SYMBOL(clk_round_rate);
int clk_set_min_rate(struct clk *clk, unsigned long rate)
{
return clk->ops->set_min_rate(clk->id, rate);
}
EXPORT_SYMBOL(clk_set_min_rate);
int clk_set_max_rate(struct clk *clk, unsigned long rate)
{
return clk->ops->set_max_rate(clk->id, rate);
}
EXPORT_SYMBOL(clk_set_max_rate);
int clk_set_parent(struct clk *clk, struct clk *parent)
{
return -ENOSYS;
......@@ -173,22 +158,153 @@ int clk_set_flags(struct clk *clk, unsigned long flags)
{
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
return pc_clk_set_flags(clk->id, flags);
return clk->ops->set_flags(clk->id, flags);
}
EXPORT_SYMBOL(clk_set_flags);
/* EBI1 is the only shared clock that several clients want to vote on as of
* this commit. If this changes in the future, then it might be better to
* make clk_min_rate handle the voting or make ebi1_clk_set_min_rate more
* generic to support different clocks.