summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Wylder <jwylder@motorola.com>2014-05-26 08:48:21 -0500
committerJames Wylder <jwylder@motorola.com>2014-05-27 20:28:40 +0000
commitdc20078f157d09c98a4daa26f2cdec578a96a1d3 (patch)
tree26afd16eaabb0579568b0f7724b13af30c795f83
parent26ab718ff0710b300cfa8c87443b7210bd6ef967 (diff)
downloadolio-linux-3.10-dc20078f157d09c98a4daa26f2cdec578a96a1d3.tar.xz
olio-linux-3.10-dc20078f157d09c98a4daa26f2cdec578a96a1d3.zip
IKXCLOCK-1705 arm: omap2: padwkup interrupt handler
This change replaces the previous, of signaling an interrupt for the gpio bank with a pure software call. Change-Id: I3380acf3745a9ff823cd3a0028f8b7be9190f20f Signed-off-by: Jim Wylder <jwylder@motorola.com>
-rw-r--r--Documentation/devicetree/bindings/ti-pad_wkup.txt17
-rw-r--r--arch/arm/configs/minnow_defconfig1
-rw-r--r--arch/arm/mach-omap2/Kconfig12
-rw-r--r--arch/arm/mach-omap2/Makefile2
-rw-r--r--arch/arm/mach-omap2/pad_wkup.c140
-rw-r--r--arch/arm/mach-omap2/pad_wkup.h5
-rw-r--r--arch/arm/mach-omap2/pm34xx.c5
7 files changed, 180 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/ti-pad_wkup.txt b/Documentation/devicetree/bindings/ti-pad_wkup.txt
new file mode 100644
index 00000000000..19df431be3a
--- /dev/null
+++ b/Documentation/devicetree/bindings/ti-pad_wkup.txt
@@ -0,0 +1,17 @@
+OMAP3 pad wkup generator
+
+Functionality to map omap pad wkup status to irq events;
+
+Required properties:
+- ti,pad_irq Maps a pad offset to a IRQ
+ on omap, the irqs are calculated as follows:
+ for the 96 intc IRQs
+ irq = 16 + irq_offset (from TRM sec 12.3.2)
+ for a gpio IRQ (banks numbered 1 to 6
+ irq = 16 + 96 + (gpio_bank - 1) * 32
+
+ ti,pad_irq = <0x008e 171>, /* m4sensor hub */
+ <0x00e6 211>, /* touch */
+ <0x013c 252>, /* battery */
+ <0x0140 254>, /* USB */
+ <0x01a2 288>; /* gpio-charger */
diff --git a/arch/arm/configs/minnow_defconfig b/arch/arm/configs/minnow_defconfig
index 478dad042d7..6b8e6d91772 100644
--- a/arch/arm/configs/minnow_defconfig
+++ b/arch/arm/configs/minnow_defconfig
@@ -351,6 +351,7 @@ CONFIG_OMAP_PACKAGE_CBP=y
CONFIG_MACH_MINNOW=y
# CONFIG_OMAP3_EMU is not set
# CONFIG_OMAP3_SDRC_AC_TIMING is not set
+# CONFIG_OMAP3_PAD_WKUP_IO is not set
CONFIG_DISABLE_OMAP_ERRATA_i583=y
# CONFIG_ARCH_SOCFPGA is not set
# CONFIG_PLAT_SPEAR is not set
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 281a0a7614a..0168b07ce0c 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -420,8 +420,18 @@ config OMAP3_SDRC_AC_TIMING
wish to say no. Selecting yes without understanding what is
going on could result in system crashes;
+
+config OMAP3_PAD_WKUP_IO
+ bool "Enable Generation of IRQ from pad status"
+ depends on ARCH_OMAP3
+ default n
+ help
+ For offmode, gpio (and possibly other) domains can wakeup the system
+ but will not retain their irq status internally. This function generates
+ the configured irq on each time the io irq (315) fires.
+
config DISABLE_OMAP_ERRATA_i583
- bool "Override errata i583
+ bool "Override errata i583"
depends on ARCH_OMAP3
default n
help
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 731e039bef0..ff5c4457325 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -8,7 +8,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
# Common support
obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o gpmc.o timer.o pm.o \
common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \
- omap_device.o sram.o
+ omap_device.o sram.o pad_wkup.o
omap-2-3-common = irq.o
hwmod-common = omap_hwmod.o omap_hwmod_reset.o \
diff --git a/arch/arm/mach-omap2/pad_wkup.c b/arch/arm/mach-omap2/pad_wkup.c
new file mode 100644
index 00000000000..6342ca91106
--- /dev/null
+++ b/arch/arm/mach-omap2/pad_wkup.c
@@ -0,0 +1,140 @@
+/*
+ * OMAP3 Pad Wakeup Handler
+ *
+ * Copyright (C) 2014-2008 Motorola, LLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/err.h>
+
+#include "soc.h"
+#include "common.h"
+#include "mux34xx.h"
+#include "prm3xxx.h"
+#include "iomap.h"
+
+#include "pad_wkup.h"
+
+#define WAKEUPEVENT 0x8000
+struct offmode_wkup {
+ struct list_head node;
+ u32 irq;
+ u32 pad;
+ u32 pad_shift;
+};
+LIST_HEAD(offmode_wkup_list);
+
+static void omap_register_pad_wkup(struct device *dev, u32 pad, u32 irq)
+{
+ struct offmode_wkup *wkup;
+
+ pr_info("register pad (0x%04x, %u)\n", pad, irq);
+
+ wkup = devm_kzalloc(dev, sizeof(struct offmode_wkup), GFP_KERNEL);
+ if (wkup) {
+ wkup->irq = irq;
+ wkup->pad = pad & 0xFFFFFFFC;
+ wkup->pad_shift = pad % 4 ? 16 : 0;
+ list_add_tail(&wkup->node, &offmode_wkup_list);
+ }
+}
+
+static inline int is_pad_wkup(const struct offmode_wkup *wkup)
+{
+ int pad = __raw_readl(
+ OMAP2_L4_IO_ADDRESS(OMAP3_CONTROL_PADCONF_MUX_PBASE)+ wkup->pad);
+ pad = pad >> wkup->pad_shift;
+
+ return (pad & WAKEUPEVENT) ? 1 : 0;
+}
+
+void prcm_handle_pad_wkup(void)
+{
+ struct offmode_wkup *wkup;
+
+ list_for_each_entry(wkup, &offmode_wkup_list, node) {
+ if (is_pad_wkup(wkup)) {
+ pr_info("%s IRQ = %d\n", __func__, wkup->irq);
+ generic_handle_irq(wkup->irq);
+ }
+ }
+}
+
+#ifdef CONFIG_OMAP3_PAD_WKUP_IO
+static irqreturn_t omap3_pad_wkup_handle_irq(int irq, void *unused)
+{
+ prcm_handle_pad_wkup();
+
+ return IRQ_HANDLED;
+}
+#endif
+
+static int omap3_pad_wkup_probe(struct platform_device *pdev)
+{
+ struct device_node *node = pdev->dev.of_node;
+ int ndx = 0;
+ u32 pad, irq;
+ int ret = 0;
+
+ if (!node)
+ return -ENODEV;
+
+ do {
+ if (of_property_read_u32_index(node, "ti,pad_irq", ndx, &pad))
+ break;
+ ndx++;
+ if (of_property_read_u32_index(node, "ti,pad_irq", ndx, &irq))
+ break;
+ ndx++;
+ omap_register_pad_wkup(&pdev->dev, pad, irq);
+ } while (1);
+
+#ifdef CONFIG_OMAP3_PAD_WKUP_IO
+ if (ndx > 1) {
+ dev_info(&pdev->dev, "request pad_wkup_io\n");
+ ret = request_irq(omap_prcm_event_to_irq("io"),
+ omap3_pad_wkup_handle_irq,
+ IRQF_SHARED | IRQF_NO_SUSPEND,
+ "pad_wkup_io", &pdev->dev);
+
+ if (ret)
+ pr_warning("wkup: Failed to setup pad_wkup_io irq %d\n",
+ ret);
+ }
+#endif
+
+ return ret;
+}
+
+static int omap3_pad_wkup_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static const struct of_device_id omap3_pad_wkup_table[] = {
+ { .compatible = "ti,pad-wkup", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, omap3_pad_wkup_table);
+
+static struct platform_driver omap3_pad_wkup_driver = {
+ .probe = omap3_pad_wkup_probe,
+ .remove = omap3_pad_wkup_remove,
+ .driver = {
+ .name = "omap3_pad_wkup",
+ .owner = THIS_MODULE,
+ .of_match_table = omap3_pad_wkup_table,
+ },
+};
+
+static int __init omap_pad_wkup_init(void)
+{
+ return platform_driver_register(&omap3_pad_wkup_driver);
+}
+omap_late_initcall(omap_pad_wkup_init);
diff --git a/arch/arm/mach-omap2/pad_wkup.h b/arch/arm/mach-omap2/pad_wkup.h
new file mode 100644
index 00000000000..9a3b402e411
--- /dev/null
+++ b/arch/arm/mach-omap2/pad_wkup.h
@@ -0,0 +1,5 @@
+#ifndef __OMAP_PADWKUP_H__
+#define __OMAP_PADWKUP_H__
+
+extern void prcm_handle_pad_wkup(void);
+#endif
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 46182a5293d..939e92c11db 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -54,6 +54,8 @@
#include "pm-debug-regs.h"
#include "iomap.h"
+#include "pad_wkup.h"
+
/* pm34xx errata defined in pm.h */
u16 pm34xx_errata;
bool suspend_debug;
@@ -375,6 +377,7 @@ void omap_sram_idle(bool in_suspend)
/* PER */
if (per_next_state < PWRDM_POWER_ON)
omap2_gpio_resume_after_idle(in_suspend);
+
}
static void omap3_pm_idle(void)
@@ -412,6 +415,8 @@ static int omap3_pm_suspend(void)
omap_sram_idle(true);
+ prcm_handle_pad_wkup();
+
restore:
/* Restore next_pwrsts */
list_for_each_entry(pwrst, &pwrst_list, node) {