Index: linux-2.6.16/arch/arm/common/sharpsl_pm.c
===================================================================
--- linux-2.6.16.orig/arch/arm/common/sharpsl_pm.c	2006-04-23 21:10:12.000000000 +0100
+++ linux-2.6.16/arch/arm/common/sharpsl_pm.c	2006-04-23 21:34:49.000000000 +0100
@@ -13,6 +13,7 @@
  */
 
 #undef DEBUG
+#define DEBUG 1
 
 #include <linux/module.h>
 #include <linux/timer.h>
@@ -454,6 +455,10 @@
 {
 	int temp, i, buff[5];
 
+	/* Some devices don't support this */
+	if (!sharpsl_pm.machinfo->charge_acin_high)
+		return 0;
+
 	for (i=0; i<5; i++) {
 		buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_ACIN_VOLT);
 		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN);
@@ -495,6 +500,10 @@
 	return 0;
 }
 
+static struct {
+	u32 ffier, fflcr, ffmcr, ffspr, ffisr, ffdll, ffdlh;
+} sys_ctx;
+
 static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
 {
 	dev_dbg(sharpsl_pm.dev, "Time is: %08x\n",RCNR);
@@ -528,8 +537,29 @@
 		RTAR = 0;
 	}
 
+	sys_ctx.ffier = FFIER;
+	sys_ctx.fflcr = FFLCR;
+	sys_ctx.ffmcr = FFMCR;
+	sys_ctx.ffspr = FFSPR;
+	sys_ctx.ffisr = FFISR;
+	FFLCR |= 0x80;
+	sys_ctx.ffdll = FFDLL;
+	sys_ctx.ffdlh = FFDLH;
+	FFLCR &= 0xef;
+
 	pxa_pm_enter(state);
 
+	FFMCR = sys_ctx.ffmcr;
+	FFSPR = sys_ctx.ffspr;
+	FFLCR = sys_ctx.fflcr;
+	FFLCR |= 0x80;
+	FFDLH = sys_ctx.ffdlh;
+	FFDLL = sys_ctx.ffdll;
+	FFLCR = sys_ctx.fflcr;
+	FFISR = sys_ctx.ffisr;
+	FFLCR = 0x07;
+	FFIER = sys_ctx.ffier;
+
 	sharpsl_pm.machinfo->postsuspend();
 
 	dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n",PEDR);
@@ -591,6 +621,9 @@
 
 	dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
 
+	if (machine_is_poodle())
+		return 0;
+
 	/* Check AC-Adapter */
 	acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
 
@@ -657,6 +690,7 @@
 		dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
 
 		/* AC Check */
+		if (!machine_is_poodle())
 		if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0))
 			return sharpsl_off_charge_error();
 
@@ -679,6 +713,7 @@
 
 		dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
 
+		if (!machine_is_poodle())
 		if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0))
 			return sharpsl_off_charge_error();
 
Index: linux-2.6.16/arch/arm/mach-pxa/Kconfig
===================================================================
--- linux-2.6.16.orig/arch/arm/mach-pxa/Kconfig	2006-04-23 21:10:12.000000000 +0100
+++ linux-2.6.16/arch/arm/mach-pxa/Kconfig	2006-04-23 21:10:20.000000000 +0100
@@ -65,6 +65,7 @@
 	bool "Enable Sharp SL-5600 (Poodle) Support"
 	depends PXA_SHARPSL_25x
 	select SHARP_LOCOMO
+	select SHARPSL_PM
 	select PXA_SSP
 
 config MACH_CORGI
Index: linux-2.6.16/arch/arm/mach-pxa/Makefile
===================================================================
--- linux-2.6.16.orig/arch/arm/mach-pxa/Makefile	2006-04-23 21:10:12.000000000 +0100
+++ linux-2.6.16/arch/arm/mach-pxa/Makefile	2006-04-23 21:10:20.000000000 +0100
@@ -14,7 +14,7 @@
 obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o
 obj-$(CONFIG_PXA_SHARP_Cxx00)	+= spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o
 obj-$(CONFIG_MACH_AKITA)	+= akita-ioexp.o
-obj-$(CONFIG_MACH_POODLE)	+= poodle.o
+obj-$(CONFIG_MACH_POODLE)	+= poodle.o corgi_ssp.o sharpsl_pm.o poodle_pm.o
 obj-$(CONFIG_MACH_TOSA)         += tosa.o
 obj-$(CONFIG_MACH_HX2750)	+= hx2750.o hx2750_test.o
 
Index: linux-2.6.16/arch/arm/mach-pxa/corgi_ssp.c
===================================================================
--- linux-2.6.16.orig/arch/arm/mach-pxa/corgi_ssp.c	2006-04-23 21:10:12.000000000 +0100
+++ linux-2.6.16/arch/arm/mach-pxa/corgi_ssp.c	2006-04-23 21:10:20.000000000 +0100
@@ -50,12 +50,14 @@
 	unsigned long ret,flag;
 
 	spin_lock_irqsave(&corgi_ssp_lock, flag);
