From patchwork Mon Sep 10 10:38:48 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruslan Bilovol X-Patchwork-Id: 1431211 Return-Path: X-Original-To: patchwork-linux-omap@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id DE2A44025E for ; Mon, 10 Sep 2012 10:39:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755969Ab2IJKjH (ORCPT ); Mon, 10 Sep 2012 06:39:07 -0400 Received: from bear.ext.ti.com ([192.94.94.41]:59916 "EHLO bear.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755918Ab2IJKjG (ORCPT ); Mon, 10 Sep 2012 06:39:06 -0400 Received: from dlelxv30.itg.ti.com ([172.17.2.17]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id q8AAco3h027581; Mon, 10 Sep 2012 05:38:50 -0500 Received: from DLEE74.ent.ti.com (dlee74.ent.ti.com [157.170.170.8]) by dlelxv30.itg.ti.com (8.13.8/8.13.8) with ESMTP id q8AAconc031039; Mon, 10 Sep 2012 05:38:50 -0500 Received: from dlelxv22.itg.ti.com (172.17.1.197) by DLEE74.ent.ti.com (157.170.170.8) with Microsoft SMTP Server id 14.1.323.3; Mon, 10 Sep 2012 05:38:49 -0500 Received: from localhost (uglx0155540.ucm2.emeaucm.ext.ti.com [10.167.145.75]) by dlelxv22.itg.ti.com (8.13.8/8.13.8) with ESMTP id q8AAcm93023297; Mon, 10 Sep 2012 05:38:49 -0500 From: Ruslan Bilovol To: , , , , , , Subject: [PATCH] ARM: OMAP2+: mux: add support for PAD wakeup event handler Date: Mon, 10 Sep 2012 13:38:48 +0300 Message-ID: <1347273528-2056-1-git-send-email-ruslan.bilovol@ti.com> X-Mailer: git-send-email 1.7.1 MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org OMAP mux now parses active wakeup events from pad registers and calls corresponding handler, if handler is not registered - corresponding hwmod ISRs once a wakeup is detected. This is useful for cases when routing wakeups to corresponding hwmod ISRs complicates those ISRs handlers (for example, ISR handler may not know who the interrupt source is) Signed-off-by: Ruslan Bilovol --- arch/arm/mach-omap2/mux.c | 14 +++++++++-- arch/arm/mach-omap2/omap_hwmod.c | 29 ++++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/omap_hwmod.h | 4 +++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 9fe6829..2918638 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -372,6 +372,7 @@ static bool omap_hwmod_mux_scan_wakeups(struct omap_hwmod_mux_info *hmux, int i, irq; unsigned int val; u32 handled_irqs = 0; + bool retval = false; for (i = 0; i < hmux->nr_pads_dynamic; i++) { struct omap_device_pad *pad = hmux->pads_dynamic[i]; @@ -384,8 +385,15 @@ static bool omap_hwmod_mux_scan_wakeups(struct omap_hwmod_mux_info *hmux, if (!(val & OMAP_WAKEUP_EVENT)) continue; - if (!hmux->irqs) - return true; + if (hmux->wakeup_handler && hmux->wakeup_handler[i]) { + hmux->wakeup_handler[i](hmux); + continue; + } + + if (!hmux->irqs) { + retval = true; + continue; + } irq = hmux->irqs[i]; /* make sure we only handle each irq once */ @@ -397,7 +405,7 @@ static bool omap_hwmod_mux_scan_wakeups(struct omap_hwmod_mux_info *hmux, generic_handle_irq(mpu_irqs[irq].irq); } - return false; + return retval; } /** diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 6ca8e51..9a41d65 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -3656,6 +3656,35 @@ int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx) } /** + * omap_hwmod_pad_wakeup_handler - add wakeup handler for an I/O pad wakeup + * @oh: struct omap_hwmod * containing hwmod mux entries + * @pad_idx: array index in oh->mux of the hwmod mux entry to handle wakeup + * @wakeup_handler: the wakeup_handler function to trigger on wakeup + */ +int omap_hwmod_pad_wakeup_handler(struct omap_hwmod *oh, int pad_idx, + int (*wakeup_handler)(struct omap_hwmod_mux_info *hmux)) +{ + might_sleep(); + + if (!oh || !oh->mux || pad_idx < 0 || + pad_idx >= oh->mux->nr_pads_dynamic) + return -EINVAL; + + if (!oh->mux->wakeup_handler) { + /* XXX What frees this? */ + oh->mux->wakeup_handler = + kzalloc(sizeof(*(oh->mux->wakeup_handler)) * + oh->mux->nr_pads_dynamic, GFP_KERNEL); + + if (!oh->mux->wakeup_handler) + return -ENOMEM; + } + oh->mux->wakeup_handler[pad_idx] = wakeup_handler; + + return 0; +} + +/** * omap_hwmod_init - initialize the hwmod code * * Sets up some function pointers needed by the hwmod code to operate on the diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 6132972..5c2bcc7 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -110,6 +110,7 @@ struct omap_hwmod_mux_info { int nr_pads_dynamic; struct omap_device_pad **pads_dynamic; int *irqs; + int (**wakeup_handler)(struct omap_hwmod_mux_info *hmux); bool enabled; }; @@ -646,6 +647,9 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh); int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx); +int omap_hwmod_pad_wakeup_handler(struct omap_hwmod *oh, int pad_idx, + int (*wakeup_handler)(struct omap_hwmod_mux_info *hmux)); + extern void __init omap_hwmod_init(void); const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh);