diff mbox

[5/5] ARM: OMAP2/3: clockdomain/PRM/CM: move the low-level clockdomain functions into PRM/CM

Message ID 20121015230545.18306.36852.stgit@dusk.lan (mailing list archive)
State New, archived
Headers show

Commit Message

Paul Walmsley Oct. 15, 2012, 11:05 p.m. UTC
Move the low-level SoC-specific clockdomain control functions into
cm*.c and prm*.c.  For example, OMAP2xxx low-level clockdomain
functions go into cm2xxx.c.  Then remove the unnecessary
clockdomain*xxx*.c files.

The objective is to centralize low-level CM and PRM register accesses
into the cm*.[ch] and prm*.[ch] files, and then to export an OMAP
SoC-independent API to higher-level OMAP power management code.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Rajendra Nayak <rnayak@ti.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
 arch/arm/mach-omap2/Makefile               |    5 
 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c |  340 ----------------------------
 arch/arm/mach-omap2/clockdomain33xx.c      |   74 ------
 arch/arm/mach-omap2/clockdomain44xx.c      |  151 ------------
 arch/arm/mach-omap2/cm2xxx.c               |   86 +++++++
 arch/arm/mach-omap2/cm2xxx_3xxx.h          |   12 +
 arch/arm/mach-omap2/cm33xx.c               |   56 +++++
 arch/arm/mach-omap2/cm3xxx.c               |  169 ++++++++++++++
 arch/arm/mach-omap2/cminst44xx.c           |  139 +++++++++++
 arch/arm/mach-omap2/prm2xxx.c              |   17 +
 arch/arm/mach-omap2/prm2xxx.h              |    6 
 arch/arm/mach-omap2/prm2xxx_3xxx.c         |   43 ++++
 arch/arm/mach-omap2/prm2xxx_3xxx.h         |    8 +
 13 files changed, 536 insertions(+), 570 deletions(-)
 delete mode 100644 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
 delete mode 100644 arch/arm/mach-omap2/clockdomain33xx.c
 delete mode 100644 arch/arm/mach-omap2/clockdomain44xx.c

Comments

Rajendra Nayak Oct. 18, 2012, 7:08 a.m. UTC | #1
On Tuesday 16 October 2012 04:35 AM, Paul Walmsley wrote:
> Move the low-level SoC-specific clockdomain control functions into
> cm*.c and prm*.c.  For example, OMAP2xxx low-level clockdomain
> functions go into cm2xxx.c.  Then remove the unnecessary
> clockdomain*xxx*.c files.
>
> The objective is to centralize low-level CM and PRM register accesses
> into the cm*.[ch] and prm*.[ch] files, and then to export an OMAP
> SoC-independent API to higher-level OMAP power management code.
>
> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> Cc: Rajendra Nayak <rnayak@ti.com>

Acked-by: Rajendra Nayak <rnayak@ti.com>

> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
>   arch/arm/mach-omap2/Makefile               |    5
>   arch/arm/mach-omap2/clockdomain2xxx_3xxx.c |  340 ----------------------------
>   arch/arm/mach-omap2/clockdomain33xx.c      |   74 ------
>   arch/arm/mach-omap2/clockdomain44xx.c      |  151 ------------
>   arch/arm/mach-omap2/cm2xxx.c               |   86 +++++++
>   arch/arm/mach-omap2/cm2xxx_3xxx.h          |   12 +
>   arch/arm/mach-omap2/cm33xx.c               |   56 +++++
>   arch/arm/mach-omap2/cm3xxx.c               |  169 ++++++++++++++
>   arch/arm/mach-omap2/cminst44xx.c           |  139 +++++++++++
>   arch/arm/mach-omap2/prm2xxx.c              |   17 +
>   arch/arm/mach-omap2/prm2xxx.h              |    6
>   arch/arm/mach-omap2/prm2xxx_3xxx.c         |   43 ++++
>   arch/arm/mach-omap2/prm2xxx_3xxx.h         |    8 +
>   13 files changed, 536 insertions(+), 570 deletions(-)
>   delete mode 100644 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
>   delete mode 100644 arch/arm/mach-omap2/clockdomain33xx.c
>   delete mode 100644 arch/arm/mach-omap2/clockdomain44xx.c
>
> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> index 56a3386..3751d56 100644
> --- a/arch/arm/mach-omap2/Makefile
> +++ b/arch/arm/mach-omap2/Makefile
> @@ -133,22 +133,17 @@ obj-$(CONFIG_SOC_OMAP5)			+= $(powerdomain-common)
>   # PRCM clockdomain control
>   clockdomain-common			+= clockdomain.o
>   obj-$(CONFIG_ARCH_OMAP2)		+= $(clockdomain-common)
> -obj-$(CONFIG_ARCH_OMAP2)		+= clockdomain2xxx_3xxx.o
>   obj-$(CONFIG_ARCH_OMAP2)		+= clockdomains2xxx_3xxx_data.o
>   obj-$(CONFIG_SOC_OMAP2420)		+= clockdomains2420_data.o
>   obj-$(CONFIG_SOC_OMAP2430)		+= clockdomains2430_data.o
>   obj-$(CONFIG_ARCH_OMAP3)		+= $(clockdomain-common)
> -obj-$(CONFIG_ARCH_OMAP3)		+= clockdomain2xxx_3xxx.o
>   obj-$(CONFIG_ARCH_OMAP3)		+= clockdomains2xxx_3xxx_data.o
>   obj-$(CONFIG_ARCH_OMAP3)		+= clockdomains3xxx_data.o
>   obj-$(CONFIG_ARCH_OMAP4)		+= $(clockdomain-common)
> -obj-$(CONFIG_ARCH_OMAP4)		+= clockdomain44xx.o
>   obj-$(CONFIG_ARCH_OMAP4)		+= clockdomains44xx_data.o
>   obj-$(CONFIG_SOC_AM33XX)		+= $(clockdomain-common)
> -obj-$(CONFIG_SOC_AM33XX)		+= clockdomain33xx.o
>   obj-$(CONFIG_SOC_AM33XX)		+= clockdomains33xx_data.o
>   obj-$(CONFIG_SOC_OMAP5)			+= $(clockdomain-common)
> -obj-$(CONFIG_SOC_OMAP5)			+= clockdomain44xx.o
>
>   # Clock framework
>   obj-$(CONFIG_ARCH_OMAP2)		+= $(clock-common) clock2xxx.o
> diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> deleted file mode 100644
> index 658487c..0000000
> --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> +++ /dev/null
> @@ -1,340 +0,0 @@
> -/*
> - * OMAP2 and OMAP3 clockdomain control
> - *
> - * Copyright (C) 2008-2010 Texas Instruments, Inc.
> - * Copyright (C) 2008-2010 Nokia Corporation
> - *
> - * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
> - * Rajendra Nayak <rnayak@ti.com>
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> - */
> -
> -#include <linux/types.h>
> -#include <plat/prcm.h>
> -#include "prm.h"
> -#include "prm2xxx_3xxx.h"
> -#include "cm.h"
> -#include "cm2xxx.h"
> -#include "cm3xxx.h"
> -#include "cm-regbits-24xx.h"
> -#include "cm-regbits-34xx.h"
> -#include "prm-regbits-24xx.h"
> -#include "clockdomain.h"
> -
> -static int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
> -						struct clockdomain *clkdm2)
> -{
> -	omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> -				clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> -	return 0;
> -}
> -
> -static int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
> -						 struct clockdomain *clkdm2)
> -{
> -	omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> -				clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> -	return 0;
> -}
> -
> -static int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
> -						 struct clockdomain *clkdm2)
> -{
> -	return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> -				PM_WKDEP, (1 << clkdm2->dep_bit));
> -}
> -
> -static int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
> -{
> -	struct clkdm_dep *cd;
> -	u32 mask = 0;
> -
> -	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> -		if (!cd->clkdm)
> -			continue; /* only happens if data is erroneous */
> -
> -		/* PRM accesses are slow, so minimize them */
> -		mask |= 1 << cd->clkdm->dep_bit;
> -		atomic_set(&cd->wkdep_usecount, 0);
> -	}
> -
> -	omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> -				 PM_WKDEP);
> -	return 0;
> -}
> -
> -static int omap3_clkdm_add_sleepdep(struct clockdomain *clkdm1,
> -						 struct clockdomain *clkdm2)
> -{
> -	omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> -				clkdm1->pwrdm.ptr->prcm_offs,
> -				OMAP3430_CM_SLEEPDEP);
> -	return 0;
> -}
> -
> -static int omap3_clkdm_del_sleepdep(struct clockdomain *clkdm1,
> -						 struct clockdomain *clkdm2)
> -{
> -	omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> -				clkdm1->pwrdm.ptr->prcm_offs,
> -				OMAP3430_CM_SLEEPDEP);
> -	return 0;
> -}
> -
> -static int omap3_clkdm_read_sleepdep(struct clockdomain *clkdm1,
> -						 struct clockdomain *clkdm2)
> -{
> -	return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> -				OMAP3430_CM_SLEEPDEP, (1 << clkdm2->dep_bit));
> -}
> -
> -static int omap3_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
> -{
> -	struct clkdm_dep *cd;
> -	u32 mask = 0;
> -
> -	for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
> -		if (!cd->clkdm)
> -			continue; /* only happens if data is erroneous */
> -
> -		/* PRM accesses are slow, so minimize them */
> -		mask |= 1 << cd->clkdm->dep_bit;
> -		atomic_set(&cd->sleepdep_usecount, 0);
> -	}
> -	omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> -				OMAP3430_CM_SLEEPDEP);
> -	return 0;
> -}
> -
> -static int omap2_clkdm_sleep(struct clockdomain *clkdm)
> -{
> -	omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
> -				clkdm->pwrdm.ptr->prcm_offs,
> -				OMAP2_PM_PWSTCTRL);
> -	return 0;
> -}
> -
> -static int omap2_clkdm_wakeup(struct clockdomain *clkdm)
> -{
> -	omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
> -				clkdm->pwrdm.ptr->prcm_offs,
> -				OMAP2_PM_PWSTCTRL);
> -	return 0;
> -}
> -
> -static void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
> -{
> -	if (atomic_read(&clkdm->usecount) > 0)
> -		_clkdm_add_autodeps(clkdm);
> -
> -	omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -				clkdm->clktrctrl_mask);
> -}
> -
> -static void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
> -{
> -	omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -				clkdm->clktrctrl_mask);
> -
> -	if (atomic_read(&clkdm->usecount) > 0)
> -		_clkdm_del_autodeps(clkdm);
> -}
> -
> -static void _enable_hwsup(struct clockdomain *clkdm)
> -{
> -	if (cpu_is_omap24xx())
> -		omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -					       clkdm->clktrctrl_mask);
> -	else if (cpu_is_omap34xx())
> -		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -					       clkdm->clktrctrl_mask);
> -}
> -
> -static void _disable_hwsup(struct clockdomain *clkdm)
> -{
> -	if (cpu_is_omap24xx())
> -		omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -						clkdm->clktrctrl_mask);
> -	else if (cpu_is_omap34xx())
> -		omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -						clkdm->clktrctrl_mask);
> -}
> -
> -static int omap3_clkdm_sleep(struct clockdomain *clkdm)
> -{
> -	omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
> -				clkdm->clktrctrl_mask);
> -	return 0;
> -}
> -
> -static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
> -{
> -	omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
> -				clkdm->clktrctrl_mask);
> -	return 0;
> -}
> -
> -static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
> -{
> -	bool hwsup = false;
> -
> -	if (!clkdm->clktrctrl_mask)
> -		return 0;
> -
> -	hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -					      clkdm->clktrctrl_mask);
> -
> -	if (hwsup) {
> -		/* Disable HW transitions when we are changing deps */
> -		_disable_hwsup(clkdm);
> -		_clkdm_add_autodeps(clkdm);
> -		_enable_hwsup(clkdm);
> -	} else {
> -		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> -			omap2_clkdm_wakeup(clkdm);
> -	}
> -
> -	return 0;
> -}
> -
> -static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm)
> -{
> -	bool hwsup = false;
> -
> -	if (!clkdm->clktrctrl_mask)
> -		return 0;
> -
> -	hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -					      clkdm->clktrctrl_mask);
> -
> -	if (hwsup) {
> -		/* Disable HW transitions when we are changing deps */
> -		_disable_hwsup(clkdm);
> -		_clkdm_del_autodeps(clkdm);
> -		_enable_hwsup(clkdm);
> -	} else {
> -		if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
> -			omap2_clkdm_sleep(clkdm);
> -	}
> -
> -	return 0;
> -}
> -
> -static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
> -{
> -	if (atomic_read(&clkdm->usecount) > 0)
> -		_clkdm_add_autodeps(clkdm);
> -
> -	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -				clkdm->clktrctrl_mask);
> -}
> -
> -static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
> -{
> -	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -				clkdm->clktrctrl_mask);
> -
> -	if (atomic_read(&clkdm->usecount) > 0)
> -		_clkdm_del_autodeps(clkdm);
> -}
> -
> -static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
> -{
> -	bool hwsup = false;
> -
> -	if (!clkdm->clktrctrl_mask)
> -		return 0;
> -
> -	/*
> -	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> -	 * more details on the unpleasant problem this is working
> -	 * around
> -	 */
> -	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
> -	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
> -		omap3_clkdm_wakeup(clkdm);
> -		return 0;
> -	}
> -
> -	hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -					      clkdm->clktrctrl_mask);
> -
> -	if (hwsup) {
> -		/* Disable HW transitions when we are changing deps */
> -		_disable_hwsup(clkdm);
> -		_clkdm_add_autodeps(clkdm);
> -		_enable_hwsup(clkdm);
> -	} else {
> -		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> -			omap3_clkdm_wakeup(clkdm);
> -	}
> -
> -	return 0;
> -}
> -
> -static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
> -{
> -	bool hwsup = false;
> -
> -	if (!clkdm->clktrctrl_mask)
> -		return 0;
> -
> -	/*
> -	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> -	 * more details on the unpleasant problem this is working
> -	 * around
> -	 */
> -	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
> -	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
> -		_enable_hwsup(clkdm);
> -		return 0;
> -	}
> -
> -	hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -					      clkdm->clktrctrl_mask);
> -
> -	if (hwsup) {
> -		/* Disable HW transitions when we are changing deps */
> -		_disable_hwsup(clkdm);
> -		_clkdm_del_autodeps(clkdm);
> -		_enable_hwsup(clkdm);
> -	} else {
> -		if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
> -			omap3_clkdm_sleep(clkdm);
> -	}
> -
> -	return 0;
> -}
> -
> -struct clkdm_ops omap2_clkdm_operations = {
> -	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,
> -	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep,
> -	.clkdm_read_wkdep	= omap2_clkdm_read_wkdep,
> -	.clkdm_clear_all_wkdeps	= omap2_clkdm_clear_all_wkdeps,
> -	.clkdm_sleep		= omap2_clkdm_sleep,
> -	.clkdm_wakeup		= omap2_clkdm_wakeup,
> -	.clkdm_allow_idle	= omap2_clkdm_allow_idle,
> -	.clkdm_deny_idle	= omap2_clkdm_deny_idle,
> -	.clkdm_clk_enable	= omap2xxx_clkdm_clk_enable,
> -	.clkdm_clk_disable	= omap2xxx_clkdm_clk_disable,
> -};
> -
> -struct clkdm_ops omap3_clkdm_operations = {
> -	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,
> -	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep,
> -	.clkdm_read_wkdep	= omap2_clkdm_read_wkdep,
> -	.clkdm_clear_all_wkdeps	= omap2_clkdm_clear_all_wkdeps,
> -	.clkdm_add_sleepdep	= omap3_clkdm_add_sleepdep,
> -	.clkdm_del_sleepdep	= omap3_clkdm_del_sleepdep,
> -	.clkdm_read_sleepdep	= omap3_clkdm_read_sleepdep,
> -	.clkdm_clear_all_sleepdeps	= omap3_clkdm_clear_all_sleepdeps,
> -	.clkdm_sleep		= omap3_clkdm_sleep,
> -	.clkdm_wakeup		= omap3_clkdm_wakeup,
> -	.clkdm_allow_idle	= omap3_clkdm_allow_idle,
> -	.clkdm_deny_idle	= omap3_clkdm_deny_idle,
> -	.clkdm_clk_enable	= omap3xxx_clkdm_clk_enable,
> -	.clkdm_clk_disable	= omap3xxx_clkdm_clk_disable,
> -};
> diff --git a/arch/arm/mach-omap2/clockdomain33xx.c b/arch/arm/mach-omap2/clockdomain33xx.c
> deleted file mode 100644
> index aca6388..0000000
> --- a/arch/arm/mach-omap2/clockdomain33xx.c
> +++ /dev/null
> @@ -1,74 +0,0 @@
> -/*
> - * AM33XX clockdomain control
> - *
> - * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
> - * Vaibhav Hiremath <hvaibhav@ti.com>
> - *
> - * Derived from mach-omap2/clockdomain44xx.c written by Rajendra Nayak
> - *
> - * 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 version 2.
> - *
> - * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> - * kind, whether express or implied; 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 "clockdomain.h"
> -#include "cm33xx.h"
> -
> -
> -static int am33xx_clkdm_sleep(struct clockdomain *clkdm)
> -{
> -	am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs);
> -	return 0;
> -}
> -
> -static int am33xx_clkdm_wakeup(struct clockdomain *clkdm)
> -{
> -	am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs);
> -	return 0;
> -}
> -
> -static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm)
> -{
> -	am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
> -}
> -
> -static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm)
> -{
> -	am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
> -}
> -
> -static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm)
> -{
> -	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> -		return am33xx_clkdm_wakeup(clkdm);
> -
> -	return 0;
> -}
> -
> -static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
> -{
> -	bool hwsup = false;
> -
> -	hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
> -
> -	if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
> -		am33xx_clkdm_sleep(clkdm);
> -
> -	return 0;
> -}
> -
> -struct clkdm_ops am33xx_clkdm_operations = {
> -	.clkdm_sleep		= am33xx_clkdm_sleep,
> -	.clkdm_wakeup		= am33xx_clkdm_wakeup,
> -	.clkdm_allow_idle	= am33xx_clkdm_allow_idle,
> -	.clkdm_deny_idle	= am33xx_clkdm_deny_idle,
> -	.clkdm_clk_enable	= am33xx_clkdm_clk_enable,
> -	.clkdm_clk_disable	= am33xx_clkdm_clk_disable,
> -};
> diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
> deleted file mode 100644
> index 6fc6155..0000000
> --- a/arch/arm/mach-omap2/clockdomain44xx.c
> +++ /dev/null
> @@ -1,151 +0,0 @@
> -/*
> - * OMAP4 clockdomain control
> - *
> - * Copyright (C) 2008-2010 Texas Instruments, Inc.
> - * Copyright (C) 2008-2010 Nokia Corporation
> - *
> - * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
> - * Rajendra Nayak <rnayak@ti.com>
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> - */
> -
> -#include <linux/kernel.h>
> -#include "clockdomain.h"
> -#include "cminst44xx.h"
> -#include "cm44xx.h"
> -
> -static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1,
> -					struct clockdomain *clkdm2)
> -{
> -	omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit),
> -					clkdm1->prcm_partition,
> -					clkdm1->cm_inst, clkdm1->clkdm_offs +
> -					OMAP4_CM_STATICDEP);
> -	return 0;
> -}
> -
> -static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1,
> -					struct clockdomain *clkdm2)
> -{
> -	omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit),
> -					clkdm1->prcm_partition,
> -					clkdm1->cm_inst, clkdm1->clkdm_offs +
> -					OMAP4_CM_STATICDEP);
> -	return 0;
> -}
> -
> -static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1,
> -					struct clockdomain *clkdm2)
> -{
> -	return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition,
> -					clkdm1->cm_inst, clkdm1->clkdm_offs +
> -					OMAP4_CM_STATICDEP,
> -					(1 << clkdm2->dep_bit));
> -}
> -
> -static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
> -{
> -	struct clkdm_dep *cd;
> -	u32 mask = 0;
> -
> -	if (!clkdm->prcm_partition)
> -		return 0;
> -
> -	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> -		if (!cd->clkdm)
> -			continue; /* only happens if data is erroneous */
> -
> -		mask |= 1 << cd->clkdm->dep_bit;
> -		atomic_set(&cd->wkdep_usecount, 0);
> -	}
> -
> -	omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition,
> -					clkdm->cm_inst, clkdm->clkdm_offs +
> -					OMAP4_CM_STATICDEP);
> -	return 0;
> -}
> -
> -static int omap4_clkdm_sleep(struct clockdomain *clkdm)
> -{
> -	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
> -					clkdm->cm_inst, clkdm->clkdm_offs);
> -	return 0;
> -}
> -
> -static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
> -{
> -	omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
> -					clkdm->cm_inst, clkdm->clkdm_offs);
> -	return 0;
> -}
> -
> -static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
> -{
> -	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
> -					clkdm->cm_inst, clkdm->clkdm_offs);
> -}
> -
> -static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
> -{
> -	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> -		omap4_clkdm_wakeup(clkdm);
> -	else
> -		omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
> -						 clkdm->cm_inst,
> -						 clkdm->clkdm_offs);
> -}
> -
> -static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
> -{
> -	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> -		return omap4_clkdm_wakeup(clkdm);
> -
> -	return 0;
> -}
> -
> -static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
> -{
> -	bool hwsup = false;
> -
> -	if (!clkdm->prcm_partition)
> -		return 0;
> -
> -	/*
> -	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> -	 * more details on the unpleasant problem this is working
> -	 * around
> -	 */
> -	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
> -	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
> -		omap4_clkdm_allow_idle(clkdm);
> -		return 0;
> -	}
> -
> -	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
> -					clkdm->cm_inst, clkdm->clkdm_offs);
> -
> -	if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
> -		omap4_clkdm_sleep(clkdm);
> -
> -	return 0;
> -}
> -
> -struct clkdm_ops omap4_clkdm_operations = {
> -	.clkdm_add_wkdep	= omap4_clkdm_add_wkup_sleep_dep,
> -	.clkdm_del_wkdep	= omap4_clkdm_del_wkup_sleep_dep,
> -	.clkdm_read_wkdep	= omap4_clkdm_read_wkup_sleep_dep,
> -	.clkdm_clear_all_wkdeps	= omap4_clkdm_clear_all_wkup_sleep_deps,
> -	.clkdm_add_sleepdep	= omap4_clkdm_add_wkup_sleep_dep,
> -	.clkdm_del_sleepdep	= omap4_clkdm_del_wkup_sleep_dep,
> -	.clkdm_read_sleepdep	= omap4_clkdm_read_wkup_sleep_dep,
> -	.clkdm_clear_all_sleepdeps	= omap4_clkdm_clear_all_wkup_sleep_deps,
> -	.clkdm_sleep		= omap4_clkdm_sleep,
> -	.clkdm_wakeup		= omap4_clkdm_wakeup,
> -	.clkdm_allow_idle	= omap4_clkdm_allow_idle,
> -	.clkdm_deny_idle	= omap4_clkdm_deny_idle,
> -	.clkdm_clk_enable	= omap4_clkdm_clk_enable,
> -	.clkdm_clk_disable	= omap4_clkdm_clk_disable,
> -};
> diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
> index 19cee91..0160893 100644
> --- a/arch/arm/mach-omap2/cm2xxx.c
> +++ b/arch/arm/mach-omap2/cm2xxx.c
> @@ -19,9 +19,11 @@
>   #include "soc.h"
>   #include "iomap.h"
>   #include "common.h"
> +#include "prm2xxx.h"
>   #include "cm.h"
>   #include "cm2xxx.h"
>   #include "cm-regbits-24xx.h"
> +#include "clockdomain.h"
>
>   /* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */
>   #define DPLL_AUTOIDLE_DISABLE				0x0
> @@ -165,3 +167,87 @@ int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
>
>   	return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
>   }
> +
> +/* Clockdomain low-level functions */
> +
> +static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm)
> +{
> +	if (atomic_read(&clkdm->usecount) > 0)
> +		_clkdm_add_autodeps(clkdm);
> +
> +	omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +				       clkdm->clktrctrl_mask);
> +}
> +
> +static void omap2xxx_clkdm_deny_idle(struct clockdomain *clkdm)
> +{
> +	omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +					clkdm->clktrctrl_mask);
> +
> +	if (atomic_read(&clkdm->usecount) > 0)
> +		_clkdm_del_autodeps(clkdm);
> +}
> +
> +static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
> +{
> +	bool hwsup = false;
> +
> +	if (!clkdm->clktrctrl_mask)
> +		return 0;
> +
> +	hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +					      clkdm->clktrctrl_mask);
> +
> +	if (hwsup) {
> +		/* Disable HW transitions when we are changing deps */
> +		omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +						clkdm->clktrctrl_mask);
> +		_clkdm_add_autodeps(clkdm);
> +		omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +					       clkdm->clktrctrl_mask);
> +	} else {
> +		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> +			omap2xxx_clkdm_wakeup(clkdm);
> +	}
> +
> +	return 0;
> +}
> +
> +static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm)
> +{
> +	bool hwsup = false;
> +
> +	if (!clkdm->clktrctrl_mask)
> +		return 0;
> +
> +	hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +					      clkdm->clktrctrl_mask);
> +
> +	if (hwsup) {
> +		/* Disable HW transitions when we are changing deps */
> +		omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +						clkdm->clktrctrl_mask);
> +		_clkdm_del_autodeps(clkdm);
> +		omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +					       clkdm->clktrctrl_mask);
> +	} else {
> +		if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
> +			omap2xxx_clkdm_sleep(clkdm);
> +	}
> +
> +	return 0;
> +}
> +
> +struct clkdm_ops omap2_clkdm_operations = {
> +	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,
> +	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep,
> +	.clkdm_read_wkdep	= omap2_clkdm_read_wkdep,
> +	.clkdm_clear_all_wkdeps	= omap2_clkdm_clear_all_wkdeps,
> +	.clkdm_sleep		= omap2xxx_clkdm_sleep,
> +	.clkdm_wakeup		= omap2xxx_clkdm_wakeup,
> +	.clkdm_allow_idle	= omap2xxx_clkdm_allow_idle,
> +	.clkdm_deny_idle	= omap2xxx_clkdm_deny_idle,
> +	.clkdm_clk_enable	= omap2xxx_clkdm_clk_enable,
> +	.clkdm_clk_disable	= omap2xxx_clkdm_clk_disable,
> +};
> +
> diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h
> index 64df725..78c218c 100644
> --- a/arch/arm/mach-omap2/cm2xxx_3xxx.h
> +++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h
> @@ -73,6 +73,18 @@ static inline u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module,
>   	return v;
>   }
>
> +/* Read a CM register, AND it, and shift the result down to bit 0 */
> +static inline u32 omap2_cm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
> +{
> +	u32 v;
> +
> +	v = omap2_cm_read_mod_reg(domain, idx);
> +	v &= mask;
> +	v >>= __ffs(mask);
> +
> +	return v;
> +}
> +
>   static inline u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
>   {
>   	return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx);
> diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c
> index 13f56ea..9b3bcff1 100644
> --- a/arch/arm/mach-omap2/cm33xx.c
> +++ b/arch/arm/mach-omap2/cm33xx.c
> @@ -24,6 +24,7 @@
>
>   #include <plat/common.h>
>
> +#include "clockdomain.h"
>   #include "cm.h"
>   #include "cm33xx.h"
>   #include "cm-regbits-34xx.h"
> @@ -311,3 +312,58 @@ void am33xx_cm_module_disable(u16 inst, s16 cdoffs, u16 clkctrl_offs)
>   	v &= ~AM33XX_MODULEMODE_MASK;
>   	am33xx_cm_write_reg(v, inst, clkctrl_offs);
>   }
> +
> +/*
> + * Clockdomain low-level functions
> + */
> +
> +static int am33xx_clkdm_sleep(struct clockdomain *clkdm)
> +{
> +	am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs);
> +	return 0;
> +}
> +
> +static int am33xx_clkdm_wakeup(struct clockdomain *clkdm)
> +{
> +	am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs);
> +	return 0;
> +}
> +
> +static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm)
> +{
> +	am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
> +}
> +
> +static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm)
> +{
> +	am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
> +}
> +
> +static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm)
> +{
> +	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> +		return am33xx_clkdm_wakeup(clkdm);
> +
> +	return 0;
> +}
> +
> +static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
> +{
> +	bool hwsup = false;
> +
> +	hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
> +
> +	if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
> +		am33xx_clkdm_sleep(clkdm);
> +
> +	return 0;
> +}
> +
> +struct clkdm_ops am33xx_clkdm_operations = {
> +	.clkdm_sleep		= am33xx_clkdm_sleep,
> +	.clkdm_wakeup		= am33xx_clkdm_wakeup,
> +	.clkdm_allow_idle	= am33xx_clkdm_allow_idle,
> +	.clkdm_deny_idle	= am33xx_clkdm_deny_idle,
> +	.clkdm_clk_enable	= am33xx_clkdm_clk_enable,
> +	.clkdm_clk_disable	= am33xx_clkdm_clk_disable,
> +};
> diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c
> index 075cabe..3493fef 100644
> --- a/arch/arm/mach-omap2/cm3xxx.c
> +++ b/arch/arm/mach-omap2/cm3xxx.c
> @@ -19,9 +19,11 @@
>   #include "soc.h"
>   #include "iomap.h"
>   #include "common.h"
> +#include "prm2xxx_3xxx.h"
>   #include "cm.h"
>   #include "cm3xxx.h"
>   #include "cm-regbits-34xx.h"
> +#include "clockdomain.h"
>
>   static const u8 omap3xxx_cm_idlest_offs[] = { CM_IDLEST1, CM_IDLEST2 };
>
> @@ -104,6 +106,173 @@ int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
>   	return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
>   }
>
> +/* Clockdomain low-level operations */
> +
> +static int omap3xxx_clkdm_add_sleepdep(struct clockdomain *clkdm1,
> +				       struct clockdomain *clkdm2)
> +{
> +	omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> +				  clkdm1->pwrdm.ptr->prcm_offs,
> +				  OMAP3430_CM_SLEEPDEP);
> +	return 0;
> +}
> +
> +static int omap3xxx_clkdm_del_sleepdep(struct clockdomain *clkdm1,
> +				       struct clockdomain *clkdm2)
> +{
> +	omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> +				    clkdm1->pwrdm.ptr->prcm_offs,
> +				    OMAP3430_CM_SLEEPDEP);
> +	return 0;
> +}
> +
> +static int omap3xxx_clkdm_read_sleepdep(struct clockdomain *clkdm1,
> +					struct clockdomain *clkdm2)
> +{
> +	return omap2_cm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> +					    OMAP3430_CM_SLEEPDEP,
> +					    (1 << clkdm2->dep_bit));
> +}
> +
> +static int omap3xxx_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
> +{
> +	struct clkdm_dep *cd;
> +	u32 mask = 0;
> +
> +	for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
> +		if (!cd->clkdm)
> +			continue; /* only happens if data is erroneous */
> +
> +		mask |= 1 << cd->clkdm->dep_bit;
> +		atomic_set(&cd->sleepdep_usecount, 0);
> +	}
> +	omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> +				    OMAP3430_CM_SLEEPDEP);
> +	return 0;
> +}
> +
> +static int omap3xxx_clkdm_sleep(struct clockdomain *clkdm)
> +{
> +	omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
> +				      clkdm->clktrctrl_mask);
> +	return 0;
> +}
> +
> +static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm)
> +{
> +	omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
> +				       clkdm->clktrctrl_mask);
> +	return 0;
> +}
> +
> +static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm)
> +{
> +	if (atomic_read(&clkdm->usecount) > 0)
> +		_clkdm_add_autodeps(clkdm);
> +
> +	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +				       clkdm->clktrctrl_mask);
> +}
> +
> +static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm)
> +{
> +	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +					clkdm->clktrctrl_mask);
> +
> +	if (atomic_read(&clkdm->usecount) > 0)
> +		_clkdm_del_autodeps(clkdm);
> +}
> +
> +static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
> +{
> +	bool hwsup = false;
> +
> +	if (!clkdm->clktrctrl_mask)
> +		return 0;
> +
> +	/*
> +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +	 * more details on the unpleasant problem this is working
> +	 * around
> +	 */
> +	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
> +	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
> +		omap3xxx_clkdm_wakeup(clkdm);
> +		return 0;
> +	}
> +
> +	hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +					      clkdm->clktrctrl_mask);
> +
> +	if (hwsup) {
> +		/* Disable HW transitions when we are changing deps */
> +		omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +						clkdm->clktrctrl_mask);
> +		_clkdm_add_autodeps(clkdm);
> +		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +					       clkdm->clktrctrl_mask);
> +	} else {
> +		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> +			omap3xxx_clkdm_wakeup(clkdm);
> +	}
> +
> +	return 0;
> +}
> +
> +static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
> +{
> +	bool hwsup = false;
> +
> +	if (!clkdm->clktrctrl_mask)
> +		return 0;
> +
> +	/*
> +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +	 * more details on the unpleasant problem this is working
> +	 * around
> +	 */
> +	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
> +	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
> +		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +					       clkdm->clktrctrl_mask);
> +		return 0;
> +	}
> +
> +	hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +					      clkdm->clktrctrl_mask);
> +
> +	if (hwsup) {
> +		/* Disable HW transitions when we are changing deps */
> +		omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +						clkdm->clktrctrl_mask);
> +		_clkdm_del_autodeps(clkdm);
> +		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +					       clkdm->clktrctrl_mask);
> +	} else {
> +		if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
> +			omap3xxx_clkdm_sleep(clkdm);
> +	}
> +
> +	return 0;
> +}
> +
> +struct clkdm_ops omap3_clkdm_operations = {
> +	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,
> +	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep,
> +	.clkdm_read_wkdep	= omap2_clkdm_read_wkdep,
> +	.clkdm_clear_all_wkdeps	= omap2_clkdm_clear_all_wkdeps,
> +	.clkdm_add_sleepdep	= omap3xxx_clkdm_add_sleepdep,
> +	.clkdm_del_sleepdep	= omap3xxx_clkdm_del_sleepdep,
> +	.clkdm_read_sleepdep	= omap3xxx_clkdm_read_sleepdep,
> +	.clkdm_clear_all_sleepdeps	= omap3xxx_clkdm_clear_all_sleepdeps,
> +	.clkdm_sleep		= omap3xxx_clkdm_sleep,
> +	.clkdm_wakeup		= omap3xxx_clkdm_wakeup,
> +	.clkdm_allow_idle	= omap3xxx_clkdm_allow_idle,
> +	.clkdm_deny_idle	= omap3xxx_clkdm_deny_idle,
> +	.clkdm_clk_enable	= omap3xxx_clkdm_clk_enable,
> +	.clkdm_clk_disable	= omap3xxx_clkdm_clk_disable,
> +};
> +
>   /*
>    * Context save/restore code - OMAP3 only
>    */
> diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
> index 1894015..9dca0ee 100644
> --- a/arch/arm/mach-omap2/cminst44xx.c
> +++ b/arch/arm/mach-omap2/cminst44xx.c
> @@ -22,6 +22,7 @@
>
>   #include "iomap.h"
>   #include "common.h"
> +#include "clockdomain.h"
>   #include "cm.h"
>   #include "cm1_44xx.h"
>   #include "cm2_44xx.h"
> @@ -343,3 +344,141 @@ void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs,
>   	v &= ~OMAP4430_MODULEMODE_MASK;
>   	omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs);
>   }
> +
> +/*
> + * Clockdomain low-level functions
> + */
> +
> +static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1,
> +					struct clockdomain *clkdm2)
> +{
> +	omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit),
> +				       clkdm1->prcm_partition,
> +				       clkdm1->cm_inst, clkdm1->clkdm_offs +
> +				       OMAP4_CM_STATICDEP);
> +	return 0;
> +}
> +
> +static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1,
> +					struct clockdomain *clkdm2)
> +{
> +	omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit),
> +					 clkdm1->prcm_partition,
> +					 clkdm1->cm_inst, clkdm1->clkdm_offs +
> +					 OMAP4_CM_STATICDEP);
> +	return 0;
> +}
> +
> +static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1,
> +					struct clockdomain *clkdm2)
> +{
> +	return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition,
> +					       clkdm1->cm_inst,
> +					       clkdm1->clkdm_offs +
> +					       OMAP4_CM_STATICDEP,
> +					       (1 << clkdm2->dep_bit));
> +}
> +
> +static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
> +{
> +	struct clkdm_dep *cd;
> +	u32 mask = 0;
> +
> +	if (!clkdm->prcm_partition)
> +		return 0;
> +
> +	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> +		if (!cd->clkdm)
> +			continue; /* only happens if data is erroneous */
> +
> +		mask |= 1 << cd->clkdm->dep_bit;
> +		atomic_set(&cd->wkdep_usecount, 0);
> +	}
> +
> +	omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition,
> +					 clkdm->cm_inst, clkdm->clkdm_offs +
> +					 OMAP4_CM_STATICDEP);
> +	return 0;
> +}
> +
> +static int omap4_clkdm_sleep(struct clockdomain *clkdm)
> +{
> +	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
> +					clkdm->cm_inst, clkdm->clkdm_offs);
> +	return 0;
> +}
> +
> +static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
> +{
> +	omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
> +					clkdm->cm_inst, clkdm->clkdm_offs);
> +	return 0;
> +}
> +
> +static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
> +{
> +	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
> +					clkdm->cm_inst, clkdm->clkdm_offs);
> +}
> +
> +static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
> +{
> +	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> +		omap4_clkdm_wakeup(clkdm);
> +	else
> +		omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
> +						 clkdm->cm_inst,
> +						 clkdm->clkdm_offs);
> +}
> +
> +static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
> +{
> +	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> +		return omap4_clkdm_wakeup(clkdm);
> +
> +	return 0;
> +}
> +
> +static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
> +{
> +	bool hwsup = false;
> +
> +	if (!clkdm->prcm_partition)
> +		return 0;
> +
> +	/*
> +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +	 * more details on the unpleasant problem this is working
> +	 * around
> +	 */
> +	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
> +	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
> +		omap4_clkdm_allow_idle(clkdm);
> +		return 0;
> +	}
> +
> +	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
> +					clkdm->cm_inst, clkdm->clkdm_offs);
> +
> +	if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
> +		omap4_clkdm_sleep(clkdm);
> +
> +	return 0;
> +}
> +
> +struct clkdm_ops omap4_clkdm_operations = {
> +	.clkdm_add_wkdep	= omap4_clkdm_add_wkup_sleep_dep,
> +	.clkdm_del_wkdep	= omap4_clkdm_del_wkup_sleep_dep,
> +	.clkdm_read_wkdep	= omap4_clkdm_read_wkup_sleep_dep,
> +	.clkdm_clear_all_wkdeps	= omap4_clkdm_clear_all_wkup_sleep_deps,
> +	.clkdm_add_sleepdep	= omap4_clkdm_add_wkup_sleep_dep,
> +	.clkdm_del_sleepdep	= omap4_clkdm_del_wkup_sleep_dep,
> +	.clkdm_read_sleepdep	= omap4_clkdm_read_wkup_sleep_dep,
> +	.clkdm_clear_all_sleepdeps	= omap4_clkdm_clear_all_wkup_sleep_deps,
> +	.clkdm_sleep		= omap4_clkdm_sleep,
> +	.clkdm_wakeup		= omap4_clkdm_wakeup,
> +	.clkdm_allow_idle	= omap4_clkdm_allow_idle,
> +	.clkdm_deny_idle	= omap4_clkdm_deny_idle,
> +	.clkdm_clk_enable	= omap4_clkdm_clk_enable,
> +	.clkdm_clk_disable	= omap4_clkdm_clk_disable,
> +};
> diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c
> index 14940c4..d08a2b9 100644
> --- a/arch/arm/mach-omap2/prm2xxx.c
> +++ b/arch/arm/mach-omap2/prm2xxx.c
> @@ -23,10 +23,27 @@
>
>   #include "vp.h"
>   #include "powerdomain.h"
> +#include "clockdomain.h"
>   #include "prm2xxx.h"
>   #include "cm2xxx_3xxx.h"
>   #include "prm-regbits-24xx.h"
>
> +int omap2xxx_clkdm_sleep(struct clockdomain *clkdm)
> +{
> +	omap2_prm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
> +				   clkdm->pwrdm.ptr->prcm_offs,
> +				   OMAP2_PM_PWSTCTRL);
> +	return 0;
> +}
> +
> +int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm)
> +{
> +	omap2_prm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
> +				     clkdm->pwrdm.ptr->prcm_offs,
> +				     OMAP2_PM_PWSTCTRL);
> +	return 0;
> +}
> +
>   struct pwrdm_ops omap2_pwrdm_operations = {
>   	.pwrdm_set_next_pwrst	= omap2_pwrdm_set_next_pwrst,
>   	.pwrdm_read_next_pwrst	= omap2_pwrdm_read_next_pwrst,
> diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h
> index 6490e1a..6d76716 100644
> --- a/arch/arm/mach-omap2/prm2xxx.h
> +++ b/arch/arm/mach-omap2/prm2xxx.h
> @@ -119,4 +119,10 @@
>   #define OMAP24XX_PRCM_IRQSTATUS_IVA			0x00f8
>   #define OMAP24XX_PRCM_IRQENABLE_IVA			0x00fc
>
> +#ifndef __ASSEMBLER__
> +/* Function prototypes */
> +extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm);
> +extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm);
> +#endif
> +
>   #endif
> diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
> index bdddf5c..30517f5 100644
> --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
> +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
> @@ -20,6 +20,7 @@
>   #include "powerdomain.h"
>   #include "prm2xxx_3xxx.h"
>   #include "prm-regbits-24xx.h"
> +#include "clockdomain.h"
>
>   /**
>    * omap2_prm_is_hardreset_asserted - read the HW reset line state of
> @@ -208,3 +209,45 @@ int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm)
>   	return 0;
>   }
>
> +int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
> +			  struct clockdomain *clkdm2)
> +{
> +	omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> +				   clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> +	return 0;
> +}
> +
> +int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
> +			  struct clockdomain *clkdm2)
> +{
> +	omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> +				     clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> +	return 0;
> +}
> +
> +int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
> +			   struct clockdomain *clkdm2)
> +{
> +	return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> +					     PM_WKDEP, (1 << clkdm2->dep_bit));
> +}
> +
> +int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
> +{
> +	struct clkdm_dep *cd;
> +	u32 mask = 0;
> +
> +	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> +		if (!cd->clkdm)
> +			continue; /* only happens if data is erroneous */
> +
> +		/* PRM accesses are slow, so minimize them */
> +		mask |= 1 << cd->clkdm->dep_bit;
> +		atomic_set(&cd->wkdep_usecount, 0);
> +	}
> +
> +	omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> +				     PM_WKDEP);
> +	return 0;
> +}
> +
> diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
> index 706b026..22a405a 100644
> --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
> +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
> @@ -116,6 +116,14 @@ extern int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank);
>   extern int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);
>   extern int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm);
>
> +extern int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
> +				 struct clockdomain *clkdm2);
> +extern int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
> +				 struct clockdomain *clkdm2);
> +extern int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
> +				  struct clockdomain *clkdm2);
> +extern int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm);
> +
>   #endif /* __ASSEMBLER */
>
>   /*
>
>
Russ Dill Oct. 18, 2012, 12:03 p.m. UTC | #2
On Mon, Oct 15, 2012 at 4:05 PM, Paul Walmsley <paul@pwsan.com> wrote:
> Move the low-level SoC-specific clockdomain control functions into
> cm*.c and prm*.c.  For example, OMAP2xxx low-level clockdomain
> functions go into cm2xxx.c.  Then remove the unnecessary
> clockdomain*xxx*.c files.
>
> The objective is to centralize low-level CM and PRM register accesses
> into the cm*.[ch] and prm*.[ch] files, and then to export an OMAP
> SoC-independent API to higher-level OMAP power management code.

The series looks good
Reviewed-by: Russ.Dill@ti.com

> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> Cc: Rajendra Nayak <rnayak@ti.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
>  arch/arm/mach-omap2/Makefile               |    5
>  arch/arm/mach-omap2/clockdomain2xxx_3xxx.c |  340 ----------------------------
>  arch/arm/mach-omap2/clockdomain33xx.c      |   74 ------
>  arch/arm/mach-omap2/clockdomain44xx.c      |  151 ------------
>  arch/arm/mach-omap2/cm2xxx.c               |   86 +++++++
>  arch/arm/mach-omap2/cm2xxx_3xxx.h          |   12 +
>  arch/arm/mach-omap2/cm33xx.c               |   56 +++++
>  arch/arm/mach-omap2/cm3xxx.c               |  169 ++++++++++++++
>  arch/arm/mach-omap2/cminst44xx.c           |  139 +++++++++++
>  arch/arm/mach-omap2/prm2xxx.c              |   17 +
>  arch/arm/mach-omap2/prm2xxx.h              |    6
>  arch/arm/mach-omap2/prm2xxx_3xxx.c         |   43 ++++
>  arch/arm/mach-omap2/prm2xxx_3xxx.h         |    8 +
>  13 files changed, 536 insertions(+), 570 deletions(-)
>  delete mode 100644 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
>  delete mode 100644 arch/arm/mach-omap2/clockdomain33xx.c
>  delete mode 100644 arch/arm/mach-omap2/clockdomain44xx.c
>
> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> index 56a3386..3751d56 100644
> --- a/arch/arm/mach-omap2/Makefile
> +++ b/arch/arm/mach-omap2/Makefile
> @@ -133,22 +133,17 @@ obj-$(CONFIG_SOC_OMAP5)                   += $(powerdomain-common)
>  # PRCM clockdomain control
>  clockdomain-common                     += clockdomain.o
>  obj-$(CONFIG_ARCH_OMAP2)               += $(clockdomain-common)
> -obj-$(CONFIG_ARCH_OMAP2)               += clockdomain2xxx_3xxx.o
>  obj-$(CONFIG_ARCH_OMAP2)               += clockdomains2xxx_3xxx_data.o
>  obj-$(CONFIG_SOC_OMAP2420)             += clockdomains2420_data.o
>  obj-$(CONFIG_SOC_OMAP2430)             += clockdomains2430_data.o
>  obj-$(CONFIG_ARCH_OMAP3)               += $(clockdomain-common)
> -obj-$(CONFIG_ARCH_OMAP3)               += clockdomain2xxx_3xxx.o
>  obj-$(CONFIG_ARCH_OMAP3)               += clockdomains2xxx_3xxx_data.o
>  obj-$(CONFIG_ARCH_OMAP3)               += clockdomains3xxx_data.o
>  obj-$(CONFIG_ARCH_OMAP4)               += $(clockdomain-common)
> -obj-$(CONFIG_ARCH_OMAP4)               += clockdomain44xx.o
>  obj-$(CONFIG_ARCH_OMAP4)               += clockdomains44xx_data.o
>  obj-$(CONFIG_SOC_AM33XX)               += $(clockdomain-common)
> -obj-$(CONFIG_SOC_AM33XX)               += clockdomain33xx.o
>  obj-$(CONFIG_SOC_AM33XX)               += clockdomains33xx_data.o
>  obj-$(CONFIG_SOC_OMAP5)                        += $(clockdomain-common)
> -obj-$(CONFIG_SOC_OMAP5)                        += clockdomain44xx.o
>
>  # Clock framework
>  obj-$(CONFIG_ARCH_OMAP2)               += $(clock-common) clock2xxx.o
> diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> deleted file mode 100644
> index 658487c..0000000
> --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> +++ /dev/null
> @@ -1,340 +0,0 @@
> -/*
> - * OMAP2 and OMAP3 clockdomain control
> - *
> - * Copyright (C) 2008-2010 Texas Instruments, Inc.
> - * Copyright (C) 2008-2010 Nokia Corporation
> - *
> - * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
> - * Rajendra Nayak <rnayak@ti.com>
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> - */
> -
> -#include <linux/types.h>
> -#include <plat/prcm.h>
> -#include "prm.h"
> -#include "prm2xxx_3xxx.h"
> -#include "cm.h"
> -#include "cm2xxx.h"
> -#include "cm3xxx.h"
> -#include "cm-regbits-24xx.h"
> -#include "cm-regbits-34xx.h"
> -#include "prm-regbits-24xx.h"
> -#include "clockdomain.h"
> -
> -static int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
> -                                               struct clockdomain *clkdm2)
> -{
> -       omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> -                               clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> -       return 0;
> -}
> -
> -static int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
> -                                                struct clockdomain *clkdm2)
> -{
> -       omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> -                               clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> -       return 0;
> -}
> -
> -static int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
> -                                                struct clockdomain *clkdm2)
> -{
> -       return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> -                               PM_WKDEP, (1 << clkdm2->dep_bit));
> -}
> -
> -static int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
> -{
> -       struct clkdm_dep *cd;
> -       u32 mask = 0;
> -
> -       for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> -               if (!cd->clkdm)
> -                       continue; /* only happens if data is erroneous */
> -
> -               /* PRM accesses are slow, so minimize them */
> -               mask |= 1 << cd->clkdm->dep_bit;
> -               atomic_set(&cd->wkdep_usecount, 0);
> -       }
> -
> -       omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> -                                PM_WKDEP);
> -       return 0;
> -}
> -
> -static int omap3_clkdm_add_sleepdep(struct clockdomain *clkdm1,
> -                                                struct clockdomain *clkdm2)
> -{
> -       omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> -                               clkdm1->pwrdm.ptr->prcm_offs,
> -                               OMAP3430_CM_SLEEPDEP);
> -       return 0;
> -}
> -
> -static int omap3_clkdm_del_sleepdep(struct clockdomain *clkdm1,
> -                                                struct clockdomain *clkdm2)
> -{
> -       omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> -                               clkdm1->pwrdm.ptr->prcm_offs,
> -                               OMAP3430_CM_SLEEPDEP);
> -       return 0;
> -}
> -
> -static int omap3_clkdm_read_sleepdep(struct clockdomain *clkdm1,
> -                                                struct clockdomain *clkdm2)
> -{
> -       return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> -                               OMAP3430_CM_SLEEPDEP, (1 << clkdm2->dep_bit));
> -}
> -
> -static int omap3_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
> -{
> -       struct clkdm_dep *cd;
> -       u32 mask = 0;
> -
> -       for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
> -               if (!cd->clkdm)
> -                       continue; /* only happens if data is erroneous */
> -
> -               /* PRM accesses are slow, so minimize them */
> -               mask |= 1 << cd->clkdm->dep_bit;
> -               atomic_set(&cd->sleepdep_usecount, 0);
> -       }
> -       omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> -                               OMAP3430_CM_SLEEPDEP);
> -       return 0;
> -}
> -
> -static int omap2_clkdm_sleep(struct clockdomain *clkdm)
> -{
> -       omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
> -                               clkdm->pwrdm.ptr->prcm_offs,
> -                               OMAP2_PM_PWSTCTRL);
> -       return 0;
> -}
> -
> -static int omap2_clkdm_wakeup(struct clockdomain *clkdm)
> -{
> -       omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
> -                               clkdm->pwrdm.ptr->prcm_offs,
> -                               OMAP2_PM_PWSTCTRL);
> -       return 0;
> -}
> -
> -static void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
> -{
> -       if (atomic_read(&clkdm->usecount) > 0)
> -               _clkdm_add_autodeps(clkdm);
> -
> -       omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -                               clkdm->clktrctrl_mask);
> -}
> -
> -static void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
> -{
> -       omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -                               clkdm->clktrctrl_mask);
> -
> -       if (atomic_read(&clkdm->usecount) > 0)
> -               _clkdm_del_autodeps(clkdm);
> -}
> -
> -static void _enable_hwsup(struct clockdomain *clkdm)
> -{
> -       if (cpu_is_omap24xx())
> -               omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -                                              clkdm->clktrctrl_mask);
> -       else if (cpu_is_omap34xx())
> -               omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -                                              clkdm->clktrctrl_mask);
> -}
> -
> -static void _disable_hwsup(struct clockdomain *clkdm)
> -{
> -       if (cpu_is_omap24xx())
> -               omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -                                               clkdm->clktrctrl_mask);
> -       else if (cpu_is_omap34xx())
> -               omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -                                               clkdm->clktrctrl_mask);
> -}
> -
> -static int omap3_clkdm_sleep(struct clockdomain *clkdm)
> -{
> -       omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
> -                               clkdm->clktrctrl_mask);
> -       return 0;
> -}
> -
> -static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
> -{
> -       omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
> -                               clkdm->clktrctrl_mask);
> -       return 0;
> -}
> -
> -static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
> -{
> -       bool hwsup = false;
> -
> -       if (!clkdm->clktrctrl_mask)
> -               return 0;
> -
> -       hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -                                             clkdm->clktrctrl_mask);
> -
> -       if (hwsup) {
> -               /* Disable HW transitions when we are changing deps */
> -               _disable_hwsup(clkdm);
> -               _clkdm_add_autodeps(clkdm);
> -               _enable_hwsup(clkdm);
> -       } else {
> -               if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> -                       omap2_clkdm_wakeup(clkdm);
> -       }
> -
> -       return 0;
> -}
> -
> -static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm)
> -{
> -       bool hwsup = false;
> -
> -       if (!clkdm->clktrctrl_mask)
> -               return 0;
> -
> -       hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -                                             clkdm->clktrctrl_mask);
> -
> -       if (hwsup) {
> -               /* Disable HW transitions when we are changing deps */
> -               _disable_hwsup(clkdm);
> -               _clkdm_del_autodeps(clkdm);
> -               _enable_hwsup(clkdm);
> -       } else {
> -               if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
> -                       omap2_clkdm_sleep(clkdm);
> -       }
> -
> -       return 0;
> -}
> -
> -static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
> -{
> -       if (atomic_read(&clkdm->usecount) > 0)
> -               _clkdm_add_autodeps(clkdm);
> -
> -       omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -                               clkdm->clktrctrl_mask);
> -}
> -
> -static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
> -{
> -       omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -                               clkdm->clktrctrl_mask);
> -
> -       if (atomic_read(&clkdm->usecount) > 0)
> -               _clkdm_del_autodeps(clkdm);
> -}
> -
> -static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
> -{
> -       bool hwsup = false;
> -
> -       if (!clkdm->clktrctrl_mask)
> -               return 0;
> -
> -       /*
> -        * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> -        * more details on the unpleasant problem this is working
> -        * around
> -        */
> -       if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
> -           (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
> -               omap3_clkdm_wakeup(clkdm);
> -               return 0;
> -       }
> -
> -       hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -                                             clkdm->clktrctrl_mask);
> -
> -       if (hwsup) {
> -               /* Disable HW transitions when we are changing deps */
> -               _disable_hwsup(clkdm);
> -               _clkdm_add_autodeps(clkdm);
> -               _enable_hwsup(clkdm);
> -       } else {
> -               if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> -                       omap3_clkdm_wakeup(clkdm);
> -       }
> -
> -       return 0;
> -}
> -
> -static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
> -{
> -       bool hwsup = false;
> -
> -       if (!clkdm->clktrctrl_mask)
> -               return 0;
> -
> -       /*
> -        * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> -        * more details on the unpleasant problem this is working
> -        * around
> -        */
> -       if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
> -           !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
> -               _enable_hwsup(clkdm);
> -               return 0;
> -       }
> -
> -       hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -                                             clkdm->clktrctrl_mask);
> -
> -       if (hwsup) {
> -               /* Disable HW transitions when we are changing deps */
> -               _disable_hwsup(clkdm);
> -               _clkdm_del_autodeps(clkdm);
> -               _enable_hwsup(clkdm);
> -       } else {
> -               if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
> -                       omap3_clkdm_sleep(clkdm);
> -       }
> -
> -       return 0;
> -}
> -
> -struct clkdm_ops omap2_clkdm_operations = {
> -       .clkdm_add_wkdep        = omap2_clkdm_add_wkdep,
> -       .clkdm_del_wkdep        = omap2_clkdm_del_wkdep,
> -       .clkdm_read_wkdep       = omap2_clkdm_read_wkdep,
> -       .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
> -       .clkdm_sleep            = omap2_clkdm_sleep,
> -       .clkdm_wakeup           = omap2_clkdm_wakeup,
> -       .clkdm_allow_idle       = omap2_clkdm_allow_idle,
> -       .clkdm_deny_idle        = omap2_clkdm_deny_idle,
> -       .clkdm_clk_enable       = omap2xxx_clkdm_clk_enable,
> -       .clkdm_clk_disable      = omap2xxx_clkdm_clk_disable,
> -};
> -
> -struct clkdm_ops omap3_clkdm_operations = {
> -       .clkdm_add_wkdep        = omap2_clkdm_add_wkdep,
> -       .clkdm_del_wkdep        = omap2_clkdm_del_wkdep,
> -       .clkdm_read_wkdep       = omap2_clkdm_read_wkdep,
> -       .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
> -       .clkdm_add_sleepdep     = omap3_clkdm_add_sleepdep,
> -       .clkdm_del_sleepdep     = omap3_clkdm_del_sleepdep,
> -       .clkdm_read_sleepdep    = omap3_clkdm_read_sleepdep,
> -       .clkdm_clear_all_sleepdeps      = omap3_clkdm_clear_all_sleepdeps,
> -       .clkdm_sleep            = omap3_clkdm_sleep,
> -       .clkdm_wakeup           = omap3_clkdm_wakeup,
> -       .clkdm_allow_idle       = omap3_clkdm_allow_idle,
> -       .clkdm_deny_idle        = omap3_clkdm_deny_idle,
> -       .clkdm_clk_enable       = omap3xxx_clkdm_clk_enable,
> -       .clkdm_clk_disable      = omap3xxx_clkdm_clk_disable,
> -};
> diff --git a/arch/arm/mach-omap2/clockdomain33xx.c b/arch/arm/mach-omap2/clockdomain33xx.c
> deleted file mode 100644
> index aca6388..0000000
> --- a/arch/arm/mach-omap2/clockdomain33xx.c
> +++ /dev/null
> @@ -1,74 +0,0 @@
> -/*
> - * AM33XX clockdomain control
> - *
> - * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
> - * Vaibhav Hiremath <hvaibhav@ti.com>
> - *
> - * Derived from mach-omap2/clockdomain44xx.c written by Rajendra Nayak
> - *
> - * 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 version 2.
> - *
> - * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> - * kind, whether express or implied; 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 "clockdomain.h"
> -#include "cm33xx.h"
> -
> -
> -static int am33xx_clkdm_sleep(struct clockdomain *clkdm)
> -{
> -       am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs);
> -       return 0;
> -}
> -
> -static int am33xx_clkdm_wakeup(struct clockdomain *clkdm)
> -{
> -       am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs);
> -       return 0;
> -}
> -
> -static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm)
> -{
> -       am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
> -}
> -
> -static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm)
> -{
> -       am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
> -}
> -
> -static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm)
> -{
> -       if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> -               return am33xx_clkdm_wakeup(clkdm);
> -
> -       return 0;
> -}
> -
> -static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
> -{
> -       bool hwsup = false;
> -
> -       hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
> -
> -       if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
> -               am33xx_clkdm_sleep(clkdm);
> -
> -       return 0;
> -}
> -
> -struct clkdm_ops am33xx_clkdm_operations = {
> -       .clkdm_sleep            = am33xx_clkdm_sleep,
> -       .clkdm_wakeup           = am33xx_clkdm_wakeup,
> -       .clkdm_allow_idle       = am33xx_clkdm_allow_idle,
> -       .clkdm_deny_idle        = am33xx_clkdm_deny_idle,
> -       .clkdm_clk_enable       = am33xx_clkdm_clk_enable,
> -       .clkdm_clk_disable      = am33xx_clkdm_clk_disable,
> -};
> diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
> deleted file mode 100644
> index 6fc6155..0000000
> --- a/arch/arm/mach-omap2/clockdomain44xx.c
> +++ /dev/null
> @@ -1,151 +0,0 @@
> -/*
> - * OMAP4 clockdomain control
> - *
> - * Copyright (C) 2008-2010 Texas Instruments, Inc.
> - * Copyright (C) 2008-2010 Nokia Corporation
> - *
> - * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
> - * Rajendra Nayak <rnayak@ti.com>
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> - */
> -
> -#include <linux/kernel.h>
> -#include "clockdomain.h"
> -#include "cminst44xx.h"
> -#include "cm44xx.h"
> -
> -static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1,
> -                                       struct clockdomain *clkdm2)
> -{
> -       omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit),
> -                                       clkdm1->prcm_partition,
> -                                       clkdm1->cm_inst, clkdm1->clkdm_offs +
> -                                       OMAP4_CM_STATICDEP);
> -       return 0;
> -}
> -
> -static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1,
> -                                       struct clockdomain *clkdm2)
> -{
> -       omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit),
> -                                       clkdm1->prcm_partition,
> -                                       clkdm1->cm_inst, clkdm1->clkdm_offs +
> -                                       OMAP4_CM_STATICDEP);
> -       return 0;
> -}
> -
> -static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1,
> -                                       struct clockdomain *clkdm2)
> -{
> -       return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition,
> -                                       clkdm1->cm_inst, clkdm1->clkdm_offs +
> -                                       OMAP4_CM_STATICDEP,
> -                                       (1 << clkdm2->dep_bit));
> -}
> -
> -static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
> -{
> -       struct clkdm_dep *cd;
> -       u32 mask = 0;
> -
> -       if (!clkdm->prcm_partition)
> -               return 0;
> -
> -       for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> -               if (!cd->clkdm)
> -                       continue; /* only happens if data is erroneous */
> -
> -               mask |= 1 << cd->clkdm->dep_bit;
> -               atomic_set(&cd->wkdep_usecount, 0);
> -       }
> -
> -       omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition,
> -                                       clkdm->cm_inst, clkdm->clkdm_offs +
> -                                       OMAP4_CM_STATICDEP);
> -       return 0;
> -}
> -
> -static int omap4_clkdm_sleep(struct clockdomain *clkdm)
> -{
> -       omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
> -                                       clkdm->cm_inst, clkdm->clkdm_offs);
> -       return 0;
> -}
> -
> -static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
> -{
> -       omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
> -                                       clkdm->cm_inst, clkdm->clkdm_offs);
> -       return 0;
> -}
> -
> -static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
> -{
> -       omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
> -                                       clkdm->cm_inst, clkdm->clkdm_offs);
> -}
> -
> -static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
> -{
> -       if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> -               omap4_clkdm_wakeup(clkdm);
> -       else
> -               omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
> -                                                clkdm->cm_inst,
> -                                                clkdm->clkdm_offs);
> -}
> -
> -static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
> -{
> -       if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> -               return omap4_clkdm_wakeup(clkdm);
> -
> -       return 0;
> -}
> -
> -static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
> -{
> -       bool hwsup = false;
> -
> -       if (!clkdm->prcm_partition)
> -               return 0;
> -
> -       /*
> -        * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> -        * more details on the unpleasant problem this is working
> -        * around
> -        */
> -       if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
> -           !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
> -               omap4_clkdm_allow_idle(clkdm);
> -               return 0;
> -       }
> -
> -       hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
> -                                       clkdm->cm_inst, clkdm->clkdm_offs);
> -
> -       if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
> -               omap4_clkdm_sleep(clkdm);
> -
> -       return 0;
> -}
> -
> -struct clkdm_ops omap4_clkdm_operations = {
> -       .clkdm_add_wkdep        = omap4_clkdm_add_wkup_sleep_dep,
> -       .clkdm_del_wkdep        = omap4_clkdm_del_wkup_sleep_dep,
> -       .clkdm_read_wkdep       = omap4_clkdm_read_wkup_sleep_dep,
> -       .clkdm_clear_all_wkdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
> -       .clkdm_add_sleepdep     = omap4_clkdm_add_wkup_sleep_dep,
> -       .clkdm_del_sleepdep     = omap4_clkdm_del_wkup_sleep_dep,
> -       .clkdm_read_sleepdep    = omap4_clkdm_read_wkup_sleep_dep,
> -       .clkdm_clear_all_sleepdeps      = omap4_clkdm_clear_all_wkup_sleep_deps,
> -       .clkdm_sleep            = omap4_clkdm_sleep,
> -       .clkdm_wakeup           = omap4_clkdm_wakeup,
> -       .clkdm_allow_idle       = omap4_clkdm_allow_idle,
> -       .clkdm_deny_idle        = omap4_clkdm_deny_idle,
> -       .clkdm_clk_enable       = omap4_clkdm_clk_enable,
> -       .clkdm_clk_disable      = omap4_clkdm_clk_disable,
> -};
> diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
> index 19cee91..0160893 100644
> --- a/arch/arm/mach-omap2/cm2xxx.c
> +++ b/arch/arm/mach-omap2/cm2xxx.c
> @@ -19,9 +19,11 @@
>  #include "soc.h"
>  #include "iomap.h"
>  #include "common.h"
> +#include "prm2xxx.h"
>  #include "cm.h"
>  #include "cm2xxx.h"
>  #include "cm-regbits-24xx.h"
> +#include "clockdomain.h"
>
>  /* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */
>  #define DPLL_AUTOIDLE_DISABLE                          0x0
> @@ -165,3 +167,87 @@ int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
>
>         return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
>  }
> +
> +/* Clockdomain low-level functions */
> +
> +static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm)
> +{
> +       if (atomic_read(&clkdm->usecount) > 0)
> +               _clkdm_add_autodeps(clkdm);
> +
> +       omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                      clkdm->clktrctrl_mask);
> +}
> +
> +static void omap2xxx_clkdm_deny_idle(struct clockdomain *clkdm)
> +{
> +       omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                       clkdm->clktrctrl_mask);
> +
> +       if (atomic_read(&clkdm->usecount) > 0)
> +               _clkdm_del_autodeps(clkdm);
> +}
> +
> +static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
> +{
> +       bool hwsup = false;
> +
> +       if (!clkdm->clktrctrl_mask)
> +               return 0;
> +
> +       hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                             clkdm->clktrctrl_mask);
> +
> +       if (hwsup) {
> +               /* Disable HW transitions when we are changing deps */
> +               omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                               clkdm->clktrctrl_mask);
> +               _clkdm_add_autodeps(clkdm);
> +               omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                              clkdm->clktrctrl_mask);
> +       } else {
> +               if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> +                       omap2xxx_clkdm_wakeup(clkdm);
> +       }
> +
> +       return 0;
> +}
> +
> +static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm)
> +{
> +       bool hwsup = false;
> +
> +       if (!clkdm->clktrctrl_mask)
> +               return 0;
> +
> +       hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                             clkdm->clktrctrl_mask);
> +
> +       if (hwsup) {
> +               /* Disable HW transitions when we are changing deps */
> +               omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                               clkdm->clktrctrl_mask);
> +               _clkdm_del_autodeps(clkdm);
> +               omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                              clkdm->clktrctrl_mask);
> +       } else {
> +               if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
> +                       omap2xxx_clkdm_sleep(clkdm);
> +       }
> +
> +       return 0;
> +}
> +
> +struct clkdm_ops omap2_clkdm_operations = {
> +       .clkdm_add_wkdep        = omap2_clkdm_add_wkdep,
> +       .clkdm_del_wkdep        = omap2_clkdm_del_wkdep,
> +       .clkdm_read_wkdep       = omap2_clkdm_read_wkdep,
> +       .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
> +       .clkdm_sleep            = omap2xxx_clkdm_sleep,
> +       .clkdm_wakeup           = omap2xxx_clkdm_wakeup,
> +       .clkdm_allow_idle       = omap2xxx_clkdm_allow_idle,
> +       .clkdm_deny_idle        = omap2xxx_clkdm_deny_idle,
> +       .clkdm_clk_enable       = omap2xxx_clkdm_clk_enable,
> +       .clkdm_clk_disable      = omap2xxx_clkdm_clk_disable,
> +};
> +
> diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h
> index 64df725..78c218c 100644
> --- a/arch/arm/mach-omap2/cm2xxx_3xxx.h
> +++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h
> @@ -73,6 +73,18 @@ static inline u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module,
>         return v;
>  }
>
> +/* Read a CM register, AND it, and shift the result down to bit 0 */
> +static inline u32 omap2_cm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
> +{
> +       u32 v;
> +
> +       v = omap2_cm_read_mod_reg(domain, idx);
> +       v &= mask;
> +       v >>= __ffs(mask);
> +
> +       return v;
> +}
> +
>  static inline u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
>  {
>         return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx);
> diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c
> index 13f56ea..9b3bcff1 100644
> --- a/arch/arm/mach-omap2/cm33xx.c
> +++ b/arch/arm/mach-omap2/cm33xx.c
> @@ -24,6 +24,7 @@
>
>  #include <plat/common.h>
>
> +#include "clockdomain.h"
>  #include "cm.h"
>  #include "cm33xx.h"
>  #include "cm-regbits-34xx.h"
> @@ -311,3 +312,58 @@ void am33xx_cm_module_disable(u16 inst, s16 cdoffs, u16 clkctrl_offs)
>         v &= ~AM33XX_MODULEMODE_MASK;
>         am33xx_cm_write_reg(v, inst, clkctrl_offs);
>  }
> +
> +/*
> + * Clockdomain low-level functions
> + */
> +
> +static int am33xx_clkdm_sleep(struct clockdomain *clkdm)
> +{
> +       am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs);
> +       return 0;
> +}
> +
> +static int am33xx_clkdm_wakeup(struct clockdomain *clkdm)
> +{
> +       am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs);
> +       return 0;
> +}
> +
> +static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm)
> +{
> +       am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
> +}
> +
> +static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm)
> +{
> +       am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
> +}
> +
> +static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm)
> +{
> +       if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> +               return am33xx_clkdm_wakeup(clkdm);
> +
> +       return 0;
> +}
> +
> +static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
> +{
> +       bool hwsup = false;
> +
> +       hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
> +
> +       if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
> +               am33xx_clkdm_sleep(clkdm);
> +
> +       return 0;
> +}
> +
> +struct clkdm_ops am33xx_clkdm_operations = {
> +       .clkdm_sleep            = am33xx_clkdm_sleep,
> +       .clkdm_wakeup           = am33xx_clkdm_wakeup,
> +       .clkdm_allow_idle       = am33xx_clkdm_allow_idle,
> +       .clkdm_deny_idle        = am33xx_clkdm_deny_idle,
> +       .clkdm_clk_enable       = am33xx_clkdm_clk_enable,
> +       .clkdm_clk_disable      = am33xx_clkdm_clk_disable,
> +};
> diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c
> index 075cabe..3493fef 100644
> --- a/arch/arm/mach-omap2/cm3xxx.c
> +++ b/arch/arm/mach-omap2/cm3xxx.c
> @@ -19,9 +19,11 @@
>  #include "soc.h"
>  #include "iomap.h"
>  #include "common.h"
> +#include "prm2xxx_3xxx.h"
>  #include "cm.h"
>  #include "cm3xxx.h"
>  #include "cm-regbits-34xx.h"
> +#include "clockdomain.h"
>
>  static const u8 omap3xxx_cm_idlest_offs[] = { CM_IDLEST1, CM_IDLEST2 };
>
> @@ -104,6 +106,173 @@ int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
>         return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
>  }
>
> +/* Clockdomain low-level operations */
> +
> +static int omap3xxx_clkdm_add_sleepdep(struct clockdomain *clkdm1,
> +                                      struct clockdomain *clkdm2)
> +{
> +       omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> +                                 clkdm1->pwrdm.ptr->prcm_offs,
> +                                 OMAP3430_CM_SLEEPDEP);
> +       return 0;
> +}
> +
> +static int omap3xxx_clkdm_del_sleepdep(struct clockdomain *clkdm1,
> +                                      struct clockdomain *clkdm2)
> +{
> +       omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> +                                   clkdm1->pwrdm.ptr->prcm_offs,
> +                                   OMAP3430_CM_SLEEPDEP);
> +       return 0;
> +}
> +
> +static int omap3xxx_clkdm_read_sleepdep(struct clockdomain *clkdm1,
> +                                       struct clockdomain *clkdm2)
> +{
> +       return omap2_cm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> +                                           OMAP3430_CM_SLEEPDEP,
> +                                           (1 << clkdm2->dep_bit));
> +}
> +
> +static int omap3xxx_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
> +{
> +       struct clkdm_dep *cd;
> +       u32 mask = 0;
> +
> +       for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
> +               if (!cd->clkdm)
> +                       continue; /* only happens if data is erroneous */
> +
> +               mask |= 1 << cd->clkdm->dep_bit;
> +               atomic_set(&cd->sleepdep_usecount, 0);
> +       }
> +       omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> +                                   OMAP3430_CM_SLEEPDEP);
> +       return 0;
> +}
> +
> +static int omap3xxx_clkdm_sleep(struct clockdomain *clkdm)
> +{
> +       omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
> +                                     clkdm->clktrctrl_mask);
> +       return 0;
> +}
> +
> +static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm)
> +{
> +       omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
> +                                      clkdm->clktrctrl_mask);
> +       return 0;
> +}
> +
> +static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm)
> +{
> +       if (atomic_read(&clkdm->usecount) > 0)
> +               _clkdm_add_autodeps(clkdm);
> +
> +       omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                      clkdm->clktrctrl_mask);
> +}
> +
> +static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm)
> +{
> +       omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                       clkdm->clktrctrl_mask);
> +
> +       if (atomic_read(&clkdm->usecount) > 0)
> +               _clkdm_del_autodeps(clkdm);
> +}
> +
> +static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
> +{
> +       bool hwsup = false;
> +
> +       if (!clkdm->clktrctrl_mask)
> +               return 0;
> +
> +       /*
> +        * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +        * more details on the unpleasant problem this is working
> +        * around
> +        */
> +       if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
> +           (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
> +               omap3xxx_clkdm_wakeup(clkdm);
> +               return 0;
> +       }
> +
> +       hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                             clkdm->clktrctrl_mask);
> +
> +       if (hwsup) {
> +               /* Disable HW transitions when we are changing deps */
> +               omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                               clkdm->clktrctrl_mask);
> +               _clkdm_add_autodeps(clkdm);
> +               omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                              clkdm->clktrctrl_mask);
> +       } else {
> +               if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> +                       omap3xxx_clkdm_wakeup(clkdm);
> +       }
> +
> +       return 0;
> +}
> +
> +static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
> +{
> +       bool hwsup = false;
> +
> +       if (!clkdm->clktrctrl_mask)
> +               return 0;
> +
> +       /*
> +        * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +        * more details on the unpleasant problem this is working
> +        * around
> +        */
> +       if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
> +           !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
> +               omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                              clkdm->clktrctrl_mask);
> +               return 0;
> +       }
> +
> +       hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                             clkdm->clktrctrl_mask);
> +
> +       if (hwsup) {
> +               /* Disable HW transitions when we are changing deps */
> +               omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                               clkdm->clktrctrl_mask);
> +               _clkdm_del_autodeps(clkdm);
> +               omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +                                              clkdm->clktrctrl_mask);
> +       } else {
> +               if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
> +                       omap3xxx_clkdm_sleep(clkdm);
> +       }
> +
> +       return 0;
> +}
> +
> +struct clkdm_ops omap3_clkdm_operations = {
> +       .clkdm_add_wkdep        = omap2_clkdm_add_wkdep,
> +       .clkdm_del_wkdep        = omap2_clkdm_del_wkdep,
> +       .clkdm_read_wkdep       = omap2_clkdm_read_wkdep,
> +       .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
> +       .clkdm_add_sleepdep     = omap3xxx_clkdm_add_sleepdep,
> +       .clkdm_del_sleepdep     = omap3xxx_clkdm_del_sleepdep,
> +       .clkdm_read_sleepdep    = omap3xxx_clkdm_read_sleepdep,
> +       .clkdm_clear_all_sleepdeps      = omap3xxx_clkdm_clear_all_sleepdeps,
> +       .clkdm_sleep            = omap3xxx_clkdm_sleep,
> +       .clkdm_wakeup           = omap3xxx_clkdm_wakeup,
> +       .clkdm_allow_idle       = omap3xxx_clkdm_allow_idle,
> +       .clkdm_deny_idle        = omap3xxx_clkdm_deny_idle,
> +       .clkdm_clk_enable       = omap3xxx_clkdm_clk_enable,
> +       .clkdm_clk_disable      = omap3xxx_clkdm_clk_disable,
> +};
> +
>  /*
>   * Context save/restore code - OMAP3 only
>   */
> diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
> index 1894015..9dca0ee 100644
> --- a/arch/arm/mach-omap2/cminst44xx.c
> +++ b/arch/arm/mach-omap2/cminst44xx.c
> @@ -22,6 +22,7 @@
>
>  #include "iomap.h"
>  #include "common.h"
> +#include "clockdomain.h"
>  #include "cm.h"
>  #include "cm1_44xx.h"
>  #include "cm2_44xx.h"
> @@ -343,3 +344,141 @@ void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs,
>         v &= ~OMAP4430_MODULEMODE_MASK;
>         omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs);
>  }
> +
> +/*
> + * Clockdomain low-level functions
> + */
> +
> +static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1,
> +                                       struct clockdomain *clkdm2)
> +{
> +       omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit),
> +                                      clkdm1->prcm_partition,
> +                                      clkdm1->cm_inst, clkdm1->clkdm_offs +
> +                                      OMAP4_CM_STATICDEP);
> +       return 0;
> +}
> +
> +static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1,
> +                                       struct clockdomain *clkdm2)
> +{
> +       omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit),
> +                                        clkdm1->prcm_partition,
> +                                        clkdm1->cm_inst, clkdm1->clkdm_offs +
> +                                        OMAP4_CM_STATICDEP);
> +       return 0;
> +}
> +
> +static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1,
> +                                       struct clockdomain *clkdm2)
> +{
> +       return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition,
> +                                              clkdm1->cm_inst,
> +                                              clkdm1->clkdm_offs +
> +                                              OMAP4_CM_STATICDEP,
> +                                              (1 << clkdm2->dep_bit));
> +}
> +
> +static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
> +{
> +       struct clkdm_dep *cd;
> +       u32 mask = 0;
> +
> +       if (!clkdm->prcm_partition)
> +               return 0;
> +
> +       for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> +               if (!cd->clkdm)
> +                       continue; /* only happens if data is erroneous */
> +
> +               mask |= 1 << cd->clkdm->dep_bit;
> +               atomic_set(&cd->wkdep_usecount, 0);
> +       }
> +
> +       omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition,
> +                                        clkdm->cm_inst, clkdm->clkdm_offs +
> +                                        OMAP4_CM_STATICDEP);
> +       return 0;
> +}
> +
> +static int omap4_clkdm_sleep(struct clockdomain *clkdm)
> +{
> +       omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
> +                                       clkdm->cm_inst, clkdm->clkdm_offs);
> +       return 0;
> +}
> +
> +static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
> +{
> +       omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
> +                                       clkdm->cm_inst, clkdm->clkdm_offs);
> +       return 0;
> +}
> +
> +static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
> +{
> +       omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
> +                                       clkdm->cm_inst, clkdm->clkdm_offs);
> +}
> +
> +static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
> +{
> +       if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> +               omap4_clkdm_wakeup(clkdm);
> +       else
> +               omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
> +                                                clkdm->cm_inst,
> +                                                clkdm->clkdm_offs);
> +}
> +
> +static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
> +{
> +       if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> +               return omap4_clkdm_wakeup(clkdm);
> +
> +       return 0;
> +}
> +
> +static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
> +{
> +       bool hwsup = false;
> +
> +       if (!clkdm->prcm_partition)
> +               return 0;
> +
> +       /*
> +        * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +        * more details on the unpleasant problem this is working
> +        * around
> +        */
> +       if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
> +           !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
> +               omap4_clkdm_allow_idle(clkdm);
> +               return 0;
> +       }
> +
> +       hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
> +                                       clkdm->cm_inst, clkdm->clkdm_offs);
> +
> +       if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
> +               omap4_clkdm_sleep(clkdm);
> +
> +       return 0;
> +}
> +
> +struct clkdm_ops omap4_clkdm_operations = {
> +       .clkdm_add_wkdep        = omap4_clkdm_add_wkup_sleep_dep,
> +       .clkdm_del_wkdep        = omap4_clkdm_del_wkup_sleep_dep,
> +       .clkdm_read_wkdep       = omap4_clkdm_read_wkup_sleep_dep,
> +       .clkdm_clear_all_wkdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
> +       .clkdm_add_sleepdep     = omap4_clkdm_add_wkup_sleep_dep,
> +       .clkdm_del_sleepdep     = omap4_clkdm_del_wkup_sleep_dep,
> +       .clkdm_read_sleepdep    = omap4_clkdm_read_wkup_sleep_dep,
> +       .clkdm_clear_all_sleepdeps      = omap4_clkdm_clear_all_wkup_sleep_deps,
> +       .clkdm_sleep            = omap4_clkdm_sleep,
> +       .clkdm_wakeup           = omap4_clkdm_wakeup,
> +       .clkdm_allow_idle       = omap4_clkdm_allow_idle,
> +       .clkdm_deny_idle        = omap4_clkdm_deny_idle,
> +       .clkdm_clk_enable       = omap4_clkdm_clk_enable,
> +       .clkdm_clk_disable      = omap4_clkdm_clk_disable,
> +};
> diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c
> index 14940c4..d08a2b9 100644
> --- a/arch/arm/mach-omap2/prm2xxx.c
> +++ b/arch/arm/mach-omap2/prm2xxx.c
> @@ -23,10 +23,27 @@
>
>  #include "vp.h"
>  #include "powerdomain.h"
> +#include "clockdomain.h"
>  #include "prm2xxx.h"
>  #include "cm2xxx_3xxx.h"
>  #include "prm-regbits-24xx.h"
>
> +int omap2xxx_clkdm_sleep(struct clockdomain *clkdm)
> +{
> +       omap2_prm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
> +                                  clkdm->pwrdm.ptr->prcm_offs,
> +                                  OMAP2_PM_PWSTCTRL);
> +       return 0;
> +}
> +
> +int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm)
> +{
> +       omap2_prm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
> +                                    clkdm->pwrdm.ptr->prcm_offs,
> +                                    OMAP2_PM_PWSTCTRL);
> +       return 0;
> +}
> +
>  struct pwrdm_ops omap2_pwrdm_operations = {
>         .pwrdm_set_next_pwrst   = omap2_pwrdm_set_next_pwrst,
>         .pwrdm_read_next_pwrst  = omap2_pwrdm_read_next_pwrst,
> diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h
> index 6490e1a..6d76716 100644
> --- a/arch/arm/mach-omap2/prm2xxx.h
> +++ b/arch/arm/mach-omap2/prm2xxx.h
> @@ -119,4 +119,10 @@
>  #define OMAP24XX_PRCM_IRQSTATUS_IVA                    0x00f8
>  #define OMAP24XX_PRCM_IRQENABLE_IVA                    0x00fc
>
> +#ifndef __ASSEMBLER__
> +/* Function prototypes */
> +extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm);
> +extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm);
> +#endif
> +
>  #endif
> diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
> index bdddf5c..30517f5 100644
> --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
> +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
> @@ -20,6 +20,7 @@
>  #include "powerdomain.h"
>  #include "prm2xxx_3xxx.h"
>  #include "prm-regbits-24xx.h"
> +#include "clockdomain.h"
>
>  /**
>   * omap2_prm_is_hardreset_asserted - read the HW reset line state of
> @@ -208,3 +209,45 @@ int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm)
>         return 0;
>  }
>
> +int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
> +                         struct clockdomain *clkdm2)
> +{
> +       omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
> +                                  clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> +       return 0;
> +}
> +
> +int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
> +                         struct clockdomain *clkdm2)
> +{
> +       omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
> +                                    clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
> +       return 0;
> +}
> +
> +int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
> +                          struct clockdomain *clkdm2)
> +{
> +       return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
> +                                            PM_WKDEP, (1 << clkdm2->dep_bit));
> +}
> +
> +int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
> +{
> +       struct clkdm_dep *cd;
> +       u32 mask = 0;
> +
> +       for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
> +               if (!cd->clkdm)
> +                       continue; /* only happens if data is erroneous */
> +
> +               /* PRM accesses are slow, so minimize them */
> +               mask |= 1 << cd->clkdm->dep_bit;
> +               atomic_set(&cd->wkdep_usecount, 0);
> +       }
> +
> +       omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
> +                                    PM_WKDEP);
> +       return 0;
> +}
> +
> diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
> index 706b026..22a405a 100644
> --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
> +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
> @@ -116,6 +116,14 @@ extern int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank);
>  extern int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);
>  extern int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm);
>
> +extern int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
> +                                struct clockdomain *clkdm2);
> +extern int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
> +                                struct clockdomain *clkdm2);
> +extern int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
> +                                 struct clockdomain *clkdm2);
> +extern int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm);
> +
>  #endif /* __ASSEMBLER */
>
>  /*
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 56a3386..3751d56 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -133,22 +133,17 @@  obj-$(CONFIG_SOC_OMAP5)			+= $(powerdomain-common)
 # PRCM clockdomain control
 clockdomain-common			+= clockdomain.o
 obj-$(CONFIG_ARCH_OMAP2)		+= $(clockdomain-common)
-obj-$(CONFIG_ARCH_OMAP2)		+= clockdomain2xxx_3xxx.o
 obj-$(CONFIG_ARCH_OMAP2)		+= clockdomains2xxx_3xxx_data.o
 obj-$(CONFIG_SOC_OMAP2420)		+= clockdomains2420_data.o
 obj-$(CONFIG_SOC_OMAP2430)		+= clockdomains2430_data.o
 obj-$(CONFIG_ARCH_OMAP3)		+= $(clockdomain-common)
-obj-$(CONFIG_ARCH_OMAP3)		+= clockdomain2xxx_3xxx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= clockdomains2xxx_3xxx_data.o
 obj-$(CONFIG_ARCH_OMAP3)		+= clockdomains3xxx_data.o
 obj-$(CONFIG_ARCH_OMAP4)		+= $(clockdomain-common)
-obj-$(CONFIG_ARCH_OMAP4)		+= clockdomain44xx.o
 obj-$(CONFIG_ARCH_OMAP4)		+= clockdomains44xx_data.o
 obj-$(CONFIG_SOC_AM33XX)		+= $(clockdomain-common)
-obj-$(CONFIG_SOC_AM33XX)		+= clockdomain33xx.o
 obj-$(CONFIG_SOC_AM33XX)		+= clockdomains33xx_data.o
 obj-$(CONFIG_SOC_OMAP5)			+= $(clockdomain-common)
-obj-$(CONFIG_SOC_OMAP5)			+= clockdomain44xx.o
 
 # Clock framework
 obj-$(CONFIG_ARCH_OMAP2)		+= $(clock-common) clock2xxx.o
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
deleted file mode 100644
index 658487c..0000000
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ /dev/null
@@ -1,340 +0,0 @@ 
-/*
- * OMAP2 and OMAP3 clockdomain control
- *
- * Copyright (C) 2008-2010 Texas Instruments, Inc.
- * Copyright (C) 2008-2010 Nokia Corporation
- *
- * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
- * Rajendra Nayak <rnayak@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/types.h>
-#include <plat/prcm.h>
-#include "prm.h"
-#include "prm2xxx_3xxx.h"
-#include "cm.h"
-#include "cm2xxx.h"
-#include "cm3xxx.h"
-#include "cm-regbits-24xx.h"
-#include "cm-regbits-34xx.h"
-#include "prm-regbits-24xx.h"
-#include "clockdomain.h"
-
-static int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
-						struct clockdomain *clkdm2)
-{
-	omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
-				clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
-	return 0;
-}
-
-static int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
-						 struct clockdomain *clkdm2)
-{
-	omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
-				clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
-	return 0;
-}
-
-static int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
-						 struct clockdomain *clkdm2)
-{
-	return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
-				PM_WKDEP, (1 << clkdm2->dep_bit));
-}
-
-static int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
-{
-	struct clkdm_dep *cd;
-	u32 mask = 0;
-
-	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
-		if (!cd->clkdm)
-			continue; /* only happens if data is erroneous */
-
-		/* PRM accesses are slow, so minimize them */
-		mask |= 1 << cd->clkdm->dep_bit;
-		atomic_set(&cd->wkdep_usecount, 0);
-	}
-
-	omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
-				 PM_WKDEP);
-	return 0;
-}
-
-static int omap3_clkdm_add_sleepdep(struct clockdomain *clkdm1,
-						 struct clockdomain *clkdm2)
-{
-	omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
-				clkdm1->pwrdm.ptr->prcm_offs,
-				OMAP3430_CM_SLEEPDEP);
-	return 0;
-}
-
-static int omap3_clkdm_del_sleepdep(struct clockdomain *clkdm1,
-						 struct clockdomain *clkdm2)
-{
-	omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
-				clkdm1->pwrdm.ptr->prcm_offs,
-				OMAP3430_CM_SLEEPDEP);
-	return 0;
-}
-
-static int omap3_clkdm_read_sleepdep(struct clockdomain *clkdm1,
-						 struct clockdomain *clkdm2)
-{
-	return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
-				OMAP3430_CM_SLEEPDEP, (1 << clkdm2->dep_bit));
-}
-
-static int omap3_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
-{
-	struct clkdm_dep *cd;
-	u32 mask = 0;
-
-	for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
-		if (!cd->clkdm)
-			continue; /* only happens if data is erroneous */
-
-		/* PRM accesses are slow, so minimize them */
-		mask |= 1 << cd->clkdm->dep_bit;
-		atomic_set(&cd->sleepdep_usecount, 0);
-	}
-	omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
-				OMAP3430_CM_SLEEPDEP);
-	return 0;
-}
-
-static int omap2_clkdm_sleep(struct clockdomain *clkdm)
-{
-	omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
-				clkdm->pwrdm.ptr->prcm_offs,
-				OMAP2_PM_PWSTCTRL);
-	return 0;
-}
-
-static int omap2_clkdm_wakeup(struct clockdomain *clkdm)
-{
-	omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
-				clkdm->pwrdm.ptr->prcm_offs,
-				OMAP2_PM_PWSTCTRL);
-	return 0;
-}
-
-static void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
-{
-	if (atomic_read(&clkdm->usecount) > 0)
-		_clkdm_add_autodeps(clkdm);
-
-	omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-				clkdm->clktrctrl_mask);
-}
-
-static void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
-{
-	omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-				clkdm->clktrctrl_mask);
-
-	if (atomic_read(&clkdm->usecount) > 0)
-		_clkdm_del_autodeps(clkdm);
-}
-
-static void _enable_hwsup(struct clockdomain *clkdm)
-{
-	if (cpu_is_omap24xx())
-		omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-					       clkdm->clktrctrl_mask);
-	else if (cpu_is_omap34xx())
-		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-					       clkdm->clktrctrl_mask);
-}
-
-static void _disable_hwsup(struct clockdomain *clkdm)
-{
-	if (cpu_is_omap24xx())
-		omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-						clkdm->clktrctrl_mask);
-	else if (cpu_is_omap34xx())
-		omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-						clkdm->clktrctrl_mask);
-}
-
-static int omap3_clkdm_sleep(struct clockdomain *clkdm)
-{
-	omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
-				clkdm->clktrctrl_mask);
-	return 0;
-}
-
-static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
-{
-	omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
-				clkdm->clktrctrl_mask);
-	return 0;
-}
-
-static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
-{
-	bool hwsup = false;
-
-	if (!clkdm->clktrctrl_mask)
-		return 0;
-
-	hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-					      clkdm->clktrctrl_mask);
-
-	if (hwsup) {
-		/* Disable HW transitions when we are changing deps */
-		_disable_hwsup(clkdm);
-		_clkdm_add_autodeps(clkdm);
-		_enable_hwsup(clkdm);
-	} else {
-		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
-			omap2_clkdm_wakeup(clkdm);
-	}
-
-	return 0;
-}
-
-static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm)
-{
-	bool hwsup = false;
-
-	if (!clkdm->clktrctrl_mask)
-		return 0;
-
-	hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-					      clkdm->clktrctrl_mask);
-
-	if (hwsup) {
-		/* Disable HW transitions when we are changing deps */
-		_disable_hwsup(clkdm);
-		_clkdm_del_autodeps(clkdm);
-		_enable_hwsup(clkdm);
-	} else {
-		if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
-			omap2_clkdm_sleep(clkdm);
-	}
-
-	return 0;
-}
-
-static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
-{
-	if (atomic_read(&clkdm->usecount) > 0)
-		_clkdm_add_autodeps(clkdm);
-
-	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-				clkdm->clktrctrl_mask);
-}
-
-static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
-{
-	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-				clkdm->clktrctrl_mask);
-
-	if (atomic_read(&clkdm->usecount) > 0)
-		_clkdm_del_autodeps(clkdm);
-}
-
-static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
-{
-	bool hwsup = false;
-
-	if (!clkdm->clktrctrl_mask)
-		return 0;
-
-	/*
-	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
-	 * more details on the unpleasant problem this is working
-	 * around
-	 */
-	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
-	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
-		omap3_clkdm_wakeup(clkdm);
-		return 0;
-	}
-
-	hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-					      clkdm->clktrctrl_mask);
-
-	if (hwsup) {
-		/* Disable HW transitions when we are changing deps */
-		_disable_hwsup(clkdm);
-		_clkdm_add_autodeps(clkdm);
-		_enable_hwsup(clkdm);
-	} else {
-		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
-			omap3_clkdm_wakeup(clkdm);
-	}
-
-	return 0;
-}
-
-static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
-{
-	bool hwsup = false;
-
-	if (!clkdm->clktrctrl_mask)
-		return 0;
-
-	/*
-	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
-	 * more details on the unpleasant problem this is working
-	 * around
-	 */
-	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
-	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
-		_enable_hwsup(clkdm);
-		return 0;
-	}
-
-	hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-					      clkdm->clktrctrl_mask);
-
-	if (hwsup) {
-		/* Disable HW transitions when we are changing deps */
-		_disable_hwsup(clkdm);
-		_clkdm_del_autodeps(clkdm);
-		_enable_hwsup(clkdm);
-	} else {
-		if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
-			omap3_clkdm_sleep(clkdm);
-	}
-
-	return 0;
-}
-
-struct clkdm_ops omap2_clkdm_operations = {
-	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,
-	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep,
-	.clkdm_read_wkdep	= omap2_clkdm_read_wkdep,
-	.clkdm_clear_all_wkdeps	= omap2_clkdm_clear_all_wkdeps,
-	.clkdm_sleep		= omap2_clkdm_sleep,
-	.clkdm_wakeup		= omap2_clkdm_wakeup,
-	.clkdm_allow_idle	= omap2_clkdm_allow_idle,
-	.clkdm_deny_idle	= omap2_clkdm_deny_idle,
-	.clkdm_clk_enable	= omap2xxx_clkdm_clk_enable,
-	.clkdm_clk_disable	= omap2xxx_clkdm_clk_disable,
-};
-
-struct clkdm_ops omap3_clkdm_operations = {
-	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,
-	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep,
-	.clkdm_read_wkdep	= omap2_clkdm_read_wkdep,
-	.clkdm_clear_all_wkdeps	= omap2_clkdm_clear_all_wkdeps,
-	.clkdm_add_sleepdep	= omap3_clkdm_add_sleepdep,
-	.clkdm_del_sleepdep	= omap3_clkdm_del_sleepdep,
-	.clkdm_read_sleepdep	= omap3_clkdm_read_sleepdep,
-	.clkdm_clear_all_sleepdeps	= omap3_clkdm_clear_all_sleepdeps,
-	.clkdm_sleep		= omap3_clkdm_sleep,
-	.clkdm_wakeup		= omap3_clkdm_wakeup,
-	.clkdm_allow_idle	= omap3_clkdm_allow_idle,
-	.clkdm_deny_idle	= omap3_clkdm_deny_idle,
-	.clkdm_clk_enable	= omap3xxx_clkdm_clk_enable,
-	.clkdm_clk_disable	= omap3xxx_clkdm_clk_disable,
-};
diff --git a/arch/arm/mach-omap2/clockdomain33xx.c b/arch/arm/mach-omap2/clockdomain33xx.c
deleted file mode 100644
index aca6388..0000000
--- a/arch/arm/mach-omap2/clockdomain33xx.c
+++ /dev/null
@@ -1,74 +0,0 @@ 
-/*
- * AM33XX clockdomain control
- *
- * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
- * Vaibhav Hiremath <hvaibhav@ti.com>
- *
- * Derived from mach-omap2/clockdomain44xx.c written by Rajendra Nayak
- *
- * 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 version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; 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 "clockdomain.h"
-#include "cm33xx.h"
-
-
-static int am33xx_clkdm_sleep(struct clockdomain *clkdm)
-{
-	am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs);
-	return 0;
-}
-
-static int am33xx_clkdm_wakeup(struct clockdomain *clkdm)
-{
-	am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs);
-	return 0;
-}
-
-static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm)
-{
-	am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
-}
-
-static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm)
-{
-	am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
-}
-
-static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm)
-{
-	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
-		return am33xx_clkdm_wakeup(clkdm);
-
-	return 0;
-}
-
-static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
-{
-	bool hwsup = false;
-
-	hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
-
-	if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
-		am33xx_clkdm_sleep(clkdm);
-
-	return 0;
-}
-
-struct clkdm_ops am33xx_clkdm_operations = {
-	.clkdm_sleep		= am33xx_clkdm_sleep,
-	.clkdm_wakeup		= am33xx_clkdm_wakeup,
-	.clkdm_allow_idle	= am33xx_clkdm_allow_idle,
-	.clkdm_deny_idle	= am33xx_clkdm_deny_idle,
-	.clkdm_clk_enable	= am33xx_clkdm_clk_enable,
-	.clkdm_clk_disable	= am33xx_clkdm_clk_disable,
-};
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
deleted file mode 100644
index 6fc6155..0000000
--- a/arch/arm/mach-omap2/clockdomain44xx.c
+++ /dev/null
@@ -1,151 +0,0 @@ 
-/*
- * OMAP4 clockdomain control
- *
- * Copyright (C) 2008-2010 Texas Instruments, Inc.
- * Copyright (C) 2008-2010 Nokia Corporation
- *
- * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
- * Rajendra Nayak <rnayak@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include "clockdomain.h"
-#include "cminst44xx.h"
-#include "cm44xx.h"
-
-static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1,
-					struct clockdomain *clkdm2)
-{
-	omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit),
-					clkdm1->prcm_partition,
-					clkdm1->cm_inst, clkdm1->clkdm_offs +
-					OMAP4_CM_STATICDEP);
-	return 0;
-}
-
-static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1,
-					struct clockdomain *clkdm2)
-{
-	omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit),
-					clkdm1->prcm_partition,
-					clkdm1->cm_inst, clkdm1->clkdm_offs +
-					OMAP4_CM_STATICDEP);
-	return 0;
-}
-
-static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1,
-					struct clockdomain *clkdm2)
-{
-	return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition,
-					clkdm1->cm_inst, clkdm1->clkdm_offs +
-					OMAP4_CM_STATICDEP,
-					(1 << clkdm2->dep_bit));
-}
-
-static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
-{
-	struct clkdm_dep *cd;
-	u32 mask = 0;
-
-	if (!clkdm->prcm_partition)
-		return 0;
-
-	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
-		if (!cd->clkdm)
-			continue; /* only happens if data is erroneous */
-
-		mask |= 1 << cd->clkdm->dep_bit;
-		atomic_set(&cd->wkdep_usecount, 0);
-	}
-
-	omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition,
-					clkdm->cm_inst, clkdm->clkdm_offs +
-					OMAP4_CM_STATICDEP);
-	return 0;
-}
-
-static int omap4_clkdm_sleep(struct clockdomain *clkdm)
-{
-	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
-					clkdm->cm_inst, clkdm->clkdm_offs);
-	return 0;
-}
-
-static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
-{
-	omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
-					clkdm->cm_inst, clkdm->clkdm_offs);
-	return 0;
-}
-
-static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
-{
-	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
-					clkdm->cm_inst, clkdm->clkdm_offs);
-}
-
-static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
-{
-	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
-		omap4_clkdm_wakeup(clkdm);
-	else
-		omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
-						 clkdm->cm_inst,
-						 clkdm->clkdm_offs);
-}
-
-static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
-{
-	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
-		return omap4_clkdm_wakeup(clkdm);
-
-	return 0;
-}
-
-static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
-{
-	bool hwsup = false;
-
-	if (!clkdm->prcm_partition)
-		return 0;
-
-	/*
-	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
-	 * more details on the unpleasant problem this is working
-	 * around
-	 */
-	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
-	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
-		omap4_clkdm_allow_idle(clkdm);
-		return 0;
-	}
-
-	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
-					clkdm->cm_inst, clkdm->clkdm_offs);
-
-	if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
-		omap4_clkdm_sleep(clkdm);
-
-	return 0;
-}
-
-struct clkdm_ops omap4_clkdm_operations = {
-	.clkdm_add_wkdep	= omap4_clkdm_add_wkup_sleep_dep,
-	.clkdm_del_wkdep	= omap4_clkdm_del_wkup_sleep_dep,
-	.clkdm_read_wkdep	= omap4_clkdm_read_wkup_sleep_dep,
-	.clkdm_clear_all_wkdeps	= omap4_clkdm_clear_all_wkup_sleep_deps,
-	.clkdm_add_sleepdep	= omap4_clkdm_add_wkup_sleep_dep,
-	.clkdm_del_sleepdep	= omap4_clkdm_del_wkup_sleep_dep,
-	.clkdm_read_sleepdep	= omap4_clkdm_read_wkup_sleep_dep,
-	.clkdm_clear_all_sleepdeps	= omap4_clkdm_clear_all_wkup_sleep_deps,
-	.clkdm_sleep		= omap4_clkdm_sleep,
-	.clkdm_wakeup		= omap4_clkdm_wakeup,
-	.clkdm_allow_idle	= omap4_clkdm_allow_idle,
-	.clkdm_deny_idle	= omap4_clkdm_deny_idle,
-	.clkdm_clk_enable	= omap4_clkdm_clk_enable,
-	.clkdm_clk_disable	= omap4_clkdm_clk_disable,
-};
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
index 19cee91..0160893 100644
--- a/arch/arm/mach-omap2/cm2xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx.c
@@ -19,9 +19,11 @@ 
 #include "soc.h"
 #include "iomap.h"
 #include "common.h"