-	GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
+	if (ssp_machinfo->cs_ads7846 >= 0)
+		GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
 
 	ssp_write_word(&corgi_ssp_dev,data);
 	ret = ssp_read_word(&corgi_ssp_dev);
 
-	GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
+	if (ssp_machinfo->cs_ads7846 >= 0)
+		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
 	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
 
 	return ret;
@@ -68,12 +70,14 @@
 void corgi_ssp_ads7846_lock(void)
 {
 	spin_lock(&corgi_ssp_lock);
-	GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
+	if (ssp_machinfo->cs_ads7846 >= 0)
+		GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
 }
 
 void corgi_ssp_ads7846_unlock(void)
 {
-	GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
+	if (ssp_machinfo->cs_ads7846 >= 0)
+		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
 	spin_unlock(&corgi_ssp_lock);
 }
 
@@ -110,11 +114,13 @@
 	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), sscr1, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_lcdcon));
 	ssp_enable(&corgi_ssp_dev);
 
-	GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
+	if (ssp_machinfo->cs_lcdcon >= 0)
+		GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
 	ssp_write_word(&corgi_ssp_dev,data);
 	/* Read null data back from device to prevent SSP overflow */
 	ssp_read_word(&corgi_ssp_dev);
-	GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
+	if (ssp_machinfo->cs_lcdcon >= 0)
+		GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
 
 	ssp_disable(&corgi_ssp_dev);
 	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
@@ -147,7 +153,8 @@
 	int voltage,voltage1,voltage2;
 
 	spin_lock_irqsave(&corgi_ssp_lock, flag);
-	GPCR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
+	if (ssp_machinfo->cs_max1111 >= 0)
+		GPCR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
 	ssp_disable(&corgi_ssp_dev);
 	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_max1111));
 	ssp_enable(&corgi_ssp_dev);
@@ -169,7 +176,8 @@
 	ssp_disable(&corgi_ssp_dev);
 	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
 	ssp_enable(&corgi_ssp_dev);
-	GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
+	if (ssp_machinfo->cs_max1111 >= 0)
+		GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
 	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
 
 	if (voltage1 & 0xc0 || voltage2 & 0x3f)
@@ -196,9 +204,12 @@
 	int ret;
 
 	/* Chip Select - Disable All */
-	pxa_gpio_mode(ssp_machinfo->cs_lcdcon  | GPIO_OUT | GPIO_DFLT_HIGH);
-        pxa_gpio_mode(ssp_machinfo->cs_max1111 | GPIO_OUT | GPIO_DFLT_HIGH);
-        pxa_gpio_mode(ssp_machinfo->cs_ads7846 | GPIO_OUT | GPIO_DFLT_HIGH);
+	if (ssp_machinfo->cs_lcdcon >= 0)
+		pxa_gpio_mode(ssp_machinfo->cs_lcdcon  | GPIO_OUT | GPIO_DFLT_HIGH);
+	if (ssp_machinfo->cs_max1111 >= 0)
+	        pxa_gpio_mode(ssp_machinfo->cs_max1111 | GPIO_OUT | GPIO_DFLT_HIGH);
+	if (ssp_machinfo->cs_ads7846 >= 0)
+        	pxa_gpio_mode(ssp_machinfo->cs_ads7846 | GPIO_OUT | GPIO_DFLT_HIGH);
 
 	ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0);
 
@@ -207,6 +218,7 @@
 	else {
 		ssp_disable(&corgi_ssp_dev);
 		ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
+	SSCR0_P(1) = 0x11ab;
 		ssp_enable(&corgi_ssp_dev);
 	}
 
