Title: [4164] trunk: Task [#3261] hook up set_irq_wake() in Blackfin's irq code
Revision
4164
Author
hennerich
Date
2008-01-29 07:28:33 -0600 (Tue, 29 Jan 2008)

Log Message

Task [#3261] hook up set_irq_wake() in Blackfin's irq code
-Add support for irq_wake on system and gpio interrupts
-Remove outdated kernel options
-Add option to select default PM mode
-Fix various places where SIC_IWRx was only handled partially

Diffstat

 arch/blackfin/Kconfig                     |   47 +++++++++++++++++-----------
 arch/blackfin/kernel/bfin_gpio.c          |   14 +++-----
 arch/blackfin/mach-common/dpmc.S          |   32 ++++++++++++++++++-
 arch/blackfin/mach-common/ints-priority.c |   49 ++++++++++++++++++++++++++++--
 arch/blackfin/mach-common/pm.c            |   40 ++++++++----------------
 drivers/char/bfin_dpmc.c                  |   39 +++++++++++++++--------
 drivers/char/bfin_dpmc.h                  |    3 -
 include/asm-blackfin/bfin-global.h        |    2 +
 include/asm-blackfin/dpmc.h               |    8 ++--
 include/asm-blackfin/gpio.h               |    1 
 10 files changed, 158 insertions(+), 77 deletions(-)

Modified Paths

Diff

Modified: trunk/arch/blackfin/Kconfig (4163 => 4164)


--- trunk/arch/blackfin/Kconfig	2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/arch/blackfin/Kconfig	2008-01-29 13:28:33 UTC (rev 4164)
@@ -538,7 +538,7 @@
 	default y
 	help
 	  If enabled, the entire ASM lowlevel exception and interrupt entry code
-	  (STORE/RESTORE CONTEXT) is linked into L1 instruction memory. 
+	  (STORE/RESTORE CONTEXT) is linked into L1 instruction memory.
 	  (less latency)
 
 config DO_IRQ_L1
@@ -895,30 +895,39 @@
 source "kernel/power/Kconfig"
 
 choice
-	prompt "Select PM Wakeup Event Source"
-	default PM_WAKEUP_GPIO_BY_SIC_IWR
+	prompt "Default Power Saving Mode"
 	depends on PM
+	default PM_BFIN_SLEEP_DEEPER
+config  PM_BFIN_SLEEP_DEEPER
+	bool "Sleep Deeper"
 	help
-	  If you have a GPIO already configured as input with the corresponding PORTx_MASK
-	  bit set - "Specify Wakeup Event by SIC_IWR value"
+	  Sleep "Deeper" Mode (High Power Savings) - This mode reduces dynamic
+	  power dissipation by disabling the clock to the processor core (CCLK).
+	  Furthermore, Standby sets the internal power supply voltage (VDDINT)
+	  to 0.85 V to provide the greatest power savings, while preserving the
+	  processor state.
+	  The PLL and system clock (SCLK) continue to operate at a very low
+	  frequency of about 3.3 MHz. To preserve data integrity in the SDRAM,
+	  the SDRAM is put into Self Refresh Mode. Typically an external event
+	  such as GPIO interrupt or RTC activity wakes up the processor.
+	  Various Peripherals such as UART, SPORT, PPI may not function as
+	  normal during Sleep Deeper, due to the reduced SCLK frequency.
+	  When in the sleep mode, system DMA access to L1 memory is not supported.
 
-config PM_WAKEUP_GPIO_BY_SIC_IWR
-	bool "Specify Wakeup Event by SIC_IWR value"
+config  PM_BFIN_SLEEP
+	bool "Sleep"
+	help
+	  Sleep Mode (High Power Savings) - The sleep mode reduces power
+	  dissipation by disabling the clock to the processor core (CCLK).
+	  The PLL and system clock (SCLK), however, continue to operate in
+	  this mode. Typically an external event or RTC activity will wake
+	  up the processor. When in the sleep mode,
+	  system DMA access to L1 memory is not supported.
+endchoice
+
 config PM_WAKEUP_BY_GPIO
 	bool "Cause Wakeup Event by GPIO"
-config PM_WAKEUP_GPIO_API
-	bool "Configure Wakeup Event by PM GPIO API"
 
-endchoice
-
-config PM_WAKEUP_SIC_IWR
-	hex "Wakeup Events (SIC_IWR)"
-	depends on PM_WAKEUP_GPIO_BY_SIC_IWR
-	default 0x8 if (BF537 || BF536 || BF534)
-	default 0x80 if (BF533 || BF532 || BF531)
-	default 0x80 if (BF54x)
-	default 0x80 if (BF52x)
-
 config PM_WAKEUP_GPIO_NUMBER
 	int "Wakeup GPIO number"
 	range 0 47

Modified: trunk/arch/blackfin/kernel/bfin_gpio.c (4163 => 4164)


--- trunk/arch/blackfin/kernel/bfin_gpio.c	2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/arch/blackfin/kernel/bfin_gpio.c	2008-01-29 13:28:33 UTC (rev 4164)
@@ -698,7 +698,6 @@
 
 u32 gpio_pm_setup(void)
 {
-	u32 sic_iwr = 0;
 	u16 bank, mask, i, gpio;
 
 	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
@@ -723,7 +722,8 @@
 			gpio = i;
 
 			while (mask) {
-				if (mask & 1) {
+				if ((mask & 1) && (wakeup_flags_map[gpio] !=
+					PM_WAKE_IGNORE)) {
 					reserved_gpio_map[gpio_bank(gpio)] |=
 							gpio_bit(gpio);
 					bfin_gpio_wakeup_type(gpio,
@@ -734,18 +734,14 @@
 				mask >>= 1;
 			}
 
-			sic_iwr |= 1 <<
-				(sic_iwr_irqs[bank] - (IRQ_CORETMR + 1));
+			bfin_internal_set_wake(sic_iwr_irqs[bank], 1);
 			gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)];
 		}
 	}
 
 	AWA_DUMMY_READ(maskb_set);
 
-	if (sic_iwr)
-		return sic_iwr;
-	else
-		return IWR_ENABLE_ALL;
+	return 0;
 }
 
 void gpio_pm_restore(void)
@@ -768,7 +764,7 @@
 
 			reserved_gpio_map[bank] =
 					gpio_bank_saved[bank].reserved;
-
+			bfin_internal_set_wake(sic_iwr_irqs[bank], 0);
 		}
 
 		gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb;

