Merge branch 'for-rmk' of git://git.kernel.org/pub/scm/linux/kernel/git/nico/orion into fixes
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 8bc1872..1d7bca6 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -280,7 +280,7 @@
 	const int port = gpio >> 3;
 	const int port_mask = 1 << (gpio & 7);
 
-	gpio_direction_output(gpio, gpio_get_value(gpio));
+	gpio_direction_input(gpio);
 
 	switch (type) {
 	case IRQT_RISING:
diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c
index 36e5835..ca85d24 100644
--- a/arch/arm/mach-ns9xxx/irq.c
+++ b/arch/arm/mach-ns9xxx/irq.c
@@ -62,7 +62,7 @@
 #if 0
 #define handle_irq handle_level_irq
 #else
-void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
+static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
 {
 	unsigned int cpu = smp_processor_id();
 	struct irqaction *action;
@@ -70,27 +70,35 @@
 
 	spin_lock(&desc->lock);
 
-	if (unlikely(desc->status & IRQ_INPROGRESS))
-		goto out_unlock;
+	BUG_ON(desc->status & IRQ_INPROGRESS);
 
 	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
 	kstat_cpu(cpu).irqs[irq]++;
 
 	action = desc->action;
 	if (unlikely(!action || (desc->status & IRQ_DISABLED)))
-		goto out_unlock;
+		goto out_mask;
 
 	desc->status |= IRQ_INPROGRESS;
 	spin_unlock(&desc->lock);
 
 	action_ret = handle_IRQ_event(irq, action);
 
+	/* XXX: There is no direct way to access noirqdebug, so check
+	 * unconditionally for spurious irqs...
+	 * Maybe this function should go to kernel/irq/chip.c? */
+	note_interrupt(irq, desc, action_ret);
+
 	spin_lock(&desc->lock);
 	desc->status &= ~IRQ_INPROGRESS;
-	if (!(desc->status & IRQ_DISABLED) && desc->chip->ack)
-		desc->chip->ack(irq);
 
-out_unlock:
+	if (desc->status & IRQ_DISABLED)
+out_mask:
+		desc->chip->mask(irq);
+
+	/* ack unconditionally to unmask lower prio irqs */
+	desc->chip->ack(irq);
+
 	spin_unlock(&desc->lock);
 }
 #define handle_irq handle_prio_irq
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 6a83085..0e6d05b 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -5,6 +5,13 @@
 # Common support (must be linked before board specific support)
 obj-y				+= clock.o devices.o generic.o irq.o dma.o \
 				   time.o gpio.o
+obj-$(CONFIG_PM)		+= pm.o sleep.o standby.o
+obj-$(CONFIG_CPU_FREQ)		+= cpu-pxa.o
+
+# Generic drivers that other drivers may depend upon
+obj-$(CONFIG_PXA_SSP)		+= ssp.o
+
+# SoC-specific code
 obj-$(CONFIG_PXA25x)		+= mfp-pxa2xx.o pxa25x.o
 obj-$(CONFIG_PXA27x)		+= mfp-pxa2xx.o pxa27x.o
 obj-$(CONFIG_PXA3xx)		+= mfp-pxa3xx.o pxa3xx.o smemc.o
@@ -48,11 +55,6 @@
 
 obj-$(CONFIG_LEDS)		+= $(led-y)
 
-# Misc features
-obj-$(CONFIG_PM)		+= pm.o sleep.o standby.o
-obj-$(CONFIG_CPU_FREQ)		+= cpu-pxa.o
-obj-$(CONFIG_PXA_SSP)		+= ssp.o
-
 ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
 endif
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 259ca82..b757dd7 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -493,8 +493,6 @@
 
 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);
@@ -503,8 +501,6 @@
 
 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);
diff --git a/arch/arm/mach-pxa/cpu-pxa.c b/arch/arm/mach-pxa/cpu-pxa.c
index 4b21479..fb9ba1a 100644
--- a/arch/arm/mach-pxa/cpu-pxa.c
+++ b/arch/arm/mach-pxa/cpu-pxa.c
@@ -49,125 +49,216 @@
 #define freq_debug  0
 #endif
 
+static unsigned int pxa27x_maxfreq;
+module_param(pxa27x_maxfreq, uint, 0);
+MODULE_PARM_DESC(pxa27x_maxfreq, "Set the pxa27x maxfreq in MHz"
+		 "(typically 624=>pxa270, 416=>pxa271, 520=>pxa272)");
+
 typedef struct {
 	unsigned int khz;
 	unsigned int membus;
 	unsigned int cccr;
 	unsigned int div2;
+	unsigned int cclkcfg;
 } pxa_freqs_t;
 
 /* Define the refresh period in mSec for the SDRAM and the number of rows */
-#define SDRAM_TREF          64      /* standard 64ms SDRAM */
-#define SDRAM_ROWS          4096    /* 64MB=8192 32MB=4096 */
-#define MDREFR_DRI(x)       (((x) * SDRAM_TREF) / (SDRAM_ROWS * 32))
+#define SDRAM_TREF	64	/* standard 64ms SDRAM */
+#define SDRAM_ROWS	4096	/* 64MB=8192 32MB=4096 */
 
-#define CCLKCFG_TURBO       0x1
-#define CCLKCFG_FCS         0x2
-#define PXA25x_MIN_FREQ     99500
-#define PXA25x_MAX_FREQ     398100
-#define MDREFR_DB2_MASK     (MDREFR_K2DB2 | MDREFR_K1DB2)
-#define MDREFR_DRI_MASK     0xFFF
+#define CCLKCFG_TURBO		0x1
+#define CCLKCFG_FCS		0x2
+#define CCLKCFG_HALFTURBO	0x4
+#define CCLKCFG_FASTBUS		0x8
+#define MDREFR_DB2_MASK		(MDREFR_K2DB2 | MDREFR_K1DB2)
+#define MDREFR_DRI_MASK		0xFFF
 
-
+/*
+ * PXA255 definitions
+ */
 /* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */
+#define CCLKCFG			CCLKCFG_TURBO | CCLKCFG_FCS
+
 static pxa_freqs_t pxa255_run_freqs[] =
 {
-    /* CPU   MEMBUS  CCCR  DIV2*/
-    { 99500,  99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50,  SDRAM=50 */
-    {132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66,  SDRAM=66 */
-    {199100,  99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99,  SDRAM=99 */
-    {265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */
-    {331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */
-    {398100,  99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */
-    {0,}
+	/* CPU   MEMBUS  CCCR  DIV2 CCLKCFG	   run  turbo PXbus SDRAM */
+	{ 99500,  99500, 0x121, 1,  CCLKCFG},	/*  99,   99,   50,   50  */
+	{132700, 132700, 0x123, 1,  CCLKCFG},	/* 133,  133,   66,   66  */
+	{199100,  99500, 0x141, 0,  CCLKCFG},	/* 199,  199,   99,   99  */
+	{265400, 132700, 0x143, 1,  CCLKCFG},	/* 265,  265,  133,   66  */
+	{331800, 165900, 0x145, 1,  CCLKCFG},	/* 331,  331,  166,   83  */
+	{398100,  99500, 0x161, 0,  CCLKCFG},	/* 398,  398,  196,   99  */
 };
-#define NUM_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs)
-
-static struct cpufreq_frequency_table pxa255_run_freq_table[NUM_RUN_FREQS+1];
 
 /* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
 static pxa_freqs_t pxa255_turbo_freqs[] =
 {
-    /* CPU   MEMBUS  CCCR  DIV2*/
-    { 99500, 99500,  0x121, 1}, /* run=99,  turbo= 99, PXbus=50, SDRAM=50 */
-    {199100, 99500,  0x221, 0}, /* run=99,  turbo=199, PXbus=50, SDRAM=99 */
-    {298500, 99500,  0x321, 0}, /* run=99,  turbo=287, PXbus=50, SDRAM=99 */
-    {298600, 99500,  0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */
-    {398100, 99500,  0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */
-    {0,}
+	/* CPU   MEMBUS  CCCR  DIV2 CCLKCFG	   run  turbo PXbus SDRAM */
+	{ 99500, 99500,  0x121, 1,  CCLKCFG},	/*  99,   99,   50,   50  */
+	{199100, 99500,  0x221, 0,  CCLKCFG},	/*  99,  199,   50,   99  */
+	{298500, 99500,  0x321, 0,  CCLKCFG},	/*  99,  287,   50,   99  */
+	{298600, 99500,  0x1c1, 0,  CCLKCFG},	/* 199,  287,   99,   99  */
+	{398100, 99500,  0x241, 0,  CCLKCFG},	/* 199,  398,   99,   99  */
 };
-#define NUM_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs)
 
-static struct cpufreq_frequency_table pxa255_turbo_freq_table[NUM_TURBO_FREQS+1];
+#define NUM_PXA25x_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs)
+#define NUM_PXA25x_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs)
+
+static struct cpufreq_frequency_table
+	pxa255_run_freq_table[NUM_PXA25x_RUN_FREQS+1];
+static struct cpufreq_frequency_table
+	pxa255_turbo_freq_table[NUM_PXA25x_TURBO_FREQS+1];
+
+/*
+ * PXA270 definitions
+ *
+ * For the PXA27x:
+ * Control variables are A, L, 2N for CCCR; B, HT, T for CLKCFG.
+ *
+ * A = 0 => memory controller clock from table 3-7,
+ * A = 1 => memory controller clock = system bus clock
+ * Run mode frequency	= 13 MHz * L
+ * Turbo mode frequency = 13 MHz * L * N
+ * System bus frequency = 13 MHz * L / (B + 1)
+ *
+ * In CCCR:
+ * A = 1
+ * L = 16	  oscillator to run mode ratio
+ * 2N = 6	  2 * (turbo mode to run mode ratio)
+ *
+ * In CCLKCFG:
+ * B = 1	  Fast bus mode
+ * HT = 0	  Half-Turbo mode
+ * T = 1	  Turbo mode
+ *
+ * For now, just support some of the combinations in table 3-7 of
+ * PXA27x Processor Family Developer's Manual to simplify frequency
+ * change sequences.
+ */
+#define PXA27x_CCCR(A, L, N2) (A << 25 | N2 << 7 | L)
+#define CCLKCFG2(B, HT, T) \
+  (CCLKCFG_FCS | \
+   ((B)  ? CCLKCFG_FASTBUS : 0) | \
+   ((HT) ? CCLKCFG_HALFTURBO : 0) | \
+   ((T)  ? CCLKCFG_TURBO : 0))
+
+static pxa_freqs_t pxa27x_freqs[] = {
+	{104000, 104000, PXA27x_CCCR(1,	 8, 2), 0, CCLKCFG2(1, 0, 1)},
+	{156000, 104000, PXA27x_CCCR(1,	 8, 6), 0, CCLKCFG2(1, 1, 1)},
+	{208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1)},
+	{312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1)},
+	{416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1)},
+	{520000, 208000, PXA27x_CCCR(1, 16, 5), 1, CCLKCFG2(1, 0, 1)},
+	{624000, 208000, PXA27x_CCCR(1, 16, 6), 1, CCLKCFG2(1, 0, 1)}
+};
+
+#define NUM_PXA27x_FREQS ARRAY_SIZE(pxa27x_freqs)
+static struct cpufreq_frequency_table
+	pxa27x_freq_table[NUM_PXA27x_FREQS+1];
 
 extern unsigned get_clk_frequency_khz(int info);
 
+static void find_freq_tables(struct cpufreq_policy *policy,
+			     struct cpufreq_frequency_table **freq_table,
+			     pxa_freqs_t **pxa_freqs)
+{
+	if (cpu_is_pxa25x()) {
+		if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
+			*pxa_freqs = pxa255_run_freqs;
+			*freq_table = pxa255_run_freq_table;
+		} else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
+			*pxa_freqs = pxa255_turbo_freqs;
+			*freq_table = pxa255_turbo_freq_table;
+		} else {
+			printk("CPU PXA: Unknown policy found. "
+			       "Using CPUFREQ_POLICY_PERFORMANCE\n");
+			*pxa_freqs = pxa255_run_freqs;
+			*freq_table = pxa255_run_freq_table;
+		}
+	}
+	if (cpu_is_pxa27x()) {
+		*pxa_freqs = pxa27x_freqs;
+		*freq_table = pxa27x_freq_table;
+	}
+}
+
+static void pxa27x_guess_max_freq(void)
+{
+	if (!pxa27x_maxfreq) {
+		pxa27x_maxfreq = 416000;
+		printk(KERN_INFO "PXA CPU 27x max frequency not defined "
+		       "(pxa27x_maxfreq), assuming pxa271 with %dkHz maxfreq\n",
+		       pxa27x_maxfreq);
+	} else {
+		pxa27x_maxfreq *= 1000;
+	}
+}
+
+static u32 mdrefr_dri(unsigned int freq)
+{
+	u32 dri = 0;
+
+	if (cpu_is_pxa25x())
+		dri = ((freq * SDRAM_TREF) / (SDRAM_ROWS * 32));
+	if (cpu_is_pxa27x())
+		dri = ((freq * SDRAM_TREF) / (SDRAM_ROWS - 31)) / 32;
+	return dri;
+}
+
 /* find a valid frequency point */
 static int pxa_verify_policy(struct cpufreq_policy *policy)
 {
 	struct cpufreq_frequency_table *pxa_freqs_table;
+	pxa_freqs_t *pxa_freqs;
 	int ret;
 
-	if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
-		pxa_freqs_table = pxa255_run_freq_table;
-	} else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
-		pxa_freqs_table = pxa255_turbo_freq_table;
-	} else {
-		printk("CPU PXA: Unknown policy found. "
-		       "Using CPUFREQ_POLICY_PERFORMANCE\n");
-		pxa_freqs_table = pxa255_run_freq_table;
-	}
-
+	find_freq_tables(policy, &pxa_freqs_table, &pxa_freqs);
 	ret = cpufreq_frequency_table_verify(policy, pxa_freqs_table);
 
 	if (freq_debug)
 		pr_debug("Verified CPU policy: %dKhz min to %dKhz max\n",
-		       policy->min, policy->max);
+			 policy->min, policy->max);
 
 	return ret;
 }
 