+#include "prm2xxx.h"
 #include "cm.h"
 #include "cm2xxx.h"
 #include "cm-regbits-24xx.h"
+#include "clockdomain.h"
 
 /* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */
 #define DPLL_AUTOIDLE_DISABLE				0x0
@@ -165,3 +167,87 @@  int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
 
 	return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
 }
+
+/* Clockdomain low-level functions */
+
+static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+	if (atomic_read(&clkdm->usecount) > 0)
+		_clkdm_add_autodeps(clkdm);
+
+	omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+				       clkdm->clktrctrl_mask);
+}
+
+static void omap2xxx_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+	omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+					clkdm->clktrctrl_mask);
+
+	if (atomic_read(&clkdm->usecount) > 0)
+		_clkdm_del_autodeps(clkdm);
+}
+
+static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+	bool hwsup = false;
+
+	if (!clkdm->clktrctrl_mask)
+		return 0;
+
+	hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+					      clkdm->clktrctrl_mask);
+
+	if (hwsup) {
+		/* Disable HW transitions when we are changing deps */
+		omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+						clkdm->clktrctrl_mask);
+		_clkdm_add_autodeps(clkdm);
+		omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+					       clkdm->clktrctrl_mask);
+	} else {
+		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+			omap2xxx_clkdm_wakeup(clkdm);
+	}
+
+	return 0;
+}
+
+static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+	bool hwsup = false;
+
+	if (!clkdm->clktrctrl_mask)
+		return 0;
+
+	hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+					      clkdm->clktrctrl_mask);
+
+	if (hwsup) {
+		/* Disable HW transitions when we are changing deps */
+		omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+						clkdm->clktrctrl_mask);
+		_clkdm_del_autodeps(clkdm);
+		omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+					       clkdm->clktrctrl_mask);
+	} else {
+		if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
+			omap2xxx_clkdm_sleep(clkdm);
+	}
+
+	return 0;
+}
+
+struct clkdm_ops omap2_clkdm_operations = {
+	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,
+	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep,
+	.clkdm_read_wkdep	= omap2_clkdm_read_wkdep,
+	.clkdm_clear_all_wkdeps	= omap2_clkdm_clear_all_wkdeps,
+	.clkdm_sleep		= omap2xxx_clkdm_sleep,
+	.clkdm_wakeup		= omap2xxx_clkdm_wakeup,
+	.clkdm_allow_idle	= omap2xxx_clkdm_allow_idle,
+	.clkdm_deny_idle	= omap2xxx_clkdm_deny_idle,
+	.clkdm_clk_enable	= omap2xxx_clkdm_clk_enable,
+	.clkdm_clk_disable	= omap2xxx_clkdm_clk_disable,
+};
+
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h
index 64df725..78c218c 100644
--- a/arch/arm/mach-omap2/cm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h
@@ -73,6 +73,18 @@  static inline u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module,
 	return v;
 }
 