Modified: trunk/arch/blackfin/mach-common/dpmc.S (4163 => 4164)


--- trunk/arch/blackfin/mach-common/dpmc.S	2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/arch/blackfin/mach-common/dpmc.S	2008-01-29 13:28:33 UTC (rev 4164)
@@ -191,6 +191,9 @@
 	call _test_pll_locked;
 
 	R0 = IWR_ENABLE(0);
+	R1 = IWR_DISABLE_ALL;
+	R2 = IWR_DISABLE_ALL;
+
 	call _set_sic_iwr;
 
 	P0.H = hi(PLL_CTL);
@@ -237,6 +240,10 @@
 
 	CLI R4;
 
+	R0 = IWR_ENABLE(0);
+	R1 = IWR_DISABLE_ALL;
+	R2 = IWR_DISABLE_ALL;
+
 	call _set_sic_iwr;
 
 	call _set_dram_srfs;
@@ -261,6 +268,9 @@
 	call _test_pll_locked;
 
 	R0 = IWR_ENABLE(0);
+	R1 = IWR_DISABLE_ALL;
+	R2 = IWR_DISABLE_ALL;
+
 	call _set_sic_iwr;
 
 	P0.H = hi(PLL_CTL);
@@ -286,7 +296,13 @@
 	CLI R4;
 
 	P3 = R0;
+	P4 = R1;
+	P5 = R2;
+
 	R0 = IWR_ENABLE(0);
+	R1 = IWR_DISABLE_ALL;
+	R2 = IWR_DISABLE_ALL;
+
 	call _set_sic_iwr;
 	call _set_dram_srfs;	/* Set SDRAM Self Refresh */
 
@@ -327,6 +343,8 @@
 	call _test_pll_locked;
 
 	R0 = P3;
+	R1 = P4;
+	R3 = P5;
 	call _set_sic_iwr;	/* Set Awake from IDLE */
 
 	P0.H = hi(PLL_CTL);
@@ -340,6 +358,9 @@
 	call _test_pll_locked;
 
 	R0 = IWR_ENABLE(0);
+	R1 = IWR_DISABLE_ALL;
+	R2 = IWR_DISABLE_ALL;
+
 	call _set_sic_iwr;	/* Set Awake from IDLE PLL */
 
 	P0.H = hi(VR_CTL);
@@ -417,14 +438,23 @@
 	RTS;
 
 ENTRY(_set_sic_iwr)
-#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)  || defined(CONFIG_BF561)
 	P0.H = hi(SIC_IWR0);
 	P0.L = lo(SIC_IWR0);
+	P1.H = hi(SIC_IWR1);
+	P1.L = lo(SIC_IWR1);
+	[P1] = R1;
+#if defined(CONFIG_BF54x)
+	P1.H = hi(SIC_IWR2);
+	P1.L = lo(SIC_IWR2);
+	[P1] = R2;
+#endif
 #else
 	P0.H = hi(SIC_IWR);
 	P0.L = lo(SIC_IWR);
 #endif
 	[P0] = R0;
+
 	SSYNC;
 	RTS;
 

Modified: trunk/arch/blackfin/mach-common/ints-priority.c (4163 => 4164)


--- trunk/arch/blackfin/mach-common/ints-priority.c	2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/arch/blackfin/mach-common/ints-priority.c	2008-01-29 13:28:33 UTC (rev 4164)
@@ -69,6 +69,10 @@
 /* The number of spurious interrupts */
 atomic_t num_spurious;
 
+#ifdef CONFIG_PM
+unsigned long bfin_sic_iwr[3];	/* Up to 3 SIC_IWRx registers */
+#endif
+
 struct ivgx {
 	/* irq number for request_irq, available in mach-bf533/irq.h */
 	unsigned int irqno;
@@ -178,6 +182,27 @@
 	SSYNC();
 }
 
+#ifdef CONFIG_PM
+int bfin_internal_set_wake(unsigned int irq, unsigned int state)
+{
+	unsigned bank, bit;
+	unsigned long flags;
+	bank = (irq - (IRQ_CORETMR + 1)) / 32;
+	bit = (irq - (IRQ_CORETMR + 1)) % 32;
+
+	local_irq_save(flags);
+
+	if (state)
+		bfin_sic_iwr[bank] |= (1 << bit);
+	else
+		bfin_sic_iwr[bank] &= ~(1 << bit);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+#endif
+
 static struct irq_chip bfin_core_irqchip = {
 	.ack = ack_noop,
 	.mask = bfin_core_mask_irq,
@@ -188,6 +213,9 @@
 	.ack = ack_noop,
 	.mask = bfin_internal_mask_irq,
 	.unmask = bfin_internal_unmask_irq,
+#ifdef CONFIG_PM
+	.set_wake = bfin_internal_set_wake,
+#endif
 };
 
 #ifdef BF537_GENERIC_ERROR_INT_DEMUX
@@ -434,6 +462,20 @@
 	return 0;
 }
 
+#ifdef CONFIG_PM
+int bfin_gpio_set_wake(unsigned int irq, unsigned int state)
+{
+	unsigned gpio = irq_to_gpio(irq);
+
+	if (state)
+		gpio_pm_wakeup_request(gpio, PM_WAKE_IGNORE);
+	else
+		gpio_pm_wakeup_free(gpio);
+
+	return 0;
+}
+#endif
+
 static struct irq_chip bfin_gpio_irqchip = {
 	.ack = bfin_gpio_ack_irq,
 	.mask = bfin_gpio_mask_irq,
@@ -441,7 +483,10 @@
 	.unmask = bfin_gpio_unmask_irq,
 	.set_type = bfin_gpio_irq_type,
 	.startup = bfin_gpio_irq_startup,
-	.shutdown = bfin_gpio_irq_shutdown
+	.shutdown = bfin_gpio_irq_shutdown,
+#ifdef CONFIG_PM
+	.set_wake = bfin_gpio_set_wake,
+#endif
 };
 
 static void bfin_demux_gpio_irq(unsigned int inta_irq,
@@ -487,7 +532,7 @@
 	}
 
 	if (search) {
-		for (i = 0; i < MAX_BLACKFIN_GPIOS; i += 16) {
+		for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
 			irq += i;
 
 			mask = get_gpiop_data(i) &

Modified: trunk/arch/blackfin/mach-common/pm.c (4163 => 4164)


--- trunk/arch/blackfin/mach-common/pm.c	2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/arch/blackfin/mach-common/pm.c	2008-01-29 13:28:33 UTC (rev 4164)
@@ -67,42 +67,30 @@
 	gpio_pm_wakeup_request(CONFIG_PM_WAKEUP_GPIO_NUMBER, WAKEUP_TYPE);
 #endif
 
-#if defined(CONFIG_PM_WAKEUP_BY_GPIO) || defined(CONFIG_PM_WAKEUP_GPIO_API)
-	{
-		u32 flags;
+	u32 flags;
 
-		local_irq_save(flags);
+	local_irq_save(flags);
+	gpio_pm_setup();
 
-		sleep_deeper(gpio_pm_setup()); /*Goto Sleep*/
-
-		gpio_pm_restore();
-
-#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
-		bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
-		bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
-# ifdef CONFIG_BF54x
-		bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
-# endif
+#ifdef CONFIG_PM_BFIN_SLEEP_DEEPER
+	sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]);
 #else
-		bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+	sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]);
 #endif
 
