From: guiming zhuo <gmzhuo@gbsoft.localdomain>
Subject: [PATCH] local/pm

pm debug

Signed-off-by: guiming zhuo <gmzhuo@gbsoft.localdomain>

---
 arch/arm/mach-pxa/ezx.c    |   69 ++++++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-pxa/pxa27x.c |   39 +++++++++++++++++++++++-
 arch/arm/mm/init.c         |   11 +++++++
 drivers/mfd/ezx-pcap.c     |   66 ++++++++++++++++++++++++++++++++++++++++++
 drivers/misc/Makefile      |    1 +
 drivers/misc/memdebug.c    |   27 +++++++++++++++++
 drivers/mmc/host/pxamci.c  |    5 ++-
 drivers/spi/pxa2xx_spi.c   |   12 +++++++
 8 files changed, 227 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c
index 5d221f3..800d392 100644
--- a/arch/arm/mach-pxa/ezx.c
+++ b/arch/arm/mach-pxa/ezx.c
@@ -53,6 +53,7 @@
 
 #include "devices.h"
 #include "generic.h"
+#include <linux/memdebug.h>
 
 #define GPIO12_A780_FLIP_LID 12
 #define GPIO15_A1200_FLIP_LID 15
@@ -191,6 +192,9 @@ static void ezx_mci_setpower(struct device *dev, unsigned int vdd)
 {
 	ezx_pcap_mmcsd_voltage(vdd);
 	ezx_pcap_mmcsd_power(1);
+	
+	memdebug("set voltage %d\n", vdd);
+	
 }
 
 static void ezx_mci_exit(struct device *dev, void *data)
@@ -1691,8 +1695,73 @@ static struct i2c_board_info __initdata e6_i2c_board_info[] = {
 	},
 };
 
+/* PM */
+extern int bp_handshake_passed(void);
+/*
+ * Flags in memory for sleep use
+ */
+#define FLAG_ADDR       PHYS_OFFSET
+#define RESUME_ADDR     (PHYS_OFFSET + 4)
+#define BPSIG_ADDR      (PHYS_OFFSET + 8)
+
+#define USER_OFF_FLAG   0x5a5a5a5a
+#define SLEEP_FLAG      0x6b6b6b6b
+#define OFF_FLAG        0x7c7c7c7c
+#define REFLASH_FLAG    0x0C1D2E3F
+#define PASS_THRU_FLAG	0x12345678
+#define CHARGE_FLAG 	0xC0C1C2C3
+#define APP_REBOOT_FLAG 0x80808080
+#define FACTORY_REBOOT_FLAG	0x46414354
+#define DEFAULT_FLAG	0x44454641
+
+#define WDI_FLAG        0xbb00dead
+#define NO_FLAG         0xaa00dead
+
+static void ezx_reboot_poweroff(char mode)
+{
+	*(unsigned long *)(phys_to_virt(BPSIG_ADDR)) = NO_FLAG;
+//	cpu_proc_fin();
+
+#ifdef CONFIG_EZX_BP
+//	if (gpio_get_value(GPIO_BB_WDI) == 0) {
+//		*(unsigned long *)(phys_to_virt(BPSIG_ADDR)) = WDI_FLAG;
+//
+//		/* reset BP */
+//		gpio_set_value(GPIO_BB_RESET, 0);
+//		mdelay(1);
+//		gpio_set_value(GPIO_BB_RESET, 1);
+//
+//		if (mode == 'z') {
+//			arch_reset('h');
+//			while (1);
+//		}
+//	}
+#endif
+//	if (mode == 'z')
+//		/* Panic! Ask PCAP to turn both processors off */
+//		gpio_set_value(GPIO_WDI_AP, 0);
+//	else
+//		arm_machine_restart(mode);
+
+	while (1);
+}
+
+static inline void ezx_poweroff(void)
+{
+	ezx_reboot_poweroff('z');
+}
+
+static inline void ezx_restart(char mode)
+{
+	ezx_reboot_poweroff(mode);
+}
+
+
 static void __init e6_init(void)
 {
+//	pm_power_off = ezx_poweroff;
+//	arm_pm_restart = ezx_restart;
+	
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config));
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(e6_pin_config));
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 411bec5..5a2c514 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -265,17 +265,52 @@ static int pxa27x_cpu_pm_valid(suspend_state_t state)
 	return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
 }
 
+/*
+ * Flags in memory for sleep use
+ */
+#define FLAG_ADDR       PHYS_OFFSET
+#define RESUME_ADDR     (PHYS_OFFSET + 4)
+#define BPSIG_ADDR      (PHYS_OFFSET + 8)
+
+#define USER_OFF_FLAG   0x5a5a5a5a
+#define SLEEP_FLAG      0x6b6b6b6b
+#define OFF_FLAG        0x7c7c7c7c
+#define REFLASH_FLAG    0x0C1D2E3F
+#define PASS_THRU_FLAG	0x12345678
+#define CHARGE_FLAG 	0xC0C1C2C3
+#define APP_REBOOT_FLAG 0x80808080
+#define FACTORY_REBOOT_FLAG	0x46414354
+#define DEFAULT_FLAG	0x44454641
+
+#define WDI_FLAG        0xbb00dead
+#define NO_FLAG         0xaa00dead
+
+
 static int pxa27x_cpu_pm_prepare(void)
 {
 	/* set resume return address */
-	PSPR = virt_to_phys(pxa_cpu_resume);
+#ifdef CONFIG_PXA_EZX
+	/* set EZX flags for blob - WM */
+	*(unsigned long *)(phys_to_virt(RESUME_ADDR)) = virt_to_phys(pxa_cpu_resume);
+	*(unsigned long *)(phys_to_virt(FLAG_ADDR)) = SLEEP_FLAG;
+	*(unsigned long *)(phys_to_virt(FLAG_ADDR+0x10)) = 0XCCAABBDD;
+#else
+ 	PSPR = virt_to_phys(pxa_cpu_resume);
+#endif
 	return 0;
 }
 
 static void pxa27x_cpu_pm_finish(void)
 {
 	/* ensure not to come back here if it wasn't intended */
-	PSPR = 0;
+#ifdef CONFIG_PXA_EZX
+	*(unsigned long *)(phys_to_virt(RESUME_ADDR)) = 0;
+	*(unsigned long *)(phys_to_virt(FLAG_ADDR)) = OFF_FLAG;
+#else
+ 	PSPR = 0;
+#endif
+	*(unsigned long *)(phys_to_virt(FLAG_ADDR+0x10)) = 0Xdddddddd;
+
 }
 
 static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = {
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 34df4d9..61dff05 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -24,6 +24,7 @@
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <linux/memdebug.h>
 
 #include "mm.h"
 
@@ -268,6 +269,16 @@ static unsigned long __init bootmem_init_node(int node, struct meminfo *mi)
 	 */
 	reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
 			     boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
+#ifdef CONFIG_PXA_EZX
+	/* reserve the first page memory for exiting sleep and user off */
+	reserve_bootmem_node(pgdat, PHYS_OFFSET, PAGE_SIZE, BOOTMEM_DEFAULT);
+	/* reserve the first page memory for exiting sleep and user off */
+	reserve_bootmem_node(pgdat, 0xac000000, 1024*1024*16, BOOTMEM_DEFAULT);
+	mdbg.startAddr = phys_to_virt(0xac000000);
+	mdbg.cur = mdbg.startAddr;
+	unsigned int *len = &mdbg.totalSize;
+	*len = 1024*1024*16;
+#endif
 
 	return end_pfn;
 }
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c
index dd37ea2..1933c6b 100644
--- a/drivers/mfd/ezx-pcap.c
+++ b/drivers/mfd/ezx-pcap.c
@@ -18,6 +18,11 @@
 #include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/rfkill.h>
+#include <mach/ssp.h>
+#include <mach/regs-ssp.h>
+#include <mach/pxa2xx_spi.h>
+#include <linux/memdebug.h>
+
 
 struct pcap_chip {
 	struct spi_device *spi;
@@ -54,7 +59,9 @@ static int ezx_pcap_putget(u32 *data)
 	*buf = *data;
 	t.tx_buf = (u8 *) buf;
 	t.rx_buf = (u8 *) buf;
+	memdebug("waiting message....");
 	status = spi_sync(pcap.spi, &m);
+	memdebug("sync finish\n");
 
 	if (status == 0)
 		*data = *buf;
@@ -63,6 +70,46 @@ static int ezx_pcap_putget(u32 *data)
 	return status;
 }
 
+static DEFINE_SPINLOCK(ezx_ssp_lock);
+static struct ssp_dev ezx_ssp_dev;
+
+#include <mach/pxa2xx_spi.h>
+
+static unsigned long ezx_ssp_pcap_putget(u32 *data)
+{
+	unsigned long flag;
+	u32 ret = 0;
+	struct pxa2xx_spi_chip *pchip = (struct pxa2xx_spi_chip *)pcap.spi->controller_data;
+	
+
+	spin_lock_irqsave(&ezx_ssp_lock, flag);
+
+	ret = ssp_init(&ezx_ssp_dev, 1, 0);
+	if (ret) {
+		printk(KERN_ERR "Unable to register SSP handler!\n");
+		return ret;
+	}
+
+	ssp_disable(&ezx_ssp_dev);
+	ssp_config(&ezx_ssp_dev,
+		(SSCR0_Motorola | SSCR0_DataSize(16) | SSCR0_EDSS),
+		(SSCR1_TxTresh(1) | SSCR1_RxTresh(1)),
+		0, SSCR0_SerClkDiv(1));
+	ssp_enable(&ezx_ssp_dev);
+	
+	pchip->cs_control(PXA2XX_CS_ASSERT);
+	
+	ssp_write_word(&ezx_ssp_dev,*data);
+ 	ssp_read_word(&ezx_ssp_dev, (u32 *)data);
+	pchip->cs_control(~PXA2XX_CS_ASSERT);
+
+	ssp_exit(&ezx_ssp_dev);
+
+	spin_unlock_irqrestore(&ezx_ssp_lock, flag);
+
+	return ret;
+}
+
 int ezx_pcap_write(u8 reg_num, u32 value)
 {
 	value &= PCAP_REGISTER_VALUE_MASK;
@@ -691,9 +738,28 @@ ret:
 	return ret;
 }
 
+static int ezx_pcap_suspend(struct spi_device *dev, pm_message_t state)
+{
+	//DEBUGP("pcap suspend!\n");
+	return 0;
+}
+
+
+static int ezx_pcap_resume(struct spi_device *dev)
+{
+	//DEBUGP("pcap resume!\n");
+	memdebug("a pcap write isrcccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n");
+	ezx_pcap_write(PCAP_REG_ISR, PCAP_CLEAR_INTERRUPT_REGISTER);
+	memdebug("a pcap write isr okcccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n");
+
+	return 0;
+}
+
 static struct spi_driver ezxpcap_driver = {
 	.probe  = ezx_pcap_probe,
 	.remove = __devexit_p(ezx_pcap_remove),
+	.resume = ezx_pcap_resume,
+	.suspend = ezx_pcap_suspend,
 	.driver = {
 		.name   = "ezx-pcap",
 		.owner  = THIS_MODULE,
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index bc11998..4a2fe71 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_SGI_GRU)		+= sgi-gru/
 obj-$(CONFIG_HP_ILO)		+= hpilo.o
 obj-$(CONFIG_C2PORT)		+= c2port/
 obj-y				+= eeprom/
+obj-y				+= memdebug.o
diff --git a/drivers/misc/memdebug.c b/drivers/misc/memdebug.c
new file mode 100644
index 0000000..b905238
--- /dev/null
+++ b/drivers/misc/memdebug.c
@@ -0,0 +1,27 @@
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/mmc/host.h>
+#include <linux/io.h>
+#include <asm/sizes.h>
+
+#include <linux/memdebug.h>
+
+struct mem_debug_info mdbg;
+
+void memdebug(const char *fmt, ...)
+{
+	unsigned leng = mdbg.totalSize - (mdbg.cur - mdbg.startAddr);
+	int curlen;
+	va_list ap;
+	va_start(ap, fmt);
+	curlen = vsnprintf(mdbg.cur, leng, fmt, ap);
+	if(curlen > 0)
+		mdbg.cur += curlen;
+}
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 9702ad3..fd5125c 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -701,13 +701,16 @@ static int pxamci_suspend(struct platform_device *dev, pm_message_t state)
 	return ret;
 }
 
+#include <linux/memdebug.h>
 static int pxamci_resume(struct platform_device *dev)
 {
 	struct mmc_host *mmc = platform_get_drvdata(dev);
 	int ret = 0;
-
+	memdebug("a:I'm in pxamci resume %d\n", ret);
+	memdebug("b:I'm in pxamci resume %d still:)\n", ret);
 	if (mmc)
 		ret = mmc_resume_host(mmc);
+	memdebug("b:after pxamci resume\n");
 
 	return ret;
 }
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index d0fc4ca..6526ad1 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -39,6 +39,7 @@
 #include <mach/regs-ssp.h>
 #include <mach/ssp.h>
 #include <mach/pxa2xx_spi.h>
+#include <linux/memdebug.h>
 
 MODULE_AUTHOR("Stephen Street");
 MODULE_DESCRIPTION("PXA2xx SSP SPI Controller");
@@ -1095,6 +1096,15 @@ static void pump_transfers(unsigned long data)
 	/* after chip select, release the data by enabling service
 	 * requests and interrupts, without changing any mode bits */
 	write_SSCR1(cr1, reg);
+	
+	memdebug("SSCR0 value %08x\n", read_SSCR0(reg));
+	memdebug("SSCR1 value %08x\n", read_SSCR1(reg));
+	memdebug("SSSR value %08x\n", read_SSSR(reg));
+	memdebug("SSITR value %08x\n", read_SSITR(reg));
+	memdebug("SSDR value %08x\n", read_SSDR(reg));
+	memdebug("SSTO value %08x\n", read_SSTO(reg));
+	memdebug("SSPSP value %08x\n", read_SSPSP(reg));
+
 }
 
 static void pump_messages(struct work_struct *work)
@@ -1639,6 +1649,7 @@ static int pxa2xx_spi_resume(struct platform_device *pdev)
 	struct driver_data *drv_data = platform_get_drvdata(pdev);
 	struct ssp_device *ssp = drv_data->ssp;
 	int status = 0;
+	memdebug("pxa2xx spi resume...");
 
 	/* Enable the SSP clock */
 	clk_enable(ssp->clk);
@@ -1649,6 +1660,7 @@ static int pxa2xx_spi_resume(struct platform_device *pdev)
 		dev_err(&pdev->dev, "problem starting queue (%d)\n", status);
 		return status;
 	}
+	memdebug("pxa2xx spi resume finish\n");
 
 	return 0;
 }
-- 
tg: (2c5ed96..) local/pm (depends on: local/debug)