+/* Read a CM register, AND it, and shift the result down to bit 0 */
+static inline u32 omap2_cm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
+{
+	u32 v;
+
+	v = omap2_cm_read_mod_reg(domain, idx);
+	v &= mask;
+	v >>= __ffs(mask);
+
+	return v;
+}
+
 static inline u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
 {
 	return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx);
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c
index 13f56ea..9b3bcff1 100644
--- a/arch/arm/mach-omap2/cm33xx.c
+++ b/arch/arm/mach-omap2/cm33xx.c
@@ -24,6 +24,7 @@ 
 
 #include <plat/common.h>
 
+#include "clockdomain.h"
 #include "cm.h"
 #include "cm33xx.h"
 #include "cm-regbits-34xx.h"
@@ -311,3 +312,58 @@  void am33xx_cm_module_disable(u16 inst, s16 cdoffs, u16 clkctrl_offs)
 	v &= ~AM33XX_MODULEMODE_MASK;
 	am33xx_cm_write_reg(v, inst, clkctrl_offs);
 }
+
+/*
+ * Clockdomain low-level functions
+ */
+
+static int am33xx_clkdm_sleep(struct clockdomain *clkdm)
+{
+	am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs);
+	return 0;
+}
+
+static int am33xx_clkdm_wakeup(struct clockdomain *clkdm)
+{
+	am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs);
+	return 0;
+}
+
+static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+	am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
+}
+
+static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+	am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
+}
+
+static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+		return am33xx_clkdm_wakeup(clkdm);
+
+	return 0;
+}
+
+static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+	bool hwsup = false;
+
+	hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
+
+	if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
+		am33xx_clkdm_sleep(clkdm);
+
+	return 0;
+}
+
+struct clkdm_ops am33xx_clkdm_operations = {
+	.clkdm_sleep		= am33xx_clkdm_sleep,
+	.clkdm_wakeup		= am33xx_clkdm_wakeup,
+	.clkdm_allow_idle	= am33xx_clkdm_allow_idle,
+	.clkdm_deny_idle	= am33xx_clkdm_deny_idle,
+	.clkdm_clk_enable	= am33xx_clkdm_clk_enable,
+	.clkdm_clk_disable	= am33xx_clkdm_clk_disable,
+};
diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c
index 075cabe..3493fef 100644
--- a/arch/arm/mach-omap2/cm3xxx.c
+++ b/arch/arm/mach-omap2/cm3xxx.c
@@ -19,9 +19,11 @@ 
 #include "soc.h"
 #include "iomap.h"
 #include "common.h"