-		local_irq_restore(flags);
-	}
-#endif
+	gpio_pm_restore();
 
-#if defined(CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR)
-	sleep_deeper(CONFIG_PM_WAKEUP_SIC_IWR);
-# if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)  || defined(CONFIG_BF561)
 	bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
 	bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
-#  ifdef CONFIG_BF54x
+# ifdef CONFIG_BF54x
 	bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
-#  endif
-# else
-	bfin_write_SIC_IWR(IWR_ENABLE_ALL);
 # endif
-#endif				/* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */
+#else
+	bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+#endif
+
+	local_irq_restore(flags);
 }
 
 

Modified: trunk/drivers/char/bfin_dpmc.c (4163 => 4164)


--- trunk/drivers/char/bfin_dpmc.c	2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/drivers/char/bfin_dpmc.c	2008-01-29 13:28:33 UTC (rev 4164)
@@ -182,6 +182,19 @@
 	return sdrrcval;
 }
 
+void dpmc_iwr_enable_all(void)
+{
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)  || defined(CONFIG_BF561)
+		bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
+		bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
+# ifdef CONFIG_BF54x
+		bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
+# endif
+#else
+		dpmc_iwr_enable_all();
+#endif
+}
+
 int get_closest_ssel(int a, int b, int c, unsigned long vco, unsigned long clock)
 {
 	int t1, t2, t3;
@@ -261,7 +274,7 @@
 			change_baud(CONSOLE_BAUD_RATE);
 #endif
 			change_baud(CONSOLE_BAUD_RATE);
-			bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+			dpmc_iwr_enable_all();
 			SSYNC();
 
 			break;
@@ -269,18 +282,18 @@
 		case IOCTL_ACTIVE_MODE:
 			active_mode();
 			change_baud(CONSOLE_BAUD_RATE);
-			bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+			dpmc_iwr_enable_all();
 			SSYNC();
 			break;
 
 		case IOCTL_SLEEP_MODE:
-			sleep_mode(IWR_ENABLE(IRQ_RTC - IVG7));
-			bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+			sleep_mode(IWR_ENABLE(IRQ_RTC - IVG7), IWR_DISABLE_ALL, IWR_DISABLE_ALL);
+			dpmc_iwr_enable_all();
 			SSYNC();
 			break;
 
 		case IOCTL_DEEP_SLEEP_MODE:
-			deep_sleep(IWR_ENABLE(IRQ_RTC - IVG7));
+			deep_sleep(IWR_ENABLE(IRQ_RTC - IVG7), IWR_DISABLE_ALL, IWR_DISABLE_ALL);
 
 /* Active Mode SCLK = CCLK is hazardous condition Anomlay 05000273 */
 /* Changed deep_sleep to return to Full On Mode */
@@ -288,19 +301,19 @@
 			/* Needed since it comes back to active mode */
 			change_baud(CONSOLE_BAUD_RATE);
 #endif
-			bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+			dpmc_iwr_enable_all();
 			SSYNC();
 			break;
 
 		case IOCTL_SLEEP_DEEPER_MODE:
-			sleep_deeper(IWR_ENABLE(IRQ_RTC - IVG7));
-			bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+			sleep_deeper(IWR_ENABLE(IRQ_RTC - IVG7), IWR_DISABLE_ALL, IWR_DISABLE_ALL);
+			dpmc_iwr_enable_all();
 			SSYNC();
 			break;
 
 		case IOCTL_HIBERNATE_MODE:
-			hibernate_mode(IWR_ENABLE(IRQ_RTC - IVG7));
-			bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+			hibernate_mode(IWR_ENABLE(IRQ_RTC - IVG7), IWR_DISABLE_ALL, IWR_DISABLE_ALL);
+			dpmc_iwr_enable_all();
 			SSYNC();
 			break;
 
@@ -351,7 +364,7 @@
 					sclk_mhz = change_sclk((vco_mhz/(DEF_SSEL * MHZ)));
 				change_baud(CONSOLE_BAUD_RATE);
 			}
