aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorTero Kristo <t-kristo@ti.com>2011-12-16 16:36:59 -0500
committerPaul Walmsley <paul@pwsan.com>2011-12-16 16:36:59 -0500
commitabc2d5456334d548328978d0b0d22c0e5d44cdcd (patch)
treee274951ab35883a19abbbdf2b497afe95dc88ae3 /arch/arm
parent13a3fe52f7525d7b327f1f6766826fe9668bd749 (diff)
ARM: OMAP: hwmod: add support for selecting mpu_irq for each wakeup pad
By default all registered pads will trigger mpu_irqs[0]. Now there is an API for selecting used mpu_irq on pad basis, which can be used to trigger different irq handlers for different pads in the same hwmod. Each pad that requires its interrupt to be re-routed this way must have a separate call to omap_hwmod_pad_route_irq(hwmod, pad, irq). Signed-off-by: Tero Kristo <t-kristo@ti.com> Acked-by: Tony Lindgren <tony@atomide.com> Tested-by: Kevin Hilman <khilman@ti.com> Reviewed-by: Kevin Hilman <khilman@ti.com> [paul@pwsan.com: moved fn to omap_hwmod.c; separated fn from mux scan_wakeups changes; added kerneldoc] Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c55
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h2
2 files changed, 57 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 21ffd8a831c3..7ea3df517d2b 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -136,6 +136,7 @@
136#include <linux/list.h> 136#include <linux/list.h>
137#include <linux/mutex.h> 137#include <linux/mutex.h>
138#include <linux/spinlock.h> 138#include <linux/spinlock.h>
139#include <linux/slab.h>
139 140
140#include <plat/common.h> 141#include <plat/common.h>
141#include <plat/cpu.h> 142#include <plat/cpu.h>
@@ -2709,3 +2710,57 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
2709 2710
2710 return 0; 2711 return 0;
2711} 2712}
2713
2714/**
2715 * omap_hwmod_pad_route_irq - route an I/O pad wakeup to a particular MPU IRQ
2716 * @oh: struct omap_hwmod * containing hwmod mux entries
2717 * @pad_idx: array index in oh->mux of the hwmod mux entry to route wakeup
2718 * @irq_idx: the hwmod mpu_irqs array index of the IRQ to trigger on wakeup
2719 *
2720 * When an I/O pad wakeup arrives for the dynamic or wakeup hwmod mux
2721 * entry number @pad_idx for the hwmod @oh, trigger the interrupt
2722 * service routine for the hwmod's mpu_irqs array index @irq_idx. If
2723 * this function is not called for a given pad_idx, then the ISR
2724 * associated with @oh's first MPU IRQ will be triggered when an I/O
2725 * pad wakeup occurs on that pad. Note that @pad_idx is the index of
2726 * the _dynamic or wakeup_ entry: if there are other entries not
2727 * marked with OMAP_DEVICE_PAD_WAKEUP or OMAP_DEVICE_PAD_REMUX, these
2728 * entries are NOT COUNTED in the dynamic pad index. This function
2729 * must be called separately for each pad that requires its interrupt
2730 * to be re-routed this way. Returns -EINVAL if there is an argument
2731 * problem or if @oh does not have hwmod mux entries or MPU IRQs;
2732 * returns -ENOMEM if memory cannot be allocated; or 0 upon success.
2733 *
2734 * XXX This function interface is fragile. Rather than using array
2735 * indexes, which are subject to unpredictable change, it should be
2736 * using hwmod IRQ names, and some other stable key for the hwmod mux
2737 * pad records.
2738 */
2739int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx)
2740{
2741 int nr_irqs;
2742
2743 might_sleep();
2744
2745 if (!oh || !oh->mux || !oh->mpu_irqs || pad_idx < 0 ||
2746 pad_idx >= oh->mux->nr_pads_dynamic)
2747 return -EINVAL;
2748
2749 /* Check the number of available mpu_irqs */
2750 for (nr_irqs = 0; oh->mpu_irqs[nr_irqs].irq >= 0; nr_irqs++)
2751 ;
2752
2753 if (irq_idx >= nr_irqs)
2754 return -EINVAL;
2755
2756 if (!oh->mux->irqs) {
2757 /* XXX What frees this? */
2758 oh->mux->irqs = kzalloc(sizeof(int) * oh->mux->nr_pads_dynamic,
2759 GFP_KERNEL);
2760 if (!oh->mux->irqs)
2761 return -ENOMEM;
2762 }
2763 oh->mux->irqs[pad_idx] = irq_idx;
2764
2765 return 0;
2766}
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index f7054926f4e7..ef4bf313fe74 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -605,6 +605,8 @@ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
605 605
606int omap_hwmod_no_setup_reset(struct omap_hwmod *oh); 606int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
607 607
608int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx);
609
608/* 610/*
609 * Chip variant-specific hwmod init routines - XXX should be converted 611 * Chip variant-specific hwmod init routines - XXX should be converted
610 * to use initcalls once the initial boot ordering is straightened out 612 * to use initcalls once the initial boot ordering is straightened out