From mboxrd@z Thu Jan 1 00:00:00 1970 From: t-kristo@ti.com (Tero Kristo) Date: Mon, 12 Dec 2011 20:15:30 +0200 Subject: [PATCHv11 5/8] ARM: OMAP2+: mux: add support for PAD wakeup interrupts In-Reply-To: <1323713733-13115-1-git-send-email-t-kristo@ti.com> References: <1323713733-13115-1-git-send-email-t-kristo@ti.com> Message-ID: <1323713733-13115-6-git-send-email-t-kristo@ti.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org OMAP mux now parses active wakeup events from pad registers and calls corresponding hwmod ISRs once a wakeup is detected. This is accomplished by registering an interrupt handler for PRCM IO event, which is raised every time the HW detects wakeups. Signed-off-by: Tero Kristo --- arch/arm/mach-omap2/mux.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 38 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 5f15ab8..0d1962e 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include @@ -39,6 +41,7 @@ #include "control.h" #include "mux.h" +#include "prcm-common.h" #define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ #define OMAP_MUX_BASE_SZ 0x5ca @@ -381,6 +384,33 @@ bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux) return ret; } +/** + * omap_hwmod_mux_handle_irq - Process wakeup events for a single hwmod + * + * Checks a single hwmod for every wakeup capable pad to see if there is an + * active wakeup event. If this is the case, call the corresponding ISR. + */ +static int _omap_hwmod_mux_handle_irq(struct omap_hwmod *oh, void *data) +{ + if (!oh->mux || !oh->mux->enabled) + return 0; + if (omap_hwmod_mux_get_wake_status(oh->mux)) + generic_handle_irq(oh->mpu_irqs[0].irq); + return 0; +} + +/** + * omap_hwmod_mux_handle_irq - Process pad wakeup irqs. + * + * Calls a function for each registered omap_hwmod to check + * pad wakeup statuses. + */ +static irqreturn_t omap_hwmod_mux_handle_irq(int irq, void *unused) +{ + omap_hwmod_for_each(_omap_hwmod_mux_handle_irq, NULL); + return IRQ_HANDLED; +} + /* Assumes the calling function takes care of locking */ void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state) { @@ -745,6 +775,7 @@ static void __init omap_mux_free_names(struct omap_mux *m) static int __init omap_mux_late_init(void) { struct omap_mux_partition *partition; + int ret; list_for_each_entry(partition, &mux_partitions, node) { struct omap_mux_entry *e, *tmp; @@ -765,6 +796,13 @@ static int __init omap_mux_late_init(void) } } + ret = request_irq(omap_prcm_event_to_irq("io"), + omap_hwmod_mux_handle_irq, IRQF_SHARED | IRQF_NO_SUSPEND, + "hwmod_io", omap_mux_late_init); + + if (ret) + printk(KERN_WARNING "Failed to setup hwmod io irq %d\n", ret); + omap_mux_dbg_init(); return 0; -- 1.7.4.1