Message ID | 20121015230545.18306.36852.stgit@dusk.lan (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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 */ > > /* > >
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 --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 */ /*
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