From: David Brownell <david-b@pacbell.net>
To: Tony Lindgren <tony@atomide.com>
Cc: linux-omap-open-source@linux.omap.com
Subject: Re: [patch 2.6.17-rc4-omap-git] rtc-omap, rtc framework driver
Date: Wed, 30 Aug 2006 01:22:13 -0700 [thread overview]
Message-ID: <200608300122.14254.david-b@pacbell.net> (raw)
In-Reply-To: <20060830075733.GH27668@atomide.com>
[-- Attachment #1: Type: text/plain, Size: 628 bytes --]
On Wednesday 30 August 2006 12:57 am, Tony Lindgren wrote:
> * David Brownell <david-b@pacbell.net> [060829 22:52]:
> > On Tuesday 29 August 2006 7:34 am, Tony Lindgren wrote:
> > >
> > > Sounds like it should be capable of waking up the system if 32KHz clock
> > > is on and the wake-up events are configured properly.
> >
> > Yes. I had more of a look at things, and have a patch (yet to be tested)
> > that should let many more things be wakeup event sources. MPUIO irqs,
> > GPIOs not in the first bank, non-MPUI/GPIO irqs (like RTC), etc.
>
> Cool.
hmm, not sure when I'll have a chance to test it, so here it is...
[-- Attachment #2: wake.patch --]
[-- Type: text/x-diff, Size: 8747 bytes --]
Handle wakeup irqs more correctly and completely ... the set of wakeup
events is dynmically specified, not statically, and any IRQ is eligible.
- (PLATFORM) Add/use MPUIO/ARMIO wakeup event handling, as for GPIO.
- (PLATFORM) Enabling a GPIO or MPUIO irq as a wakeup event source
automatically enables its parent MPU L1 or L2 IRQ; this is easy
now that wakeup enables/disables are properly refcounted.
- (OMAP1) Move pm wakeup event setup from pm.c into irq.c so that it can
obey driver {en,dis}able_irq_wake() calls ... so now any L1 or L2
IRQ source can be a wakeup event, not just a small static group.
- (OMAP1) Only L1->L2 cascades are always marked as wakeup sources.
This means that drivers can now use /sys/devices/.../power/wakeup userspace
configuration for board-specific policies about activating wakeup sources.
UNTESTED.
TODO: Various drivers, notably the keypad driver, need to learn about
being device_can_wakeup() and {en,dis}able_irq_wake().
Index: osk2/arch/arm/plat-omap/gpio.c
===================================================================
--- osk2.orig/arch/arm/plat-omap/gpio.c 2006-08-29 09:02:28.000000000 -0700
+++ osk2/arch/arm/plat-omap/gpio.c 2006-08-29 09:15:37.000000000 -0700
@@ -646,13 +646,17 @@ static inline void _set_gpio_irqenable(s
static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
{
switch (bank->method) {
+ case METHOD_MPUIO:
case METHOD_GPIO_1610:
case METHOD_GPIO_24XX:
spin_lock(&bank->lock);
- if (enable)
+ if (enable) {
bank->suspend_wakeup |= (1 << gpio);
- else
+ enable_irq_wake(bank->irq);
+ } else {
bank->suspend_wakeup &= ~(1 << gpio);
+ disable_irq_wake(bank->irq);
+ }
spin_unlock(&bank->lock);
return 0;
default:
@@ -945,6 +949,21 @@ static void gpio_unmask_irq(unsigned int
_set_gpio_irqenable(bank, gpio_idx, 1);
}
+static struct irq_chip gpio_irq_chip = {
+ .name = "GPIO",
+ .startup = gpio_irq_startup,
+ .shutdown = gpio_irq_shutdown,
+ .ack = gpio_ack_irq,
+ .mask = gpio_mask_irq,
+ .unmask = gpio_unmask_irq,
+ .set_type = gpio_irq_type,
+ .set_wake = gpio_wake_enable,
+};
+
+/*---------------------------------------------------------------------*/
+
+#ifndef CONFIG_ARCH_OMAP24XX
+
static void mpuio_ack_irq(unsigned int irq)
{
/* The ISR is reset automatically, so do nothing here. */
@@ -966,24 +985,46 @@ static void mpuio_unmask_irq(unsigned in
_set_gpio_irqenable(bank, gpio, 1);
}
-static struct irq_chip gpio_irq_chip = {
- .name = "GPIO",
- .startup = gpio_irq_startup,
- .shutdown = gpio_irq_shutdown,
- .ack = gpio_ack_irq,
- .mask = gpio_mask_irq,
- .unmask = gpio_unmask_irq,
- .set_type = gpio_irq_type,
+static struct irq_chip mpuio_irq_chip = {
+ .name = "MPUIO",
+ .ack = mpuio_ack_irq,
+ .mask = mpuio_mask_irq,
+ .unmask = mpuio_unmask_irq,
.set_wake = gpio_wake_enable,
};
-static struct irq_chip mpuio_irq_chip = {
- .name = "MPUIO",
- .ack = mpuio_ack_irq,
- .mask = mpuio_mask_irq,
- .unmask = mpuio_unmask_irq
+static int omap_mpuio_suspend(struct sys_device *dev, pm_message_t mesg)
+{
+ void __iomem *reg = gpio_bank[0].base + OMAP_MPUIO_GPIO_MASKIT;
+
+ gpio_bank[0].saved_wakeup = __raw_readw(reg);
+ __raw_writew(~gpio_bank[0].suspend_wakeup, reg);
+ return 0;
+}
+
+static int omap_mpuio_resume(struct sys_device *dev)
+{
+ void __iomem *reg = gpio_bank[0].base + OMAP_MPUIO_GPIO_MASKIT;
+
+ __raw_writew(gpio_bank[0].saved_wakeup, reg);
+ return 0;
+}
+
+static struct sysdev_class omap_mpuio_sysclass = {
+ set_kset_name("mpuio"),
+ .suspend = omap_mpuio_suspend,
+ .resume = omap_mpuio_resume,
+};
+
+static struct sys_device omap_mpuio_device = {
+ .id = 0,
+ .cls = &omap_mpuio_sysclass,
};
+#endif
+
+/*---------------------------------------------------------------------*/
+
static int initialized;
static struct clk * gpio_ick;
static struct clk * gpio_fck;
@@ -1215,6 +1256,14 @@ static int __init omap_gpio_sysinit(void
if (!initialized)
ret = _omap_gpio_init();
+#ifndef CONFIG_ARCH_OMAP24XX
+ if (ret == 0) {
+ ret = sysdev_class_register(&omap_mpuio_sysclass);
+ if (ret == 0)
+ ret = sysdev_register(&omap_mpuio_device);
+ }
+#endif
+
#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX)
if (cpu_is_omap16xx() || cpu_is_omap24xx()) {
if (ret == 0) {
Index: osk2/arch/arm/mach-omap1/irq.c
===================================================================
--- osk2.orig/arch/arm/mach-omap1/irq.c 2006-08-29 09:02:27.000000000 -0700
+++ osk2/arch/arm/mach-omap1/irq.c 2006-08-29 09:08:38.000000000 -0700
@@ -118,6 +118,39 @@ static int omap_wake_irq(unsigned int ir
return 0;
}
+#ifdef CONFIG_PM
+
+/* enable_irq_wake() calls from drivers will normally be configured
+ * based on /sys/devices/.../power/wakeup settings, for drivers that
+ * that support wakeup events.
+ */
+void omap_pm_wakeup_setup(void)
+{
+ /* MPU level 1 controller ... take driver settings, plus
+ * L1->L2 cascade ... GPIO and MPUIO handled via sysdev
+ */
+ omap_writel(~irq_banks[0].wake_enable, OMAP_IH1_MIR);
+
+ /* MPU level 2 controller ... take driver settings, plus for
+ * omap730 and omap16xx peripheral wakeup (enabled by irq setup)
+ */
+ omap_writel(~irq_banks[1].wake_enable, OMAP_IH2_0_MIR);
+
+ if (cpu_is_omap730()) {
+ omap_writel(~irq_banks[1].wake_enable, OMAP_IH2_1_MIR);
+ }
+ if (cpu_is_omap16xx()) {
+ omap_writel(~irq_banks[1].wake_enable, OMAP_IH2_1_MIR);
+ omap_writel(~irq_banks[3].wake_enable, OMAP_IH2_2_MIR);
+ omap_writel(~irq_banks[4].wake_enable, OMAP_IH2_3_MIR);
+ }
+
+ /* New IRQ agreement, recalculate in cascade order */
+ omap_writel(1, OMAP_IH2_CONTROL);
+ omap_writel(1, OMAP_IH1_CONTROL);
+}
+
+#endif /* PM */
/*
* Allows tuning the IRQ type and priority
@@ -184,12 +217,17 @@ void __init omap_init_irq(void)
if (cpu_is_omap730()) {
irq_banks = omap730_irq_banks;
irq_bank_count = ARRAY_SIZE(omap730_irq_banks);
+
+ omap_wake_irq(INT_730_IH2_IRQ, 1);
+ omap_wake_irq(INT_730_WAKE_UP_REQ, 1);
}
#endif
#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
irq_banks = omap1510_irq_banks;
irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
+
+ omap_wake_irq(INT_1510_IH2_IRQ, 1);
}
if (cpu_is_omap310()) {
irq_banks = omap310_irq_banks;
@@ -200,6 +238,9 @@ void __init omap_init_irq(void)
if (cpu_is_omap16xx()) {
irq_banks = omap1610_irq_banks;
irq_bank_count = ARRAY_SIZE(omap1610_irq_banks);
+
+ omap_wake_irq(INT_1610_IH2_IRQ, 1);
+ omap_wake_irq(INT_1610_WAKE_UP_REQ, 1);
}
#endif
printk("Total of %i interrupts in %i interrupt banks\n",
Index: osk2/arch/arm/mach-omap1/pm.c
===================================================================
--- osk2.orig/arch/arm/mach-omap1/pm.c 2006-08-29 09:02:27.000000000 -0700
+++ osk2/arch/arm/mach-omap1/pm.c 2006-08-29 09:08:38.000000000 -0700
@@ -187,57 +187,8 @@ void omap_pm_idle(void)
local_irq_enable();
}
-/*
- * Configuration of the wakeup event is board specific. For the
- * moment we put it into this helper function. Later it may move
- * to board specific files.
- */
-static void omap_pm_wakeup_setup(void)
-{
- u32 level1_wake = 0;
- u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
-
- /*
- * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
- * and the L2 wakeup interrupts: keypad and UART2. Note that the
- * drivers must still separately call omap_set_gpio_wakeup() to
- * wake up to a GPIO interrupt.
- */
- if (cpu_is_omap730())
- level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) |
- OMAP_IRQ_BIT(INT_730_IH2_IRQ);
- else if (cpu_is_omap15xx())
- level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
- OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
- else if (cpu_is_omap16xx())
- level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
- OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
-
- omap_writel(~level1_wake, OMAP_IH1_MIR);
-
- if (cpu_is_omap730()) {
- omap_writel(~level2_wake, OMAP_IH2_0_MIR);
- omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) |
- OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)),
- OMAP_IH2_1_MIR);
- } else if (cpu_is_omap15xx()) {
- level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
- omap_writel(~level2_wake, OMAP_IH2_MIR);
- } else if (cpu_is_omap16xx()) {
- level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
- omap_writel(~level2_wake, OMAP_IH2_0_MIR);
-
- /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
- omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ),
- OMAP_IH2_1_MIR);
- omap_writel(~0x0, OMAP_IH2_2_MIR);
- omap_writel(~0x0, OMAP_IH2_3_MIR);
- }
+extern void omap_pm_wakeup_setup(void);
- /* New IRQ agreement, recalculate in cascade order */
- omap_writel(1, OMAP_IH2_CONTROL);
- omap_writel(1, OMAP_IH1_CONTROL);
-}
#define EN_DSPCK 13 /* ARM_CKCTL */
#define EN_APICK 6 /* ARM_IDLECT2 */
[-- Attachment #3: Type: text/plain, Size: 0 bytes --]
next prev parent reply other threads:[~2006-08-30 8:22 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-08-15 17:03 [patch 2.6.17-rc4-omap-git] rtc-omap, rtc framework driver David Brownell
2006-08-15 17:25 ` Johnson, Steve-OMAP
2006-08-15 22:01 ` David Brownell
2006-08-15 22:03 ` Johnson, Steve-OMAP
2006-08-15 22:17 ` David Brownell
2006-08-16 3:12 ` Interrupts on Omap5912 OJ Ravadilla
2006-08-16 6:13 ` Arnold
2006-08-29 14:34 ` [patch 2.6.17-rc4-omap-git] rtc-omap, rtc framework driver Tony Lindgren
2006-08-29 19:51 ` David Brownell
2006-08-30 7:57 ` Tony Lindgren
2006-08-30 8:22 ` David Brownell [this message]
-- strict thread matches above, loose matches on Subject: below --
2006-08-15 17:58 Woodruff, Richard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200608300122.14254.david-b@pacbell.net \
--to=david-b@pacbell.net \
--cc=linux-omap-open-source@linux.omap.com \
--cc=tony@atomide.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox