summaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2/prm3xxx.c
diff options
context:
space:
mode:
authorTero Kristo <t-kristo@ti.com>2014-02-25 17:40:30 +0400
committerTero Kristo <t-kristo@ti.com>2014-07-04 18:02:00 +0400
commit0efc0f6ec2d6c6497e401df171705c5762f5a061 (patch)
treefbe9d4c8e36c64dcf2c36fed671ac53fe2e82e55 /arch/arm/mach-omap2/prm3xxx.c
parent7171511eaec5bf23fb06078f59784a3a0626b38f (diff)
downloadlinux-0efc0f6ec2d6c6497e401df171705c5762f5a061.tar.xz
ARM: OMAP3: PRM: move prcm wakeup helper to prm driver
Done in preparation to make the prm an individual driver. Signed-off-by: Tero Kristo <t-kristo@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/prm3xxx.c')
-rw-r--r--arch/arm/mach-omap2/prm3xxx.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c
index 4bd7a2dca8af..014ba70d2dfb 100644
--- a/arch/arm/mach-omap2/prm3xxx.c
+++ b/arch/arm/mach-omap2/prm3xxx.c
@@ -26,6 +26,8 @@
#include "prm2xxx_3xxx.h"
#include "cm2xxx_3xxx.h"
#include "prm-regbits-34xx.h"
+#include "cm3xxx.h"
+#include "cm-regbits-34xx.h"
static const struct omap_prcm_irq omap3_prcm_irqs[] = {
OMAP_PRCM_IRQ("wkup", 0, 0),
@@ -206,6 +208,57 @@ void omap3xxx_prm_restore_irqen(u32 *saved_mask)
}
/**
+ * omap3xxx_prm_clear_mod_irqs - clear wake-up events from PRCM interrupt
+ * @module: PRM module to clear wakeups from
+ * @regs: register set to clear, 1 or 3
+ * @ignore_bits: wakeup status bits to ignore
+ *
+ * The purpose of this function is to clear any wake-up events latched
+ * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
+ * may occur whilst attempting to clear a PM_WKST_x register and thus
+ * set another bit in this register. A while loop is used to ensure
+ * that any peripheral wake-up events occurring while attempting to
+ * clear the PM_WKST_x are detected and cleared.
+ */
+int omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits)
+{
+ u32 wkst, fclk, iclk, clken;
+ u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
+ u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
+ u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
+ u16 grpsel_off = (regs == 3) ?
+ OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
+ int c = 0;
+
+ wkst = omap2_prm_read_mod_reg(module, wkst_off);
+ wkst &= omap2_prm_read_mod_reg(module, grpsel_off);
+ wkst &= ~ignore_bits;
+ if (wkst) {
+ iclk = omap2_cm_read_mod_reg(module, iclk_off);
+ fclk = omap2_cm_read_mod_reg(module, fclk_off);
+ while (wkst) {
+ clken = wkst;
+ omap2_cm_set_mod_reg_bits(clken, module, iclk_off);
+ /*
+ * For USBHOST, we don't know whether HOST1 or
+ * HOST2 woke us up, so enable both f-clocks
+ */
+ if (module == OMAP3430ES2_USBHOST_MOD)
+ clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT;
+ omap2_cm_set_mod_reg_bits(clken, module, fclk_off);
+ omap2_prm_write_mod_reg(wkst, module, wkst_off);
+ wkst = omap2_prm_read_mod_reg(module, wkst_off);
+ wkst &= ~ignore_bits;
+ c++;
+ }
+ omap2_cm_write_mod_reg(iclk, module, iclk_off);
+ omap2_cm_write_mod_reg(fclk, module, fclk_off);
+ }
+
+ return c;
+}
+
+/**
* omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
*
* Clear any previously-latched I/O wakeup events and ensure that the