@@ -229,9 +241,12 @@
 
 static int corgi_ssp_resume(struct platform_device *dev)
 {
-	GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
-	GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
-	GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
+	if (ssp_machinfo->cs_lcdcon >= 0)
+		GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
+	if (ssp_machinfo->cs_max1111 >= 0)
+		GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
+	if (ssp_machinfo->cs_ads7846 >= 0)
+		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
 	ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
 	ssp_enable(&corgi_ssp_dev);
 
Index: linux-2.6.16/arch/arm/mach-pxa/poodle.c
===================================================================
--- linux-2.6.16.orig/arch/arm/mach-pxa/poodle.c	2006-04-23 21:10:12.000000000 +0100
+++ linux-2.6.16/arch/arm/mach-pxa/poodle.c	2006-04-23 21:10:20.000000000 +0100
@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/fb.h>
 #include <linux/pm.h>
+#include <linux/delay.h>
 
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
@@ -45,6 +46,7 @@
 #include <asm/mach/sharpsl_param.h>
 
 #include "generic.h"
+#include "sharpsl.h"
 
 static struct resource poodle_scoop_resources[] = {
 	[0] = {
@@ -122,86 +124,36 @@
 	},
 };
 
-static struct platform_device locomo_device = {
+struct platform_device poodle_locomo_device = {
 	.name		= "locomo",
 	.id		= 0,
 	.num_resources	= ARRAY_SIZE(locomo_resources),
 	.resource	= locomo_resources,
 };
 
-/*
- * Temp hacks
- */
-static struct ssp_dev corgi_ssp_dev;
-
-unsigned long corgi_get_hsync_len(void)
-{
-	return 0;
-}
-
-void corgi_put_hsync(void)
-{
-}
-
-void corgi_wait_hsync(void)
-{
-}
-
-unsigned long corgi_ssp_ads7846_putget(ulong data)
-{
-	unsigned long ret,flag;
-
-	ssp_write_word(&corgi_ssp_dev,data);
-	ret = ssp_read_word(&corgi_ssp_dev);
-
-	return ret;
-}
+EXPORT_SYMBOL(poodle_locomo_device);
 
 /*
- * NOTE: These functions should always be called in interrupt context
- * and use the _lock and _unlock functions. They are very time sensitive.
+ * Corgi SSP Device
+ *
+ * Set the parent as the scoop device because a lot of SSP devices
+ * also use scoop functions and this makes the power up/down order
+ * work correctly.
  */
-void corgi_ssp_ads7846_lock(void)
-{
-}
-
-void corgi_ssp_ads7846_unlock(void)
-{
-}
-
-void corgi_ssp_ads7846_put(ulong data)
-{
-	ssp_write_word(&corgi_ssp_dev, data);
-}
-
-unsigned long corgi_ssp_ads7846_get(void)
-{
-	return ssp_read_word(&corgi_ssp_dev);
-}
-
-EXPORT_SYMBOL(corgi_ssp_ads7846_putget);
-EXPORT_SYMBOL(corgi_ssp_ads7846_lock);
-EXPORT_SYMBOL(corgi_ssp_ads7846_unlock);
-EXPORT_SYMBOL(corgi_ssp_ads7846_put);
-EXPORT_SYMBOL(corgi_ssp_ads7846_get);
-
-static int __init poodle_ssp_init(void)
-{
-	int ret;
-
-	ret = ssp_init(&corgi_ssp_dev, 1, 0);
-
-	if (ret)
-		printk(KERN_ERR "Unable to register SSP handler!\n");
-	else {
-		ssp_disable(&corgi_ssp_dev);
-		ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
-		SSCR0_P(1) = 0x11ab;
-		ssp_enable(&corgi_ssp_dev);
-	}
+struct platform_device poodle_ssp_device = {
+	.name		= "corgi-ssp",
+	.id		= -1,
+};
 
-	return ret;
-}
+struct corgissp_machinfo poodle_ssp_machinfo = {
+	.port		= 1,
+	.cs_lcdcon	= -1,
+	.cs_ads7846	= -1,
+	.cs_max1111	= -1,
+	.clk_lcdcon	= 2,
+	.clk_ads7846	= 36,
+	.clk_max1111	= 2,
+};
 
 
 /*
@@ -215,13 +167,22 @@
 	},
 };
 
+static unsigned long poodle_get_hsync_len(void)
+{
+	return 0;
+}
+
+static void poodle_null_hsync(void)
+{
+}
+
 static struct corgits_machinfo  poodle_ts_machinfo = {
-	.get_hsync_len   = corgi_get_hsync_len,
-	.put_hsync       = corgi_put_hsync,
-	.wait_hsync      = corgi_wait_hsync,
+	.get_hsync_len   = poodle_get_hsync_len,
+	.put_hsync       = poodle_null_hsync,
+	.wait_hsync      = poodle_null_hsync,
 };
 
-static struct platform_device poodlets_device = {
+static struct platform_device poodle_ts_device = {
 	.name		= "corgi-ts",
 	.dev		= {
 		.platform_data	= &poodle_ts_machinfo,
@@ -248,7 +209,10 @@
 	pxa_gpio_mode(GPIO6_MMCCLK_MD);
 	pxa_gpio_mode(GPIO8_MMCCS0_MD);
 	pxa_gpio_mode(POODLE_GPIO_nSD_DETECT | GPIO_IN);
+	pxa_gpio_mode(POODLE_GPIO_nSD_WP | GPIO_IN);
 	pxa_gpio_mode(POODLE_GPIO_SD_PWR | GPIO_OUT);
+	pxa_gpio_mode(POODLE_GPIO_SD_PWR1 | GPIO_OUT);
+
 
 	poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 
@@ -267,12 +231,22 @@
 {
 	struct pxamci_platform_data* p_d = dev->platform_data;
 
-	if (( 1 << vdd) & p_d->ocr_mask)
-		GPSR1 = GPIO_bit(POODLE_GPIO_SD_PWR);
-	else
-		GPCR1 = GPIO_bit(POODLE_GPIO_SD_PWR);
+	if (( 1 << vdd) & p_d->ocr_mask) {
+		GPSR(POODLE_GPIO_SD_PWR) = GPIO_bit(POODLE_GPIO_SD_PWR);
+		mdelay(2);
+		GPSR(POODLE_GPIO_SD_PWR1) = GPIO_bit(POODLE_GPIO_SD_PWR1);
+	} else {
+		GPCR(POODLE_GPIO_SD_PWR1) = GPIO_bit(POODLE_GPIO_SD_PWR1);
+		GPCR(POODLE_GPIO_SD_PWR) = GPIO_bit(POODLE_GPIO_SD_PWR);
+	}
+}
+
+static int poodle_mci_get_ro(struct device *dev)
+{
+	return GPLR(POODLE_GPIO_nSD_WP) & GPIO_bit(POODLE_GPIO_nSD_WP);
 }
 
+
 static void poodle_mci_exit(struct device *dev, void *data)
 {
 	free_irq(POODLE_IRQ_GPIO_nSD_DETECT, data);
@@ -281,6 +255,7 @@
 static struct pxamci_platform_data poodle_mci_platform_data = {
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
 	.init 		= poodle_mci_init,
+	.get_ro		= poodle_mci_get_ro,
 	.setpower 	= poodle_mci_setpower,
 	.exit		= poodle_mci_exit,
 };
@@ -350,9 +325,10 @@
 };
 
 static struct platform_device *devices[] __initdata = {
-	&locomo_device,
+	&poodle_locomo_device,
 	&poodle_scoop_device,
-	&poodlets_device,
+	&poodle_ssp_device,
+	&poodle_ts_device,
 };
 
 static void poodle_poweroff(void)
@@ -405,6 +381,7 @@
   	GPSR1 = 0x00000000;
         GPSR2 = 0x00000000;
 
+	set_pxa_fb_parent(&poodle_locomo_device.dev);
 	set_pxa_fb_info(&poodle_fb_info);
 	pxa_gpio_mode(POODLE_GPIO_USB_PULLUP | GPIO_OUT);
 	pxa_gpio_mode(POODLE_GPIO_IR_ON | GPIO_OUT);
@@ -418,7 +395,7 @@
 	if (ret) {
 		printk(KERN_WARNING "poodle: Unable to register LoCoMo device\n");
 	}
-	poodle_ssp_init();
+	corgi_ssp_set_machinfo(&poodle_ssp_machinfo);
 }
 
 static void __init fixup_poodle(struct machine_desc *desc,
Index: linux-2.6.16/arch/arm/mach-pxa/poodle_pm.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.16/arch/arm/mach-pxa/poodle_pm.c	2006-04-23 21:10:20.000000000 +0100
@@ -0,0 +1,355 @@
+/*
+ * Battery and Power Management code for the Sharp SL-5600
+ *
+ * Copyright (c) 2006 Richard Purdie
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/stat.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <asm/apm.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/hardware/scoop.h>
+#include <asm/hardware/locomo.h>
+
+#include <asm/arch/sharpsl.h>
+#include <asm/arch/poodle.h>
+#include <asm/arch/pxa-regs.h>
+#include "sharpsl.h"
+
+#if 0
+#define SHARPSL_CHARGE_ON_VOLT         0x99  /* 2.9V */
+#define SHARPSL_CHARGE_ON_TEMP         0xe0  /* 2.9V */
+#define SHARPSL_CHARGE_ON_ACIN_HIGH    0x9b  /* 6V */
+#define SHARPSL_CHARGE_ON_ACIN_LOW     0x34  /* 2V */
+#define SHARPSL_FATAL_ACIN_VOLT        182   /* 3.45V */
+#define SHARPSL_FATAL_NOACIN_VOLT      170   /* 3.40V */
+#endif
+
+#define SHARPSL_CHARGE_ON_VOLT			1187	// 2.9V
+#define SHARPSL_CHARGE_ON_TEMP			2441
+#define SHARPSL_FATAL_NOACIN_VOLT	1454    // 3.55V
+#define SHARPSL_FATAL_ACIN_VOLT	1474    // 3.60V
+
+
+#if 0
+#define SHARPSL_POWER_MODE_CHECK		1475
+#define SHARPSL_POODLE_FATAL_VOLT		1433
+#define SHARPSL_POODLE_FATAL_NOACIN_FLON_VOLT	1454    // 3.55V
+#define SHARPSL_POODLE_FATAL_NOACIN_FLOFF_VOLT	1433    // 3.50V
+#define SHARPSL_POODLE_FATAL_ACIN_FLON_VOLT	1474    // 3.60V
+#define SHARPSL_POODLE_FATAL_ACIN_FLOFF_VOLT	1454    // 3.55V
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP	5	// 50msec
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT	1	// 10msec
+#define SHARPSL_WAIT_DISCHARGE_ON		5	// 50msec
+#endif
+
+
+struct battery_thresh poodle_battery_levels_fl[] = {
+    {1582, 100},
+    {1527,  75},
+    {1482,  50},
+    {1458,  25},
+    {1404,   5},
+    {   0,   0},
+};
+
+struct battery_thresh poodle_battery_levels_nofl[] = {
+    {1589, 100},
+    {1536,  75},
+    {1490,  50},
+    {1466,  25},
+    {1413,   5},
+    {   0,   0},
+};
+
+struct battery_thresh poodle_battery_levels_acin_fl[] = {
+    {1601, 100},
+    {1536,  75},
+    {1503,  50},
+    {1482,  25},
+    {   0,   5},
+    {   0,   0},
+};
+
+struct battery_thresh poodle_battery_levels_acin_nofl[] = {
+    {1609, 100},
+    {1548,  75},
+    {1527,  50},
+    {1495,  25},
+    {   0,   5},
+    {   0,   0},
+};
+
+static void poodle_charger_init(void)
+{
+	pxa_gpio_mode(POODLE_GPIO_ADC_TEMP_ON | GPIO_OUT);
+	pxa_gpio_mode(POODLE_GPIO_CHRG_ON | GPIO_OUT);
+	pxa_gpio_mode(POODLE_GPIO_BYPASS_ON | GPIO_OUT);
+	pxa_gpio_mode(POODLE_GPIO_ON_KEY | GPIO_IN);
+	sharpsl_pm_pxa_init();
+}
+
+static void poodle_measure_temp(int on)
+{
+	if (on)
+		GPSR(POODLE_GPIO_ADC_TEMP_ON) = GPIO_bit(POODLE_GPIO_ADC_TEMP_ON);
+	else
+		GPCR(POODLE_GPIO_ADC_TEMP_ON) = GPIO_bit(POODLE_GPIO_ADC_TEMP_ON);
+}
+
+extern struct locomo_dev *frontlight_dev;
+
+static void poodle_charge(int on)
+{
+	if (on) {
+		GPSR(POODLE_GPIO_CHRG_ON) = GPIO_bit(POODLE_GPIO_CHRG_ON);
+		locomo_gpio_write(frontlight_dev, POODLE_LOCOMO_GPIO_JK_B, 1);
+	} else {
+		GPCR(POODLE_GPIO_CHRG_ON) = GPIO_bit(POODLE_GPIO_CHRG_ON);
+		locomo_gpio_write(frontlight_dev, POODLE_LOCOMO_GPIO_JK_B, 0);
+	}
+}
+
+static void poodle_discharge(int on)
+{
+	if (on)
+		GPSR(POODLE_GPIO_DISCHARGE_ON) = GPIO_bit(POODLE_GPIO_DISCHARGE_ON);
+	else
+		GPCR(POODLE_GPIO_DISCHARGE_ON) = GPIO_bit(POODLE_GPIO_DISCHARGE_ON);
+}
+
+static void poodle_presuspend(void)
+{
+	int i;
+	unsigned long wakeup_mask;
+
+	/* charging , so CHARGE_ON bit is HIGH during OFF. */
+	if (READ_GPIO_BIT(POODLE_GPIO_CHRG_ON))
+		PGSR1 |= GPIO_bit(POODLE_GPIO_CHRG_ON);
+	else
+		PGSR1 &= ~GPIO_bit(POODLE_GPIO_CHRG_ON);
+
+//	if (READ_GPIO_BIT(CORGI_GPIO_CHRG_UKN))
+//		PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_UKN);
+//	else
+//		PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_UKN);
+
+	/* Resume on keyboard power key */
+//	PGSR2 = (PGSR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(0);
+
+	wakeup_mask = GPIO_bit(POODLE_GPIO_ON_KEY) | GPIO_bit(POODLE_GPIO_WAKEUP);
+	wakeup_mask |= GPIO_bit(POODLE_GPIO_AC_IN) | GPIO_bit(POODLE_GPIO_CHRG_FULL);
+	wakeup_mask |= GPIO_bit(POODLE_GPIO_MAIN_BAT_LOW) | GPIO_bit(POODLE_GPIO_CF_CD);
+	wakeup_mask |= GPIO_bit(POODLE_GPIO_HP_IN) | GPIO_bit(POODLE_GPIO_GA_INT) | GPIO_bit(POODLE_GPIO_nSD_INT);
+
+
+//	if (!machine_is_corgi())
+//		GPDR0 &= ~(GPIO_bit(15) | GPIO_bit(8)); /* Float n_CS1 */
+
+	PWER = wakeup_mask | PWER_RTC;
+	PRER = wakeup_mask;
+	PFER = wakeup_mask;
+
+	for (i = 0; i <=15; i++) {
+		if (PRER & PFER & GPIO_bit(i)) {
+			if (GPLR0 & GPIO_bit(i) )
+				PRER &= ~GPIO_bit(i);
+			else
+				PFER &= ~GPIO_bit(i);
+		}
+	}
+}
+
+static void poodle_postsuspend(void)
+{
+//	if (!machine_is_corgi())
+//		GPDR0 |= GPIO_bit(15) | GPIO_bit(8); /* Un-Float n_CS1 */
+}
+
+/*
+ * Check what brought us out of the suspend.
+ * Return: 0 to sleep, otherwise wake
+ */
+static int poodle_should_wakeup(unsigned int resume_on_alarm)
+{
+	int is_resume = 0;
+
+	dev_dbg(sharpsl_pm.dev, "GPLR0 = %x,%x\n", GPLR0, PEDR);
+
+	if ((PEDR & GPIO_bit(POODLE_GPIO_AC_IN))) {
+		if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
+			/* charge on */
+			dev_dbg(sharpsl_pm.dev, "ac insert\n");
+			sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
+		} else {
+			/* charge off */
+			dev_dbg(sharpsl_pm.dev, "ac remove\n");
+			sharpsl_pm_led(SHARPSL_LED_OFF);
+			sharpsl_pm.machinfo->charge(0);
+			sharpsl_pm.charge_mode = CHRG_OFF;
+		}
+	}
+
+	if ((PEDR & GPIO_bit(POODLE_GPIO_CHRG_FULL)))
+		dev_dbg(sharpsl_pm.dev, "Charge full interrupt\n");
+
+	if (PEDR & GPIO_bit(POODLE_GPIO_ON_KEY))
+		is_resume |= GPIO_bit(POODLE_GPIO_ON_KEY);
+
+	if (PEDR & GPIO_bit(POODLE_GPIO_WAKEUP))
+		is_resume |= GPIO_bit(POODLE_GPIO_WAKEUP);
+
+//	if ( (apm_wakeup_factor & GPIO_bit(GPIO_GA_INT)) && (LCM_KIC & 1) ) {
+//		LCM_KIC &= ~0x100;
+//		LCM_ICR &= ~0x100;
+//		is_resume |= GPIO_bit(GPIO_GA_INT);
+//	}
+
+	if (PEDR & GPIO_bit(POODLE_GPIO_CF_STSCHG))
+		is_resume |= GPIO_bit(POODLE_GPIO_CF_STSCHG);
+
+	if (PEDR & GPIO_bit(POODLE_GPIO_nSD_INT))
+		is_resume |= GPIO_bit(POODLE_GPIO_nSD_INT);
+
+	if (PEDR & GPIO_bit(POODLE_GPIO_HP_IN))
+		is_resume |= GPIO_bit(POODLE_GPIO_HP_IN);
+
+	if (resume_on_alarm && (PEDR & PWER_RTC))
+		is_resume |= PWER_RTC;
+
+	dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume);
+	return is_resume;
+}
+
+static unsigned long poodle_charger_wakeup(void)
+{
+	return ~GPLR0 & ( GPIO_bit(POODLE_GPIO_AC_IN) | GPIO_bit(POODLE_GPIO_ON_KEY) | GPIO_bit(POODLE_GPIO_WAKEUP) );
+}
+
+#define MUX_CHL    6u
+#define BATT_CHL   2u
+
+/* ADS7846 Touch Screen Controller bit definitions */
+#define ADSCTRL_PD0		(1u << 0)	/* PD0 */
+#define ADSCTRL_PD1		(1u << 1)	/* PD1 */
+#define ADSCTRL_DFR		(1u << 2)	/* SER/DFR */
+#define ADSCTRL_MOD		(1u << 3)	/* Mode */
+#define ADSCTRL_ADR_SH	4	/* Address setting */
+#define ADSCTRL_STS		(1u << 7)	/* Start Bit */
+
+int poodle_pm_read_ads7846(int channel)
+{
+	int voltage;
+	int cmd = ADSCTRL_PD0 | ADSCTRL_PD1 | ADSCTRL_DFR |
+		(channel << ADSCTRL_ADR_SH) | ADSCTRL_STS;
+
+	corgi_ssp_ads7846_lock();
+
+	corgi_ssp_ads7846_put(cmd);
+	corgi_ssp_ads7846_get();
+
+	corgi_ssp_ads7846_put(cmd);
+	voltage = corgi_ssp_ads7846_get();
+
+	/* Power-Down Enable */
+	corgi_ssp_ads7846_put((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
+	corgi_ssp_ads7846_get();
+
+	corgi_ssp_ads7846_unlock();
+
+	return voltage;
+}
+
+unsigned long poodlepm_read_devdata(int type)
+{
+	switch(type) {
+	case SHARPSL_STATUS_ACIN:
+		return ((GPLR(POODLE_GPIO_AC_IN) & GPIO_bit(POODLE_GPIO_AC_IN)) != 0);
+	case SHARPSL_STATUS_LOCK:
+		return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock);
+	case SHARPSL_STATUS_CHRGFULL:
+		return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull);
+	case SHARPSL_STATUS_FATAL:
+		return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal);
+//	case SHARPSL_ACIN_VOLT:
+//		return poodle_pm_read_ads7846(MAX1111_ACIN_VOLT);
+// FIXME
+	case SHARPSL_BATT_TEMP:
+		return poodle_pm_read_ads7846(MUX_CHL);
+	case SHARPSL_BATT_VOLT:
+	default:
+		return poodle_pm_read_ads7846(BATT_CHL);
+	}
+}
+
+static void poodle_limit_intensity(int limit)
+{
+}
+
+static struct sharpsl_charger_machinfo poodle_pm_machinfo = {
+	.init            = poodle_charger_init,
+	.exit            = sharpsl_pm_pxa_remove,
+	.gpio_batlock    = POODLE_GPIO_BAT_COVER,
+	.gpio_acin       = POODLE_GPIO_AC_IN,
+	.gpio_batfull    = POODLE_GPIO_CHRG_FULL,
+	.batfull_irq	  = 1,
+	.discharge       = poodle_discharge,
+	.charge          = poodle_charge,
+	.measure_temp    = poodle_measure_temp,
+	.presuspend      = poodle_presuspend,
+	.postsuspend     = poodle_postsuspend,
+	.read_devdata    = poodlepm_read_devdata,
+	.charger_wakeup  = poodle_charger_wakeup,
+	.should_wakeup   = poodle_should_wakeup,
+	.backlight_limit =  poodle_limit_intensity,
+	.charge_on_volt	  = SHARPSL_CHARGE_ON_VOLT,
+	.charge_on_temp	  = SHARPSL_CHARGE_ON_TEMP,
+	.fatal_acin_volt  = SHARPSL_FATAL_ACIN_VOLT,
+	.fatal_noacin_volt= SHARPSL_FATAL_NOACIN_VOLT,
+	.bat_levels       = 6,
+	.bat_levels_noac  = poodle_battery_levels_fl,
+	.bat_levels_acin  = poodle_battery_levels_nofl,
+	.status_high_acin = 1490,
+	.status_low_acin  = 1466,
+	.status_high_noac = 1482,
+	.status_low_noac  = 1458,
+};
+
+static struct platform_device *poodlepm_device;
+
+static int __devinit poodlepm_init(void)
+{
+	int ret;
+
+	poodlepm_device = platform_device_alloc("sharpsl-pm", -1);
+	if (!poodlepm_device)
+		return -ENOMEM;
+
+	poodlepm_device->dev.platform_data = &poodle_pm_machinfo;
+	ret = platform_device_add(poodlepm_device);
+
+	if (ret)
+		platform_device_put(poodlepm_device);
+
+	return ret;
+}
+
+static void poodlepm_exit(void)
+{
+	platform_device_unregister(poodlepm_device);
+}
+
+module_init(poodlepm_init);
+module_exit(poodlepm_exit);
Index: linux-2.6.16/drivers/leds/leds-locomo.c
===================================================================
--- linux-2.6.16.orig/drivers/leds/leds-locomo.c	2006-04-23 21:10:12.000000000 +0100
+++ linux-2.6.16/drivers/leds/leds-locomo.c	2006-04-23 21:10:20.000000000 +0100
@@ -45,11 +45,13 @@
 
 static struct led_classdev locomo_led0 = {
 	.name			= "locomo:amber",
+	.default_trigger	= "sharpsl-charge",
 	.brightness_set		= locomoled_brightness_set0,
 };
 
 static struct led_classdev locomo_led1 = {
 	.name			= "locomo:green",
+	.default_trigger	= "nand-disk",
 	.brightness_set		= locomoled_brightness_set1,
 };
 
