Explorar el Código

Merge Zaurus branch

Russell King hace 19 años
padre
commit
3a8182bd88

+ 11 - 17
arch/arm/common/sharpsl_pm.c

@@ -49,13 +49,6 @@
 #define SHARPSL_CHARGE_CO_CHECK_TIME           5   /* 5 msec */
 #define SHARPSL_CHARGE_RETRY_CNT               1   /* eqv. 10 min */
 
-#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 */
-
 /*
  * Prototypes
  */
@@ -82,12 +75,13 @@ DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger);
 static int get_percentage(int voltage)
 {
 	int i = sharpsl_pm.machinfo->bat_levels - 1;
+	int bl_status = sharpsl_pm.machinfo->backlight_get_status ? sharpsl_pm.machinfo->backlight_get_status() : 0;
 	struct battery_thresh *thresh;
 
 	if (sharpsl_pm.charge_mode == CHRG_ON)
-		thresh=sharpsl_pm.machinfo->bat_levels_acin;
+		thresh = bl_status ? sharpsl_pm.machinfo->bat_levels_acin_bl : sharpsl_pm.machinfo->bat_levels_acin;
 	else
-		thresh=sharpsl_pm.machinfo->bat_levels_noac;
+		thresh = bl_status ? sharpsl_pm.machinfo->bat_levels_noac_bl : sharpsl_pm.machinfo->bat_levels_noac;
 
 	while (i > 0 && (voltage > thresh[i].voltage))
 		i--;
@@ -131,7 +125,7 @@ static void sharpsl_battery_thread(void *private_)
 	sharpsl_pm.battstat.ac_status = (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN) ? APM_AC_ONLINE : APM_AC_OFFLINE);
 
 	/* Corgi cannot confirm when battery fully charged so periodically kick! */
-	if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON)
+	if (!sharpsl_pm.machinfo->batfull_irq && (sharpsl_pm.charge_mode == CHRG_ON)
 			&& time_after(jiffies, sharpsl_pm.charge_start_time +  SHARPSL_CHARGE_ON_TIME_INTERVAL))
 		schedule_work(&toggle_charger);
 
@@ -166,11 +160,11 @@ static void sharpsl_battery_thread(void *private_)
 			&& ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) ||
 			(sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) {
 		if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) {
-			corgibl_limit_intensity(1);
+			sharpsl_pm.machinfo->backlight_limit(1);
 			sharpsl_pm.flags |= SHARPSL_BL_LIMIT;
 		}
 	} else if (sharpsl_pm.flags & SHARPSL_BL_LIMIT) {
-		corgibl_limit_intensity(0);
+		sharpsl_pm.machinfo->backlight_limit(0);
 		sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT;
 	}
 
@@ -418,7 +412,7 @@ static int sharpsl_check_battery_temp(void)
 	val = get_select_val(buff);
 
 	dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val);
-	if (val > SHARPSL_CHARGE_ON_TEMP)
+	if (val > sharpsl_pm.machinfo->charge_on_temp)
 		return -1;
 
 	return 0;
@@ -450,7 +444,7 @@ static int sharpsl_check_battery_voltage(void)
 	val = get_select_val(buff);
 	dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val);
 
-	if (val < SHARPSL_CHARGE_ON_VOLT)
+	if (val < sharpsl_pm.machinfo->charge_on_volt)
 		return -1;
 
 	return 0;
@@ -468,7 +462,7 @@ static int sharpsl_ac_check(void)
 	temp = get_select_val(buff);
 	dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);
 
-	if ((temp > SHARPSL_CHARGE_ON_ACIN_HIGH) || (temp < SHARPSL_CHARGE_ON_ACIN_LOW)) {
+	if ((temp > sharpsl_pm.machinfo->charge_acin_high) || (temp < sharpsl_pm.machinfo->charge_acin_low)) {
 		dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");
 		return -1;
 	}
@@ -627,8 +621,8 @@ static int sharpsl_fatal_check(void)
 	temp = get_select_val(buff);
 	dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT));
 
-	if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) ||
-			(!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT)))
+	if ((acin && (temp < sharpsl_pm.machinfo->fatal_acin_volt)) ||
+			(!acin && (temp < sharpsl_pm.machinfo->fatal_noacin_volt)))
 		return -1;
 	return 0;
 }

+ 35 - 26
arch/arm/kernel/process.c

@@ -28,6 +28,7 @@
 #include <linux/init.h>
 #include <linux/cpu.h>
 #include <linux/elfcore.h>
+#include <linux/pm.h>
 
 #include <asm/leds.h>
 #include <asm/processor.h>
