[PATCH 5/5] ARM: OMAP2/3: clockdomain/PRM/CM: move the low-level clockdomain functions into PRM/CM
Rajendra Nayak
rnayak at ti.com
Thu Oct 18 03:08:36 EDT 2012
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 at pwsan.com>
> Cc: Rajendra Nayak <rnayak at ti.com>
Acked-by: Rajendra Nayak <rnayak at ti.com>
> Cc: Vaibhav Hiremath <hvaibhav at 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 at 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 at 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 at 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 */
>
> /*
>
>
More information about the linux-arm-kernel
mailing list