Index: linux-2.6.16/drivers/serial/pxa.c
===================================================================
--- linux-2.6.16.orig/drivers/serial/pxa.c	2006-04-23 21:10:12.000000000 +0100
+++ linux-2.6.16/drivers/serial/pxa.c	2006-04-23 21:10:20.000000000 +0100
@@ -801,8 +801,8 @@
 {
         struct uart_pxa_port *sport = platform_get_drvdata(dev);
 
-        if (sport)
-                uart_suspend_port(&serial_pxa_reg, &sport->port);
+//        if (sport)
+//                uart_suspend_port(&serial_pxa_reg, &sport->port);
 
         return 0;
 }
@@ -811,8 +811,8 @@
 {
         struct uart_pxa_port *sport = platform_get_drvdata(dev);
 
-        if (sport)
-                uart_resume_port(&serial_pxa_reg, &sport->port);
+//        if (sport)
+//                uart_resume_port(&serial_pxa_reg, &sport->port);
 
         return 0;
 }
Index: linux-2.6.16/include/asm-arm/arch-pxa/poodle.h
===================================================================
--- linux-2.6.16.orig/include/asm-arm/arch-pxa/poodle.h	2006-04-23 21:10:12.000000000 +0100
+++ linux-2.6.16/include/asm-arm/arch-pxa/poodle.h	2006-04-23 21:10:20.000000000 +0100
@@ -31,6 +31,7 @@
 #define POODLE_GPIO_CF_CD		(14)
 #define POODLE_GPIO_CF_STSCHG		(14)
 #define POODLE_GPIO_SD_PWR		(33)