+static unsigned int pxa_cpufreq_get(unsigned int cpu)
+{
+	return get_clk_frequency_khz(0);
+}
+
 static int pxa_set_target(struct cpufreq_policy *policy,
-			   unsigned int target_freq,
-			   unsigned int relation)
+			  unsigned int target_freq,
+			  unsigned int relation)
 {
 	struct cpufreq_frequency_table *pxa_freqs_table;
 	pxa_freqs_t *pxa_freq_settings;
 	struct cpufreq_freqs freqs;
 	unsigned int idx;
 	unsigned long flags;
-	unsigned int unused, preset_mdrefr, postset_mdrefr;
-	void *ramstart = phys_to_virt(0xa0000000);
+	unsigned int new_freq_cpu, new_freq_mem;
+	unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg;
 
 	/* Get the current policy */
-	if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
-		pxa_freq_settings = pxa255_run_freqs;
-		pxa_freqs_table   = pxa255_run_freq_table;
-	} else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
-		pxa_freq_settings = pxa255_turbo_freqs;
-		pxa_freqs_table   = pxa255_turbo_freq_table;
-	} else {
-		printk("CPU PXA: Unknown policy found. "
-		       "Using CPUFREQ_POLICY_PERFORMANCE\n");
-		pxa_freq_settings = pxa255_run_freqs;
-		pxa_freqs_table   = pxa255_run_freq_table;
-	}
+	find_freq_tables(policy, &pxa_freqs_table, &pxa_freq_settings);
 
 	/* Lookup the next frequency */
 	if (cpufreq_frequency_table_target(policy, pxa_freqs_table,
-	                                   target_freq, relation, &idx)) {
+					   target_freq, relation, &idx)) {
 		return -EINVAL;
 	}
 
+	new_freq_cpu = pxa_freq_settings[idx].khz;
+	new_freq_mem = pxa_freq_settings[idx].membus;
 	freqs.old = policy->cur;
-	freqs.new = pxa_freq_settings[idx].khz;
+	freqs.new = new_freq_cpu;
 	freqs.cpu = policy->cpu;
 
 	if (freq_debug)
-		pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n",
-		       freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
-		       (pxa_freq_settings[idx].membus / 2000) :
-		       (pxa_freq_settings[idx].membus / 1000));
+		pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, "
+			 "(SDRAM %d Mhz)\n",
+			 freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
+			 (new_freq_mem / 2000) : (new_freq_mem / 1000));
 
 	/*
 	 * Tell everyone what we're about to do...
@@ -177,16 +268,16 @@
 	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 
 	/* Calculate the next MDREFR.  If we're slowing down the SDRAM clock
-	 * we need to preset the smaller DRI before the change.  If we're speeding
-	 * up we need to set the larger DRI value after the change.
+	 * we need to preset the smaller DRI before the change.	 If we're
+	 * speeding up we need to set the larger DRI value after the change.
 	 */
 	preset_mdrefr = postset_mdrefr = MDREFR;