+#include "prm2xxx_3xxx.h"
 #include "cm.h"
 #include "cm3xxx.h"
 #include "cm-regbits-34xx.h"
+#include "clockdomain.h"
 
 static const u8 omap3xxx_cm_idlest_offs[] = { CM_IDLEST1, CM_IDLEST2 };
 
@@ -104,6 +106,173 @@  int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
 	return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
 }
 
+/* Clockdomain low-level operations */
+
+static int omap3xxx_clkdm_add_sleepdep(struct clockdomain *clkdm1,
+				       struct clockdomain *clkdm2)
+{
+	omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
+				  clkdm1->pwrdm.ptr->prcm_offs,
+				  OMAP3430_CM_SLEEPDEP);
+	return 0;
+}
+
+static int omap3xxx_clkdm_del_sleepdep(struct clockdomain *clkdm1,
+				       struct clockdomain *clkdm2)
+{
+	omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
+				    clkdm1->pwrdm.ptr->prcm_offs,
+				    OMAP3430_CM_SLEEPDEP);
+	return 0;
+}
+
+static int omap3xxx_clkdm_read_sleepdep(struct clockdomain *clkdm1,
+					struct clockdomain *clkdm2)
+{
+	return omap2_cm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
+					    OMAP3430_CM_SLEEPDEP,
+					    (1 << clkdm2->dep_bit));
+}
+
+static int omap3xxx_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
+{
+	struct clkdm_dep *cd;
+	u32 mask = 0;
+
+	for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
+		if (!cd->clkdm)
+			continue; /* only happens if data is erroneous */
+
+		mask |= 1 << cd->clkdm->dep_bit;
+		atomic_set(&cd->sleepdep_usecount, 0);
+	}
+	omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
+				    OMAP3430_CM_SLEEPDEP);
+	return 0;
+}
+
+static int omap3xxx_clkdm_sleep(struct clockdomain *clkdm)
+{
+	omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
+				      clkdm->clktrctrl_mask);
+	return 0;
+}
+
+static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm)
+{
+	omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
+				       clkdm->clktrctrl_mask);
+	return 0;
+}
+
+static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+	if (atomic_read(&clkdm->usecount) > 0)
+		_clkdm_add_autodeps(clkdm);
+
+	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+				       clkdm->clktrctrl_mask);
+}
+
+static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+					clkdm->clktrctrl_mask);
+
+	if (atomic_read(&clkdm->usecount) > 0)
+		_clkdm_del_autodeps(clkdm);
+}
+
+static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+	bool hwsup = false;
+
+	if (!clkdm->clktrctrl_mask)
+		return 0;
+
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
+	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
+		omap3xxx_clkdm_wakeup(clkdm);
+		return 0;
+	}
+
+	hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+					      clkdm->clktrctrl_mask);
+
+	if (hwsup) {
+		/* Disable HW transitions when we are changing deps */
+		omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+						clkdm->clktrctrl_mask);
+		_clkdm_add_autodeps(clkdm);
+		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+					       clkdm->clktrctrl_mask);
+	} else {
+		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+			omap3xxx_clkdm_wakeup(clkdm);
+	}
+
+	return 0;
+}
+
+static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+	bool hwsup = false;
+
+	if (!clkdm->clktrctrl_mask)
+		return 0;
+
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+					       clkdm->clktrctrl_mask);
+		return 0;
+	}
+
+	hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+					      clkdm->clktrctrl_mask);
+
+	if (hwsup) {
+		/* Disable HW transitions when we are changing deps */
+		omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+						clkdm->clktrctrl_mask);
+		_clkdm_del_autodeps(clkdm);
+		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+					       clkdm->clktrctrl_mask);
+	} else {
+		if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
+			omap3xxx_clkdm_sleep(clkdm);
+	}
+
+	return 0;
+}
+
+struct clkdm_ops omap3_clkdm_operations = {
+	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,
+	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep,
+	.clkdm_read_wkdep	= omap2_clkdm_read_wkdep,
+	.clkdm_clear_all_wkdeps	= omap2_clkdm_clear_all_wkdeps,
+	.clkdm_add_sleepdep	= omap3xxx_clkdm_add_sleepdep,
+	.clkdm_del_sleepdep	= omap3xxx_clkdm_del_sleepdep,
+	.clkdm_read_sleepdep	= omap3xxx_clkdm_read_sleepdep,
+	.clkdm_clear_all_sleepdeps	= omap3xxx_clkdm_clear_all_sleepdeps,
+	.clkdm_sleep		= omap3xxx_clkdm_sleep,
+	.clkdm_wakeup		= omap3xxx_clkdm_wakeup,
+	.clkdm_allow_idle	= omap3xxx_clkdm_allow_idle,
+	.clkdm_deny_idle	= omap3xxx_clkdm_deny_idle,
+	.clkdm_clk_enable	= omap3xxx_clkdm_clk_enable,
+	.clkdm_clk_disable	= omap3xxx_clkdm_clk_disable,
+};
+
 /*
  * Context save/restore code - OMAP3 only
  */
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
index 1894015..9dca0ee 100644
--- a/arch/arm/mach-omap2/cminst44xx.c
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -22,6 +22,7 @@ 
 
 #include "iomap.h"
 #include "common.h"
