linux-sh.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] wip: convert imx27 to common struct clk
Date: Tue, 22 Feb 2011 23:33:19 +0000	[thread overview]
Message-ID: <1298417599-23522-1-git-send-email-u.kleine-koenig@pengutronix.de> (raw)
In-Reply-To: <1298256658.861611.43913489619.0.gpush@pororo>

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
Hello,

on top of .38-rc6 + making the clk_{un,}prepare stubs static inline,
this patch makes use of Jeremy's common struct clk (v13) on a i.MX27 based
machine.

This is compile tested using mx21_defconfig and runtime tested using
mx27_defconfig.

I had to degrade one WARN_ON to WARN_ON_ONCE in drivers/clk/clk.c to
actually make it work.  Otherwise console output results in a warning
that results in console output ...

Best regards
Uwe

 arch/arm/mach-imx/Kconfig               |    1 +
 arch/arm/mach-imx/clock-imx27.c         |  186 ++++++++++++++++--------------
 arch/arm/plat-mxc/clock.c               |  127 +++++++++++++++++++++
 arch/arm/plat-mxc/include/mach/clkdev.h |    4 +
 arch/arm/plat-mxc/include/mach/clock.h  |   32 ++++--
 drivers/clk/clk.c                       |    2 +-
 6 files changed, 255 insertions(+), 97 deletions(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 56684b5..f2d3708 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -30,6 +30,7 @@ config SOC_IMX27
 	select IMX_HAVE_DMA_V1
 	select IMX_HAVE_IOMUX_V1
 	select MXC_AVIC
+	select USE_COMMON_STRUCT_CLK
 
 if ARCH_MX1
 
diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c
index 583f251..f413f7b 100644
--- a/arch/arm/mach-imx/clock-imx27.c
+++ b/arch/arm/mach-imx/clock-imx27.c
@@ -68,35 +68,35 @@
 #define CCM_SPCTL1_LF           (1 << 15)
 #define CCM_SPCTL1_BRMO         (1 << 6)
 
-static struct clk mpll_main1_clk, mpll_main2_clk;
+static struct clk_mxc mpll_main1_clk, mpll_main2_clk;
 
-static int clk_pccr_enable(struct clk *clk)
+static int clk_pccr_enable(struct clk_mxc *clk_mxc)
 {
 	unsigned long reg;
 
-	if (!clk->enable_reg)
+	if (!clk_mxc->enable_reg)
 		return 0;
 
-	reg = __raw_readl(clk->enable_reg);
-	reg |= 1 << clk->enable_shift;
-	__raw_writel(reg, clk->enable_reg);
+	reg = __raw_readl(clk_mxc->enable_reg);
+	reg |= 1 << clk_mxc->enable_shift;
+	__raw_writel(reg, clk_mxc->enable_reg);
 
 	return 0;
 }
 
-static void clk_pccr_disable(struct clk *clk)
+static void clk_pccr_disable(struct clk_mxc *clk_mxc)
 {
 	unsigned long reg;
 
-	if (!clk->enable_reg)
+	if (!clk_mxc->enable_reg)
 		return;
 
-	reg = __raw_readl(clk->enable_reg);
-	reg &= ~(1 << clk->enable_shift);
-	__raw_writel(reg, clk->enable_reg);
+	reg = __raw_readl(clk_mxc->enable_reg);
+	reg &= ~(1 << clk_mxc->enable_shift);
+	__raw_writel(reg, clk_mxc->enable_reg);
 }
 
-static int clk_spll_enable(struct clk *clk)
+static int clk_spll_enable(struct clk_mxc *clk_mxc)
 {
 	unsigned long reg;
 
@@ -109,7 +109,7 @@ static int clk_spll_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_spll_disable(struct clk *clk)
+static void clk_spll_disable(struct clk_mxc *clk_mxc)
 {
 	unsigned long reg;
 
@@ -118,11 +118,11 @@ static void clk_spll_disable(struct clk *clk)
 	__raw_writel(reg, CCM_CSCR);
 }
 
-static int clk_cpu_set_parent(struct clk *clk, struct clk *parent)
+static int clk_cpu_set_parent(struct clk_mxc *clk_mxc, struct clk_mxc *parent)
 {
 	int cscr = __raw_readl(CCM_CSCR);
 
-	if (clk->parent = parent)
+	if (clk_mxc->parent = parent)
 		return 0;
 
 	if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
@@ -135,18 +135,18 @@ static int clk_cpu_set_parent(struct clk *clk, struct clk *parent)
 				return -EINVAL;
 		}
 		__raw_writel(cscr, CCM_CSCR);
-		clk->parent = parent;
+		clk_mxc->parent = parent;
 		return 0;
 	}
 	return -ENODEV;
 }
 
-static unsigned long round_rate_cpu(struct clk *clk, unsigned long rate)
+static unsigned long round_rate_cpu(struct clk_mxc *clk_mxc, unsigned long rate)
 {
 	int div;
 	unsigned long parent_rate;
 
-	parent_rate = clk_get_rate(clk->parent);
+	parent_rate = clk_get_rate(&clk_mxc->parent->clk);
 
 	div = parent_rate / rate;
 	if (parent_rate % rate)
@@ -158,13 +158,13 @@ static unsigned long round_rate_cpu(struct clk *clk, unsigned long rate)
 	return parent_rate / div;
 }
 
