summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/cminst44xx.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-12 11:45:16 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-12 11:45:16 -0800
commit8287361abca36504da813638310d2547469283eb (patch)
tree8d98e9a910885efdb09ae5390a3ae44040557e2f /arch/arm/mach-omap2/cminst44xx.c
parent2989950cea13711f0cc573c26cde8fe08a36be03 (diff)
parent8556650dd3370a927217f16444aac5cc0c71e61b (diff)
downloadlinux-8287361abca36504da813638310d2547469283eb.tar.gz
linux-8287361abca36504da813638310d2547469283eb.tar.bz2
linux-8287361abca36504da813638310d2547469283eb.zip
Merge tag 'headers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC Header cleanups from Olof Johansson: "This is a collection of header file cleanups, mostly for OMAP and AT91, that keeps moving the platforms in the direction of multiplatform by removing the need for mach-dependent header files used in drivers and other places." Fix up mostly trivial conflicts as per Olof. * tag 'headers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (106 commits) ARM: OMAP2+: Move iommu/iovmm headers to platform_data ARM: OMAP2+: Make some definitions local ARM: OMAP2+: Move iommu2 to drivers/iommu/omap-iommu2.c ARM: OMAP2+: Move plat/iovmm.h to include/linux/omap-iommu.h ARM: OMAP2+: Move iopgtable header to drivers/iommu/ ARM: OMAP: Merge iommu2.h into iommu.h atmel: move ATMEL_MAX_UART to platform_data/atmel.h ARM: OMAP: Remove omap_init_consistent_dma_size() arm: at91: move at91rm9200 rtc header in drivers/rtc arm: at91: move reset controller header to arm/arm/mach-at91 arm: at91: move pit define to the driver arm: at91: move at91_shdwc.h to arch/arm/mach-at91 arm: at91: move board header to arch/arm/mach-at91 arn: at91: move at91_tc.h to arch/arm/mach-at91 arm: at91 move at91_aic.h to arch/arm/mach-at91 arm: at91 move board.h to arch/arm/mach-at91 arm: at91: move platfarm_data to include/linux/platform_data/atmel.h arm: at91: drop machine defconfig ARM: OMAP: Remove NEED_MACH_GPIO_H ARM: OMAP: Remove unnecessary mach and plat includes ...
Diffstat (limited to 'arch/arm/mach-omap2/cminst44xx.c')
-rw-r--r--arch/arm/mach-omap2/cminst44xx.c142
1 files changed, 141 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
index 1894015ff04b..7f9a464f01e9 100644
--- a/arch/arm/mach-omap2/cminst44xx.c
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -2,8 +2,9 @@
* OMAP4 CM instance functions
*
* Copyright (C) 2009 Nokia Corporation
- * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2008-2011 Texas Instruments, Inc.
* 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
@@ -22,6 +23,7 @@
#include "iomap.h"
#include "common.h"
+#include "clockdomain.h"
#include "cm.h"
#include "cm1_44xx.h"
#include "cm2_44xx.h"
@@ -343,3 +345,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,
+};