+#include "clockdomain.h"
 #include "cm.h"
 #include "cm1_44xx.h"
 #include "cm2_44xx.h"
@@ -343,3 +344,141 @@  void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs,
 	v &= ~OMAP4430_MODULEMODE_MASK;
 	omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs);
 }
+
+/*
+ * Clockdomain low-level functions
+ */
+
+static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1,
+					struct clockdomain *clkdm2)
+{
+	omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit),
+				       clkdm1->prcm_partition,
+				       clkdm1->cm_inst, clkdm1->clkdm_offs +
+				       OMAP4_CM_STATICDEP);
+	return 0;
+}
+
+static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1,
+					struct clockdomain *clkdm2)
+{
+	omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit),
+					 clkdm1->prcm_partition,
+					 clkdm1->cm_inst, clkdm1->clkdm_offs +
+					 OMAP4_CM_STATICDEP);
+	return 0;
+}
+
+static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1,
+					struct clockdomain *clkdm2)
+{
+	return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition,
+					       clkdm1->cm_inst,
+					       clkdm1->clkdm_offs +
+					       OMAP4_CM_STATICDEP,
+					       (1 << clkdm2->dep_bit));
+}
+
+static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
+{
+	struct clkdm_dep *cd;
+	u32 mask = 0;
+
+	if (!clkdm->prcm_partition)
+		return 0;
+
+	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
+		if (!cd->clkdm)
+			continue; /* only happens if data is erroneous */
+
+		mask |= 1 << cd->clkdm->dep_bit;
+		atomic_set(&cd->wkdep_usecount, 0);
+	}
+
+	omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition,
+					 clkdm->cm_inst, clkdm->clkdm_offs +
+					 OMAP4_CM_STATICDEP);
+	return 0;
+}
+
+static int omap4_clkdm_sleep(struct clockdomain *clkdm)
+{
+	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
+					clkdm->cm_inst, clkdm->clkdm_offs);
+	return 0;
+}
+
+static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
+{
+	omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
+					clkdm->cm_inst, clkdm->clkdm_offs);
+	return 0;
+}
+
+static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
+					clkdm->cm_inst, clkdm->clkdm_offs);
+}
+
+static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+		omap4_clkdm_wakeup(clkdm);
+	else
+		omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
+						 clkdm->cm_inst,
+						 clkdm->clkdm_offs);
+}
+
+static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+		return omap4_clkdm_wakeup(clkdm);
+
+	return 0;
+}
+
+static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+	bool hwsup = false;
+
+	if (!clkdm->prcm_partition)
+		return 0;
+
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		omap4_clkdm_allow_idle(clkdm);
+		return 0;
+	}
+
+	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
+					clkdm->cm_inst, clkdm->clkdm_offs);
+
+	if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
+		omap4_clkdm_sleep(clkdm);
+
+	return 0;
+}
+
+struct clkdm_ops omap4_clkdm_operations = {
+	.clkdm_add_wkdep	= omap4_clkdm_add_wkup_sleep_dep,
+	.clkdm_del_wkdep	= omap4_clkdm_del_wkup_sleep_dep,
+	.clkdm_read_wkdep	= omap4_clkdm_read_wkup_sleep_dep,
+	.clkdm_clear_all_wkdeps	= omap4_clkdm_clear_all_wkup_sleep_deps,
+	.clkdm_add_sleepdep	= omap4_clkdm_add_wkup_sleep_dep,
+	.clkdm_del_sleepdep	= omap4_clkdm_del_wkup_sleep_dep,
+	.clkdm_read_sleepdep	= omap4_clkdm_read_wkup_sleep_dep,
+	.clkdm_clear_all_sleepdeps	= omap4_clkdm_clear_all_wkup_sleep_deps,
+	.clkdm_sleep		= omap4_clkdm_sleep,
+	.clkdm_wakeup		= omap4_clkdm_wakeup,
+	.clkdm_allow_idle	= omap4_clkdm_allow_idle,
+	.clkdm_deny_idle	= omap4_clkdm_deny_idle,
+	.clkdm_clk_enable	= omap4_clkdm_clk_enable,
+	.clkdm_clk_disable	= omap4_clkdm_clk_disable,
+};
diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c
index 14940c4..d08a2b9 100644
--- a/arch/arm/mach-omap2/prm2xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx.c
@@ -23,10 +23,27 @@ 
 
 #include "vp.h"
 #include "powerdomain.h"
