From: Russell King <rmk+kernel@arm.linux.org.uk>
Date: Thu, 6 Jan 2011 22:33:32 +0000 (+0000)
Subject: Merge branch 'devel-stable' into devel
X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=404a02cbd2ae8bf256a2fa1169bdfe86bb5ebb34;p=GitHub%2Fexynos8895%2Fandroid_kernel_samsung_universal8895.git

Merge branch 'devel-stable' into devel

Conflicts:
	arch/arm/mach-pxa/clock.c
	arch/arm/mach-pxa/clock.h
---

404a02cbd2ae8bf256a2fa1169bdfe86bb5ebb34
diff --cc arch/arm/Kconfig
index 32cbf3e888ff,fac58916adec..a3fb23be87f3
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@@ -815,8 -804,9 +823,9 @@@ config ARCH_U850
  	select CPU_V7
  	select ARM_AMBA
  	select GENERIC_CLOCKEVENTS
 -	select COMMON_CLKDEV
 +	select CLKDEV_LOOKUP
  	select ARCH_REQUIRE_GPIOLIB
+ 	select ARCH_HAS_CPUFREQ
  	help
  	  Support for ST-Ericsson's Ux500 architecture
  
diff --cc arch/arm/mach-davinci/time.c
index c1486716de77,5d1eea026635..e1969ce904dc
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@@ -272,10 -272,21 +272,20 @@@ static cycle_t read_cycles(struct clock
  	return (cycles_t)timer32_read(t);
  }
  
+ /*
+  * Kernel assumes that sched_clock can be called early but may not have
+  * things ready yet.
+  */
+ static cycle_t read_dummy(struct clocksource *cs)
+ {
+ 	return 0;
+ }
+ 
+ 
  static struct clocksource clocksource_davinci = {
  	.rating		= 300,
- 	.read		= read_cycles,
+ 	.read		= read_dummy,
  	.mask		= CLOCKSOURCE_MASK(32),
 -	.shift		= 24,
  	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
  };
  