@@ -71,8 +72,36 @@ static int __init hlt_setup(char *__unused)
 __setup("nohlt", nohlt_setup);
 __setup("hlt", hlt_setup);
 
+void arm_machine_restart(char mode)
+{
+	/*
+	 * Clean and disable cache, and turn off interrupts
+	 */
+	cpu_proc_fin();
+
+	/*
+	 * Tell the mm system that we are going to reboot -
+	 * we may need it to insert some 1:1 mappings so that
+	 * soft boot works.
+	 */
+	setup_mm_for_reboot(mode);
+
+	/*
+	 * Now call the architecture specific reboot code.
+	 */
+	arch_reset(mode);
+
+	/*
+	 * Whoops - the architecture was unable to reboot.
+	 * Tell the user!
+	 */
+	mdelay(1000);
+	printk("Reboot failed -- System halted\n");
+	while (1);
+}
+
 /*
- * The following aren't currently used.
+ * Function pointers to optional machine specific functions
  */
 void (*pm_idle)(void);
 EXPORT_SYMBOL(pm_idle);
@@ -80,6 +109,10 @@ EXPORT_SYMBOL(pm_idle);
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
+void (*arm_pm_restart)(char str) = arm_machine_restart;
+EXPORT_SYMBOL_GPL(arm_pm_restart);
+
+
 /*
  * This is our default idle handler.  We need to disable
  * interrupts here to ensure we don't miss a wakeup call.
@@ -151,33 +184,9 @@ void machine_power_off(void)
 		pm_power_off();
 }
 
-
 void machine_restart(char * __unused)
 {
-	/*
-	 * Clean and disable cache, and turn off interrupts
-	 */
-	cpu_proc_fin();
-
-	/*
-	 * Tell the mm system that we are going to reboot -
-	 * we may need it to insert some 1:1 mappings so that
-	 * soft boot works.
-	 */
-	setup_mm_for_reboot(reboot_mode);
-
-	/*
-	 * Now call the architecture specific reboot code.
-	 */
-	arch_reset(reboot_mode);
-
-	/*
-	 * Whoops - the architecture was unable to reboot.
-	 * Tell the user!
-	 */
-	mdelay(1000);
-	printk("Reboot failed -- System halted\n");
-	while (1);
+	arm_pm_restart(reboot_mode);
 }
 
 void __show_regs(struct pt_regs *regs)

+ 1 - 0
arch/arm/mach-pxa/Kconfig

@@ -61,6 +61,7 @@ config MACH_POODLE
 	bool "Enable Sharp SL-5600 (Poodle) Support"
 	depends PXA_SHARPSL_25x
 	select SHARP_LOCOMO
+	select PXA_SSP
 
 config MACH_CORGI
 	bool "Enable Sharp SL-C700 (Corgi) Support"

+ 1 - 1
arch/arm/mach-pxa/Makefile

@@ -15,7 +15,7 @@ obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
 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
 obj-$(CONFIG_MACH_TOSA)         += tosa.o
 
 # Support for blinky lights

+ 25 - 0
arch/arm/mach-pxa/corgi.c

@@ -19,6 +19,7 @@
 #include <linux/fs.h>
 #include <linux/interrupt.h>
 #include <linux/mmc/host.h>
+#include <linux/pm.h>
 
 #include <asm/setup.h>
 #include <asm/memory.h>
@@ -26,6 +27,7 @@
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/io.h>
+#include <asm/system.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -310,8 +312,31 @@ static struct platform_device *devices[] __initdata = {
 	&corgiled_device,
 };
 
+static void corgi_poweroff(void)
+{
+	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
+	if (!machine_is_corgi())
+		/* Green LED off tells the bootloader to halt */
+		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
+	arm_machine_restart('h');
+}
+
+static void corgi_restart(char mode)
+{
+	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
+	if (!machine_is_corgi())
+		/* Green LED on tells the bootloader to reboot */
+		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
+	arm_machine_restart('h');
+}
+
 static void __init corgi_init(void)
 {
+	pm_power_off = corgi_poweroff;
+	arm_pm_restart = corgi_restart;
+
 	/* setup sleep mode values */
 	PWER  = 0x00000002;
 	PFER  = 0x00000000;

+ 20 - 3
arch/arm/mach-pxa/corgi_pm.c

@@ -27,6 +27,13 @@
 #include <asm/arch/pxa-regs.h>
 #include "sharpsl.h"
 
+#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 */
+
 static void corgi_charger_init(void)
 {
 	pxa_gpio_mode(CORGI_GPIO_ADC_TEMP_ON | GPIO_OUT);
@@ -195,9 +202,16 @@ static struct sharpsl_charger_machinfo corgi_pm_machinfo = {
 	.read_devdata    = corgipm_read_devdata,
 	.charger_wakeup  = corgi_charger_wakeup,
 	.should_wakeup   = corgi_should_wakeup,
-	.bat_levels      = 40,
-	.bat_levels_noac = spitz_battery_levels_noac,
-	.bat_levels_acin = spitz_battery_levels_acin,
+	.backlight_limit = corgibl_limit_intensity,
+	.charge_on_volt	  = SHARPSL_CHARGE_ON_VOLT,
+	.charge_on_temp	  = SHARPSL_CHARGE_ON_TEMP,
+	.charge_acin_high = SHARPSL_CHARGE_ON_ACIN_HIGH,
+	.charge_acin_low  = SHARPSL_CHARGE_ON_ACIN_LOW,
+	.fatal_acin_volt  = SHARPSL_FATAL_ACIN_VOLT,
+	.fatal_noacin_volt= SHARPSL_FATAL_NOACIN_VOLT,
+	.bat_levels       = 40,
+	.bat_levels_noac  = spitz_battery_levels_noac,
+	.bat_levels_acin  = spitz_battery_levels_acin,
 	.status_high_acin = 188,
 	.status_low_acin  = 178,
 	.status_high_noac = 185,
@@ -214,6 +228,9 @@ static int __devinit corgipm_init(void)
 	if (!corgipm_device)
 		return -ENOMEM;
 
+	if (!machine_is_corgi())
+	    corgi_pm_machinfo.batfull_irq = 1;
+
 	corgipm_device->dev.platform_data = &corgi_pm_machinfo;
 	ret = platform_device_add(corgipm_device);
 

+ 28 - 14
arch/arm/mach-pxa/corgi_ssp.c

@@ -50,12 +50,14 @@ unsigned long corgi_ssp_ads7846_putget(ulong data)
 	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 @@ unsigned long corgi_ssp_ads7846_putget(ulong data)
 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 @@ unsigned long corgi_ssp_dac_put(ulong data)
 	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 corgi_ssp_max1111_get(ulong data)
 	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 @@ int corgi_ssp_max1111_get(ulong data)
 	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 @@ static int __init corgi_ssp_probe(struct platform_device *dev)
 	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);
 
@@ -229,9 +240,12 @@ static int corgi_ssp_suspend(struct platform_device *dev, pm_message_t state)
 
 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);
 

+ 102 - 6
arch/arm/mach-pxa/poodle.c

@@ -18,11 +18,14 @@
 #include <linux/init.h>
 #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>
 #include <asm/irq.h>
 #include <asm/setup.h>
+#include <asm/system.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -34,12 +37,15 @@
 #include <asm/arch/irda.h>
 #include <asm/arch/poodle.h>
 #include <asm/arch/pxafb.h>
+#include <asm/arch/sharpsl.h>
+#include <asm/arch/ssp.h>
 
 #include <asm/hardware/scoop.h>
 #include <asm/hardware/locomo.h>
 #include <asm/mach/sharpsl_param.h>
 
 #include "generic.h"
+#include "sharpsl.h"
 
 static struct resource poodle_scoop_resources[] = {
 	[0] = {
@@ -117,13 +123,71 @@ static struct resource locomo_resources[] = {
 	},
 };
 
-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,
 };
 
+EXPORT_SYMBOL(poodle_locomo_device);
+
+/*
+ * Poodle SSP Device
+ */
+
+struct platform_device poodle_ssp_device = {
+	.name		= "corgi-ssp",
+	.id		= -1,
+};
+
+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,
+};
+
+
+/*
+ * Poodle Touch Screen Device
+ */
+static struct resource poodlets_resources[] = {
+	[0] = {
+		.start		= POODLE_IRQ_GPIO_TP_INT,
+		.end		= POODLE_IRQ_GPIO_TP_INT,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+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   = poodle_get_hsync_len,
+	.put_hsync       = poodle_null_hsync,
+	.wait_hsync      = poodle_null_hsync,
+};
+
+static struct platform_device poodle_ts_device = {
+	.name		= "corgi-ts",
+	.dev		= {
+		.platform_data	= &poodle_ts_machinfo,
+	},
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(poodlets_resources),
+	.resource	= poodlets_resources,
+};
+
 
 /*
  * MMC/SD Device
@@ -141,7 +205,9 @@ static int poodle_mci_init(struct device *dev, irqreturn_t (*poodle_detect_int)(
 	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);
 
@@ -160,12 +226,22 @@ static void poodle_mci_setpower(struct device *dev, unsigned int vdd)
 {
 	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);
@@ -174,6 +250,7 @@ static void poodle_mci_exit(struct device *dev, void *data)
 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,
 };
@@ -243,14 +320,31 @@ static struct pxafb_mach_info poodle_fb_info __initdata = {
 };
 
 static struct platform_device *devices[] __initdata = {
-	&locomo_device,
+	&poodle_locomo_device,
 	&poodle_scoop_device,
+	&poodle_ssp_device,
+	&poodle_ts_device,
 };
 
+static void poodle_poweroff(void)
+{
+	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+	arm_machine_restart('h');
+}
+
+static void poodle_restart(char mode)
+{
+	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+	arm_machine_restart('h');
+}
+
 static void __init poodle_init(void)
 {
 	int ret = 0;
 
+	pm_power_off = poodle_poweroff;
+	arm_pm_restart = poodle_restart;
+
 	/* setup sleep mode values */
 	PWER  = 0x00000002;
 	PFER  = 0x00000000;
@@ -288,6 +382,7 @@ static void __init poodle_init(void)
   	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);