-	if ((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa_freq_settings[idx].membus)) {
-		preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) |
-		                MDREFR_DRI(pxa_freq_settings[idx].membus);
+	if ((MDREFR & MDREFR_DRI_MASK) > mdrefr_dri(new_freq_mem)) {
+		preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK);
+		preset_mdrefr |= mdrefr_dri(new_freq_mem);
 	}
-	postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) |
-		            MDREFR_DRI(pxa_freq_settings[idx].membus);
+	postset_mdrefr =
+		(postset_mdrefr & ~MDREFR_DRI_MASK) | mdrefr_dri(new_freq_mem);
 
 	/* If we're dividing the memory clock by two for the SDRAM clock, this
 	 * must be set prior to the change.  Clearing the divide must be done
@@ -201,26 +292,27 @@
 
 	local_irq_save(flags);
 
-	/* Set new the CCCR */
+	/* Set new the CCCR and prepare CCLKCFG */
 	CCCR = pxa_freq_settings[idx].cccr;
+	cclkcfg = pxa_freq_settings[idx].cclkcfg;
 
 	asm volatile("							\n\
 		ldr	r4, [%1]		/* load MDREFR */	\n\
 		b	2f						\n\
-		.align	5 						\n\
+		.align	5						\n\
 1:									\n\
-		str	%4, [%1]		/* preset the MDREFR */	\n\
+		str	%3, [%1]		/* preset the MDREFR */	\n\
 		mcr	p14, 0, %2, c6, c0, 0	/* set CCLKCFG[FCS] */	\n\
-		str	%5, [%1]		/* postset the MDREFR */ \n\
+		str	%4, [%1]		/* postset the MDREFR */ \n\
 									\n\
 		b	3f						\n\
 2:		b	1b						\n\
 3:		nop							\n\
 	  "
-	  : "=&r" (unused)
-	  : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart),
-	    "r" (preset_mdrefr), "r" (postset_mdrefr)
-	  : "r4", "r5");
+		     : "=&r" (unused)
+		     : "r" (&MDREFR), "r" (cclkcfg),
+		       "r" (preset_mdrefr), "r" (postset_mdrefr)
+		     : "r4", "r5");
 	local_irq_restore(flags);
 
 	/*
@@ -233,38 +325,57 @@
 	return 0;
 }
 
-static unsigned int pxa_cpufreq_get(unsigned int cpu)
-{
-	return get_clk_frequency_khz(0);
-}
-
-static int pxa_cpufreq_init(struct cpufreq_policy *policy)
+static __init int pxa_cpufreq_init(struct cpufreq_policy *policy)
 {
 	int i;
+	unsigned int freq;
+
+	/* try to guess pxa27x cpu */
+	if (cpu_is_pxa27x())
+		pxa27x_guess_max_freq();
 
 	/* set default policy and cpuinfo */
 	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
-	policy->cpuinfo.max_freq = PXA25x_MAX_FREQ;
-	policy->cpuinfo.min_freq = PXA25x_MIN_FREQ;
+	if (cpu_is_pxa25x())
+		policy->policy = CPUFREQ_POLICY_PERFORMANCE;
 	policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
-	policy->cur = get_clk_frequency_khz(0);    /* current freq */
+	policy->cur = get_clk_frequency_khz(0);	   /* current freq */
 	policy->min = policy->max = policy->cur;
 