-static int set_rate_cpu(struct clk *clk, unsigned long rate)
+static int set_rate_cpu(struct clk_mxc *clk_mxc, unsigned long rate)
 {
 	unsigned int div;
 	uint32_t reg;
 	unsigned long parent_rate;
 
-	parent_rate = clk_get_rate(clk->parent);
+	parent_rate = clk_get_rate(&clk_mxc->parent->clk);
 
 	div = parent_rate / rate;
 
@@ -186,12 +186,12 @@ static int set_rate_cpu(struct clk *clk, unsigned long rate)
 	return 0;
 }
 
-static unsigned long round_rate_per(struct clk *clk, unsigned long rate)
+static unsigned long round_rate_per(struct clk_mxc *clk_mxc, unsigned long rate)
 {
 	u32 div;
 	unsigned long parent_rate;
 
-	parent_rate = clk_get_rate(clk->parent);
+	parent_rate = clk_get_rate(&clk_mxc->parent->clk);
 
 	div = parent_rate / rate;
 	if (parent_rate % rate)
@@ -203,15 +203,15 @@ static unsigned long round_rate_per(struct clk *clk, unsigned long rate)
 	return parent_rate / div;
 }
 
-static int set_rate_per(struct clk *clk, unsigned long rate)
+static int set_rate_per(struct clk_mxc *clk_mxc, unsigned long rate)
 {
 	u32 reg;
 	u32 div;
 	unsigned long parent_rate;
 
-	parent_rate = clk_get_rate(clk->parent);
+	parent_rate = clk_get_rate(&clk_mxc->parent->clk);
 
-	if (clk->id < 0 || clk->id > 3)
+	if (clk_mxc->id < 0 || clk_mxc->id > 3)
 		return -EINVAL;
 
 	div = parent_rate / rate;
@@ -219,30 +219,30 @@ static int set_rate_per(struct clk *clk, unsigned long rate)
 		return -EINVAL;
 	div--;
 
-	reg = __raw_readl(CCM_PCDR1) & ~(0x3f << (clk->id << 3));
-	reg |= div << (clk->id << 3);
+	reg = __raw_readl(CCM_PCDR1) & ~(0x3f << (clk_mxc->id << 3));
+	reg |= div << (clk_mxc->id << 3);
 	__raw_writel(reg, CCM_PCDR1);
 
 	return 0;
 }
 
-static unsigned long get_rate_usb(struct clk *clk)
+static unsigned long get_rate_usb(struct clk_mxc *clk_mxc)
 {
 	unsigned long usb_pdf;
 	unsigned long parent_rate;
 
-	parent_rate = clk_get_rate(clk->parent);
+	parent_rate = clk_get_rate(&clk_mxc->parent->clk);
 
 	usb_pdf = (__raw_readl(CCM_CSCR) >> 28) & 0x7;
 
 	return parent_rate / (usb_pdf + 1U);
 }
 
-static unsigned long get_rate_ssix(struct clk *clk, unsigned long pdf)
+static unsigned long get_rate_ssix(struct clk_mxc *clk_mxc, unsigned long pdf)
 {
 	unsigned long parent_rate;
 
-	parent_rate = clk_get_rate(clk->parent);
+	parent_rate = clk_get_rate(&clk_mxc->parent->clk);
 
 	if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
 		pdf += 4;  /* MX27 TO2+ */
@@ -252,22 +252,22 @@ static unsigned long get_rate_ssix(struct clk *clk, unsigned long pdf)
 	return 2UL * parent_rate / pdf;
 }
 
-static unsigned long get_rate_ssi1(struct clk *clk)
+static unsigned long get_rate_ssi1(struct clk_mxc *clk_mxc)
 {
-	return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 16) & 0x3f);
+	return get_rate_ssix(clk_mxc, (__raw_readl(CCM_PCDR0) >> 16) & 0x3f);
 }
 
-static unsigned long get_rate_ssi2(struct clk *clk)
+static unsigned long get_rate_ssi2(struct clk_mxc *clk_mxc)
 {
-	return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 26) & 0x3f);
+	return get_rate_ssix(clk_mxc, (__raw_readl(CCM_PCDR0) >> 26) & 0x3f);
 }
 
-static unsigned long get_rate_nfc(struct clk *clk)
+static unsigned long get_rate_nfc(struct clk_mxc *clk_mxc)
 {
 	unsigned long nfc_pdf;
 	unsigned long parent_rate;
 
-	parent_rate = clk_get_rate(clk->parent);
+	parent_rate = clk_get_rate(&clk_mxc->parent->clk);
 
 	if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
 		nfc_pdf = (__raw_readl(CCM_PCDR0) >> 6) & 0xf;
@@ -277,12 +277,12 @@ static unsigned long get_rate_nfc(struct clk *clk)
 	return parent_rate / (nfc_pdf + 1);
 }
 
-static unsigned long get_rate_vpu(struct clk *clk)
+static unsigned long get_rate_vpu(struct clk_mxc *clk_mxc)
 {
 	unsigned long vpu_pdf;
 	unsigned long parent_rate;
 
-	parent_rate = clk_get_rate(clk->parent);
+	parent_rate = clk_get_rate(&clk_mxc->parent->clk);
 
 	if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
 		vpu_pdf = (__raw_readl(CCM_PCDR0) >> 10) & 0x3f;
@@ -295,25 +295,25 @@ static unsigned long get_rate_vpu(struct clk *clk)
 	return 2UL * parent_rate / vpu_pdf;
 }
 
-static unsigned long round_rate_parent(struct clk *clk, unsigned long rate)
+static unsigned long round_rate_parent(struct clk_mxc *clk_mxc, unsigned long rate)
 {
-	return clk->parent->round_rate(clk->parent, rate);
+	return clk_round_rate(&clk_mxc->parent->clk, rate);
 }
 
-static unsigned long get_rate_parent(struct clk *clk)
+static unsigned long get_rate_parent(struct clk_mxc *clk_mxc)
 {
-	return clk_get_rate(clk->parent);
+	return clk_get_rate(&clk_mxc->parent->clk);
 }
 
-static int set_rate_parent(struct clk *clk, unsigned long rate)
+static int set_rate_parent(struct clk_mxc *clk_mxc, unsigned long rate)
 {
-	return clk->parent->set_rate(clk->parent, rate);
+	return clk_set_rate(&clk_mxc->parent->clk, rate);
 }
 
 /* in Hz */
 static unsigned long external_high_reference = 26000000;
 
-static unsigned long get_rate_high_reference(struct clk *clk)
+static unsigned long get_rate_high_reference(struct clk_mxc *clk)
 {
 	return external_high_reference;
 }
@@ -321,44 +321,44 @@ static unsigned long get_rate_high_reference(struct clk *clk)
 /* in Hz */
 static unsigned long external_low_reference = 32768;
 
-static unsigned long get_rate_low_reference(struct clk *clk)
+static unsigned long get_rate_low_reference(struct clk_mxc *clk_mxc)
 {
 	return external_low_reference;
 }
 
-static unsigned long get_rate_fpm(struct clk *clk)
+static unsigned long get_rate_fpm(struct clk_mxc *clk_mxc)
 {
-	return clk_get_rate(clk->parent) * 1024;
+	return clk_get_rate(&clk_mxc->parent->clk) * 1024;
 }
 
-static unsigned long get_rate_mpll(struct clk *clk)
+static unsigned long get_rate_mpll(struct clk_mxc *clk_mxc)
 {
 	return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
-			clk_get_rate(clk->parent));
+			clk_get_rate(&clk_mxc->parent->clk));
 }
 
-static unsigned long get_rate_mpll_main(struct clk *clk)
+static unsigned long get_rate_mpll_main(struct clk_mxc *clk_mxc)
 {
 	unsigned long parent_rate;
 
-	parent_rate = clk_get_rate(clk->parent);
+	parent_rate = clk_get_rate(&clk_mxc->parent->clk);
 
 	/* i.MX27 TO2:
 	 * clk->id = 0: arm clock source path 1 which is from 2 * MPLL / 2
 	 * clk->id = 1: arm clock source path 2 which is from 2 * MPLL / 3
 	 */
-	if (mx27_revision() >= IMX_CHIP_REVISION_2_0 && clk->id = 1)
+	if (mx27_revision() >= IMX_CHIP_REVISION_2_0 && clk_mxc->id = 1)
 		return 2UL * parent_rate / 3UL;
 
 	return parent_rate;
 }
 
-static unsigned long get_rate_spll(struct clk *clk)
+static unsigned long get_rate_spll(struct clk_mxc *clk_mxc)
 {
 	uint32_t reg;
 	unsigned long rate;
 
-	rate = clk_get_rate(clk->parent);
+	rate = clk_get_rate(&clk_mxc->parent->clk);
 
 	reg = __raw_readl(CCM_SPCTL0);
 
@@ -371,7 +371,7 @@ static unsigned long get_rate_spll(struct clk *clk)
 	return mxc_decode_pll(reg, rate);
 }
 
-static unsigned long get_rate_cpu(struct clk *clk)
+static unsigned long get_rate_cpu(struct clk_mxc *clk_mxc)
 {
 	u32 div;
 	unsigned long rate;
@@ -381,11 +381,11 @@ static unsigned long get_rate_cpu(struct clk *clk)
 	else
 		div = (__raw_readl(CCM_CSCR) >> 13) & 0x7;
 
-	rate = clk_get_rate(clk->parent);
+	rate = clk_get_rate(&clk_mxc->parent->clk);
 	return rate / (div + 1);
 }
 