@@@ -376,9 -398,12 +397,10 @@@ static void __init davinci_timer_init(v
  	davinci_clock_tick_rate = clk_get_rate(timer_clk);
  
  	/* setup clocksource */
+ 	clocksource_davinci.read = read_cycles;
  	clocksource_davinci.name = id_to_name[clocksource_id];
 -	clocksource_davinci.mult =
 -		clocksource_khz2mult(davinci_clock_tick_rate/1000,
 -				     clocksource_davinci.shift);
 -	if (clocksource_register(&clocksource_davinci))
 +	if (clocksource_register_hz(&clocksource_davinci,
 +				    davinci_clock_tick_rate))
  		printk(err, clocksource_davinci.name);
  
  	/* setup clockevent */
diff --cc arch/arm/mach-imx/clock-imx25.c
index 000000000000,21ef34c501e5..daa0165b6772
mode 000000,100644..100644
--- a/arch/arm/mach-imx/clock-imx25.c
+++ b/arch/arm/mach-imx/clock-imx25.c
@@@ -1,0 -1,332 +1,331 @@@
+ /*
+  * Copyright (C) 2009 by Sascha Hauer, Pengutronix
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+  * as published by the Free Software Foundation; either version 2
+  * of the License, or (at your option) any later version.
+  * 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.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+  * MA 02110-1301, USA.
+  */
+ 
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/list.h>
+ #include <linux/clk.h>
+ #include <linux/io.h>
 -
 -#include <asm/clkdev.h>
++#include <linux/clkdev.h>
+ 
+ #include <mach/clock.h>
+ #include <mach/hardware.h>
+ #include <mach/common.h>
+ #include <mach/mx25.h>
+ 
+ #define CRM_BASE	MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
+ 
+ #define CCM_MPCTL	0x00
+ #define CCM_UPCTL	0x04
+ #define CCM_CCTL	0x08
+ #define CCM_CGCR0	0x0C
+ #define CCM_CGCR1	0x10
+ #define CCM_CGCR2	0x14
+ #define CCM_PCDR0	0x18
+ #define CCM_PCDR1	0x1C
+ #define CCM_PCDR2	0x20
+ #define CCM_PCDR3	0x24
+ #define CCM_RCSR	0x28
+ #define CCM_CRDR	0x2C
+ #define CCM_DCVR0	0x30
+ #define CCM_DCVR1	0x34
+ #define CCM_DCVR2	0x38
+ #define CCM_DCVR3	0x3c
+ #define CCM_LTR0	0x40
+ #define CCM_LTR1	0x44
+ #define CCM_LTR2	0x48
+ #define CCM_LTR3	0x4c
+ 
+ static unsigned long get_rate_mpll(void)
+ {
+ 	ulong mpctl = __raw_readl(CRM_BASE + CCM_MPCTL);
+ 
+ 	return mxc_decode_pll(mpctl, 24000000);
+ }
+ 
+ static unsigned long get_rate_upll(void)
+ {
+ 	ulong mpctl = __raw_readl(CRM_BASE + CCM_UPCTL);
+ 
+ 	return mxc_decode_pll(mpctl, 24000000);
+ }
+ 
+ unsigned long get_rate_arm(struct clk *clk)
+ {
+ 	unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
+ 	unsigned long rate = get_rate_mpll();
+ 
+ 	if (cctl & (1 << 14))
+ 		rate = (rate * 3) >> 2;
+ 
+ 	return rate / ((cctl >> 30) + 1);
+ }
+ 
+ static unsigned long get_rate_ahb(struct clk *clk)
+ {
+ 	unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
+ 
+ 	return get_rate_arm(NULL) / (((cctl >> 28) & 0x3) + 1);
+ }
+ 
+ static unsigned long get_rate_ipg(struct clk *clk)
+ {
+ 	return get_rate_ahb(NULL) >> 1;
+ }
+ 
+ static unsigned long get_rate_per(int per)
+ {
+ 	unsigned long ofs = (per & 0x3) * 8;
+ 	unsigned long reg = per & ~0x3;
+ 	unsigned long val = (readl(CRM_BASE + CCM_PCDR0 + reg) >> ofs) & 0x3f;
+ 	unsigned long fref;
+ 
+ 	if (readl(CRM_BASE + 0x64) & (1 << per))
+ 		fref = get_rate_upll();
+ 	else
+ 		fref = get_rate_ahb(NULL);
+ 
+ 	return fref / (val + 1);
+ }
+ 
+ static unsigned long get_rate_uart(struct clk *clk)
+ {
+ 	return get_rate_per(15);
+ }
+ 
+ static unsigned long get_rate_ssi2(struct clk *clk)
+ {
+ 	return get_rate_per(14);
+ }
+ 
+ static unsigned long get_rate_ssi1(struct clk *clk)
+ {
+ 	return get_rate_per(13);
+ }
+ 
+ static unsigned long get_rate_i2c(struct clk *clk)
+ {
+ 	return get_rate_per(6);
+ }
+ 
+ static unsigned long get_rate_nfc(struct clk *clk)
+ {
+ 	return get_rate_per(8);
+ }
+ 
+ static unsigned long get_rate_gpt(struct clk *clk)
+ {
+ 	return get_rate_per(5);
+ }
+ 
+ static unsigned long get_rate_lcdc(struct clk *clk)
+ {
+ 	return get_rate_per(7);
+ }
+ 
+ static unsigned long get_rate_esdhc1(struct clk *clk)
+ {
+ 	return get_rate_per(3);
+ }
+ 
+ static unsigned long get_rate_esdhc2(struct clk *clk)
+ {
+ 	return get_rate_per(4);
+ }
+ 
+ static unsigned long get_rate_csi(struct clk *clk)
+ {
+ 	return get_rate_per(0);
+ }
+ 
+ static unsigned long get_rate_otg(struct clk *clk)
+ {
+ 	unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
+ 	unsigned long rate = get_rate_upll();
+ 
+ 	return (cctl & (1 << 23)) ? 0 : rate / ((0x3F & (cctl >> 16)) + 1);
+ }
+ 
+ static int clk_cgcr_enable(struct clk *clk)
+ {
+ 	u32 reg;
+ 
+ 	reg = __raw_readl(clk->enable_reg);
+ 	reg |= 1 << clk->enable_shift;
+ 	__raw_writel(reg, clk->enable_reg);
+ 
+ 	return 0;
+ }
+ 
+ static void clk_cgcr_disable(struct clk *clk)
+ {
+ 	u32 reg;
+ 
+ 	reg = __raw_readl(clk->enable_reg);
+ 	reg &= ~(1 << clk->enable_shift);
+ 	__raw_writel(reg, clk->enable_reg);
+ }
+ 
+ #define DEFINE_CLOCK(name, i, er, es, gr, sr, s)	\
+ 	static struct clk name = {			\
+ 		.id		= i,			\
+ 		.enable_reg	= CRM_BASE + er,	\
+ 		.enable_shift	= es,			\
+ 		.get_rate	= gr,			\
+ 		.set_rate	= sr,			\
+ 		.enable		= clk_cgcr_enable,	\
+ 		.disable	= clk_cgcr_disable,	\
+ 		.secondary	= s,			\
+ 	}
+ 
+ /*
+  * Note: the following IPG clock gating bits are wrongly marked "Reserved" in
+  * the i.MX25 Reference Manual Rev 1, table 15-13. The information below is
+  * taken from the Freescale released BSP.
+  *
+  * bit	reg	offset	clock
+  *
+  * 0	CGCR1	0	AUDMUX
+  * 12	CGCR1	12	ESAI
+  * 16	CGCR1	16	GPIO1
+  * 17	CGCR1	17	GPIO2
+  * 18	CGCR1	18	GPIO3
+  * 23	CGCR1	23	I2C1
+  * 24	CGCR1	24	I2C2
+  * 25	CGCR1	25	I2C3
+  * 27	CGCR1	27	IOMUXC
+  * 28	CGCR1	28	KPP
+  * 30	CGCR1	30	OWIRE
+  * 36	CGCR2	4	RTIC
+  * 51	CGCR2	19	WDOG
+  */
+ 
+ DEFINE_CLOCK(gpt_clk,    0, CCM_CGCR0,  5, get_rate_gpt, NULL, NULL);
+ DEFINE_CLOCK(uart_per_clk, 0, CCM_CGCR0, 15, get_rate_uart, NULL, NULL);
+ DEFINE_CLOCK(ssi1_per_clk, 0, CCM_CGCR0, 13, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(ssi2_per_clk, 0, CCM_CGCR0, 14, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(cspi1_clk,  0, CCM_CGCR1,  5, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(cspi2_clk,  0, CCM_CGCR1,  6, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(cspi3_clk,  0, CCM_CGCR1,  7, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(esdhc1_ahb_clk, 0, CCM_CGCR0, 21, get_rate_esdhc1,	 NULL, NULL);
+ DEFINE_CLOCK(esdhc1_per_clk, 0, CCM_CGCR0,  3, get_rate_esdhc1,	 NULL,
+ 		&esdhc1_ahb_clk);
+ DEFINE_CLOCK(esdhc2_ahb_clk, 0, CCM_CGCR0, 22, get_rate_esdhc2,	 NULL, NULL);
+ DEFINE_CLOCK(esdhc2_per_clk, 0, CCM_CGCR0,  4, get_rate_esdhc2,	 NULL,
+ 		&esdhc2_ahb_clk);
+ DEFINE_CLOCK(fec_ahb_clk, 0, CCM_CGCR0, 23, NULL,	 NULL, NULL);
+ DEFINE_CLOCK(lcdc_ahb_clk, 0, CCM_CGCR0, 24, NULL,	 NULL, NULL);
+ DEFINE_CLOCK(lcdc_per_clk, 0, CCM_CGCR0,  7, NULL,	 NULL, &lcdc_ahb_clk);
+ DEFINE_CLOCK(csi_ahb_clk, 0, CCM_CGCR0, 18, get_rate_csi, NULL, NULL);
+ DEFINE_CLOCK(csi_per_clk, 0, CCM_CGCR0, 0, get_rate_csi, NULL, &csi_ahb_clk);
+ DEFINE_CLOCK(uart1_clk,  0, CCM_CGCR2, 14, get_rate_uart, NULL, &uart_per_clk);
+ DEFINE_CLOCK(uart2_clk,  0, CCM_CGCR2, 15, get_rate_uart, NULL, &uart_per_clk);
+ DEFINE_CLOCK(uart3_clk,  0, CCM_CGCR2, 16, get_rate_uart, NULL, &uart_per_clk);
+ DEFINE_CLOCK(uart4_clk,  0, CCM_CGCR2, 17, get_rate_uart, NULL, &uart_per_clk);
+ DEFINE_CLOCK(uart5_clk,  0, CCM_CGCR2, 18, get_rate_uart, NULL, &uart_per_clk);
+ DEFINE_CLOCK(nfc_clk,    0, CCM_CGCR0,  8, get_rate_nfc, NULL, NULL);
+ DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, NULL, NULL);
+ DEFINE_CLOCK(pwm1_clk,	 0, CCM_CGCR1, 31, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(pwm2_clk,	 0, CCM_CGCR2,  0, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(pwm3_clk,	 0, CCM_CGCR2,  1, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(pwm4_clk,	 0, CCM_CGCR2,  2, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(kpp_clk,	 0, CCM_CGCR1, 28, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(tsc_clk,	 0, CCM_CGCR2, 13, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(i2c_clk,	 0, CCM_CGCR0,  6, get_rate_i2c, NULL, NULL);
+ DEFINE_CLOCK(fec_clk,	 0, CCM_CGCR1, 15, get_rate_ipg, NULL, &fec_ahb_clk);
+ DEFINE_CLOCK(dryice_clk, 0, CCM_CGCR1,  8, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(lcdc_clk,	 0, CCM_CGCR1, 29, get_rate_lcdc, NULL, &lcdc_per_clk);
+ DEFINE_CLOCK(wdt_clk,    0, CCM_CGCR2, 19, get_rate_ipg, NULL,  NULL);
+ DEFINE_CLOCK(ssi1_clk,  0, CCM_CGCR2, 11, get_rate_ssi1, NULL, &ssi1_per_clk);
+ DEFINE_CLOCK(ssi2_clk,  1, CCM_CGCR2, 12, get_rate_ssi2, NULL, &ssi2_per_clk);
+ DEFINE_CLOCK(esdhc1_clk,  0, CCM_CGCR1, 13, get_rate_esdhc1, NULL,
+ 		&esdhc1_per_clk);
+ DEFINE_CLOCK(esdhc2_clk,  1, CCM_CGCR1, 14, get_rate_esdhc2, NULL,
+ 		&esdhc2_per_clk);
+ DEFINE_CLOCK(audmux_clk, 0, CCM_CGCR1, 0, NULL, NULL, NULL);
+ DEFINE_CLOCK(csi_clk,    0, CCM_CGCR1,  4, get_rate_csi, NULL,  &csi_per_clk);
+ DEFINE_CLOCK(can1_clk,	 0, CCM_CGCR1,  2, get_rate_ipg, NULL, NULL);
+ DEFINE_CLOCK(can2_clk,	 1, CCM_CGCR1,  3, get_rate_ipg, NULL, NULL);
+ 
+ #define _REGISTER_CLOCK(d, n, c)	\
+ 	{				\
+ 		.dev_id = d,		\
+ 		.con_id = n,		\
+ 		.clk = &c,		\
+ 	},
+ 
+ static struct clk_lookup lookups[] = {
+ 	_REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+ 	_REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+ 	_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+ 	_REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
+ 	_REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
+ 	_REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
+ 	_REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
+ 	_REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
+ 	_REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
+ 	_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
+ 	_REGISTER_CLOCK("imx25-cspi.0", NULL, cspi1_clk)
+ 	_REGISTER_CLOCK("imx25-cspi.1", NULL, cspi2_clk)
+ 	_REGISTER_CLOCK("imx25-cspi.2", NULL, cspi3_clk)
+ 	_REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk)
+ 	_REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk)
+ 	_REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk)
+ 	_REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk)
+ 	_REGISTER_CLOCK("imx-keypad", NULL, kpp_clk)
+ 	_REGISTER_CLOCK("mx25-adc", NULL, tsc_clk)
+ 	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
+ 	_REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
+ 	_REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
+ 	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ 	_REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk)
+ 	_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
+ 	_REGISTER_CLOCK("imx2-wdt.0", NULL, wdt_clk)
+ 	_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
+ 	_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+ 	_REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
+ 	_REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
+ 	_REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
+ 	_REGISTER_CLOCK(NULL, "audmux", audmux_clk)
+ 	_REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
+ 	_REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
+ };
+ 
+ int __init mx25_clocks_init(void)
+ {
+ 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+ 
+ 	/* Turn off all clocks except the ones we need to survive, namely:
+ 	 * EMI, GPIO1-3 (CCM_CGCR1[18:16]), GPT1, IOMUXC (CCM_CGCR1[27]), IIM,
+ 	 * SCC
+ 	 */
+ 	__raw_writel((1 << 19), CRM_BASE + CCM_CGCR0);
+ 	__raw_writel((0xf << 16) | (3 << 26), CRM_BASE + CCM_CGCR1);
+ 	__raw_writel((1 << 5), CRM_BASE + CCM_CGCR2);
+ #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
+ 	clk_enable(&uart1_clk);
+ #endif
+ 
+ 	/* Clock source for lcdc and csi is upll */
+ 	__raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7) | (1 << 0),
+ 			CRM_BASE + 0x64);
+ 
+ 	mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
+ 
+ 	return 0;
+ }
diff --cc arch/arm/mach-mx5/clock-mx51-mx53.c
index 000000000000,b21bc47d4827..785e1a336183
mode 000000,100644..100644
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@@ -1,0 -1,1420 +1,1420 @@@
+ /*
+  * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+  * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+  *
+  * The code contained herein is licensed under the GNU General Public
+  * License. You may obtain a copy of the GNU General Public License
+  * Version 2 or later at the following locations:
+  *
+  * http://www.opensource.org/licenses/gpl-license.html
+  * http://www.gnu.org/copyleft/gpl.html
+  */
+ 
+ #include <linux/mm.h>
+ #include <linux/delay.h>
+ #include <linux/clk.h>
+ #include <linux/io.h>
++#include <linux/clkdev.h>
+ 
 -#include <asm/clkdev.h>
+ #include <asm/div64.h>
+ 
+ #include <mach/hardware.h>
+ #include <mach/common.h>
+ #include <mach/clock.h>
+ 
+ #include "crm_regs.h"
+ 
+ /* External clock values passed-in by the board code */
+ static unsigned long external_high_reference, external_low_reference;
+ static unsigned long oscillator_reference, ckih2_reference;
+ 
+ static struct clk osc_clk;
+ static struct clk pll1_main_clk;
+ static struct clk pll1_sw_clk;
+ static struct clk pll2_sw_clk;
+ static struct clk pll3_sw_clk;
+ static struct clk mx53_pll4_sw_clk;
+ static struct clk lp_apm_clk;
+ static struct clk periph_apm_clk;
+ static struct clk ahb_clk;
+ static struct clk ipg_clk;
+ static struct clk usboh3_clk;
+ static struct clk emi_fast_clk;
+ static struct clk ipu_clk;
+ static struct clk mipi_hsc1_clk;
+ 
+ #define MAX_DPLL_WAIT_TRIES	1000 /* 1000 * udelay(1) = 1ms */
+ 
+ /* calculate best pre and post dividers to get the required divider */
+ static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post,
+ 	u32 max_pre, u32 max_post)
+ {
+ 	if (div >= max_pre * max_post) {
+ 		*pre = max_pre;
+ 		*post = max_post;
+ 	} else if (div >= max_pre) {
+ 		u32 min_pre, temp_pre, old_err, err;
+ 		min_pre = DIV_ROUND_UP(div, max_post);
+ 		old_err = max_pre;
+ 		for (temp_pre = max_pre; temp_pre >= min_pre; temp_pre--) {
+ 			err = div % temp_pre;
+ 			if (err == 0) {
+ 				*pre = temp_pre;
+ 				break;
+ 			}
+ 			err = temp_pre - err;
+ 			if (err < old_err) {
+ 				old_err = err;
+ 				*pre = temp_pre;
+ 			}
+ 		}
+ 		*post = DIV_ROUND_UP(div, *pre);
+ 	} else {
+ 		*pre = div;
+ 		*post = 1;
+ 	}
+ }
+ 
+ static void _clk_ccgr_setclk(struct clk *clk, unsigned mode)
+ {
+ 	u32 reg = __raw_readl(clk->enable_reg);
+ 
+ 	reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+ 	reg |= mode << clk->enable_shift;
+ 
+ 	__raw_writel(reg, clk->enable_reg);
+ }
+ 
+ static int _clk_ccgr_enable(struct clk *clk)
+ {
+ 	_clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_ON);
+ 	return 0;
+ }
+ 
+ static void _clk_ccgr_disable(struct clk *clk)
+ {
+ 	_clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_OFF);
+ }
+ 
+ static int _clk_ccgr_enable_inrun(struct clk *clk)
+ {
+ 	_clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
+ 	return 0;
+ }
+ 
+ static void _clk_ccgr_disable_inwait(struct clk *clk)
+ {
+ 	_clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
+ }
+ 
+ /*
+  * For the 4-to-1 muxed input clock
+  */
+ static inline u32 _get_mux(struct clk *parent, struct clk *m0,
+ 			   struct clk *m1, struct clk *m2, struct clk *m3)
+ {
+ 	if (parent == m0)
+ 		return 0;
+ 	else if (parent == m1)
+ 		return 1;
+ 	else if (parent == m2)
+ 		return 2;
+ 	else if (parent == m3)
+ 		return 3;
+ 	else
+ 		BUG();
+ 
+ 	return -EINVAL;
+ }
+ 
+ static inline void __iomem *_mx51_get_pll_base(struct clk *pll)
+ {
+ 	if (pll == &pll1_main_clk)
+ 		return MX51_DPLL1_BASE;
+ 	else if (pll == &pll2_sw_clk)
+ 		return MX51_DPLL2_BASE;
+ 	else if (pll == &pll3_sw_clk)
+ 		return MX51_DPLL3_BASE;
+ 	else
+ 		BUG();
+ 
+ 	return NULL;
+ }
+ 
+ static inline void __iomem *_mx53_get_pll_base(struct clk *pll)
+ {
+ 	if (pll == &pll1_main_clk)
+ 		return MX53_DPLL1_BASE;
+ 	else if (pll == &pll2_sw_clk)
+ 		return MX53_DPLL2_BASE;
+ 	else if (pll == &pll3_sw_clk)
+ 		return MX53_DPLL3_BASE;
+ 	else if (pll == &mx53_pll4_sw_clk)
+ 		return MX53_DPLL4_BASE;
+ 	else
+ 		BUG();
+ 
+ 	return NULL;
+ }
+ 
+ static inline void __iomem *_get_pll_base(struct clk *pll)
+ {
+ 	if (cpu_is_mx51())
+ 		return _mx51_get_pll_base(pll);
+ 	else
+ 		return _mx53_get_pll_base(pll);
+ }
+ 
+ static unsigned long clk_pll_get_rate(struct clk *clk)
+ {
+ 	long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+ 	unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
+ 	void __iomem *pllbase;
+ 	s64 temp;
+ 	unsigned long parent_rate;
+ 
+ 	parent_rate = clk_get_rate(clk->parent);
+ 
+ 	pllbase = _get_pll_base(clk);
+ 
+ 	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ 	pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+ 	dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
+ 
+ 	if (pll_hfsm == 0) {
+ 		dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
+ 		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
+ 		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
+ 	} else {
+ 		dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
+ 		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
+ 		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
+ 	}
+ 	pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
+ 	mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
+ 	mfi = (mfi <= 5) ? 5 : mfi;
+ 	mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
+ 	mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
+ 	/* Sign extend to 32-bits */
+ 	if (mfn >= 0x04000000) {
+ 		mfn |= 0xFC000000;
+ 		mfn_abs = -mfn;
+ 	}
+ 
+ 	ref_clk = 2 * parent_rate;
+ 	if (dbl != 0)
+ 		ref_clk *= 2;
+ 
+ 	ref_clk /= (pdf + 1);
+ 	temp = (u64) ref_clk * mfn_abs;
+ 	do_div(temp, mfd + 1);
+ 	if (mfn < 0)
+ 		temp = -temp;
+ 	temp = (ref_clk * mfi) + temp;
+ 
+ 	return temp;
+ }
+ 
+ static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
+ {
+ 	u32 reg;
+ 	void __iomem *pllbase;
+ 
+ 	long mfi, pdf, mfn, mfd = 999999;
+ 	s64 temp64;
+ 	unsigned long quad_parent_rate;
+ 	unsigned long pll_hfsm, dp_ctl;
+ 	unsigned long parent_rate;
+ 
+ 	parent_rate = clk_get_rate(clk->parent);
+ 
+ 	pllbase = _get_pll_base(clk);
+ 
+ 	quad_parent_rate = 4 * parent_rate;
+ 	pdf = mfi = -1;
+ 	while (++pdf < 16 && mfi < 5)
+ 		mfi = rate * (pdf+1) / quad_parent_rate;
+ 	if (mfi > 15)
+ 		return -EINVAL;
+ 	pdf--;
+ 
+ 	temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
+ 	do_div(temp64, quad_parent_rate/1000000);
+ 	mfn = (long)temp64;
+ 
+ 	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ 	/* use dpdck0_2 */
+ 	__raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
+ 	pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+ 	if (pll_hfsm == 0) {
+ 		reg = mfi << 4 | pdf;
+ 		__raw_writel(reg, pllbase + MXC_PLL_DP_OP);
+ 		__raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
+ 		__raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
+ 	} else {
+ 		reg = mfi << 4 | pdf;
+ 		__raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
+ 		__raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
+ 		__raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
+ 	}
+ 
+ 	return 0;
+ }
+ 
+ static int _clk_pll_enable(struct clk *clk)
+ {
+ 	u32 reg;
+ 	void __iomem *pllbase;
+ 	int i = 0;
+ 
+ 	pllbase = _get_pll_base(clk);
+ 	reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
+ 	__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+ 
+ 	/* Wait for lock */
+ 	do {
+ 		reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ 		if (reg & MXC_PLL_DP_CTL_LRF)
+ 			break;
+ 
+ 		udelay(1);
+ 	} while (++i < MAX_DPLL_WAIT_TRIES);
+ 
+ 	if (i == MAX_DPLL_WAIT_TRIES) {
+ 		pr_err("MX5: pll locking failed\n");
+ 		return -EINVAL;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+ static void _clk_pll_disable(struct clk *clk)
+ {
+ 	u32 reg;
+ 	void __iomem *pllbase;
+ 
+ 	pllbase = _get_pll_base(clk);
+ 	reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
+ 	__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+ }
+ 
+ static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
+ {
+ 	u32 reg, step;
+ 
+ 	reg = __raw_readl(MXC_CCM_CCSR);
+ 
+ 	/* When switching from pll_main_clk to a bypass clock, first select a
+ 	 * multiplexed clock in 'step_sel', then shift the glitchless mux
+ 	 * 'pll1_sw_clk_sel'.
+ 	 *
+ 	 * When switching back, do it in reverse order
+ 	 */
+ 	if (parent == &pll1_main_clk) {
+ 		/* Switch to pll1_main_clk */
+ 		reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ 		__raw_writel(reg, MXC_CCM_CCSR);
+ 		/* step_clk mux switched to lp_apm, to save power. */
+ 		reg = __raw_readl(MXC_CCM_CCSR);
+ 		reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
+ 		reg |= (MXC_CCM_CCSR_STEP_SEL_LP_APM <<
+ 				MXC_CCM_CCSR_STEP_SEL_OFFSET);
+ 	} else {
+ 		if (parent == &lp_apm_clk) {
+ 			step = MXC_CCM_CCSR_STEP_SEL_LP_APM;
+ 		} else  if (parent == &pll2_sw_clk) {
+ 			step = MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED;
+ 		} else  if (parent == &pll3_sw_clk) {
+ 			step = MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED;
+ 		} else
+ 			return -EINVAL;
+ 
+ 		reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
+ 		reg |= (step << MXC_CCM_CCSR_STEP_SEL_OFFSET);
+ 
+ 		__raw_writel(reg, MXC_CCM_CCSR);
+ 		/* Switch to step_clk */
+ 		reg = __raw_readl(MXC_CCM_CCSR);
+ 		reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ 	}
+ 	__raw_writel(reg, MXC_CCM_CCSR);
+ 	return 0;
+ }
+ 
+ static unsigned long clk_pll1_sw_get_rate(struct clk *clk)
+ {
+ 	u32 reg, div;
+ 	unsigned long parent_rate;
+ 
+ 	parent_rate = clk_get_rate(clk->parent);
+ 
+ 	reg = __raw_readl(MXC_CCM_CCSR);
+ 
+ 	if (clk->parent == &pll2_sw_clk) {
+ 		div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
+ 		       MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
+ 	} else if (clk->parent == &pll3_sw_clk) {
+ 		div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
+ 		       MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
+ 	} else
+ 		div = 1;
+ 	return parent_rate / div;
+ }
+ 
+ static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent)
+ {
+ 	u32 reg;
+ 
+ 	reg = __raw_readl(MXC_CCM_CCSR);
+ 
+ 	if (parent == &pll2_sw_clk)
+ 		reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
+ 	else
+ 		reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
+ 
+ 	__raw_writel(reg, MXC_CCM_CCSR);
+ 	return 0;
+ }
+ 
+ static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
+ {
+ 	u32 reg;
+ 
+ 	if (parent == &osc_clk)
+ 		reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
+ 	else
+ 		return -EINVAL;
+ 
+ 	__raw_writel(reg, MXC_CCM_CCSR);
+ 
+ 	return 0;
+ }
+ 
+ static unsigned long clk_cpu_get_rate(struct clk *clk)
+ {
+ 	u32 cacrr, div;
+ 	unsigned long parent_rate;
+ 
+ 	parent_rate = clk_get_rate(clk->parent);
+ 	cacrr = __raw_readl(MXC_CCM_CACRR);
+ 	div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
+ 
+ 	return parent_rate / div;
+ }
+ 
+ static int clk_cpu_set_rate(struct clk *clk, unsigned long rate)
+ {
+ 	u32 reg, cpu_podf;
+ 	unsigned long parent_rate;
+ 
+ 	parent_rate = clk_get_rate(clk->parent);
+ 	cpu_podf = parent_rate / rate - 1;
+ 	/* use post divider to change freq */
+ 	reg = __raw_readl(MXC_CCM_CACRR);
+ 	reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK;
+ 	reg |= cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET;
+ 	__raw_writel(reg, MXC_CCM_CACRR);
+ 
+ 	return 0;
+ }
+ 
+ static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
+ {
+ 	u32 reg, mux;
+ 	int i = 0;
+ 
+ 	mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL);
+ 
+ 	reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK;
+ 	reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET;
+ 	__raw_writel(reg, MXC_CCM_CBCMR);
+ 
+ 	/* Wait for lock */
+ 	do {
+ 		reg = __raw_readl(MXC_CCM_CDHIPR);
+ 		if (!(reg &  MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY))
+ 			break;
+ 
+ 		udelay(1);
+ 	} while (++i < MAX_DPLL_WAIT_TRIES);
+ 
+ 	if (i == MAX_DPLL_WAIT_TRIES) {
+ 		pr_err("MX5: Set parent for periph_apm clock failed\n");
+ 		return -EINVAL;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+ static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
+ {
+ 	u32 reg;
+ 
+ 	reg = __raw_readl(MXC_CCM_CBCDR);
+ 
+ 	if (parent == &pll2_sw_clk)
+ 		reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+ 	else if (parent == &periph_apm_clk)
+ 		reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+ 	else
+ 		return -EINVAL;
+ 
+ 	__raw_writel(reg, MXC_CCM_CBCDR);
+ 
+ 	return 0;
+ }
+ 
+ static struct clk main_bus_clk = {
+ 	.parent = &pll2_sw_clk,
+ 	.set_parent = _clk_main_bus_set_parent,
+ };
+ 
+ static unsigned long clk_ahb_get_rate(struct clk *clk)
+ {
+ 	u32 reg, div;
+ 	unsigned long parent_rate;
+ 
+ 	parent_rate = clk_get_rate(clk->parent);
+ 
+ 	reg = __raw_readl(MXC_CCM_CBCDR);
+ 	div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
+ 	       MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
+ 	return parent_rate / div;
+ }
+ 
+ 
+ static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
+ {
+ 	u32 reg, div;
+ 	unsigned long parent_rate;
+ 	int i = 0;
+ 
+ 	parent_rate = clk_get_rate(clk->parent);
+ 
+ 	div = parent_rate / rate;
+ 	if (div > 8 || div < 1 || ((parent_rate / div) != rate))
+ 		return -EINVAL;
+ 
+ 	reg = __raw_readl(MXC_CCM_CBCDR);
+ 	reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
+ 	reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET;
+ 	__raw_writel(reg, MXC_CCM_CBCDR);
+ 
+ 	/* Wait for lock */
+ 	do {
+ 		reg = __raw_readl(MXC_CCM_CDHIPR);
+ 		if (!(reg & MXC_CCM_CDHIPR_AHB_PODF_BUSY))
+ 			break;
+ 
+ 		udelay(1);
+ 	} while (++i < MAX_DPLL_WAIT_TRIES);
+ 
+ 	if (i == MAX_DPLL_WAIT_TRIES) {
+ 		pr_err("MX5: clk_ahb_set_rate failed\n");
+ 		return -EINVAL;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+ static unsigned long _clk_ahb_round_rate(struct clk *clk,
+ 						unsigned long rate)
+ {
+ 	u32 div;
+ 	unsigned long parent_rate;
+ 
+ 	parent_rate = clk_get_rate(clk->parent);
+ 
+ 	div = parent_rate / rate;
+ 	if (div > 8)
+ 		div = 8;
+ 	else if (div == 0)
+ 		div++;
+ 	return parent_rate / div;
+ }
+ 
+ 
+ static int _clk_max_enable(struct clk *clk)
+ {
+ 	u32 reg;
+ 
+ 	_clk_ccgr_enable(clk);
+ 
+ 	/* Handshake with MAX when LPM is entered. */
+ 	reg = __raw_readl(MXC_CCM_CLPCR);
+ 	if (cpu_is_mx51())
+ 		reg &= ~MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ 	else if (cpu_is_mx53())
+ 		reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ 	__raw_writel(reg, MXC_CCM_CLPCR);
+ 
+ 	return 0;
+ }
+ 
+ static void _clk_max_disable(struct clk *clk)
+ {
+ 	u32 reg;
+ 
+ 	_clk_ccgr_disable_inwait(clk);
+ 
+ 	/* No Handshake with MAX when LPM is entered as its disabled. */
+ 	reg = __raw_readl(MXC_CCM_CLPCR);
+ 	if (cpu_is_mx51())
+ 		reg |= MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ 	else if (cpu_is_mx53())
+ 		reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ 	__raw_writel(reg, MXC_CCM_CLPCR);
+ }
+ 
+ static unsigned long clk_ipg_get_rate(struct clk *clk)
+ {
+ 	u32 reg, div;
+ 	unsigned long parent_rate;
+ 
+ 	parent_rate = clk_get_rate(clk->parent);
+ 
+ 	reg = __raw_readl(MXC_CCM_CBCDR);
+ 	div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
+ 	       MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
+ 
+ 	return parent_rate / div;
+ }
+ 
+ static unsigned long clk_ipg_per_get_rate(struct clk *clk)
+ {
+ 	u32 reg, prediv1, prediv2, podf;
+ 	unsigned long parent_rate;
+ 
+ 	parent_rate = clk_get_rate(clk->parent);
+ 
+ 	if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) {
+ 		/* the main_bus_clk is the one before the DVFS engine */
+ 		reg = __raw_readl(MXC_CCM_CBCDR);
+ 		prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
+ 			   MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1;
+ 		prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
+ 			   MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1;
+ 		podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
+ 			MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1;
+ 		return parent_rate / (prediv1 * prediv2 * podf);
+ 	} else if (clk->parent == &ipg_clk)
+ 		return parent_rate;
+ 	else
+ 		BUG();
+ }
+ 
+ static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
+ {
+ 	u32 reg;
+ 
+ 	reg = __raw_readl(MXC_CCM_CBCMR);
+ 
+ 	reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+ 	reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+ 
+ 	if (parent == &ipg_clk)
+ 		reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+ 	else if (parent == &lp_apm_clk)
+ 		reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+ 	else if (parent != &main_bus_clk)
+ 		return -EINVAL;
+ 
+ 	__raw_writel(reg, MXC_CCM_CBCMR);
+ 
+ 	return 0;
+ }
+ 
+ #define clk_nfc_set_parent	NULL
+ 
+ static unsigned long clk_nfc_get_rate(struct clk *clk)
+ {
+ 	unsigned long rate;
+ 	u32 reg, div;
+ 
+ 	reg = __raw_readl(MXC_CCM_CBCDR);
+ 	div = ((reg & MXC_CCM_CBCDR_NFC_PODF_MASK) >>
+ 	       MXC_CCM_CBCDR_NFC_PODF_OFFSET) + 1;
+ 	rate = clk_get_rate(clk->parent) / div;
+ 	WARN_ON(rate == 0);
+ 	return rate;
+ }
+ 
+ static unsigned long clk_nfc_round_rate(struct clk *clk,
+ 						unsigned long rate)
+ {
+ 	u32 div;
+ 	unsigned long parent_rate = clk_get_rate(clk->parent);
+ 
+ 	if (!rate)
+ 		return -EINVAL;
+ 
+ 	div = parent_rate / rate;
+ 
+ 	if (parent_rate % rate)
+ 		div++;
+ 
+ 	if (div > 8)
+ 		return -EINVAL;
+ 
+ 	return parent_rate / div;
+ 
+ }
+ 
+ static int clk_nfc_set_rate(struct clk *clk, unsigned long rate)
+ {
+ 	u32 reg, div;
+ 
+ 	div = clk_get_rate(clk->parent) / rate;
+ 	if (div == 0)
+ 		div++;
+ 	if (((clk_get_rate(clk->parent) / div) != rate) || (div > 8))
+ 		return -EINVAL;
+ 
+ 	reg = __raw_readl(MXC_CCM_CBCDR);
+ 	reg &= ~MXC_CCM_CBCDR_NFC_PODF_MASK;
+ 	reg |= (div - 1) << MXC_CCM_CBCDR_NFC_PODF_OFFSET;
+ 	__raw_writel(reg, MXC_CCM_CBCDR);
+ 
+ 	while (__raw_readl(MXC_CCM_CDHIPR) &
+ 			MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY){
+ 	}
+ 
+ 	return 0;
+ }
+ 
+ static unsigned long get_high_reference_clock_rate(struct clk *clk)
+ {
+ 	return external_high_reference;
+ }
+ 
+ static unsigned long get_low_reference_clock_rate(struct clk *clk)
+ {
+ 	return external_low_reference;
+ }
+ 
+ static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
+ {
+ 	return oscillator_reference;
+ }
+ 
+ static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
+ {
+ 	return ckih2_reference;
+ }
+ 
+ static unsigned long clk_emi_slow_get_rate(struct clk *clk)
+ {
+ 	u32 reg, div;
+ 
+ 	reg = __raw_readl(MXC_CCM_CBCDR);
+ 	div = ((reg & MXC_CCM_CBCDR_EMI_PODF_MASK) >>
+ 	       MXC_CCM_CBCDR_EMI_PODF_OFFSET) + 1;
+ 
+ 	return clk_get_rate(clk->parent) / div;
+ }
+ 
+ static unsigned long _clk_ddr_hf_get_rate(struct clk *clk)
+ {
+ 	unsigned long rate;
+ 	u32 reg, div;
+ 
+ 	reg = __raw_readl(MXC_CCM_CBCDR);
+ 	div = ((reg & MXC_CCM_CBCDR_DDR_PODF_MASK) >>
+ 		MXC_CCM_CBCDR_DDR_PODF_OFFSET) + 1;
+ 	rate = clk_get_rate(clk->parent) / div;
+ 
+ 	return rate;
+ }
+ 
+ /* External high frequency clock */
+ static struct clk ckih_clk = {
+ 	.get_rate = get_high_reference_clock_rate,
+ };
+ 
+ static struct clk ckih2_clk = {
+ 	.get_rate = get_ckih2_reference_clock_rate,
+ };
+ 
+ static struct clk osc_clk = {
+ 	.get_rate = get_oscillator_reference_clock_rate,
+ };
+ 
+ /* External low frequency (32kHz) clock */
+ static struct clk ckil_clk = {
+ 	.get_rate = get_low_reference_clock_rate,
+ };
+ 
+ static struct clk pll1_main_clk = {
+ 	.parent = &osc_clk,
+ 	.get_rate = clk_pll_get_rate,
+ 	.enable = _clk_pll_enable,
+ 	.disable = _clk_pll_disable,
+ };
+ 
+ /* Clock tree block diagram (WIP):
+  * 	CCM: Clock Controller Module
+  *
+  * PLL output -> |
+  *               | CCM Switcher -> CCM_CLK_ROOT_GEN ->
+  * PLL bypass -> |
+  *
+  */
+ 
+ /* PLL1 SW supplies to ARM core */
+ static struct clk pll1_sw_clk = {
+ 	.parent = &pll1_main_clk,
+ 	.set_parent = _clk_pll1_sw_set_parent,
+ 	.get_rate = clk_pll1_sw_get_rate,
+ };
+ 
+ /* PLL2 SW supplies to AXI/AHB/IP buses */
+ static struct clk pll2_sw_clk = {
+ 	.parent = &osc_clk,
+ 	.get_rate = clk_pll_get_rate,
+ 	.set_rate = _clk_pll_set_rate,
+ 	.set_parent = _clk_pll2_sw_set_parent,
+ 	.enable = _clk_pll_enable,
+ 	.disable = _clk_pll_disable,
+ };
+ 
+ /* PLL3 SW supplies to serial clocks like USB, SSI, etc. */
+ static struct clk pll3_sw_clk = {
+ 	.parent = &osc_clk,
+ 	.set_rate = _clk_pll_set_rate,
+ 	.get_rate = clk_pll_get_rate,
+ 	.enable = _clk_pll_enable,
+ 	.disable = _clk_pll_disable,
+ };
+ 
+ /* PLL4 SW supplies to LVDS Display Bridge(LDB) */
+ static struct clk mx53_pll4_sw_clk = {
+ 	.parent = &osc_clk,
+ 	.set_rate = _clk_pll_set_rate,
+ 	.enable = _clk_pll_enable,
+ 	.disable = _clk_pll_disable,
+ };
+ 
+ /* Low-power Audio Playback Mode clock */
+ static struct clk lp_apm_clk = {
+ 	.parent = &osc_clk,
+ 	.set_parent = _clk_lp_apm_set_parent,
+ };
+ 
+ static struct clk periph_apm_clk = {
+ 	.parent = &pll1_sw_clk,
+ 	.set_parent = _clk_periph_apm_set_parent,
+ };
+ 
+ static struct clk cpu_clk = {
+ 	.parent = &pll1_sw_clk,
+ 	.get_rate = clk_cpu_get_rate,
+ 	.set_rate = clk_cpu_set_rate,
+ };
+ 
+ static struct clk ahb_clk = {
+ 	.parent = &main_bus_clk,
+ 	.get_rate = clk_ahb_get_rate,
+ 	.set_rate = _clk_ahb_set_rate,
+ 	.round_rate = _clk_ahb_round_rate,
+ };
+ 
+ static struct clk iim_clk = {
+ 	.parent = &ipg_clk,
+ 	.enable_reg = MXC_CCM_CCGR0,
+ 	.enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+ };
+ 
+ /* Main IP interface clock for access to registers */
+ static struct clk ipg_clk = {
+ 	.parent = &ahb_clk,
+ 	.get_rate = clk_ipg_get_rate,
+ };
+ 
+ static struct clk ipg_perclk = {
+ 	.parent = &lp_apm_clk,
+ 	.get_rate = clk_ipg_per_get_rate,
+ 	.set_parent = _clk_ipg_per_set_parent,
+ };
+ 
+ static struct clk ahb_max_clk = {
+ 	.parent = &ahb_clk,
+ 	.enable_reg = MXC_CCM_CCGR0,
+ 	.enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ 	.enable = _clk_max_enable,
+ 	.disable = _clk_max_disable,
+ };
+ 
+ static struct clk aips_tz1_clk = {
+ 	.parent = &ahb_clk,
+ 	.secondary = &ahb_max_clk,
+ 	.enable_reg = MXC_CCM_CCGR0,
+ 	.enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ 	.enable = _clk_ccgr_enable,
+ 	.disable = _clk_ccgr_disable_inwait,
+ };
+ 
+ static struct clk aips_tz2_clk = {
+ 	.parent = &ahb_clk,
+ 	.secondary = &ahb_max_clk,
+ 	.enable_reg = MXC_CCM_CCGR0,
+ 	.enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ 	.enable = _clk_ccgr_enable,
+ 	.disable = _clk_ccgr_disable_inwait,
+ };
+ 
+ static struct clk gpt_32k_clk = {
+ 	.id = 0,
+ 	.parent = &ckil_clk,
+ };
+ 
+ static struct clk kpp_clk = {
+ 	.id = 0,
+ };
+ 
+ static struct clk dummy_clk = {
+ 	.id = 0,
+ };
+ 
+ static struct clk emi_slow_clk = {
+ 	.parent = &pll2_sw_clk,
+ 	.enable_reg = MXC_CCM_CCGR5,
+ 	.enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ 	.enable = _clk_ccgr_enable,
+ 	.disable = _clk_ccgr_disable_inwait,
+ 	.get_rate = clk_emi_slow_get_rate,
+ };
+ 
+ static int clk_ipu_enable(struct clk *clk)
+ {
+ 	u32 reg;
+ 
+ 	_clk_ccgr_enable(clk);
+ 
+ 	/* Enable handshake with IPU when certain clock rates are changed */
+ 	reg = __raw_readl(MXC_CCM_CCDR);
+ 	reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
+ 	__raw_writel(reg, MXC_CCM_CCDR);
+ 
+ 	/* Enable handshake with IPU when LPM is entered */
+ 	reg = __raw_readl(MXC_CCM_CLPCR);
+ 	reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
+ 	__raw_writel(reg, MXC_CCM_CLPCR);
+ 
+ 	return 0;
+ }
+ 
+ static void clk_ipu_disable(struct clk *clk)
+ {
+ 	u32 reg;
+ 
+ 	_clk_ccgr_disable(clk);
+ 
+ 	/* Disable handshake with IPU whe dividers are changed */
+ 	reg = __raw_readl(MXC_CCM_CCDR);
+ 	reg |= MXC_CCM_CCDR_IPU_HS_MASK;
+ 	__raw_writel(reg, MXC_CCM_CCDR);
+ 
+ 	/* Disable handshake with IPU when LPM is entered */
+ 	reg = __raw_readl(MXC_CCM_CLPCR);
+ 	reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
+ 	__raw_writel(reg, MXC_CCM_CLPCR);
+ }
+ 
+ static struct clk ahbmux1_clk = {
+ 	.parent = &ahb_clk,
+ 	.secondary = &ahb_max_clk,
+ 	.enable_reg = MXC_CCM_CCGR0,
+ 	.enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ 	.enable = _clk_ccgr_enable,
+ 	.disable = _clk_ccgr_disable_inwait,
+ };
+ 
+ static struct clk ipu_sec_clk = {
+ 	.parent = &emi_fast_clk,
+ 	.secondary = &ahbmux1_clk,
+ };
+ 
+ static struct clk ddr_hf_clk = {
+ 	.parent = &pll1_sw_clk,
+ 	.get_rate = _clk_ddr_hf_get_rate,
+ };
+ 
+ static struct clk ddr_clk = {
+ 	.parent = &ddr_hf_clk,
+ };
+ 
+ /* clock definitions for MIPI HSC unit which has been removed
+  * from documentation, but not from hardware
+  */
+ static int _clk_hsc_enable(struct clk *clk)
+ {
+ 	u32 reg;
+ 
+ 	_clk_ccgr_enable(clk);
+ 	/* Handshake with IPU when certain clock rates are changed. */
+ 	reg = __raw_readl(MXC_CCM_CCDR);
+ 	reg &= ~MXC_CCM_CCDR_HSC_HS_MASK;
+ 	__raw_writel(reg, MXC_CCM_CCDR);
+ 
+ 	reg = __raw_readl(MXC_CCM_CLPCR);
+ 	reg &= ~MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
+ 	__raw_writel(reg, MXC_CCM_CLPCR);
+ 
+ 	return 0;
+ }
+ 
+ static void _clk_hsc_disable(struct clk *clk)
+ {
+ 	u32 reg;
+ 
+ 	_clk_ccgr_disable(clk);
+ 	/* No handshake with HSC as its not enabled. */
+ 	reg = __raw_readl(MXC_CCM_CCDR);
+ 	reg |= MXC_CCM_CCDR_HSC_HS_MASK;
+ 	__raw_writel(reg, MXC_CCM_CCDR);
+ 
+ 	reg = __raw_readl(MXC_CCM_CLPCR);
+ 	reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
+ 	__raw_writel(reg, MXC_CCM_CLPCR);
+ }
+ 
+ static struct clk mipi_hsp_clk = {
+ 	.parent = &ipu_clk,
+ 	.enable_reg = MXC_CCM_CCGR4,
+ 	.enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ 	.enable = _clk_hsc_enable,
+ 	.disable = _clk_hsc_disable,
+ 	.secondary = &mipi_hsc1_clk,
+ };
+ 
+ #define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s)	\
+ 	static struct clk name = {			\
+ 		.id		= i,			\
+ 		.enable_reg	= er,			\
+ 		.enable_shift	= es,			\
+ 		.get_rate	= pfx##_get_rate,	\
+ 		.set_rate	= pfx##_set_rate,	\
+ 		.round_rate	= pfx##_round_rate,	\
+ 		.set_parent	= pfx##_set_parent,	\
+ 		.enable		= _clk_ccgr_enable,	\
+ 		.disable	= _clk_ccgr_disable,	\
+ 		.parent		= p,			\
+ 		.secondary	= s,			\
+ 	}
+ 
+ #define DEFINE_CLOCK_MAX(name, i, er, es, pfx, p, s)	\
+ 	static struct clk name = {			\
+ 		.id		= i,			\
+ 		.enable_reg	= er,			\
+ 		.enable_shift	= es,			\
+ 		.get_rate	= pfx##_get_rate,	\
+ 		.set_rate	= pfx##_set_rate,	\
+ 		.set_parent	= pfx##_set_parent,	\
+ 		.enable		= _clk_max_enable,	\
+ 		.disable	= _clk_max_disable,	\
+ 		.parent		= p,			\
+ 		.secondary	= s,			\
+ 	}
+ 
+ #define CLK_GET_RATE(name, nr, bitsname)				\
+ static unsigned long clk_##name##_get_rate(struct clk *clk)		\
+ {									\
+ 	u32 reg, pred, podf;						\
+ 									\
+ 	reg = __raw_readl(MXC_CCM_CSCDR##nr);				\
+ 	pred = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK)	\
+ 		>> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET;	\
+ 	podf = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK)	\
+ 		>> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET;	\
+ 									\
+ 	return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent),		\
+ 			(pred + 1) * (podf + 1));			\
+ }
+ 
+ #define CLK_SET_PARENT(name, nr, bitsname)				\
+ static int clk_##name##_set_parent(struct clk *clk, struct clk *parent)	\
+ {									\
+ 	u32 reg, mux;							\
+ 									\
+ 	mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk,		\
+ 			&pll3_sw_clk, &lp_apm_clk);			\
+ 	reg = __raw_readl(MXC_CCM_CSCMR##nr) &				\
+ 		~MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_MASK;		\
+ 	reg |= mux << MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_OFFSET;	\
+ 	__raw_writel(reg, MXC_CCM_CSCMR##nr);				\
+ 									\
+ 	return 0;							\
+ }
+ 
+ #define CLK_SET_RATE(name, nr, bitsname)				\
+ static int clk_##name##_set_rate(struct clk *clk, unsigned long rate)	\
+ {									\
+ 	u32 reg, div, parent_rate;					\
+ 	u32 pre = 0, post = 0;						\
+ 									\
+ 	parent_rate = clk_get_rate(clk->parent);			\
+ 	div = parent_rate / rate;					\
+ 									\
+ 	if ((parent_rate / div) != rate)				\
+ 		return -EINVAL;						\
+ 									\
+ 	__calc_pre_post_dividers(div, &pre, &post,			\
+ 		(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK >>	\
+ 		MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET) + 1,	\
+ 		(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK >>	\
+ 		MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET) + 1);\
+ 									\
+ 	/* Set sdhc1 clock divider */					\
+ 	reg = __raw_readl(MXC_CCM_CSCDR##nr) &				\
+ 		~(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK	\
+ 		| MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK);	\
+ 	reg |= (post - 1) <<						\
+ 		MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET;	\
+ 	reg |= (pre - 1) <<						\
+ 		MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET;	\
+ 	__raw_writel(reg, MXC_CCM_CSCDR##nr);				\
+ 									\
+ 	return 0;							\
+ }
+ 
+ /* UART */
+ CLK_GET_RATE(uart, 1, UART)
+ CLK_SET_PARENT(uart, 1, UART)
+ 
+ static struct clk uart_root_clk = {
+ 	.parent = &pll2_sw_clk,
+ 	.get_rate = clk_uart_get_rate,
+ 	.set_parent = clk_uart_set_parent,
+ };
+ 
+ /* USBOH3 */
+ CLK_GET_RATE(usboh3, 1, USBOH3)
+ CLK_SET_PARENT(usboh3, 1, USBOH3)
+ 
+ static struct clk usboh3_clk = {
+ 	.parent = &pll2_sw_clk,
+ 	.get_rate = clk_usboh3_get_rate,
+ 	.set_parent = clk_usboh3_set_parent,
+ 	.enable = _clk_ccgr_enable,
+ 	.disable = _clk_ccgr_disable,
+ 	.enable_reg = MXC_CCM_CCGR2,
+ 	.enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ };
+ 
+ static struct clk usb_ahb_clk = {
+ 	.parent = &ipg_clk,
+ 	.enable = _clk_ccgr_enable,
+ 	.disable = _clk_ccgr_disable,
+ 	.enable_reg = MXC_CCM_CCGR2,
+ 	.enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ };
+ 
+ static int clk_usb_phy1_set_parent(struct clk *clk, struct clk *parent)
+ {
+ 	u32 reg;
+ 
+ 	reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL;
+ 
+ 	if (parent == &pll3_sw_clk)
+ 		reg |= 1 << MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET;
+ 
+ 	__raw_writel(reg, MXC_CCM_CSCMR1);
+ 
+ 	return 0;
+ }
+ 
+ static struct clk usb_phy1_clk = {
+ 	.parent = &pll3_sw_clk,
+ 	.set_parent = clk_usb_phy1_set_parent,
+ 	.enable = _clk_ccgr_enable,
+ 	.enable_reg = MXC_CCM_CCGR2,
+ 	.enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ 	.disable = _clk_ccgr_disable,
+ };
+ 
+ /* eCSPI */
+ CLK_GET_RATE(ecspi, 2, CSPI)
+ CLK_SET_PARENT(ecspi, 1, CSPI)
+ 
+ static struct clk ecspi_main_clk = {
+ 	.parent = &pll3_sw_clk,
+ 	.get_rate = clk_ecspi_get_rate,
+ 	.set_parent = clk_ecspi_set_parent,
+ };
+ 
+ /* eSDHC */
+ CLK_GET_RATE(esdhc1, 1, ESDHC1_MSHC1)
+ CLK_SET_PARENT(esdhc1, 1, ESDHC1_MSHC1)
+ CLK_SET_RATE(esdhc1, 1, ESDHC1_MSHC1)
+ 
+ CLK_GET_RATE(esdhc2, 1, ESDHC2_MSHC2)
+ CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2)
+ CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2)
+ 
+ #define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s)		\
+ 	static struct clk name = {					\
+ 		.id		= i,					\
+ 		.enable_reg	= er,					\
+ 		.enable_shift	= es,					\
+ 		.get_rate	= gr,					\
+ 		.set_rate	= sr,					\
+ 		.enable		= e,					\
+ 		.disable	= d,					\
+ 		.parent		= p,					\
+ 		.secondary	= s,					\
+ 	}
+ 
+ #define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s)			\
+ 	DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, _clk_ccgr_enable, _clk_ccgr_disable, p, s)
+ 
+ /* Shared peripheral bus arbiter */
+ DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET,
+ 	NULL,  NULL, &ipg_clk, NULL);
+ 
+ /* UART */
+ DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET,
+ 	NULL,  NULL, &ipg_clk, &aips_tz1_clk);
+ DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET,
+ 	NULL,  NULL, &ipg_clk, &aips_tz1_clk);
+ DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
+ 	NULL,  NULL, &ipg_clk, &spba_clk);
+ DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET,
+ 	NULL,  NULL, &uart_root_clk, &uart1_ipg_clk);
+ DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET,
+ 	NULL,  NULL, &uart_root_clk, &uart2_ipg_clk);
+ DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET,
+ 	NULL,  NULL, &uart_root_clk, &uart3_ipg_clk);
+ 
+ /* GPT */
+ DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
+ 	NULL,  NULL, &ipg_clk, NULL);
+ DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
+ 	NULL,  NULL, &ipg_clk, &gpt_ipg_clk);
+ 
+ /* I2C */
+ DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET,
+ 	NULL, NULL, &ipg_clk, NULL);
+ DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG10_OFFSET,
+ 	NULL, NULL, &ipg_clk, NULL);
+ DEFINE_CLOCK(hsi2c_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET,
+ 	NULL, NULL, &ipg_clk, NULL);
+ 
+ /* FEC */
+ DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
+ 	NULL,  NULL, &ipg_clk, NULL);
+ 
+ /* NFC */
+ DEFINE_CLOCK_CCGR(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET,
+ 	clk_nfc, &emi_slow_clk, NULL);
+ 
+ /* SSI */
+ DEFINE_CLOCK(ssi1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG8_OFFSET,
+ 	NULL, NULL, &ipg_clk, NULL);
+ DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG9_OFFSET,
+ 	NULL, NULL, &pll3_sw_clk, &ssi1_ipg_clk);
+ DEFINE_CLOCK(ssi2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG10_OFFSET,
+ 	NULL, NULL, &ipg_clk, NULL);
+ DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG11_OFFSET,
+ 	NULL, NULL, &pll3_sw_clk, &ssi2_ipg_clk);
+ DEFINE_CLOCK(ssi3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG12_OFFSET,
+ 	NULL, NULL, &ipg_clk, NULL);
+ DEFINE_CLOCK(ssi3_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG13_OFFSET,
+ 	NULL, NULL, &pll3_sw_clk, &ssi3_ipg_clk);
+ 
+ /* eCSPI */
+ DEFINE_CLOCK_FULL(ecspi1_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET,
+ 		NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable,
+ 		&ipg_clk, &spba_clk);
+ DEFINE_CLOCK(ecspi1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG10_OFFSET,
+ 		NULL, NULL, &ecspi_main_clk, &ecspi1_ipg_clk);
+ DEFINE_CLOCK_FULL(ecspi2_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG11_OFFSET,
+ 		NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable,
+ 		&ipg_clk, &aips_tz2_clk);
+ DEFINE_CLOCK(ecspi2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG12_OFFSET,
+ 		NULL, NULL, &ecspi_main_clk, &ecspi2_ipg_clk);
+ 
+ /* CSPI */
+ DEFINE_CLOCK(cspi_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET,
+ 		NULL, NULL, &ipg_clk, &aips_tz2_clk);
+ DEFINE_CLOCK(cspi_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG13_OFFSET,
+ 		NULL, NULL, &ipg_clk, &cspi_ipg_clk);
+ 
+ /* SDMA */
+ DEFINE_CLOCK(sdma_clk, 1, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG15_OFFSET,
+ 		NULL, NULL, &ahb_clk, NULL);
+ 
+ /* eSDHC */
+ DEFINE_CLOCK_FULL(esdhc1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG0_OFFSET,
+ 	NULL,  NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
+ DEFINE_CLOCK_MAX(esdhc1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG1_OFFSET,
+ 	clk_esdhc1, &pll2_sw_clk, &esdhc1_ipg_clk);
+ DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET,
+ 	NULL,  NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
+ DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET,
+ 	clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk);
+ 
+ DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk);
+ DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk);
+ DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk);
+ 
+ /* IPU */
+ DEFINE_CLOCK_FULL(ipu_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG5_OFFSET,
+ 	NULL,  NULL, clk_ipu_enable, clk_ipu_disable, &ahb_clk, &ipu_sec_clk);
+ 
+ DEFINE_CLOCK_FULL(emi_fast_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG7_OFFSET,
+ 		NULL, NULL, _clk_ccgr_enable, _clk_ccgr_disable_inwait,
+ 		&ddr_clk, NULL);
+ 
+ DEFINE_CLOCK(ipu_di0_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG5_OFFSET,
+ 		NULL, NULL, &pll3_sw_clk, NULL);
+ DEFINE_CLOCK(ipu_di1_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG6_OFFSET,
+ 		NULL, NULL, &pll3_sw_clk, NULL);
+ 
+ #define _REGISTER_CLOCK(d, n, c) \
+        { \
+ 		.dev_id = d, \
+ 		.con_id = n, \
+ 		.clk = &c,   \
+        },
+ 
+ static struct clk_lookup mx51_lookups[] = {
+ 	_REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+ 	_REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+ 	_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+ 	_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
+ 	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ 	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+ 	_REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+ 	_REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk)
+ 	_REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk)
+ 	_REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_ahb_clk)
+ 	_REGISTER_CLOCK("mxc-ehci.0", "usb_phy1", usb_phy1_clk)
+ 	_REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk)
+ 	_REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_ahb_clk)
+ 	_REGISTER_CLOCK("mxc-ehci.2", "usb", usboh3_clk)
+ 	_REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_ahb_clk)
+ 	_REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk)
+ 	_REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk)
+ 	_REGISTER_CLOCK("imx-keypad.0", NULL, kpp_clk)
+ 	_REGISTER_CLOCK("mxc_nand", NULL, nfc_clk)
+ 	_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
+ 	_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+ 	_REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk)
+ 	_REGISTER_CLOCK("imx-sdma", NULL, sdma_clk)
+ 	_REGISTER_CLOCK(NULL, "ckih", ckih_clk)
+ 	_REGISTER_CLOCK(NULL, "ckih2", ckih2_clk)
+ 	_REGISTER_CLOCK(NULL, "gpt_32k", gpt_32k_clk)
+ 	_REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk)
+ 	_REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk)
+ 	_REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_clk)
+ 	_REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
+ 	_REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
+ 	_REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk)
+ 	_REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
+ 	_REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk)
+ 	_REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk)
+ 	_REGISTER_CLOCK(NULL, "mipi_hsp", mipi_hsp_clk)
+ 	_REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk)
+ 	_REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk)
+ 	_REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk)
+ };
+ 
+ static struct clk_lookup mx53_lookups[] = {
+ 	_REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+ 	_REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+ 	_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+ 	_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
+ 	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ 	_REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
+ };
+ 
+ static void clk_tree_init(void)
+ {
+ 	u32 reg;
+ 
+ 	ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);
+ 
+ 	/*
+ 	 * Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
+ 	 * 8MHz, its derived from lp_apm.
+ 	 *
+ 	 * FIXME: Verify if true for all boards
+ 	 */
+ 	reg = __raw_readl(MXC_CCM_CBCDR);
+ 	reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK;
+ 	reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK;
+ 	reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK;
+ 	reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET);
+ 	__raw_writel(reg, MXC_CCM_CBCDR);
+ }
+ 
+ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
+ 			unsigned long ckih1, unsigned long ckih2)
+ {
+ 	int i;
+ 
+ 	external_low_reference = ckil;
+ 	external_high_reference = ckih1;
+ 	ckih2_reference = ckih2;
+ 	oscillator_reference = osc;
+ 
+ 	for (i = 0; i < ARRAY_SIZE(mx51_lookups); i++)
+ 		clkdev_add(&mx51_lookups[i]);
+ 
+ 	clk_tree_init();
+ 
+ 	clk_set_parent(&uart_root_clk, &pll3_sw_clk);
+ 	clk_enable(&cpu_clk);
+ 	clk_enable(&main_bus_clk);
+ 
+ 	clk_enable(&iim_clk);
+ 	mx51_revision();
+ 	clk_disable(&iim_clk);
+ 
+ 	/* move usb_phy_clk to 24MHz */
+ 	clk_set_parent(&usb_phy1_clk, &osc_clk);
+ 
+ 	/* set the usboh3_clk parent to pll2_sw_clk */
+ 	clk_set_parent(&usboh3_clk, &pll2_sw_clk);
+ 
+ 	/* Set SDHC parents to be PLL2 */
+ 	clk_set_parent(&esdhc1_clk, &pll2_sw_clk);
+ 	clk_set_parent(&esdhc2_clk, &pll2_sw_clk);
+ 
+ 	/* set SDHC root clock as 166.25MHZ*/
+ 	clk_set_rate(&esdhc1_clk, 166250000);
+ 	clk_set_rate(&esdhc2_clk, 166250000);
+ 
+ 	/* System timer */
+ 	mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
+ 		MX51_MXC_INT_GPT);
+ 	return 0;
+ }
+ 
+ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
+ 			unsigned long ckih1, unsigned long ckih2)
+ {
+ 	int i;
+ 
+ 	external_low_reference = ckil;
+ 	external_high_reference = ckih1;
+ 	ckih2_reference = ckih2;
+ 	oscillator_reference = osc;
+ 
+ 	for (i = 0; i < ARRAY_SIZE(mx53_lookups); i++)
+ 		clkdev_add(&mx53_lookups[i]);
+ 
+ 	clk_tree_init();
+ 
+ 	clk_enable(&cpu_clk);
+ 	clk_enable(&main_bus_clk);
+ 
+ 	clk_enable(&iim_clk);
+ 	mx53_revision();
+ 	clk_disable(&iim_clk);
+ 
+ 	/* System timer */
+ 	mxc_timer_init(&gpt_clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
+ 		MX53_INT_GPT);
+ 	return 0;
+ }
diff --cc arch/arm/mach-pxa/clock.c
index 4e4a84be96ba,8184fe2d71c3..d5152220ce94
--- a/arch/arm/mach-pxa/clock.c
+++ b/arch/arm/mach-pxa/clock.c
@@@ -3,21 -3,12 +3,11 @@@
   */
  #include <linux/module.h>
  #include <linux/kernel.h>
- #include <linux/list.h>
- #include <linux/errno.h>
- #include <linux/err.h>
- #include <linux/string.h>
  #include <linux/clk.h>
  #include <linux/spinlock.h>
- #include <linux/platform_device.h>
  #include <linux/delay.h>
 -
 -#include <asm/clkdev.h>
 +#include <linux/clkdev.h>
  
- #include <mach/pxa2xx-regs.h>
- #include <mach/hardware.h>
- 
- #include "devices.h"
- #include "generic.h"
  #include "clock.h"
  
  static DEFINE_SPINLOCK(clocks_lock);
diff --cc arch/arm/mach-pxa/clock.h
index 12cc0e87e6c4,6e949944f2ec..f9f349a21b54
--- a/arch/arm/mach-pxa/clock.h
+++ b/arch/arm/mach-pxa/clock.h
@@@ -1,4 -1,5 +1,5 @@@
 +#include <linux/clkdev.h>
+ #include <linux/sysdev.h>
 -#include <asm/clkdev.h>
  
  struct clkops {
  	void			(*enable)(struct clk *);
diff --cc arch/arm/mach-ux500/cpu.c
index 7328c0179769,a3700bc374d3..5730409c0f7d
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@@ -54,15 -50,10 +50,10 @@@ void __init ux500_map_io(void
  	iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc));
  }
  
