public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
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 --]



  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