-static unsigned long get_rate_ahb(struct clk *clk)
+static unsigned long get_rate_ahb(struct clk_mxc *clk_mxc)
 {
 	unsigned long rate, bclk_pdf;
 
@@ -394,33 +394,33 @@ static unsigned long get_rate_ahb(struct clk *clk)
 	else
 		bclk_pdf = (__raw_readl(CCM_CSCR) >> 9) & 0xf;
 
-	rate = clk_get_rate(clk->parent);
+	rate = clk_get_rate(&clk_mxc->parent->clk);
 	return rate / (bclk_pdf + 1);
 }
 
-static unsigned long get_rate_ipg(struct clk *clk)
+static unsigned long get_rate_ipg(struct clk_mxc *clk_mxc)
 {
 	unsigned long rate, ipg_pdf;
 
 	if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
-		return clk_get_rate(clk->parent);
+		return clk_get_rate(&clk_mxc->parent->clk);
 	else
 		ipg_pdf = (__raw_readl(CCM_CSCR) >> 8) & 1;
 
-	rate = clk_get_rate(clk->parent);
+	rate = clk_get_rate(&clk_mxc->parent->clk);
 	return rate / (ipg_pdf + 1);
 }
 
-static unsigned long get_rate_per(struct clk *clk)
+static unsigned long get_rate_per(struct clk_mxc *clk_mxc)
 {
 	unsigned long perclk_pdf, parent_rate;
 
-	parent_rate = clk_get_rate(clk->parent);
+	parent_rate = clk_get_rate(&clk_mxc->parent->clk);
 
-	if (clk->id < 0 || clk->id > 3)
+	if (clk_mxc->id < 0 || clk_mxc->id > 3)
 		return 0;
 
-	perclk_pdf = (__raw_readl(CCM_PCDR1) >> (clk->id << 3)) & 0x3f;
+	perclk_pdf = (__raw_readl(CCM_PCDR1) >> (clk_mxc->id << 3)) & 0x3f;
 
 	return parent_rate / (perclk_pdf + 1);
 }
@@ -430,11 +430,13 @@ static unsigned long get_rate_per(struct clk *clk)
  * Default case is 26MHz. Could be changed at runtime
  * with a call to change_external_high_reference()
  */