+#define POODLE_GPIO_SD_PWR1		(3)
 #define POODLE_GPIO_nSD_CLK		(6)
 #define POODLE_GPIO_nSD_WP		(7)
 #define POODLE_GPIO_nSD_INT		(8)
@@ -42,6 +43,7 @@
 #define POODLE_GPIO_BYPASS_ON		(36)
 #define POODLE_GPIO_CHRG_ON		(38)
 #define POODLE_GPIO_CHRG_FULL		(16)
+#define POODLE_GPIO_DISCHARGE_ON        (42) /* Enable battery Discharge */
 
 /* PXA GPIOs */
 #define POODLE_IRQ_GPIO_ON_KEY		IRQ_GPIO(0)
@@ -68,4 +70,6 @@
 #define POODLE_SCOOP_IO_DIR	( POODLE_SCOOP_VPEN | POODLE_SCOOP_HS_OUT )
 #define POODLE_SCOOP_IO_OUT	( 0 )
 
+extern struct platform_device poodle_locomo_device;
+
 #endif /* __ASM_ARCH_POODLE_H  */
Index: linux-2.6.16/include/asm-arm/hardware/locomo.h
===================================================================
--- linux-2.6.16.orig/include/asm-arm/hardware/locomo.h	2006-04-23 21:10:12.000000000 +0100
+++ linux-2.6.16/include/asm-arm/hardware/locomo.h	2006-04-23 21:10:20.000000000 +0100
@@ -95,6 +95,11 @@
 #define LOCOMO_GPIO_DAC_SDATA	LOCOMO_GPIO(10)
 #define LOCOMO_GPIO_DAC_SCK	LOCOMO_GPIO(11)
 #define LOCOMO_GPIO_DAC_SLOAD	LOCOMO_GPIO(12)
