Blackfin arch: Functional power management support

Enable: PM_SUSPEND_MEM -> Blackfin Hibernate to SDRAM
This feature requires a special bootloader (u-boot)
supporting return from hibernate.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>

diff --git a/include/asm-blackfin/dma.h b/include/asm-blackfin/dma.h
index c0d5259..3cd4b52 100644
--- a/include/asm-blackfin/dma.h
+++ b/include/asm-blackfin/dma.h
@@ -144,8 +144,16 @@
 	void *data;
 	unsigned int dma_enable_flag;
 	unsigned int loopback_flag;
+#ifdef CONFIG_PM
+	unsigned short saved_peripheral_map;
+#endif
 };
 
+#ifdef CONFIG_PM
+int blackfin_dma_suspend(void);
+void blackfin_dma_resume(void);
+#endif
+
 /*******************************************************************************
 *	DMA API's
 *******************************************************************************/
diff --git a/include/asm-blackfin/dpmc.h b/include/asm-blackfin/dpmc.h
index 7f34cd3..de28e6e 100644
--- a/include/asm-blackfin/dpmc.h
+++ b/include/asm-blackfin/dpmc.h
@@ -7,63 +7,18 @@
 #ifndef _BLACKFIN_DPMC_H_
 #define _BLACKFIN_DPMC_H_
 
-#define SLEEP_MODE		1
-#define DEEP_SLEEP_MODE		2
-#define ACTIVE_PLL_DISABLED	3
-#define FULLON_MODE		4
-#define ACTIVE_PLL_ENABLED	5
-#define HIBERNATE_MODE		6
-
-#define IOCTL_FULL_ON_MODE	_IO('s', 0xA0)
-#define IOCTL_ACTIVE_MODE	_IO('s', 0xA1)
-#define IOCTL_SLEEP_MODE	_IO('s', 0xA2)
-#define IOCTL_DEEP_SLEEP_MODE	_IO('s', 0xA3)
-#define IOCTL_HIBERNATE_MODE	_IO('s', 0xA4)
-#define IOCTL_CHANGE_FREQUENCY	_IOW('s', 0xA5, unsigned long)
-#define IOCTL_CHANGE_VOLTAGE	_IOW('s', 0xA6, unsigned long)
-#define IOCTL_SET_CCLK		_IOW('s', 0xA7, unsigned long)
-#define IOCTL_SET_SCLK		_IOW('s', 0xA8, unsigned long)
-#define IOCTL_GET_PLLSTATUS	_IOW('s', 0xA9, unsigned long)
-#define IOCTL_GET_CORECLOCK	_IOW('s', 0xAA, unsigned long)
-#define IOCTL_GET_SYSTEMCLOCK	_IOW('s', 0xAB, unsigned long)
-#define IOCTL_GET_VCO		_IOW('s', 0xAC, unsigned long)
-#define IOCTL_DISABLE_WDOG_TIMER _IO('s', 0xAD)
-#define IOCTL_UNMASK_WDOG_WAKEUP_EVENT _IO('s',0xAE)
-#define IOCTL_PROGRAM_WDOG_TIMER _IOW('s',0xAF,unsigned long)
-#define IOCTL_CLEAR_WDOG_WAKEUP_EVENT _IO('s',0xB0)
-#define IOCTL_SLEEP_DEEPER_MODE _IO('s',0xB1)
-
-#define DPMC_MINOR		254
-
-#define ON	0
-#define OFF	1
-
 #ifdef __KERNEL__
+#ifndef __ASSEMBLY__
 
-unsigned long calc_volt(void);
-int calc_vlev(int vlt);
-unsigned long change_voltage(unsigned long volt);
-int calc_msel(int vco_hz);
-unsigned long change_frequency(unsigned long vco_mhz);
-int set_pll_div(unsigned short sel, unsigned char flag);
-int get_vco(void);
-unsigned long change_system_clock(unsigned long clock);
-unsigned long change_core_clock(unsigned long clock);
-unsigned long get_pll_status(void);
-void change_baud(int baud);
-void fullon_mode(void);
-void active_mode(void);
 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);
-void disable_wdog_timer(void);
+void do_hibernate(int wakeup);
+void set_dram_srfs(void);
+void unset_dram_srfs(void);
 
-extern unsigned long get_cclk(void);
-extern unsigned long get_sclk(void);
+#define VRPAIR(vlev, freq) (((vlev) << 16) | ((freq) >> 16))
 
 struct bfin_dpmc_platform_data {
 	const unsigned int *tuple_tab;
@@ -71,8 +26,33 @@
 	unsigned short vr_settling_time; /* in us */
 };
 
-#define VRPAIR(vlev, freq) (((vlev) << 16) | ((freq) >> 16))
+#else
 
+#define PM_PUSH(x) \
+	R0 = [P0 + (x - SRAM_BASE_ADDRESS)];\
+	[--SP] =  R0;\
+
+#define PM_POP(x) \
+	R0 = [SP++];\
+	[P0 + (x - SRAM_BASE_ADDRESS)] = R0;\
+
+#define PM_SYS_PUSH(x) \
+	R0 = [P0 + (x - PLL_CTL)];\
+	[--SP] =  R0;\
+
+#define PM_SYS_POP(x) \
+	R0 = [SP++];\
+	[P0 + (x - PLL_CTL)] = R0;\
+
+#define PM_SYS_PUSH16(x) \
+	R0 = w[P0 + (x - PLL_CTL)];\
+	[--SP] =  R0;\
+
+#define PM_SYS_POP16(x) \
+	R0 = [SP++];\
+	w[P0 + (x - PLL_CTL)] = R0;\
+
+#endif
 #endif	/* __KERNEL__ */
 
 #endif	/*_BLACKFIN_DPMC_H_*/
diff --git a/include/asm-blackfin/gpio.h b/include/asm-blackfin/gpio.h
index ff95e9d..168f125 100644
--- a/include/asm-blackfin/gpio.h
+++ b/include/asm-blackfin/gpio.h
@@ -376,8 +376,12 @@
 #endif
 
 #ifdef CONFIG_PM
-unsigned int bfin_pm_setup(void);
-void bfin_pm_restore(void);
+
+unsigned int bfin_pm_standby_setup(void);
+void bfin_pm_standby_restore(void);
+
+void bfin_gpio_pm_hibernate_restore(void);
+void bfin_gpio_pm_hibernate_suspend(void);
 
 #ifndef CONFIG_BF54x
 #define PM_WAKE_RISING	0x1
@@ -392,17 +396,8 @@
 
 struct gpio_port_s {
 	unsigned short data;
-	unsigned short data_clear;
-	unsigned short data_set;
-	unsigned short toggle;
 	unsigned short maska;
-	unsigned short maska_clear;
-	unsigned short maska_set;
-	unsigned short maska_toggle;
 	unsigned short maskb;
-	unsigned short maskb_clear;
-	unsigned short maskb_set;
-	unsigned short maskb_toggle;
 	unsigned short dir;
 	unsigned short polar;
 	unsigned short edge;
@@ -411,10 +406,10 @@
 
 	unsigned short fer;
 	unsigned short reserved;
+	unsigned short mux;
 };
 #endif /*CONFIG_BF54x*/
 #endif /*CONFIG_PM*/
-
 /***********************************************************
 *
 * FUNCTIONS: Blackfin GPIO Driver
diff --git a/include/asm-blackfin/mach-bf548/gpio.h b/include/asm-blackfin/mach-bf548/gpio.h
index cb8b0f1..bba82dc 100644
--- a/include/asm-blackfin/mach-bf548/gpio.h
+++ b/include/asm-blackfin/mach-bf548/gpio.h
@@ -209,3 +209,11 @@
 	unsigned short dummy7;
 	unsigned int port_mux;
 };
+
+struct gpio_port_s {
+	unsigned short fer;
+	unsigned short data;
+	unsigned short dir;
+	unsigned short inen;
+	unsigned int mux;
+};