+#include "clockdomain.h"
 #include "prm2xxx.h"
 #include "cm2xxx_3xxx.h"
 #include "prm-regbits-24xx.h"
 
+int omap2xxx_clkdm_sleep(struct clockdomain *clkdm)
+{
+	omap2_prm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
+				   clkdm->pwrdm.ptr->prcm_offs,
+				   OMAP2_PM_PWSTCTRL);
+	return 0;
+}
+
+int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm)
+{
+	omap2_prm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
+				     clkdm->pwrdm.ptr->prcm_offs,
+				     OMAP2_PM_PWSTCTRL);
+	return 0;
+}
+
 struct pwrdm_ops omap2_pwrdm_operations = {
 	.pwrdm_set_next_pwrst	= omap2_pwrdm_set_next_pwrst,
 	.pwrdm_read_next_pwrst	= omap2_pwrdm_read_next_pwrst,
diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h
index 6490e1a..6d76716 100644
--- a/arch/arm/mach-omap2/prm2xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx.h
@@ -119,4 +119,10 @@ 
 #define OMAP24XX_PRCM_IRQSTATUS_IVA			0x00f8
 #define OMAP24XX_PRCM_IRQENABLE_IVA			0x00fc
 
+#ifndef __ASSEMBLER__
+/* Function prototypes */
+extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm);
+extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm);
+#endif
+
 #endif
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index bdddf5c..30517f5 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -20,6 +20,7 @@ 
 #include "powerdomain.h"
 #include "prm2xxx_3xxx.h"
 #include "prm-regbits-24xx.h"