@@ -301,6 +396,7 @@ static void __init poodle_init(void)
 	if (ret) {
 		printk(KERN_WARNING "poodle: Unable to register LoCoMo device\n");
 	}
+	corgi_ssp_set_machinfo(&poodle_ssp_machinfo);
 }
 
 static void __init fixup_poodle(struct machine_desc *desc,

+ 5 - 2
arch/arm/mach-pxa/sharpsl_pm.c

@@ -128,6 +128,9 @@ struct battery_thresh  spitz_battery_levels_noac[] = {
  */
 int sharpsl_pm_pxa_read_max1111(int channel)
 {
+	if (machine_is_tosa()) // Ugly, better move this function into another module
+	    return 0;
+
 	return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1
 			| MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
 }
@@ -156,7 +159,7 @@ void sharpsl_pm_pxa_init(void)
 		else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQT_FALLING);
 	}
 
-	if (!machine_is_corgi())
+	if (sharpsl_pm.machinfo->batfull_irq)
 	{
 		/* Register interrupt handler. */
 		if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, SA_INTERRUPT, "CO", sharpsl_chrg_full_isr)) {
@@ -174,6 +177,6 @@ void sharpsl_pm_pxa_remove(void)
 	if (sharpsl_pm.machinfo->gpio_fatal)
 		free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr);
 
-	if (!machine_is_corgi())
+	if (sharpsl_pm.machinfo->batfull_irq)
 		free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr);
 }

+ 25 - 0
arch/arm/mach-pxa/spitz.c

@@ -20,6 +20,7 @@
 #include <linux/fs.h>
 #include <linux/interrupt.h>
 #include <linux/mmc/host.h>
+#include <linux/pm.h>
 
 #include <asm/setup.h>
 #include <asm/memory.h>
@@ -27,6 +28,7 @@
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/io.h>
+#include <asm/system.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -432,8 +434,31 @@ static struct platform_device *devices[] __initdata = {
 	&spitzled_device,
 };
 
+static void spitz_poweroff(void)
+{
+	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
+	pxa_gpio_mode(SPITZ_GPIO_ON_RESET | GPIO_OUT);
+	GPSR(SPITZ_GPIO_ON_RESET) = GPIO_bit(SPITZ_GPIO_ON_RESET);
+
+	mdelay(1000);
+	arm_machine_restart('h');
+}
+
+static void spitz_restart(char mode)
+{
+	/* Bootloader magic for a reboot */
+	if((MSC0 & 0xffff0000) == 0x7ff00000)
+		MSC0 = (MSC0 & 0xffff) | 0x7ee00000;
+
+	spitz_poweroff();
+}
+
 static void __init common_init(void)
 {
+	pm_power_off = spitz_poweroff;
+	arm_pm_restart = spitz_restart;
+
 	PMCR = 0x00;
 
 	/* setup sleep mode values */

+ 15 - 0
arch/arm/mach-pxa/spitz_pm.c

@@ -27,6 +27,13 @@
 #include <asm/arch/pxa-regs.h>
 #include "sharpsl.h"
 
+#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 */
+
 static int spitz_last_ac_status;
 
 static void spitz_charger_init(void)
@@ -190,6 +197,7 @@ struct sharpsl_charger_machinfo spitz_pm_machinfo = {
 	.gpio_batlock     = SPITZ_GPIO_BAT_COVER,
 	.gpio_acin        = SPITZ_GPIO_AC_IN,
 	.gpio_batfull     = SPITZ_GPIO_CHRG_FULL,
+	.batfull_irq	  = 1,
 	.gpio_fatal       = SPITZ_GPIO_FATAL_BAT,
 	.discharge        = spitz_discharge,
 	.discharge1       = spitz_discharge1,
@@ -200,6 +208,13 @@ struct sharpsl_charger_machinfo spitz_pm_machinfo = {
 	.read_devdata     = spitzpm_read_devdata,
 	.charger_wakeup   = spitz_charger_wakeup,
 	.should_wakeup    = spitz_should_wakeup,
+        .backlight_limit  = corgibl_limit_intensity,
+	.charge_on_volt	  = SHARPSL_CHARGE_ON_VOLT,
+	.charge_on_temp	  = SHARPSL_CHARGE_ON_TEMP,
+	.charge_acin_high = SHARPSL_CHARGE_ON_ACIN_HIGH,
+	.charge_acin_low  = SHARPSL_CHARGE_ON_ACIN_LOW,
+	.fatal_acin_volt  = SHARPSL_FATAL_ACIN_VOLT,
+	.fatal_noacin_volt= SHARPSL_FATAL_NOACIN_VOLT,
 	.bat_levels       = 40,
 	.bat_levels_noac  = spitz_battery_levels_noac,
 	.bat_levels_acin  = spitz_battery_levels_acin,

+ 25 - 0
arch/arm/mach-pxa/tosa.c

@@ -19,12 +19,14 @@
 #include <linux/fs.h>
 #include <linux/interrupt.h>
 #include <linux/mmc/host.h>
+#include <linux/pm.h>
 
 #include <asm/setup.h>
 #include <asm/memory.h>
 #include <asm/mach-types.h>
 #include <asm/hardware.h>
 #include <asm/irq.h>
+#include <asm/system.h>
 #include <asm/arch/irda.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/udc.h>
@@ -266,8 +268,31 @@ static struct platform_device *devices[] __initdata = {
 	&tosaled_device,
 };
 
+static void tosa_poweroff(void)
+{
+	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
+	pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_OUT);
+	GPSR(TOSA_GPIO_ON_RESET) = GPIO_bit(TOSA_GPIO_ON_RESET);
+
+	mdelay(1000);
+	arm_machine_restart('h');
+}
+
+static void tosa_restart(char mode)
+{
+	/* Bootloader magic for a reboot */
+	if((MSC0 & 0xffff0000) == 0x7ff00000)
+		MSC0 = (MSC0 & 0xffff) | 0x7ee00000;
+
+	tosa_poweroff();
+}
+
 static void __init tosa_init(void)
 {
+	pm_power_off = tosa_poweroff;
+	arm_pm_restart = tosa_restart;
+
 	pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN);
 	pxa_gpio_mode(TOSA_GPIO_TC6393_INT | GPIO_IN);
 	pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN);

+ 4 - 0
include/asm-arm/arch-pxa/poodle.h

@@ -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  */

+ 1 - 0
include/asm-arm/arch-pxa/system.h

@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <asm/proc-fns.h>
 #include "hardware.h"
 #include "pxa-regs.h"
 

+ 11 - 0
include/asm-arm/hardware/sharpsl_pm.h

@@ -16,6 +16,7 @@ struct sharpsl_charger_machinfo {
 	void (*exit)(void);
 	int gpio_acin;
 	int gpio_batfull;
+	int batfull_irq;
 	int gpio_batlock;
 	int gpio_fatal;
 	void (*discharge)(int);
@@ -34,9 +35,19 @@ struct sharpsl_charger_machinfo {
 #define SHARPSL_STATUS_FATAL    7
 	unsigned long (*charger_wakeup)(void);
 	int (*should_wakeup)(unsigned int resume_on_alarm);
+	void (*backlight_limit)(int);
+	int (*backlight_get_status) (void);
+	int charge_on_volt;
+	int charge_on_temp;
+	int charge_acin_high;
+	int charge_acin_low;
+	int fatal_acin_volt;
+	int fatal_noacin_volt;
 	int bat_levels;
 	struct battery_thresh *bat_levels_noac;
 	struct battery_thresh *bat_levels_acin;
+	struct battery_thresh *bat_levels_noac_bl;
+	struct battery_thresh *bat_levels_acin_bl;
 	int status_high_acin;
 	int status_low_acin;
 	int status_high_noac;

+ 3 - 0
include/asm-arm/system.h

@@ -108,6 +108,9 @@ extern void __show_regs(struct pt_regs *);
 extern int cpu_architecture(void);
 extern void cpu_init(void);
 
+void arm_machine_restart(char mode);
+extern void (*arm_pm_restart)(char str);
+
 /*
  * Intel's XScale3 core supports some v6 features (supersections, L2)
  * but advertises itself as v5 as it does not support the v6 ISA.  For