From patchwork Fri Oct 11 16:15:40 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tero Kristo X-Patchwork-Id: 3025251 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id CD013BF924 for ; Fri, 11 Oct 2013 16:27:25 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9DE0B202A1 for ; Fri, 11 Oct 2013 16:27:24 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 61B1E20279 for ; Fri, 11 Oct 2013 16:27:23 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VUfY7-0005i9-3E; Fri, 11 Oct 2013 16:26:47 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VUfPh-0007sN-NQ; Fri, 11 Oct 2013 16:18:05 +0000 Received: from comal.ext.ti.com ([198.47.26.152]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VUfOE-0007fl-2l for linux-arm-kernel@lists.infradead.org; Fri, 11 Oct 2013 16:16:39 +0000 Received: from dflxv15.itg.ti.com ([128.247.5.124]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id r9BGGDvK027474; Fri, 11 Oct 2013 11:16:13 -0500 Received: from DFLE72.ent.ti.com (dfle72.ent.ti.com [128.247.5.109]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id r9BGGDTC009859; Fri, 11 Oct 2013 11:16:13 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE72.ent.ti.com (128.247.5.109) with Microsoft SMTP Server id 14.2.342.3; Fri, 11 Oct 2013 11:16:13 -0500 Received: from sokoban.tieu.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id r9BGFnET005990; Fri, 11 Oct 2013 11:16:11 -0500 From: Tero Kristo To: , , , Subject: [PATCH 10/11] ARM: OMAP3: PRM: move PRCM interrupt handler helper to PRM driver Date: Fri, 11 Oct 2013 19:15:40 +0300 Message-ID: <1381508141-15244-11-git-send-email-t-kristo@ti.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1381508141-15244-1-git-send-email-t-kristo@ti.com> References: <1381508141-15244-1-git-send-email-t-kristo@ti.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131011_121634_417303_E1CE361E X-CRM114-Status: GOOD ( 19.20 ) X-Spam-Score: -7.1 (-------) Cc: linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP PM core code should not directly access PRM registers. Thus move the PRCM interrupt handler helper out of the core PM code to PRM driver, and use the new API from the core. Signed-off-by: Tero Kristo --- arch/arm/mach-omap2/pm34xx.c | 65 ++------------------------------- arch/arm/mach-omap2/prm3xxx.c | 79 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/prm3xxx.h | 2 ++ 3 files changed, 83 insertions(+), 63 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 4320541..6a5302a 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -132,60 +132,11 @@ 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 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 = omap3_cm_read_module_clken(module, regs, false); - fclk = omap3_cm_read_module_clken(module, regs, true); - while (wkst) { - clken = wkst; - omap3_cm_write_module_clken(module, regs, false, - iclk | clken); - /* - * 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; - omap3_cm_write_module_clken(module, regs, true, - fclk | clken); - omap2_prm_write_mod_reg(wkst, module, wkst_off); - wkst = omap2_prm_read_mod_reg(module, wkst_off); - wkst &= ~ignore_bits; - c++; - } - omap3_cm_write_module_clken(module, regs, false, iclk); - omap3_cm_write_module_clken(module, regs, true, fclk); - } - - 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 = omap3_prcm_clear_io_irq(); return c ? IRQ_HANDLED : IRQ_NONE; } @@ -194,19 +145,7 @@ static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused) { int c; - /* - * Clear all except ST_IO and ST_IO_CHAIN for wkup module, - * 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); - 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 = omap3_prcm_clear_wkup_irq(); return c ? IRQ_HANDLED : IRQ_NONE; } diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c index 3813e9a..50177e9 100644 --- a/arch/arm/mach-omap2/prm3xxx.c +++ b/arch/arm/mach-omap2/prm3xxx.c @@ -27,6 +27,7 @@ #include "cm2xxx_3xxx.h" #include "prm-regbits-34xx.h" #include "cm3xxx.h" +#include "cm-regbits-34xx.h" #include "control.h" static const struct omap_prcm_irq omap3_prcm_irqs[] = { @@ -399,6 +400,84 @@ struct pwrdm_ops omap3_pwrdm_operations = { }; /** + * omap3_prcm_clear_mod_irqs: PRCM interrupt handler helper function + * @module: module offset + * @regs: register index + * @ignore_bits: bit-mask to ignore while checking wakeup status + * + * 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 omap3_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 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 = omap3_cm_read_module_clken(module, regs, false); + fclk = omap3_cm_read_module_clken(module, regs, true); + while (wkst) { + clken = wkst; + omap3_cm_write_module_clken(module, regs, false, + iclk | clken); + /* + * 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; + omap3_cm_write_module_clken(module, regs, true, + fclk | clken); + omap2_prm_write_mod_reg(wkst, module, wkst_off); + wkst = omap2_prm_read_mod_reg(module, wkst_off); + wkst &= ~ignore_bits; + c++; + } + omap3_cm_write_module_clken(module, regs, false, iclk); + omap3_cm_write_module_clken(module, regs, true, fclk); + } + + return c; +} + +int omap3_prcm_clear_io_irq(void) +{ + return omap3_prcm_clear_mod_irqs(WKUP_MOD, 1, + ~(OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK)); +} + +int omap3_prcm_clear_wkup_irq(void) +{ + int c; + + /* + * Clear all except ST_IO and ST_IO_CHAIN for wkup module, + * these are handled in a separate handler to avoid acking + * IO events before parsing in mux code + */ + c = omap3_prcm_clear_mod_irqs(WKUP_MOD, 1, + OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK); + c += omap3_prcm_clear_mod_irqs(CORE_MOD, 1, 0); + c += omap3_prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0); + if (omap_rev() > OMAP3430_REV_ES1_0) { + c += omap3_prcm_clear_mod_irqs(CORE_MOD, 3, 0); + c += omap3_prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0); + } + + return c; +} + +/** * omap3_prcm_force_idle_iva: ensure IVA is in idle so it can be put into * retention * diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h index 1befb23..c7d1616 100644 --- a/arch/arm/mach-omap2/prm3xxx.h +++ b/arch/arm/mach-omap2/prm3xxx.h @@ -154,6 +154,8 @@ extern void omap3xxx_prm_restore_irqen(u32 *saved_mask); extern void omap3xxx_prm_dpll3_reset(void); +extern int omap3_prcm_clear_io_irq(void); +extern int omap3_prcm_clear_wkup_irq(void); extern void omap3_prm_force_idle_iva(void); extern int __init omap3xxx_prm_init(void);