+#include "clockdomain.h"
 
 /**
  * omap2_prm_is_hardreset_asserted - read the HW reset line state of
@@ -208,3 +209,45 @@  int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm)
 	return 0;
 }
 
+int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
+			  struct clockdomain *clkdm2)
+{
+	omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
+				   clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+	return 0;
+}
+
+int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
+			  struct clockdomain *clkdm2)
+{
+	omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
+				     clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+	return 0;
+}
+
+int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
+			   struct clockdomain *clkdm2)
+{
+	return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
+					     PM_WKDEP, (1 << clkdm2->dep_bit));
+}
+
+int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
+{
+	struct clkdm_dep *cd;
+	u32 mask = 0;
+
+	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
+		if (!cd->clkdm)
+			continue; /* only happens if data is erroneous */
+
+		/* PRM accesses are slow, so minimize them */
+		mask |= 1 << cd->clkdm->dep_bit;
+		atomic_set(&cd->wkdep_usecount, 0);
+	}
+
+	omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
+				     PM_WKDEP);
+	return 0;
+}
+
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
index 706b026..22a405a 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -116,6 +116,14 @@  extern int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank);
 extern int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);
 extern int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm);
 
+extern int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
+				 struct clockdomain *clkdm2);
+extern int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
+				 struct clockdomain *clkdm2);
+extern int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
+				  struct clockdomain *clkdm2);
+extern int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm);
+
 #endif /* __ASSEMBLER */
 
 /*