- void __init ux500_init_devices(void)
- {
- 	amba_add_devices(ux500_amba_devs, ARRAY_SIZE(ux500_amba_devs));
- }
- 
  void __init ux500_init_irq(void)
  {
 -	gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29);
 -	gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE));
 +	gic_init(0, 29, __io_address(UX500_GIC_DIST_BASE),
 +		 __io_address(UX500_GIC_CPU_BASE));
  
  	/*
  	 * Init clocks here so that they are available for system timer
diff --cc arch/arm/mach-ux500/platsmp.c
index 2115a0cf07b0,ade2e17f253c..d77e76cb7edd
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@@ -25,19 -26,11 +25,19 @@@
   * control for which core is the next to come out of the secondary
   * boot "holding pen"
   */
- volatile int __cpuinitdata pen_release = -1;
+ volatile int pen_release = -1;
  
 -static unsigned int __init get_core_count(void)
 +/*
 + * Write pen_release in a way that is guaranteed to be visible to all
 + * observers, irrespective of whether they're taking part in coherency
 + * or not.  This is necessary for the hotplug code to work reliably.
 + */
 +static void write_pen_release(int val)
  {
 -	return scu_get_core_count(__io_address(UX500_SCU_BASE));
 +	pen_release = val;
 +	smp_wmb();
 +	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
 +	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
  }
  
  static DEFINE_SPINLOCK(boot_lock);