aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArve Hjønnevåg <arve@android.com>2011-12-14 18:38:10 -0800
committerArve Hjønnevåg <arve@android.com>2011-12-14 18:38:10 -0800
commitf59af41fc01252a22f54411a06d6aa7d170909a2 (patch)
tree1af7215d6efeebcc319785967798e20019281e56
parentc572dd62d8b57b026c96def77f5d17b650a031e1 (diff)
parent7ee11a3df703bae7db9e85796aa266f82f2e5c51 (diff)
downloadkernel_samsung_espresso10-f59af41fc01252a22f54411a06d6aa7d170909a2.tar.gz
kernel_samsung_espresso10-f59af41fc01252a22f54411a06d6aa7d170909a2.tar.bz2
kernel_samsung_espresso10-f59af41fc01252a22f54411a06d6aa7d170909a2.zip
Merge branch 'linux-omap-3.0' into android-omap-3.0
-rw-r--r--arch/arm/mach-omap2/mux.c10
-rw-r--r--arch/arm/mach-omap2/mux.h5
-rw-r--r--arch/arm/mach-omap2/pm44xx.c25
-rw-r--r--drivers/gpio/gpio-omap.c29
4 files changed, 65 insertions, 4 deletions
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index a2ed524713e..c7d0b21c7f5 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -968,6 +968,16 @@ void omap_mux_set_gpio(u16 val, int gpio)
pr_err("%s: Could not set gpio%i\n", __func__, gpio);
}
+bool omap_mux_get_wakeupevent(struct omap_mux *m)
+{
+ u16 val;
+ if (IS_ERR_OR_NULL(m) || !cpu_is_omap44xx())
+ return false;
+
+ val = omap_mux_read(m->partition, m->reg_offset);
+ return val & OMAP_WAKEUP_EVENT;
+}
+
/* Has no locking, don't use on a pad that is remuxed (by hwmod or otherwise) */
bool omap_mux_get_wakeupenable(struct omap_mux *m)
{
diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
index 87bf022aa41..e631b5e82b9 100644
--- a/arch/arm/mach-omap2/mux.h
+++ b/arch/arm/mach-omap2/mux.h
@@ -286,6 +286,11 @@ int omap_mux_clear_wakeupenable(struct omap_mux *m);
*/
bool omap_mux_get_wakeupenable(struct omap_mux *m);
+/** omap_mux_get_wakeupevent() - get the wakeupevent bit from a mux struct
+ * @m: mux struct
+ */
+bool omap_mux_get_wakeupevent(struct omap_mux *m);
+
/**
* omap_mux_set_gpio() - set mux register value based on GPIO number
* @val: New mux register value
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 08597af99dd..b9e2bf1f574 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -117,13 +117,30 @@ void omap4_trigger_ioctrl(void)
/* Trigger WUCLKIN enable */
omap4_prminst_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, OMAP4430_WUCLK_CTRL_MASK,
OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET);
- omap_test_timeout(
- ((omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET)
- >> OMAP4430_WUCLK_STATUS_SHIFT) == 1),
- MAX_IOPAD_LATCH_TIME, i);
+ omap_test_timeout((((omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_DEVICE_INST,
+ OMAP4_PRM_IO_PMCTRL_OFFSET) &
+ OMAP4430_WUCLK_STATUS_MASK) >>
+ OMAP4430_WUCLK_STATUS_SHIFT) == 1),
+ MAX_IOPAD_LATCH_TIME, i);
+ if (i == MAX_IOPAD_LATCH_TIME)
+ pr_err("%s: Max IO latch time reached for WUCLKIN enable\n",
+ __func__);
+
/* Trigger WUCLKIN disable */
omap4_prminst_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0,
OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET);
+
+ /* Ensure this is cleared */
+ omap_test_timeout((((omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_DEVICE_INST,
+ OMAP4_PRM_IO_PMCTRL_OFFSET) &
+ OMAP4430_WUCLK_STATUS_MASK) >>
+ OMAP4430_WUCLK_STATUS_SHIFT) == 0),
+ MAX_IOPAD_LATCH_TIME, i);
+ if (i == MAX_IOPAD_LATCH_TIME)
+ pr_err("%s: Max IO latch time reached for WUCLKIN disable\n",
+ __func__);
return;
}
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 197e4db7271..561cb4f1f7e 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -29,6 +29,7 @@
#include <mach/gpio.h>
#include <asm/mach/irq.h>
#include <plat/omap-pm.h>
+#include <plat/usb.h> /* for omap4_trigger_ioctrl */
#include "../mux.h"
@@ -1320,6 +1321,19 @@ static void omap2_gpio_set_wakeupenables(struct gpio_bank *bank)
pad_wakeup = __raw_readl(bank->base + bank->regs->irqenable);
+ /*
+ * HACK: Ignore gpios that have multiple sources.
+ * Gpio 0-3 and 86 are special and may be used as gpio
+ * interrupts without being connected to the pad that
+ * mux points to.
+ */
+ if (cpu_is_omap44xx()) {
+ if (bank->id == 0)
+ pad_wakeup &= ~0xf;
+ if (bank->id == 2)
+ pad_wakeup &= ~BIT(22);
+ }
+
for_each_set_bit(i, &pad_wakeup, bank->width) {
if (!omap_mux_get_wakeupenable(bank->mux[i])) {
bank->context.pad_set_wakeupenable |= BIT(i);
@@ -1384,6 +1398,8 @@ static int omap_gpio_pm_runtime_resume(struct device *dev)
struct gpio_bank *bank = platform_get_drvdata(pdev);
u32 l = 0, gen, gen0, gen1;
int j;
+ unsigned long pad_wakeup;
+ int i;
for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
clk_enable(bank->dbck);
@@ -1407,6 +1423,11 @@ static int omap_gpio_pm_runtime_resume(struct device *dev)
l ^= bank->saved_datain;
l &= bank->enabled_non_wakeup_gpios;
+ pad_wakeup = bank->enabled_non_wakeup_gpios;
+ for_each_set_bit(i, &pad_wakeup, bank->width)
+ if (omap_mux_get_wakeupevent(bank->mux[i]))
+ l |= BIT(i);
+
/*
* No need to generate IRQs for the rising edge for gpio IRQs
* configured with falling edge only; and vice versa.
@@ -1561,6 +1582,14 @@ int omap2_gpio_prepare_for_idle(int off_mode, bool suspend)
if (omap2_gpio_set_edge_wakeup(bank, suspend))
ret = -EBUSY;
+ }
+
+ if (cpu_is_omap44xx())
+ omap4_trigger_ioctrl();
+
+ list_for_each_entry(bank, &omap_gpio_list, node) {
+ if (!bank->mod_usage)
+ continue;
if (bank->loses_context)
if (pm_runtime_put_sync_suspend(bank->dev) < 0)