Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0efc0f6e authored by Tero Kristo's avatar Tero Kristo
Browse files

ARM: OMAP3: PRM: move prcm wakeup helper to prm driver



Done in preparation to make the prm an individual driver.

Signed-off-by: default avatarTero Kristo <t-kristo@ti.com>
parent 7171511e
Loading
Loading
Loading
Loading
+10 −56
Original line number Diff line number Diff line
@@ -133,60 +133,13 @@ static void omap3_save_secure_ram_context(void)
	}
}

/*
 * PRCM Interrupt Handler Helper Function
 *
 * 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.
 */
static int prcm_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;
}

static irqreturn_t _prcm_int_handle_io(int irq, void *unused)
{
	int c;

	c = prcm_clear_mod_irqs(WKUP_MOD, 1,
		~(OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK));
	c = omap3xxx_prm_clear_mod_irqs(WKUP_MOD, 1,
					~(OMAP3430_ST_IO_MASK |
					  OMAP3430_ST_IO_CHAIN_MASK));

	return c ? IRQ_HANDLED : IRQ_NONE;
}
@@ -200,13 +153,14 @@ static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused)
	 * these are handled in a separate handler to avoid acking
	 * IO events before parsing in mux code
	 */
	c = prcm_clear_mod_irqs(WKUP_MOD, 1,
		OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK);
	c += prcm_clear_mod_irqs(CORE_MOD, 1, 0);
	c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0);
	c = omap3xxx_prm_clear_mod_irqs(WKUP_MOD, 1,
					OMAP3430_ST_IO_MASK |
					OMAP3430_ST_IO_CHAIN_MASK);
	c += omap3xxx_prm_clear_mod_irqs(CORE_MOD, 1, 0);
	c += omap3xxx_prm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0);
	if (omap_rev() > OMAP3430_REV_ES1_0) {
		c += prcm_clear_mod_irqs(CORE_MOD, 3, 0);
		c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0);
		c += omap3xxx_prm_clear_mod_irqs(CORE_MOD, 3, 0);
		c += omap3xxx_prm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0);
	}

	return c ? IRQ_HANDLED : IRQ_NONE;
+53 −0
Original line number Diff line number Diff line
@@ -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),
@@ -205,6 +207,57 @@ void omap3xxx_prm_restore_irqen(u32 *saved_mask)
				OMAP3_PRM_IRQENABLE_MPU_OFFSET);
}

/**
 * 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
 *
+1 −0
Original line number Diff line number Diff line
@@ -162,6 +162,7 @@ extern void omap3xxx_prm_dpll3_reset(void);

extern int __init omap3xxx_prm_init(void);
extern u32 omap3xxx_prm_get_reset_sources(void);
int omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits);

#endif /* __ASSEMBLER */