-			bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+			dpmc_iwr_enable_all();
 			SSYNC();
 			copy_to_user((unsigned long *)arg, &vco_mhz, sizeof(unsigned long));
 			break;
@@ -833,8 +846,8 @@
 	}
 
 	if (val) {
-		sleep_deeper(val);
-		bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+		sleep_deeper(val, 0, 0);
+		dpmc_iwr_enable_all();
 	}
 
 	return count;

Modified: trunk/drivers/char/bfin_dpmc.h (4163 => 4164)


--- trunk/drivers/char/bfin_dpmc.h	2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/drivers/char/bfin_dpmc.h	2008-01-29 13:28:33 UTC (rev 4164)
@@ -40,9 +40,6 @@
 
 void fullon_mode(void);
 void active_mode(void);
-void sleep_mode(u32 sic_iwr);
-void deep_sleep(u32 sic_iwr);
-void hibernate_mode(u32 sic_iwr);
 void program_wdog_timer(unsigned long);
 void unmask_wdog_wakeup_evt(void);
 void clear_wdog_wakeup_evt(void);

Modified: trunk/include/asm-blackfin/bfin-global.h (4163 => 4164)


--- trunk/include/asm-blackfin/bfin-global.h	2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/include/asm-blackfin/bfin-global.h	2008-01-29 13:28:33 UTC (rev 4164)
@@ -70,6 +70,7 @@
 extern void evt14_softirq(void);
 extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs);
 extern void bfin_gpio_interrupt_setup(int irq, int irq_pfx, int type);
+extern int bfin_internal_set_wake(unsigned int irq, unsigned int state);
 
 extern asmlinkage void finish_atomic_sections (struct pt_regs *regs);
 extern char fixed_code_start;
@@ -121,6 +122,7 @@
 
 extern unsigned long table_start, table_end;
 
+extern unsigned long bfin_sic_iwr[];
 extern u16 _bfin_swrst; /* shadow for Software Reset Register (SWRST) */
 extern struct file_operations dpmc_fops;
 extern char _start;

Modified: trunk/include/asm-blackfin/dpmc.h (4163 => 4164)


--- trunk/include/asm-blackfin/dpmc.h	2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/include/asm-blackfin/dpmc.h	2008-01-29 13:28:33 UTC (rev 4164)
@@ -53,10 +53,10 @@
 void change_baud(int baud);
 void fullon_mode(void);
 void active_mode(void);
-void sleep_mode(u32 sic_iwr);
-void deep_sleep(u32 sic_iwr);
-void hibernate_mode(u32 sic_iwr);
-void sleep_deeper(u32 sic_iwr);
+void sleep_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
+void deep_sleep(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
+void hibernate_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
+void sleep_deeper(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
 void program_wdog_timer(unsigned long);
 void unmask_wdog_wakeup_evt(void);
 void clear_wdog_wakeup_evt(void);

Modified: trunk/include/asm-blackfin/gpio.h (4163 => 4164)


--- trunk/include/asm-blackfin/gpio.h	2008-01-29 09:29:26 UTC (rev 4163)
+++ trunk/include/asm-blackfin/gpio.h	2008-01-29 13:28:33 UTC (rev 4164)
@@ -381,6 +381,7 @@
 #define PM_WAKE_HIGH	0x4
 #define PM_WAKE_LOW	0x8
 #define PM_WAKE_BOTH_EDGES	(PM_WAKE_RISING | PM_WAKE_FALLING)
+#define PM_WAKE_IGNORE	0xF0
 
 int gpio_pm_wakeup_request(unsigned gpio, unsigned char type);
 void gpio_pm_wakeup_free(unsigned gpio);
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
http://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to