-	/* Generate the run cpufreq_frequency_table struct */
-	for (i = 0; i < NUM_RUN_FREQS; i++) {
+	/* Generate pxa25x the run cpufreq_frequency_table struct */
+	for (i = 0; i < NUM_PXA25x_RUN_FREQS; i++) {
 		pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz;
 		pxa255_run_freq_table[i].index = i;
 	}
-
 	pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
-	/* Generate the turbo cpufreq_frequency_table struct */
-	for (i = 0; i < NUM_TURBO_FREQS; i++) {
-		pxa255_turbo_freq_table[i].frequency = pxa255_turbo_freqs[i].khz;
+
+	/* Generate pxa25x the turbo cpufreq_frequency_table struct */
+	for (i = 0; i < NUM_PXA25x_TURBO_FREQS; i++) {
+		pxa255_turbo_freq_table[i].frequency =
+			pxa255_turbo_freqs[i].khz;
 		pxa255_turbo_freq_table[i].index = i;
 	}
 	pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
 
+	/* Generate the pxa27x cpufreq_frequency_table struct */
+	for (i = 0; i < NUM_PXA27x_FREQS; i++) {
+		freq = pxa27x_freqs[i].khz;
+		if (freq > pxa27x_maxfreq)
+			break;
+		pxa27x_freq_table[i].frequency = freq;
+		pxa27x_freq_table[i].index = i;
+	}
+	pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+	/*
+	 * Set the policy's minimum and maximum frequencies from the tables
+	 * just constructed.  This sets cpuinfo.mxx_freq, min and max.
+	 */
+	if (cpu_is_pxa25x())
+		cpufreq_frequency_table_cpuinfo(policy, pxa255_run_freq_table);
+	else if (cpu_is_pxa27x())
+		cpufreq_frequency_table_cpuinfo(policy, pxa27x_freq_table);
+
 	printk(KERN_INFO "PXA CPU frequency change support initialized\n");
 
 	return 0;
@@ -275,26 +386,25 @@
 	.target	= pxa_set_target,
 	.init	= pxa_cpufreq_init,
 	.get	= pxa_cpufreq_get,
-	.name	= "PXA25x",
+	.name	= "PXA2xx",
 };
 
 static int __init pxa_cpu_init(void)
 {
 	int ret = -ENODEV;
-	if (cpu_is_pxa25x())
+	if (cpu_is_pxa25x() || cpu_is_pxa27x())
 		ret = cpufreq_register_driver(&pxa_cpufreq_driver);
 	return ret;
 }
 
 static void __exit pxa_cpu_exit(void)
 {
-	if (cpu_is_pxa25x())
-		cpufreq_unregister_driver(&pxa_cpufreq_driver);
+	cpufreq_unregister_driver(&pxa_cpufreq_driver);
 }
 
 
-MODULE_AUTHOR ("Intrinsyc Software Inc.");
-MODULE_DESCRIPTION ("CPU frequency changing driver for the PXA architecture");
+MODULE_AUTHOR("Intrinsyc Software Inc.");
+MODULE_DESCRIPTION("CPU frequency changing driver for the PXA architecture");
 MODULE_LICENSE("GPL");
 module_init(pxa_cpu_init);
 module_exit(pxa_cpu_exit);
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 0993f4d..7b9bdd0 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -396,7 +396,7 @@
 	.cmap_inverse	= 0,
 	.cmap_static	= 0,
 	.lcd_conn	= LCD_COLOR_DSTN_16BPP | LCD_PCLK_EDGE_FALL |
-			  LCD_AC_BIAS_FREQ(255);
+			  LCD_AC_BIAS_FREQ(255),
 };
 
 #define	MMC_POLL_RATE		msecs_to_jiffies(1000)
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index ec1bbf3..7d4debb 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -42,20 +42,17 @@
 	if (state != PM_SUSPEND_STANDBY) {
 		pxa_cpu_pm_fns->save(sleep_save);
 		/* before sleeping, calculate and save a checksum */
-		for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
+		for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
 			sleep_save_checksum += sleep_save[i];
 	}
 
-	/* Clear reset status */
-	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
 	/* *** go zzz *** */
 	pxa_cpu_pm_fns->enter(state);
 	cpu_init();
 
 	if (state != PM_SUSPEND_STANDBY) {
 		/* after sleeping, validate the checksum */
-		for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
+		for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
 			checksum += sleep_save[i];
 
 		/* if invalid, display message and wait for a hardware reset */
@@ -101,7 +98,8 @@
 		return -EINVAL;
 	}
 
-	sleep_save = kmalloc(pxa_cpu_pm_fns->save_size, GFP_KERNEL);
+	sleep_save = kmalloc(pxa_cpu_pm_fns->save_count * sizeof(unsigned long),
+			     GFP_KERNEL);
 	if (!sleep_save) {
 		printk(KERN_ERR "failed to alloc memory for pm save\n");
 		return -ENOMEM;
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index ca5ac19..0b30f25 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -326,13 +326,11 @@
 
 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');
 }
 
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index d9b5450..e5b417d 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -150,9 +150,7 @@
  * More ones like CP and general purpose register values are preserved
  * with the stack pointer in sleep.S.
  */
-enum {	SLEEP_SAVE_START = 0,
-
-	SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2,
+enum {	SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2,
 
 	SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
 	SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U,
@@ -162,7 +160,7 @@
 
 	SLEEP_SAVE_CKEN,
 
-	SLEEP_SAVE_SIZE
+	SLEEP_SAVE_COUNT
 };
 
 
@@ -200,6 +198,9 @@
 
 static void pxa25x_cpu_pm_enter(suspend_state_t state)
 {
+	/* Clear reset status */
+	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
 	switch (state) {
 	case PM_SUSPEND_MEM:
 		/* set resume return address */
@@ -210,7 +211,7 @@
 }
 
 static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = {
-	.save_size	= SLEEP_SAVE_SIZE,
+	.save_count	= SLEEP_SAVE_COUNT,
 	.valid		= suspend_valid_only_mem,
 	.save		= pxa25x_cpu_pm_save,
 	.restore	= pxa25x_cpu_pm_restore,
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 7a2449d..7e94583 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -181,9 +181,7 @@
  * More ones like CP and general purpose register values are preserved
  * with the stack pointer in sleep.S.
  */
-enum {	SLEEP_SAVE_START = 0,
-
-	SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
+enum {	SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
 
 	SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
 	SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U,
@@ -198,7 +196,7 @@
 	SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER,
 	SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR,
 
-	SLEEP_SAVE_SIZE
+	SLEEP_SAVE_COUNT
 };
 
 void pxa27x_cpu_pm_save(unsigned long *sleep_save)
@@ -251,6 +249,9 @@
 	/* Clear edge-detect status register. */
 	PEDR = 0xDF12FE1B;
 
+	/* Clear reset status */
+	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
 	switch (state) {
 	case PM_SUSPEND_STANDBY:
 		pxa_cpu_standby();
@@ -269,7 +270,7 @@
 }
 
 static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = {
-	.save_size	= SLEEP_SAVE_SIZE,
+	.save_count	= SLEEP_SAVE_COUNT,
 	.save		= pxa27x_cpu_pm_save,
 	.restore	= pxa27x_cpu_pm_restore,
 	.valid		= pxa27x_cpu_pm_valid,
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index b6a6f5f..644550b 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -256,12 +256,11 @@
 #define SAVE(x)		sleep_save[SLEEP_SAVE_##x] = x
 #define RESTORE(x)	x = sleep_save[SLEEP_SAVE_##x]
 
-enum {	SLEEP_SAVE_START = 0,
-	SLEEP_SAVE_CKENA,
+enum {	SLEEP_SAVE_CKENA,
 	SLEEP_SAVE_CKENB,
 	SLEEP_SAVE_ACCR,
 
-	SLEEP_SAVE_SIZE,
+	SLEEP_SAVE_COUNT,
 };
 
 static void pxa3xx_cpu_pm_save(unsigned long *sleep_save)
@@ -376,7 +375,7 @@
 }
 
 static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = {
-	.save_size	= SLEEP_SAVE_SIZE,
+	.save_count	= SLEEP_SAVE_COUNT,
 	.save		= pxa3xx_cpu_pm_save,
 	.restore	= pxa3xx_cpu_pm_restore,
 	.valid		= pxa3xx_cpu_pm_valid,
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 62a02c3..e7d0fcd 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -529,8 +529,6 @@
 
 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);
 
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 7a7f5f9..23f050f 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -119,9 +119,6 @@
 	/* nRESET_OUT Disable */
 	PSLR |= PSLR_SL_ROD;
 
-	/* Clear reset status */
-	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
 	/* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
 	PCFR = PCFR_GPR_EN | PCFR_OPDE;
 }
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 6458f6d..c2cbd66 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -467,8 +467,6 @@
 
 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);
 
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
index 246c573..1693d44 100644
--- a/arch/arm/mach-sa1100/pm.c
+++ b/arch/arm/mach-sa1100/pm.c
@@ -43,20 +43,18 @@
  * More ones like CP and general purpose register values are preserved
  * on the stack and then the stack pointer is stored last in sleep.S.
  */
-enum {	SLEEP_SAVE_SP = 0,
-
-	SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
+enum {	SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
 	SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,
 
 	SLEEP_SAVE_Ser1SDCR0,
 
-	SLEEP_SAVE_SIZE
+	SLEEP_SAVE_COUNT
 };
 
 
 static int sa11x0_pm_enter(suspend_state_t state)
 {
-	unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE];
+	unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT];
 
 	gpio = GPLR;
 
diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c
index d84167f..3ac8d8d 100644
--- a/arch/arm/plat-s3c24xx/clock.c
+++ b/arch/arm/plat-s3c24xx/clock.c
@@ -411,7 +411,7 @@
 
 	clk->parent = parent;
 
-	if (clk == &s3c24xx_dclk0)
+	if (clk == &s3c24xx_clkout0)
 		mask = S3C2410_MISCCR_CLK0_MASK;
 	else {
 		source <<= 4;
@@ -437,7 +437,7 @@
 struct clk s3c24xx_dclk1 = {
 	.name		= "dclk1",
 	.id		= -1,
-	.ctrlbit	= S3C2410_DCLKCON_DCLK0EN,
+	.ctrlbit	= S3C2410_DCLKCON_DCLK1EN,
 	.enable		= s3c24xx_dclk_enable,
 	.set_parent	= s3c24xx_dclk_setparent,
 	.set_rate	= s3c24xx_set_dclk_rate,
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 626ac08..da5feca 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -425,7 +425,7 @@
 			host->cclk = host->mclk;
 		} else {
 			clk = host->mclk / (2 * ios->clock) - 1;
-			if (clk > 256)
+			if (clk >= 256)
 				clk = 255;
 			host->cclk = host->mclk / (2 * (clk + 1));
 		}
@@ -512,6 +512,18 @@
 
 	host->plat = plat;
 	host->mclk = clk_get_rate(host->clk);
+	/*
+	 * According to the spec, mclk is max 100 MHz,
+	 * so we try to adjust the clock down to this,
+	 * (if possible).
+	 */
+	if (host->mclk > 100000000) {
+		ret = clk_set_rate(host->clk, 100000000);
+		if (ret < 0)
+			goto clk_disable;
+		host->mclk = clk_get_rate(host->clk);
+		DBG(host, "eventual mclk rate: %u Hz\n", host->mclk);
+	}
 	host->mmc = mmc;
 	host->base = ioremap(dev->res.start, SZ_4K);
 	if (!host->base) {
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 3ab6e3d..48aea39 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -1301,8 +1301,8 @@
 	}
 }
 
-static int pxafb_decode_mach_info(struct pxafb_info *fbi,
-				  struct pxafb_mach_info *inf)
+static void pxafb_decode_mach_info(struct pxafb_info *fbi,
+				   struct pxafb_mach_info *inf)
 {
 	unsigned int lcd_conn = inf->lcd_conn;
 
@@ -1333,7 +1333,7 @@
 		fbi->lccr0 = inf->lccr0;
 		fbi->lccr3 = inf->lccr3;
 		fbi->lccr4 = inf->lccr4;
-		return -EINVAL;
+		goto decode_mode;
 	}
 
 	if (lcd_conn == LCD_MONO_STN_8BPP)
@@ -1343,8 +1343,8 @@
 	fbi->lccr3 |= (lcd_conn & LCD_BIAS_ACTIVE_LOW) ? LCCR3_OEP : 0;
 	fbi->lccr3 |= (lcd_conn & LCD_PCLK_EDGE_FALL)  ? LCCR3_PCP : 0;
 
+decode_mode:
 	pxafb_decode_mode_info(fbi, inf->modes, inf->num_modes);
-	return 0;
 }
 
 static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
diff --git a/include/asm-arm/arch-pxa/pm.h b/include/asm-arm/arch-pxa/pm.h
index 9d9f4b5..261e5bc 100644
--- a/include/asm-arm/arch-pxa/pm.h
+++ b/include/asm-arm/arch-pxa/pm.h
@@ -10,7 +10,7 @@
 #include <linux/suspend.h>
 
 struct pxa_cpu_pm_fns {
-	int	save_size;
+	int	save_count;
 	void	(*save)(unsigned long *);
 	void	(*restore)(unsigned long *);
 	int	(*valid)(suspend_state_t state);
diff --git a/include/asm-arm/arch-pxa/system.h b/include/asm-arm/arch-pxa/system.h
index a758a71..9aa6c2e 100644
--- a/include/asm-arm/arch-pxa/system.h
+++ b/include/asm-arm/arch-pxa/system.h
@@ -22,7 +22,8 @@
 
 static inline void arch_reset(char mode)
 {
-	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+	if (cpu_is_pxa2xx())
+		RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
 
 	if (mode == 's') {
 		/* Jump into ROM at address 0 */