+#define POODLE_LOCOMO_GPIO_AMP_ON      LOCOMO_GPIO(8)
+#define POODLE_LOCOMO_GPIO_MUTE_L      LOCOMO_GPIO(10)
+#define POODLE_LOCOMO_GPIO_MUTE_R      LOCOMO_GPIO(11)
+#define POODLE_LOCOMO_GPIO_232VCC_ON   LOCOMO_GPIO(12)
+#define POODLE_LOCOMO_GPIO_JK_B        LOCOMO_GPIO(13)
 
 /* Start the definitions of the devices.  Each device has an initial
  * base address and a series of offsets from that base address. */
Index: linux-2.6.16/arch/arm/common/locomo.c
===================================================================
--- linux-2.6.16.orig/arch/arm/common/locomo.c	2006-04-23 21:10:12.000000000 +0100
+++ linux-2.6.16/arch/arm/common/locomo.c	2006-04-23 21:10:20.000000000 +0100
@@ -565,6 +565,7 @@
 	spin_lock_irqsave(&lchip->lock, flags);
 
 	save->LCM_GPO     = locomo_readl(lchip->base + LOCOMO_GPO);	/* GPIO */
+	// FIXME - should save JK_B
 	locomo_writel(0x00, lchip->base + LOCOMO_GPO);
 	save->LCM_SPICT   = locomo_readl(lchip->base + LOCOMO_SPICT);	/* SPI */
 	locomo_writel(0x40, lchip->base + LOCOMO_SPICT);
@@ -1049,11 +1050,16 @@
 
 static struct locomo *locomo_chip_driver(struct locomo_dev *ldev);
 
+struct locomo_dev *frontlight_dev;
+EXPORT_SYMBOL(frontlight_dev);
+
 void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf)
 {
 	unsigned long flags;
 	struct locomo *lchip = locomo_chip_driver(dev);
 
+	frontlight_dev = dev;
+
 	if (vr)
 		locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 1);
 	else
Index: linux-2.6.16/drivers/video/backlight/locomolcd.c
===================================================================
--- linux-2.6.16.orig/drivers/video/backlight/locomolcd.c	2006-04-23 21:10:12.000000000 +0100
+++ linux-2.6.16/drivers/video/backlight/locomolcd.c	2006-04-23 21:10:20.000000000 +0100
@@ -130,6 +130,8 @@
 	if (locomolcd_flags & LOCOMOLCD_SUSPENDED)
 		intensity = 0;
 
+	locomolcd_power(1);
+
 	switch (intensity) {
 	/* AC and non-AC are handled differently, but produce same results in sharp code? */
 	case 0: locomo_frontlight_set(locomolcd_dev, 0, 0, 161); break;