-static struct clk ckih_clk = {
+static struct clk_mxc ckih_clk = {
+	.clk = INIT_CLK_MXC(ckih_clk),
 	.get_rate	= get_rate_high_reference,
 };
 
-static struct clk mpll_clk = {
+static struct clk_mxc mpll_clk = {
+	.clk = INIT_CLK_MXC(mpll_clk),
 	.parent		= &ckih_clk,
 	.get_rate	= get_rate_mpll,
 };
@@ -442,7 +444,8 @@ static struct clk mpll_clk = {
 /* For i.MX27 TO2, it is the MPLL path 1 of ARM core
  * It provides the clock source whose rate is same as MPLL
  */
-static struct clk mpll_main1_clk = {
+static struct clk_mxc mpll_main1_clk = {
+	.clk = INIT_CLK_MXC(mpll_main1_clk),
 	.id		= 0,
 	.parent		= &mpll_clk,
 	.get_rate	= get_rate_mpll_main,
@@ -451,23 +454,27 @@ static struct clk mpll_main1_clk = {
 /* For i.MX27 TO2, it is the MPLL path 2 of ARM core
  * It provides the clock source whose rate is same MPLL * 2 / 3
  */
-static struct clk mpll_main2_clk = {
+static struct clk_mxc mpll_main2_clk = {
+	.clk = INIT_CLK_MXC(mpll_main2_clk),
 	.id		= 1,
 	.parent		= &mpll_clk,
 	.get_rate	= get_rate_mpll_main,
 };
 
-static struct clk ahb_clk = {
+static struct clk_mxc ahb_clk = {
+	.clk = INIT_CLK_MXC(ahb_clk),
 	.parent		= &mpll_main2_clk,
 	.get_rate	= get_rate_ahb,
 };
 
-static struct clk ipg_clk = {
+static struct clk_mxc ipg_clk = {
+	.clk = INIT_CLK_MXC(ipg_clk),
 	.parent		= &ahb_clk,
 	.get_rate	= get_rate_ipg,
 };
 
-static struct clk cpu_clk = {
+static struct clk_mxc cpu_clk = {
+	.clk = INIT_CLK_MXC(cpu_clk),
 	.parent = &mpll_main2_clk,
 	.set_parent = clk_cpu_set_parent,
 	.round_rate = round_rate_cpu,
@@ -475,7 +482,8 @@ static struct clk cpu_clk = {
 	.set_rate = set_rate_cpu,
 };
 
-static struct clk spll_clk = {
+static struct clk_mxc spll_clk = {
+	.clk = INIT_CLK_MXC(spll_clk),
 	.parent = &ckih_clk,
 	.get_rate = get_rate_spll,
 	.enable = clk_spll_enable,
@@ -486,12 +494,14 @@ static struct clk spll_clk = {
  * the low frequency external clock reference
  * Default case is 32.768kHz.
  */
-static struct clk ckil_clk = {
+static struct clk_mxc ckil_clk = {
+	.clk = INIT_CLK_MXC(ckil_clk),
 	.get_rate = get_rate_low_reference,
 };
 
 /* Output of frequency pre multiplier */
-static struct clk fpm_clk = {
+static struct clk_mxc fpm_clk = {
+	.clk = INIT_CLK_MXC(fpm_clk),
 	.parent = &ckil_clk,
 	.get_rate = get_rate_fpm,
 };
@@ -500,7 +510,8 @@ static struct clk fpm_clk = {
 #define PCCR1 CCM_PCCR1
 
 #define DEFINE_CLOCK(name, i, er, es, gr, s, p)		\
-	static struct clk name = {			\
+	static struct clk_mxc name = {			\
+		.clk = INIT_CLK_MXC(name),		\
 		.id		= i,			\
 		.enable_reg	= er,			\
 		.enable_shift	= es,			\
@@ -512,7 +523,8 @@ static struct clk fpm_clk = {
 	}
 
 #define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p)	\
-	static struct clk name = {				\
+	static struct clk_mxc name = {				\
+		.clk = INIT_CLK_MXC(name),			\
 		.id		= i,				\
 		.enable_reg	= er,				\
 		.enable_shift	= es,				\
@@ -526,7 +538,7 @@ static struct clk fpm_clk = {
 	}
 
 /* Forward declaration to keep the following list in order */
-static struct clk slcdc_clk1, sahara2_clk1, rtic_clk1, fec_clk1, emma_clk1,
+static struct clk_mxc slcdc_clk1, sahara2_clk1, rtic_clk1, fec_clk1, emma_clk1,
 		  dma_clk1, lcdc_clk2, vpu_clk1;
 
 /* All clocks we can gate through PCCRx in the order of PCCRx bits */
@@ -620,7 +632,7 @@ DEFINE_CLOCK1(csi_clk,     0, NULL,   0, parent, &csi_clk1, &per4_clk);
 	{ \
 		.dev_id = d, \
 		.con_id = n, \
-		.clk = &c, \
+		.clk = &c.clk, \
 	},
 
 static struct clk_lookup lookups[] = {
@@ -746,16 +758,16 @@ int __init mx27_clocks_init(unsigned long fref)
 	spll_clk.disable(&spll_clk);
 
 	/* enable basic clocks */
-	clk_enable(&per1_clk);
-	clk_enable(&gpio_clk);
-	clk_enable(&emi_clk);
-	clk_enable(&iim_clk);
+	clk_enable(&per1_clk.clk);
+	clk_enable(&gpio_clk.clk);
+	clk_enable(&emi_clk.clk);
+	clk_enable(&iim_clk.clk);
 
 #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
-	clk_enable(&uart1_clk);
+	clk_enable(&uart1_clk.clk);
 #endif
 
-	mxc_timer_init(&gpt1_clk, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR),
+	mxc_timer_init(&gpt1_clk.clk, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR),
 			MX27_INT_GPT1);
 
 	return 0;
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c
index 2ed3ab1..3fc75dd 100644
--- a/arch/arm/plat-mxc/clock.c
+++ b/arch/arm/plat-mxc/clock.c
@@ -44,6 +44,131 @@
 static LIST_HEAD(clocks);
 static DEFINE_MUTEX(clocks_mutex);
 
+#ifdef CONFIG_USE_COMMON_STRUCT_CLK
+static int clk_mxc_enable(struct clk *clk)
+{
+	struct clk_mxc *clk_mxc = to_clk_mxc(clk);
+	int ret = 0;
+
+	if (clk_mxc->parent)
+		ret = clk_enable(&clk_mxc->parent->clk);
+
+	if (!ret && clk_mxc->secondary)
+		ret = clk_enable(&clk_mxc->secondary->clk);
+
+	if (!ret && clk_mxc->enable)
+		ret = clk_mxc->enable(clk_mxc);
+
+	return ret;
+}
+
+static void clk_mxc_disable(struct clk *clk)
+{
+	struct clk_mxc *clk_mxc = to_clk_mxc(clk);
+
+	if (clk_mxc->disable)
+		clk_mxc->disable(clk_mxc);
+
+	if (clk_mxc->secondary)
+		clk_disable(&clk_mxc->secondary->clk);
+
+	if (clk_mxc->parent)
+		clk_disable(&clk_mxc->parent->clk);
+}
+
+static unsigned long clk_mxc_get_rate(struct clk *clk)
+{
+	struct clk_mxc *clk_mxc = to_clk_mxc(clk);
+
+	if (clk_mxc->get_rate)
+		return clk_mxc->get_rate(clk_mxc);
+	else if (clk_mxc->parent)
+		return clk_get_rate(&clk_mxc->parent->clk);
+	else
+		return 0UL;
+}
+
+static long clk_mxc_round_rate(struct clk *clk, unsigned long rate)
+{
+	struct clk_mxc *clk_mxc = to_clk_mxc(clk);
+
+	if (clk_mxc->round_rate)
+		return clk_mxc->round_rate(clk_mxc, rate);
+
+	return 0L;
+}
+
+static int clk_mxc_set_rate(struct clk *clk, unsigned long rate)
+{
+	struct clk_mxc *clk_mxc = to_clk_mxc(clk);
+	int ret = -EINVAL;
+
+	if (clk_mxc->set_rate && rate != 0)
+		ret = clk_mxc->set_rate(clk_mxc, rate);
+
+	return ret;
+}
+
+static int clk_mxc_set_parent(struct clk *clk, struct clk *parent)
+{
+	struct clk_mxc *clk_mxc = to_clk_mxc(clk);
+	struct clk *old_parent = parent;
+	struct clk_mxc *parent_mxc = to_clk_mxc(parent);
+	int ret;
+
+	if (!clk_mxc->set_parent)
+		return -EINVAL;
+
+	if (clk->prepare_count) {
+		ret = clk_prepare(parent);
+		if (ret)
+			goto err_prepare_parent;
+	}
+
+	if (clk->enable_count) {
+		ret = clk_enable(parent);
+		if (ret)
+			goto err_enable_parent;
+	}
+
+	ret = clk_mxc->set_parent(clk_mxc, parent_mxc);
+	if (ret = 0) {
+		old_parent = &clk_mxc->parent->clk;
+		clk_mxc->parent = to_clk_mxc(parent);
+	}
+
+	if (clk->enable_count)
+		clk_disable(old_parent);
+err_enable_parent:
+
+	if (clk->prepare_count)
+		clk_unprepare(old_parent);
+err_prepare_parent:
+
+	return ret;
+}
+
+static struct clk *clk_mxc_get_parent(struct clk *clk)
+{
+	struct clk_mxc *clk_mxc = to_clk_mxc(clk);
+
+	if (clk_mxc->parent)
+		return &clk_mxc->parent->clk;
+
+	return NULL;
+}
+
+const struct clk_ops clk_mxc_ops = {
+	.enable = clk_mxc_enable,
+	.disable = clk_mxc_disable,
+	.get_rate = clk_mxc_get_rate,
+	.round_rate = clk_mxc_round_rate,
+	.set_rate = clk_mxc_set_rate,
+	.set_parent = clk_mxc_set_parent,
+	.get_parent = clk_mxc_get_parent,
+};
+#else
+
 /*-------------------------------------------------------------------------
  * Standard clock functions defined in include/linux/clk.h
  *-------------------------------------------------------------------------*/
@@ -200,6 +325,8 @@ struct clk *clk_get_parent(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_get_parent);
 
+#endif
+
 /*
  * Get the resulting clock rate from a PLL register value and the input
  * frequency. PLLs with this register layout can at least be found on
diff --git a/arch/arm/plat-mxc/include/mach/clkdev.h b/arch/arm/plat-mxc/include/mach/clkdev.h
index 04b37a8..f663af3 100644
--- a/arch/arm/plat-mxc/include/mach/clkdev.h
+++ b/arch/arm/plat-mxc/include/mach/clkdev.h
@@ -1,7 +1,11 @@
 #ifndef __ASM_MACH_CLKDEV_H
 #define __ASM_MACH_CLKDEV_H
 
+#ifndef CONFIG_USE_COMMON_STRUCT_CLK
+
 #define __clk_get(clk) ({ 1; })
 #define __clk_put(clk) do { } while (0)
 
 #endif
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h
index 753a598..d8efa77 100644
--- a/arch/arm/plat-mxc/include/mach/clock.h
+++ b/arch/arm/plat-mxc/include/mach/clock.h
@@ -23,14 +23,24 @@
 #ifndef __ASSEMBLY__
 #include <linux/list.h>
 
+#include <linux/clk.h>
+
 struct module;
 
-struct clk {
+#ifndef CONFIG_USE_COMMON_STRUCT_CLK
+#define clk_mxc clk
+#endif
+
+struct clk_mxc {
+#ifdef CONFIG_USE_COMMON_STRUCT_CLK
+	struct clk clk;
+#endif
+
 	int id;
 	/* Source clock this clk depends on */
-	struct clk *parent;
+	struct clk_mxc *parent;
 	/* Secondary clock to enable/disable with this clock */
-	struct clk *secondary;
+	struct clk_mxc *secondary;
 	/* Reference count of clock enable/disable */
 	__s8 usecount;
 	/* Register bit position for clock's enable/disable control. */
@@ -39,23 +49,27 @@ struct clk {
 	void __iomem *enable_reg;
 	u32 flags;
 	/* get the current clock rate (always a fresh value) */
-	unsigned long (*get_rate) (struct clk *);
+	unsigned long (*get_rate) (struct clk_mxc *);
 	/* Function ptr to set the clock to a new rate. The rate must match a
 	   supported rate returned from round_rate. Leave blank if clock is not
 	   programmable */
-	int (*set_rate) (struct clk *, unsigned long);
+	int (*set_rate) (struct clk_mxc *, unsigned long);
 	/* Function ptr to round the requested clock rate to the nearest
 	   supported rate that is less than or equal to the requested rate. */
-	unsigned long (*round_rate) (struct clk *, unsigned long);
+	unsigned long (*round_rate) (struct clk_mxc *, unsigned long);
 	/* Function ptr to enable the clock. Leave blank if clock can not
 	   be gated. */
-	int (*enable) (struct clk *);
+	int (*enable) (struct clk_mxc *);
 	/* Function ptr to disable the clock. Leave blank if clock can not
 	   be gated. */
-	void (*disable) (struct clk *);
+	void (*disable) (struct clk_mxc *);
 	/* Function ptr to set the parent clock of the clock. */
-	int (*set_parent) (struct clk *, struct clk *);
+	int (*set_parent) (struct clk_mxc *, struct clk_mxc *);
 };
+#define to_clk_mxc(_clk_mxc)        container_of(_clk_mxc, struct clk_mxc, clk)
+
+extern const struct clk_ops clk_mxc_ops;
+#define INIT_CLK_MXC(name)	INIT_CLK(name.clk, clk_mxc_ops)
 
 int clk_register(struct clk *clk);
 void clk_unregister(struct clk *clk);
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 0da0bb9..fbafcb6 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -47,7 +47,7 @@ int clk_enable(struct clk *clk)
 	unsigned long flags;
 	int ret = 0;
 
-	WARN_ON(clk->prepare_count = 0);
+	WARN_ON_ONCE(clk->prepare_count = 0);
 
 	spin_lock_irqsave(&clk->enable_lock, flags);
 	if (clk->enable_count = 0 && clk->ops->enable)
-- 
1.7.2.3


  parent reply	other threads:[~2011-02-22 23:33 UTC|newest]

Thread overview: 127+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-01  9:11 Locking in the clk API, part 2: clk_prepare/clk_unprepare Jeremy Kerr
2011-02-01 10:54 ` 
2011-02-01 13:05   ` Jassi Brar
2011-02-01 14:00     ` 
2011-02-01 15:14       ` Russell King - ARM Linux
2011-02-01 15:22         ` 
2011-02-01 15:28           ` Russell King - ARM Linux
2011-02-01 20:57             ` Saravana Kannan
2011-02-02  2:31             ` Jassi Brar
2011-02-01 13:15   ` Russell King - ARM Linux
2011-02-01 14:18     ` 
2011-02-01 14:39       ` Russell King - ARM Linux
2011-02-01 15:18         ` 
2011-02-01 15:24           ` Russell King - ARM Linux
2011-02-01 15:53             ` 
2011-02-01 17:06               ` Russell King - ARM Linux
2011-02-01 19:32                 ` 
2011-02-01 19:56                   ` Russell King - ARM Linux
2011-02-01 20:21                     ` Saravana Kannan
2011-02-01 20:43                       ` 
2011-02-04  9:33                         ` Richard Zhao
2011-02-01 20:06                   ` Nicolas Pitre
2011-02-01 20:33             ` Saravana Kannan
2011-02-01 20:36               ` Russell King - ARM Linux
2011-02-01 20:59             ` Stephen Boyd
2011-02-01 21:24               ` Russell King - ARM Linux
2011-02-04  9:54                 ` Richard Zhao
2011-02-04 10:21                   ` 
2011-02-04 10:57                     ` Russell King - ARM Linux
2011-02-04 10:48                   ` Russell King - ARM Linux
2011-02-04 11:04                     ` Jassi Brar
2011-02-04 11:18                       ` Russell King - ARM Linux
2011-02-04 11:51                         ` Jassi Brar
2011-02-04 12:05                           ` Russell King - ARM Linux
2011-02-01 14:40       ` Jeremy Kerr
2011-02-04 12:45 ` Richard Zhao
2011-02-04 13:20   ` Russell King - ARM Linux
2011-02-07  6:07 ` [RFC,PATCH 1/3] Add a common struct clk Jeremy Kerr
2011-02-07  7:05   ` 
2011-02-07  7:09   ` 
2011-02-07  8:08   ` 
     [not found]   ` <AANLkTim1S9zpebn3yj1fBZTtOkqj2FLwhYWBZ2HXJajR@mail.gmail.com>
2011-02-07  8:22     ` Jeremy Kerr
2011-02-07 19:59   ` Colin Cross
2011-02-08  1:40     ` Jeremy Kerr
2011-02-07 20:20   ` Ryan Mallon
2011-02-08  2:54     ` Jeremy Kerr
2011-02-08  3:30       ` Ryan Mallon
2011-02-08  7:28         ` Jeremy Kerr
2011-02-07  6:07 ` [RFC,PATCH 2/3] clk: Generic support for fixed-rate clocks Jeremy Kerr
2011-02-07  6:07 ` [RFC,PATCH 0/3] Common struct clk implementation, v11 Jeremy Kerr
2011-02-07  6:07 ` [RFC, Jeremy Kerr
2011-02-07  6:29   ` [RFC, PATCH 3/3] clk: add warnings for incorrect enable/prepare semantics Jassi Brar
2011-02-07  7:00     ` Jeremy Kerr
2011-02-07  8:05   ` [RFC, PATCH 3/3] clk: add warnings for incorrect 
2011-02-07  8:08     ` [RFC, PATCH 3/3] clk: add warnings for incorrect enable/prepare semantics Jeremy Kerr
2011-02-07 14:24       ` [RFC, PATCH 3/3] clk: add warnings for incorrect enable/prepare Nicolas Pitre
2011-02-10  4:26         ` Saravana Kannan
2011-02-09  6:41 ` [RFC,PATCH 0/3] Common struct clk implementation, v12 Jeremy Kerr
2011-02-09  6:41   ` [RFC,PATCH 2/3] clk: Generic support for fixed-rate clocks Jeremy Kerr
2011-02-09  6:58     ` Fabio Giovagnini
2011-02-10 23:23     ` Ryan Mallon
2011-02-15  1:41       ` Jeremy Kerr
2011-02-15  4:51         ` Saravana Kannan
2011-02-15  6:18           ` Jeremy Kerr
2011-02-15  6:31             ` Saravana Kannan
2011-02-09  6:41   ` [RFC,PATCH 1/3] Add a common struct clk Jeremy Kerr
2011-02-09  9:00     ` 
2011-02-09 20:21     ` Ryan Mallon
2011-02-09 20:39       ` 
2011-02-09 20:42         ` Ryan Mallon
2011-02-10 10:03       ` Richard Zhao
2011-02-10 10:10         ` Ryan Mallon
2011-02-10 12:45           ` Richard Zhao
2011-02-10 10:46         ` 
2011-02-10 13:08           ` Richard Zhao
2011-02-10 13:13             ` Russell King - ARM Linux
2011-02-15  1:36       ` Jeremy Kerr
2011-02-15  1:43         ` Ryan Mallon
2011-02-10  5:16     ` Saravana Kannan
2011-02-15  2:41       ` Jeremy Kerr
2011-02-15  5:33         ` Saravana Kannan
2011-02-15  7:26           ` Jeremy Kerr
2011-02-15  8:33             ` Saravana Kannan
2011-02-15  8:37             ` Russell King - ARM Linux
2011-02-15  9:33               ` Jeremy Kerr
2011-02-15 14:13                 ` Richard Zhao
2011-02-20 13:07                 ` Russell King - ARM Linux
2011-02-16  4:53           ` Saravana Kannan
2011-02-20 13:13           ` Russell King - ARM Linux
2011-02-09  6:41   ` [RFC, Jeremy Kerr
2011-02-10  9:37     ` [RFC, PATCH 3/3] clk: add warnings for incorrect Richard Zhao
2011-02-15  2:00       ` [RFC, PATCH 3/3] clk: add warnings for incorrect enable/prepare semantics Jeremy Kerr
2011-02-21  2:50 ` [PATCH 0/2] Common struct clk implementation, v13 Jeremy Kerr
2011-02-21  2:50   ` [PATCH 1/2] Add a common struct clk Jeremy Kerr
2011-02-22 20:17     ` 
2011-02-23  2:49       ` Jeremy Kerr
2011-02-21  2:50   ` [PATCH 2/2] clk: Generic support for fixed-rate clocks Jeremy Kerr
2011-02-21 19:51     ` Ryan Mallon
2011-02-21 23:29       ` Jeremy Kerr
2011-02-22 23:33   `  [this message]
2011-02-23  4:17     ` [PATCH] wip: convert imx27 to common struct clk Saravana Kannan
2011-02-23  8:15       ` 
2011-03-03  6:40 ` [PATCH 0/2] Common struct clk implementation, v14 Jeremy Kerr
2011-03-03  6:40   ` [PATCH 1/2] Add a common struct clk Jeremy Kerr
2011-04-14 12:49     ` Tony Lindgren
2011-03-03  6:40   ` [PATCH 2/2] clk: Generic support for fixed-rate clocks Jeremy Kerr
2011-03-14 10:16   ` [PATCH 0/2] Common struct clk implementation, v14 
2011-03-15  4:31   ` Jeremy Kerr
2011-03-21  2:33     ` Jeremy Kerr
2011-04-14  4:20   ` Jeremy Kerr
2011-04-14 10:00     ` Russell King - ARM Linux
2011-04-14 10:23       ` Jeremy Kerr
2011-04-14 10:26         ` Russell King - ARM Linux
2011-04-14 10:25       ` Benjamin Herrenschmidt
2011-04-14 10:32         ` Russell King - ARM Linux
2011-04-14 11:59           ` Nicolas Pitre
2011-04-14 12:09             ` Russell King - ARM Linux
2011-04-14 13:39               ` Nicolas Pitre
2011-04-14 14:00                 ` Mark Brown
2011-04-14 15:38                 ` Russell King - ARM Linux
2011-04-14 16:06                   ` Nicolas Pitre
2011-04-14 17:20                   ` 
2011-04-18 10:54                   ` Paul Mundt
2011-04-20 14:28                     ` 
2011-04-20 16:41                       ` Thomas Gleixner
2011-04-14 19:29               ` Saravana Kannan
2011-04-14 16:08           ` 

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1298417599-23522-1-git-send-email-u.kleine-koenig@pengutronix.de \
    --to=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).