Browse Source

Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm

* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (65 commits)
  ARM: 6826/1: Merge v6 and v7 DEBUG_LL DCC support
  ARM: 6838/1: etm: fix section mismatch warning
  ARM: 6837/1: remove unused pci_fixup_prpmc1100
  ARM: 6836/1: kprobes/fix emulation of LDR/STR instruction when Rn == PC
  Fix the broken build for Marvell Dove platform.
  ARM: 6835/1: perf: ensure overflows aren't missed due to IRQ latency
  ARM: 6834/1: perf: reset counters on all CPUs during initialisation
  ARM: 6833/1: perf: add required isbs() to ARMv7 backend
  ARM: 6825/1: kernel/sleep.S: fix Thumb2 compilation issues
  ARM: 6807/1: realview: Fix secondary GIC initialisation for EB with MPCore tile
  arm: mach-mx3: pcm043: add write-protect and card-detect for SD1
  eukrea_mbimxsd51: add SD Card detect
  eukrea_mbimxsd25-baseboard: add SD card detect
  mx3/eukrea_mbimxsd-baseboard: add SD card detect support
  mx3/eukrea_mbimxsd-baseboard: fix gpio request
  ARM: mxs/mx28evk: add mmc device
  ARM: mxs/mx23evk: add mmc device
  ARM: mxs: dynamically allocate mmc device
  ARM: mx51_efika: update platform data for new mfd changes
  mx2/iomux: Set direction for CSPI2 pins
  ...
Linus Torvalds 14 years ago
parent
commit
85eb1513c1
100 changed files with 1194 additions and 688 deletions
  1. 1 0
      arch/arm/Kconfig
  2. 1 9
      arch/arm/boot/compressed/head.S
  3. 1 11
      arch/arm/boot/compressed/misc.c
  4. 0 2
      arch/arm/include/asm/mach/udc_pxa2xx.h
  5. 1 18
      arch/arm/kernel/debug.S
  6. 2 2
      arch/arm/kernel/etm.c
  7. 6 4
      arch/arm/kernel/kprobes-decode.c
  8. 25 8
      arch/arm/kernel/perf_event.c
  9. 1 1
      arch/arm/kernel/perf_event_v6.c
  10. 19 7
      arch/arm/kernel/perf_event_v7.c
  11. 2 2
      arch/arm/kernel/perf_event_xscale.c
  12. 11 3
      arch/arm/kernel/sleep.S
  13. 1 0
      arch/arm/mach-imx/Kconfig
  14. 7 1
      arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
  15. 7 0
      arch/arm/mach-kirkwood/sheevaplug-setup.c
  16. 11 3
      arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
  17. 11 1
      arch/arm/mach-mx3/mach-pcm043.c
  18. 1 0
      arch/arm/mach-mx5/Kconfig
  19. 1 1
      arch/arm/mach-mx5/Makefile
  20. 2 3
      arch/arm/mach-mx5/board-mx51_babbage.c
  21. 4 5
      arch/arm/mach-mx5/board-mx53_evk.c
  22. 25 0
      arch/arm/mach-mx5/board-mx53_loco.c
  23. 9 0
      arch/arm/mach-mx5/clock-mx51-mx53.c
  24. 59 0
      arch/arm/mach-mx5/cpu.c
  25. 4 0
      arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
  26. 0 1
      arch/arm/mach-mx5/mx51_efika.c
  27. 84 0
      arch/arm/mach-mx5/system.c
  28. 2 0
      arch/arm/mach-mxs/Kconfig
  29. 15 0
      arch/arm/mach-mxs/clock-mx23.c
  30. 18 0
      arch/arm/mach-mxs/clock-mx28.c
  31. 4 0
      arch/arm/mach-mxs/devices-mx23.h
  32. 4 0
      arch/arm/mach-mxs/devices-mx28.h
  33. 3 0
      arch/arm/mach-mxs/devices/Kconfig
  34. 1 0
      arch/arm/mach-mxs/devices/Makefile
  35. 73 0
      arch/arm/mach-mxs/devices/platform-mxs-mmc.c
  36. 13 0
      arch/arm/mach-mxs/include/mach/devices-common.h
  37. 44 0
      arch/arm/mach-mxs/mach-mx23evk.c
  38. 89 0
      arch/arm/mach-mxs/mach-mx28evk.c
  39. 35 6
      arch/arm/mach-mxs/module-tx28.c
  40. 1 0
      arch/arm/mach-mxs/module-tx28.h
  41. 9 9
      arch/arm/mach-orion5x/ts78xx-setup.c
  42. 4 4
      arch/arm/mach-pxa/am200epd.c
  43. 7 6
      arch/arm/mach-pxa/am300epd.c
  44. 1 1
      arch/arm/mach-pxa/balloon3.c
  45. 1 1
      arch/arm/mach-pxa/cm-x2xx.c
  46. 1 1
      arch/arm/mach-pxa/cm-x300.c
  47. 1 1
      arch/arm/mach-pxa/colibri-pxa270-income.c
  48. 1 1
      arch/arm/mach-pxa/colibri-pxa3xx.c
  49. 0 1
      arch/arm/mach-pxa/corgi.c
  50. 2 7
      arch/arm/mach-pxa/devices.c
  51. 1 1
      arch/arm/mach-pxa/em-x270.c
  52. 27 9
      arch/arm/mach-pxa/eseries.c
  53. 6 6
      arch/arm/mach-pxa/ezx.c
  54. 11 2
      arch/arm/mach-pxa/gumstix.c
  55. 1 1
      arch/arm/mach-pxa/idp.c
  56. 5 0
      arch/arm/mach-pxa/include/mach/palmz72.h
  57. 2 2
      arch/arm/mach-pxa/include/mach/pxafb.h
  58. 1 2
      arch/arm/mach-pxa/include/mach/z2.h
  59. 1 1
      arch/arm/mach-pxa/littleton.c
  60. 1 1
      arch/arm/mach-pxa/lpd270.c
  61. 1 1
      arch/arm/mach-pxa/lubbock.c
  62. 1 1
      arch/arm/mach-pxa/magician.c
  63. 1 1
      arch/arm/mach-pxa/mainstone.c
  64. 1 1
      arch/arm/mach-pxa/mioa701.c
  65. 2 3
      arch/arm/mach-pxa/palm27x.c
  66. 1 1
      arch/arm/mach-pxa/palmtc.c
  67. 8 25
      arch/arm/mach-pxa/palmte2.c
  68. 127 0
      arch/arm/mach-pxa/palmz72.c
  69. 1 1
      arch/arm/mach-pxa/pcm990-baseboard.c
  70. 1 2
      arch/arm/mach-pxa/poodle.c
  71. 1 1
      arch/arm/mach-pxa/raumfeld.c
  72. 1 1
      arch/arm/mach-pxa/saar.c
  73. 1 1
      arch/arm/mach-pxa/spitz.c
  74. 1 1
      arch/arm/mach-pxa/tavorevb.c
  75. 2 3
      arch/arm/mach-pxa/time.c
  76. 11 2
      arch/arm/mach-pxa/tosa.c
  77. 2 2
      arch/arm/mach-pxa/trizeps4.c
  78. 1 1
      arch/arm/mach-pxa/viper.c
  79. 1 1
      arch/arm/mach-pxa/vpac270.c
  80. 38 39
      arch/arm/mach-pxa/z2.c
  81. 1 1
      arch/arm/mach-pxa/zeus.c
  82. 2 2
      arch/arm/mach-pxa/zylonite.c
  83. 1 1
      arch/arm/mach-realview/realview_eb.c
  84. 1 1
      arch/arm/plat-mxc/devices/platform-fec.c
  85. 1 1
      arch/arm/plat-mxc/devices/platform-imxdi_rtc.c
  86. 9 1
      arch/arm/plat-mxc/include/mach/audmux.h
  87. 6 6
      arch/arm/plat-mxc/include/mach/iomux-mx2x.h
  88. 4 0
      arch/arm/plat-mxc/include/mach/mx50.h
  89. 1 0
      arch/arm/plat-mxc/include/mach/mx51.h
  90. 23 0
      arch/arm/plat-mxc/include/mach/mxc.h
  91. 5 1
      arch/arm/plat-mxc/include/mach/system.h
  92. 24 1
      arch/arm/plat-mxc/time.c
  93. 22 21
      drivers/ata/pata_palmld.c
  94. 49 84
      drivers/pcmcia/pxa2xx_colibri.c
  95. 10 32
      drivers/pcmcia/pxa2xx_palmld.c
  96. 13 62
      drivers/pcmcia/pxa2xx_palmtc.c
  97. 12 45
      drivers/pcmcia/pxa2xx_palmtx.c
  98. 30 80
      drivers/pcmcia/pxa2xx_vpac270.c
  99. 7 69
      drivers/usb/gadget/pxa25x_udc.c
  100. 89 47
      drivers/video/pxafb.c

+ 1 - 0
arch/arm/Kconfig

@@ -366,6 +366,7 @@ config ARCH_MXC
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_CLOCKEVENTS
 	select ARCH_REQUIRE_GPIOLIB
 	select ARCH_REQUIRE_GPIOLIB
 	select CLKDEV_LOOKUP
 	select CLKDEV_LOOKUP
+	select HAVE_SCHED_CLOCK
 	help
 	help
 	  Support for Freescale MXC/iMX-based family of processors
 	  Support for Freescale MXC/iMX-based family of processors
 
 

+ 1 - 9
arch/arm/boot/compressed/head.S

@@ -21,20 +21,12 @@
 
 
 #if defined(CONFIG_DEBUG_ICEDCC)
 #if defined(CONFIG_DEBUG_ICEDCC)
 
 
-#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
 		.macro	loadsp, rb, tmp
 		.macro	loadsp, rb, tmp
 		.endm
 		.endm
 		.macro	writeb, ch, rb
 		.macro	writeb, ch, rb
 		mcr	p14, 0, \ch, c0, c5, 0
 		mcr	p14, 0, \ch, c0, c5, 0
 		.endm
 		.endm
-#elif defined(CONFIG_CPU_V7)
-		.macro	loadsp, rb, tmp
-		.endm
-		.macro	writeb, ch, rb
-wait:		mrc	p14, 0, pc, c0, c1, 0
-		bcs	wait
-		mcr	p14, 0, \ch, c0, c5, 0
-		.endm
 #elif defined(CONFIG_CPU_XSCALE)
 #elif defined(CONFIG_CPU_XSCALE)
 		.macro	loadsp, rb, tmp
 		.macro	loadsp, rb, tmp
 		.endm
 		.endm

+ 1 - 11
arch/arm/boot/compressed/misc.c

@@ -36,7 +36,7 @@ extern void error(char *x);
 
 
 #ifdef CONFIG_DEBUG_ICEDCC
 #ifdef CONFIG_DEBUG_ICEDCC
 
 
-#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
 
 
 static void icedcc_putc(int ch)
 static void icedcc_putc(int ch)
 {
 {
@@ -52,16 +52,6 @@ static void icedcc_putc(int ch)
 	asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
 	asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
 }
 }
 
 
-#elif defined(CONFIG_CPU_V7)
-
-static void icedcc_putc(int ch)
-{
-	asm(
-	"wait:	mrc	p14, 0, pc, c0, c1, 0			\n\
-		bcs	wait					\n\
-		mcr     p14, 0, %0, c0, c5, 0			"
-	: : "r" (ch));
-}
 
 
 #elif defined(CONFIG_CPU_XSCALE)
 #elif defined(CONFIG_CPU_XSCALE)
 
 

+ 0 - 2
arch/arm/include/asm/mach/udc_pxa2xx.h

@@ -20,8 +20,6 @@ struct pxa2xx_udc_mach_info {
 	 * VBUS IRQ and omit the methods above.  Store the GPIO number
 	 * VBUS IRQ and omit the methods above.  Store the GPIO number
 	 * here.  Note that sometimes the signals go through inverters...
 	 * here.  Note that sometimes the signals go through inverters...
 	 */
 	 */
-	bool	gpio_vbus_inverted;
-	int	gpio_vbus;			/* high == vbus present */
 	bool	gpio_pullup_inverted;
 	bool	gpio_pullup_inverted;
 	int	gpio_pullup;			/* high == pullup activated */
 	int	gpio_pullup;			/* high == pullup activated */
 };
 };

+ 1 - 18
arch/arm/kernel/debug.S

@@ -25,7 +25,7 @@
 		.macro	addruart, rp, rv
 		.macro	addruart, rp, rv
 		.endm
 		.endm
 
 
-#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
 
 
 		.macro	senduart, rd, rx
 		.macro	senduart, rd, rx
 		mcr	p14, 0, \rd, c0, c5, 0
 		mcr	p14, 0, \rd, c0, c5, 0
@@ -49,23 +49,6 @@
 1002:
 1002:
 		.endm
 		.endm
 
 
-#elif defined(CONFIG_CPU_V7)
-
-		.macro	senduart, rd, rx
-		mcr	p14, 0, \rd, c0, c5, 0
-		.endm
-
-		.macro	busyuart, rd, rx
-busy:		mrc	p14, 0, pc, c0, c1, 0
-		bcs	busy
-		.endm
-
-		.macro	waituart, rd, rx
-wait:		mrc	p14, 0, pc, c0, c1, 0
-		bcs	wait
-
-		.endm
-
 #elif defined(CONFIG_CPU_XSCALE)
 #elif defined(CONFIG_CPU_XSCALE)
 
 
 		.macro	senduart, rd, rx
 		.macro	senduart, rd, rx

+ 2 - 2
arch/arm/kernel/etm.c

@@ -338,7 +338,7 @@ static struct miscdevice etb_miscdev = {
 	.fops = &etb_fops,
 	.fops = &etb_fops,
 };
 };
 
 
-static int __init etb_probe(struct amba_device *dev, const struct amba_id *id)
+static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id)
 {
 {
 	struct tracectx *t = &tracer;
 	struct tracectx *t = &tracer;
 	int ret = 0;
 	int ret = 0;
@@ -530,7 +530,7 @@ static ssize_t trace_mode_store(struct kobject *kobj,
 static struct kobj_attribute trace_mode_attr =
 static struct kobj_attribute trace_mode_attr =
 	__ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
 	__ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
 
 
-static int __init etm_probe(struct amba_device *dev, const struct amba_id *id)
+static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id)
 {
 {
 	struct tracectx *t = &tracer;
 	struct tracectx *t = &tracer;
 	int ret = 0;
 	int ret = 0;

+ 6 - 4
arch/arm/kernel/kprobes-decode.c

@@ -594,7 +594,8 @@ static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
 	long cpsr = regs->ARM_cpsr;
 	long cpsr = regs->ARM_cpsr;
 
 
 	fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn);
 	fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn);
-	regs->uregs[rn] = fnr.r0;  /* Save Rn in case of writeback. */
+	if (rn != 15)
+		regs->uregs[rn] = fnr.r0;  /* Save Rn in case of writeback. */
 	rdv = fnr.r1;
 	rdv = fnr.r1;
 
 
 	if (rd == 15) {
 	if (rd == 15) {
@@ -622,10 +623,11 @@ static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs)
 	long rdv = (rd == 15) ? iaddr + str_pc_offset : regs->uregs[rd];
 	long rdv = (rd == 15) ? iaddr + str_pc_offset : regs->uregs[rd];
 	long rnv = (rn == 15) ? iaddr +  8 : regs->uregs[rn];
 	long rnv = (rn == 15) ? iaddr +  8 : regs->uregs[rn];
 	long rmv = regs->uregs[rm];  /* rm/rmv may be invalid, don't care. */
 	long rmv = regs->uregs[rm];  /* rm/rmv may be invalid, don't care. */
+	long rnv_wb;
 
 
-	/* Save Rn in case of writeback. */
-	regs->uregs[rn] =
-		insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn);
+	rnv_wb = insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn);
+	if (rn != 15)
+		regs->uregs[rn] = rnv_wb;  /* Save Rn in case of writeback. */
 }
 }
 
 
 static void __kprobes emulate_mrrc(struct kprobe *p, struct pt_regs *regs)
 static void __kprobes emulate_mrrc(struct kprobe *p, struct pt_regs *regs)

+ 25 - 8
arch/arm/kernel/perf_event.c

@@ -79,6 +79,7 @@ struct arm_pmu {
 	void		(*write_counter)(int idx, u32 val);
 	void		(*write_counter)(int idx, u32 val);
 	void		(*start)(void);
 	void		(*start)(void);
 	void		(*stop)(void);
 	void		(*stop)(void);
+	void		(*reset)(void *);
 	const unsigned	(*cache_map)[PERF_COUNT_HW_CACHE_MAX]
 	const unsigned	(*cache_map)[PERF_COUNT_HW_CACHE_MAX]
 				    [PERF_COUNT_HW_CACHE_OP_MAX]
 				    [PERF_COUNT_HW_CACHE_OP_MAX]
 				    [PERF_COUNT_HW_CACHE_RESULT_MAX];
 				    [PERF_COUNT_HW_CACHE_RESULT_MAX];
@@ -204,11 +205,9 @@ armpmu_event_set_period(struct perf_event *event,
 static u64
 static u64
 armpmu_event_update(struct perf_event *event,
 armpmu_event_update(struct perf_event *event,
 		    struct hw_perf_event *hwc,
 		    struct hw_perf_event *hwc,
-		    int idx)
+		    int idx, int overflow)
 {
 {
-	int shift = 64 - 32;
-	s64 prev_raw_count, new_raw_count;
-	u64 delta;
+	u64 delta, prev_raw_count, new_raw_count;
 
 
 again:
 again:
 	prev_raw_count = local64_read(&hwc->prev_count);
 	prev_raw_count = local64_read(&hwc->prev_count);
@@ -218,8 +217,13 @@ again:
 			     new_raw_count) != prev_raw_count)
 			     new_raw_count) != prev_raw_count)
 		goto again;
 		goto again;
 
 
-	delta = (new_raw_count << shift) - (prev_raw_count << shift);
-	delta >>= shift;
+	new_raw_count &= armpmu->max_period;
+	prev_raw_count &= armpmu->max_period;
+
+	if (overflow)
+		delta = armpmu->max_period - prev_raw_count + new_raw_count;
+	else
+		delta = new_raw_count - prev_raw_count;
 
 
 	local64_add(delta, &event->count);
 	local64_add(delta, &event->count);
 	local64_sub(delta, &hwc->period_left);
 	local64_sub(delta, &hwc->period_left);
@@ -236,7 +240,7 @@ armpmu_read(struct perf_event *event)
 	if (hwc->idx < 0)
 	if (hwc->idx < 0)
 		return;
 		return;
 
 
-	armpmu_event_update(event, hwc, hwc->idx);
+	armpmu_event_update(event, hwc, hwc->idx, 0);
 }
 }
 
 
 static void
 static void
@@ -254,7 +258,7 @@ armpmu_stop(struct perf_event *event, int flags)
 	if (!(hwc->state & PERF_HES_STOPPED)) {
 	if (!(hwc->state & PERF_HES_STOPPED)) {
 		armpmu->disable(hwc, hwc->idx);
 		armpmu->disable(hwc, hwc->idx);
 		barrier(); /* why? */
 		barrier(); /* why? */
-		armpmu_event_update(event, hwc, hwc->idx);
+		armpmu_event_update(event, hwc, hwc->idx, 0);
 		hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
 		hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
 	}
 	}
 }
 }
@@ -624,6 +628,19 @@ static struct pmu pmu = {
 #include "perf_event_v6.c"
 #include "perf_event_v6.c"
 #include "perf_event_v7.c"
 #include "perf_event_v7.c"
 
 
+/*
+ * Ensure the PMU has sane values out of reset.
+ * This requires SMP to be available, so exists as a separate initcall.
+ */
+static int __init
+armpmu_reset(void)
+{
+	if (armpmu && armpmu->reset)
+		return on_each_cpu(armpmu->reset, NULL, 1);
+	return 0;
+}
+arch_initcall(armpmu_reset);
+
 static int __init
 static int __init
 init_hw_perf_events(void)
 init_hw_perf_events(void)
 {
 {

+ 1 - 1
arch/arm/kernel/perf_event_v6.c

@@ -474,7 +474,7 @@ armv6pmu_handle_irq(int irq_num,
 			continue;
 			continue;
 
 
 		hwc = &event->hw;
 		hwc = &event->hw;
-		armpmu_event_update(event, hwc, idx);
+		armpmu_event_update(event, hwc, idx, 1);
 		data.period = event->hw.last_period;
 		data.period = event->hw.last_period;
 		if (!armpmu_event_set_period(event, hwc, idx))
 		if (!armpmu_event_set_period(event, hwc, idx))
 			continue;
 			continue;

+ 19 - 7
arch/arm/kernel/perf_event_v7.c

@@ -466,6 +466,7 @@ static inline unsigned long armv7_pmnc_read(void)
 static inline void armv7_pmnc_write(unsigned long val)
 static inline void armv7_pmnc_write(unsigned long val)
 {
 {
 	val &= ARMV7_PMNC_MASK;
 	val &= ARMV7_PMNC_MASK;
+	isb();
 	asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
 	asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
 }
 }
 
 
@@ -502,6 +503,7 @@ static inline int armv7_pmnc_select_counter(unsigned int idx)
 
 
 	val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK;
 	val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK;
 	asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
 	asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
+	isb();
 
 
 	return idx;
 	return idx;
 }
 }
@@ -780,7 +782,7 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
 			continue;
 			continue;
 
 
 		hwc = &event->hw;
 		hwc = &event->hw;
-		armpmu_event_update(event, hwc, idx);
+		armpmu_event_update(event, hwc, idx, 1);
 		data.period = event->hw.last_period;
 		data.period = event->hw.last_period;
 		if (!armpmu_event_set_period(event, hwc, idx))
 		if (!armpmu_event_set_period(event, hwc, idx))
 			continue;
 			continue;
@@ -847,6 +849,18 @@ static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc,
 	}
 	}
 }
 }
 
 
+static void armv7pmu_reset(void *info)
+{
+	u32 idx, nb_cnt = armpmu->num_events;
+
+	/* The counter and interrupt enable registers are unknown at reset. */
+	for (idx = 1; idx < nb_cnt; ++idx)
+		armv7pmu_disable_event(NULL, idx);
+
+	/* Initialize & Reset PMNC: C and P bits */
+	armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
+}
+
 static struct arm_pmu armv7pmu = {
 static struct arm_pmu armv7pmu = {
 	.handle_irq		= armv7pmu_handle_irq,
 	.handle_irq		= armv7pmu_handle_irq,
 	.enable			= armv7pmu_enable_event,
 	.enable			= armv7pmu_enable_event,
@@ -856,17 +870,15 @@ static struct arm_pmu armv7pmu = {
 	.get_event_idx		= armv7pmu_get_event_idx,
 	.get_event_idx		= armv7pmu_get_event_idx,
 	.start			= armv7pmu_start,
 	.start			= armv7pmu_start,
 	.stop			= armv7pmu_stop,
 	.stop			= armv7pmu_stop,
+	.reset			= armv7pmu_reset,
 	.raw_event_mask		= 0xFF,
 	.raw_event_mask		= 0xFF,
 	.max_period		= (1LLU << 32) - 1,
 	.max_period		= (1LLU << 32) - 1,
 };
 };
 
 
-static u32 __init armv7_reset_read_pmnc(void)
+static u32 __init armv7_read_num_pmnc_events(void)
 {
 {
 	u32 nb_cnt;
 	u32 nb_cnt;
 
 
-	/* Initialize & Reset PMNC: C and P bits */
-	armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
-
 	/* Read the nb of CNTx counters supported from PMNC */
 	/* Read the nb of CNTx counters supported from PMNC */
 	nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
 	nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
 
 
@@ -880,7 +892,7 @@ static const struct arm_pmu *__init armv7_a8_pmu_init(void)
 	armv7pmu.name		= "ARMv7 Cortex-A8";
 	armv7pmu.name		= "ARMv7 Cortex-A8";
 	armv7pmu.cache_map	= &armv7_a8_perf_cache_map;
 	armv7pmu.cache_map	= &armv7_a8_perf_cache_map;
 	armv7pmu.event_map	= &armv7_a8_perf_map;
 	armv7pmu.event_map	= &armv7_a8_perf_map;
-	armv7pmu.num_events	= armv7_reset_read_pmnc();
+	armv7pmu.num_events	= armv7_read_num_pmnc_events();
 	return &armv7pmu;
 	return &armv7pmu;
 }
 }
 
 
@@ -890,7 +902,7 @@ static const struct arm_pmu *__init armv7_a9_pmu_init(void)
 	armv7pmu.name		= "ARMv7 Cortex-A9";
 	armv7pmu.name		= "ARMv7 Cortex-A9";
 	armv7pmu.cache_map	= &armv7_a9_perf_cache_map;
 	armv7pmu.cache_map	= &armv7_a9_perf_cache_map;
 	armv7pmu.event_map	= &armv7_a9_perf_map;
 	armv7pmu.event_map	= &armv7_a9_perf_map;
-	armv7pmu.num_events	= armv7_reset_read_pmnc();
+	armv7pmu.num_events	= armv7_read_num_pmnc_events();
 	return &armv7pmu;
 	return &armv7pmu;
 }
 }
 #else
 #else

+ 2 - 2
arch/arm/kernel/perf_event_xscale.c

@@ -246,7 +246,7 @@ xscale1pmu_handle_irq(int irq_num, void *dev)
 			continue;
 			continue;
 
 
 		hwc = &event->hw;
 		hwc = &event->hw;
-		armpmu_event_update(event, hwc, idx);
+		armpmu_event_update(event, hwc, idx, 1);
 		data.period = event->hw.last_period;
 		data.period = event->hw.last_period;
 		if (!armpmu_event_set_period(event, hwc, idx))
 		if (!armpmu_event_set_period(event, hwc, idx))
 			continue;
 			continue;
@@ -578,7 +578,7 @@ xscale2pmu_handle_irq(int irq_num, void *dev)
 			continue;
 			continue;
 
 
 		hwc = &event->hw;
 		hwc = &event->hw;
-		armpmu_event_update(event, hwc, idx);
+		armpmu_event_update(event, hwc, idx, 1);
 		data.period = event->hw.last_period;
 		data.period = event->hw.last_period;
 		if (!armpmu_event_set_period(event, hwc, idx))
 		if (!armpmu_event_set_period(event, hwc, idx))
 			continue;
 			continue;

+ 11 - 3
arch/arm/kernel/sleep.S

@@ -119,11 +119,19 @@ ENTRY(cpu_resume)
 #else
 #else
 	ldr	r0, sleep_save_sp	@ stack phys addr
 	ldr	r0, sleep_save_sp	@ stack phys addr
 #endif
 #endif
-	msr	cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
+	setmode	PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1  @ set SVC, irqs off
 #ifdef MULTI_CPU
 #ifdef MULTI_CPU
-	ldmia	r0!, {r1, sp, lr, pc}	@ load v:p, stack, return fn, resume fn
+	@ load v:p, stack, return fn, resume fn
+  ARM(	ldmia	r0!, {r1, sp, lr, pc}	)
+THUMB(	ldmia	r0!, {r1, r2, r3, r4}	)
+THUMB(	mov	sp, r2			)
+THUMB(	mov	lr, r3			)
+THUMB(	bx	r4			)
 #else
 #else
-	ldmia	r0!, {r1, sp, lr}	@ load v:p, stack, return fn
+	@ load v:p, stack, return fn
+  ARM(	ldmia	r0!, {r1, sp, lr}	)
+THUMB(	ldmia	r0!, {r1, r2, lr}	)
+THUMB(	mov	sp, r2			)
 	b	cpu_do_resume
 	b	cpu_do_resume
 #endif
 #endif
 ENDPROC(cpu_resume)
 ENDPROC(cpu_resume)

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

@@ -255,6 +255,7 @@ config MACH_IMX27_VISSTRIM_M10
 	bool "Vista Silicon i.MX27 Visstrim_m10"
 	bool "Vista Silicon i.MX27 Visstrim_m10"
 	select SOC_IMX27
 	select SOC_IMX27
 	select IMX_HAVE_PLATFORM_IMX_I2C
 	select IMX_HAVE_PLATFORM_IMX_I2C
+	select IMX_HAVE_PLATFORM_IMX_SSI
 	select IMX_HAVE_PLATFORM_IMX_UART
 	select IMX_HAVE_PLATFORM_IMX_UART
 	select IMX_HAVE_PLATFORM_MXC_MMC
 	select IMX_HAVE_PLATFORM_MXC_MMC
 	select IMX_HAVE_PLATFORM_MXC_EHCI
 	select IMX_HAVE_PLATFORM_MXC_EHCI

+ 7 - 1
arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c

@@ -34,6 +34,7 @@
 #include <mach/mx25.h>
 #include <mach/mx25.h>
 #include <mach/imx-uart.h>
 #include <mach/imx-uart.h>
 #include <mach/audmux.h>
 #include <mach/audmux.h>
+#include <mach/esdhc.h>
 
 
 #include "devices-imx25.h"
 #include "devices-imx25.h"
 
 
@@ -242,6 +243,11 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
 	.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
 	.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
 };
 };
 
 
+static struct esdhc_platform_data sd1_pdata = {
+	.cd_gpio = GPIO_SD1CD,
+	.wp_gpio = -EINVAL,
+};
+
 /*
 /*
  * system init for baseboard usage. Will be called by cpuimx25 init.
  * system init for baseboard usage. Will be called by cpuimx25 init.
  *
  *
@@ -275,7 +281,7 @@ void __init eukrea_mbimxsd25_baseboard_init(void)
 	imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
 	imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
 
 
 	imx25_add_flexcan1(NULL);
 	imx25_add_flexcan1(NULL);
-	imx25_add_sdhci_esdhc_imx(0, NULL);
+	imx25_add_sdhci_esdhc_imx(0, &sd1_pdata);
 
 
 	gpio_request(GPIO_LED1, "LED1");
 	gpio_request(GPIO_LED1, "LED1");
 	gpio_direction_output(GPIO_LED1, 1);
 	gpio_direction_output(GPIO_LED1, 1);

+ 7 - 0
arch/arm/mach-kirkwood/sheevaplug-setup.c

@@ -57,6 +57,12 @@ static struct mvsdio_platform_data sheeva_esata_mvsdio_data = {
 };
 };
 
 
 static struct gpio_led sheevaplug_led_pins[] = {
 static struct gpio_led sheevaplug_led_pins[] = {
+	{
+		.name			= "plug:red:misc",
+		.default_trigger	= "none",
+		.gpio			= 46,
+		.active_low		= 1,
+	},
 	{
 	{
 		.name			= "plug:green:health",
 		.name			= "plug:green:health",
 		.default_trigger	= "default-on",
 		.default_trigger	= "default-on",
@@ -80,6 +86,7 @@ static struct platform_device sheevaplug_leds = {
 
 
 static unsigned int sheevaplug_mpp_config[] __initdata = {
 static unsigned int sheevaplug_mpp_config[] __initdata = {
 	MPP29_GPIO,	/* USB Power Enable */
 	MPP29_GPIO,	/* USB Power Enable */
+	MPP46_GPIO,	/* LED Red */
 	MPP49_GPIO,	/* LED */
 	MPP49_GPIO,	/* LED */
 	0
 	0
 };
 };

+ 11 - 3
arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c

@@ -43,6 +43,7 @@
 #include <mach/ipu.h>
 #include <mach/ipu.h>
 #include <mach/mx3fb.h>
 #include <mach/mx3fb.h>
 #include <mach/audmux.h>
 #include <mach/audmux.h>
+#include <mach/esdhc.h>
 
 
 #include "devices-imx35.h"
 #include "devices-imx35.h"
 #include "devices.h"
 #include "devices.h"
@@ -163,11 +164,14 @@ static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
 	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
 	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
 	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
 	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
 	MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
 	MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+	/* SD1 CD */
+	MX35_PAD_LD18__GPIO3_24,
 };
 };
 
 
 #define GPIO_LED1	IMX_GPIO_NR(3, 29)
 #define GPIO_LED1	IMX_GPIO_NR(3, 29)
 #define GPIO_SWITCH1	IMX_GPIO_NR(3, 25)
 #define GPIO_SWITCH1	IMX_GPIO_NR(3, 25)
-#define GPIO_LCDPWR	(4)
+#define GPIO_LCDPWR	IMX_GPIO_NR(1, 4)
+#define GPIO_SD1CD	IMX_GPIO_NR(3, 24)
 
 
 static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd,
 static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd,
 				   unsigned int power)
 				   unsigned int power)
@@ -254,6 +258,11 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
 	.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
 	.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
 };
 };
 
 
+static struct esdhc_platform_data sd1_pdata = {
+	.cd_gpio = GPIO_SD1CD,
+	.wp_gpio = -EINVAL,
+};
+
 /*
 /*
  * system init for baseboard usage. Will be called by cpuimx35 init.
  * system init for baseboard usage. Will be called by cpuimx35 init.
  *
  *
@@ -289,7 +298,7 @@ void __init eukrea_mbimxsd35_baseboard_init(void)
 	imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
 	imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
 
 
 	imx35_add_flexcan1(NULL);
 	imx35_add_flexcan1(NULL);
-	imx35_add_sdhci_esdhc_imx(0, NULL);
+	imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);
 
 
 	gpio_request(GPIO_LED1, "LED1");
 	gpio_request(GPIO_LED1, "LED1");
 	gpio_direction_output(GPIO_LED1, 1);
 	gpio_direction_output(GPIO_LED1, 1);
@@ -301,7 +310,6 @@ void __init eukrea_mbimxsd35_baseboard_init(void)
 
 
 	gpio_request(GPIO_LCDPWR, "LCDPWR");
 	gpio_request(GPIO_LCDPWR, "LCDPWR");
 	gpio_direction_output(GPIO_LCDPWR, 1);
 	gpio_direction_output(GPIO_LCDPWR, 1);
-	gpio_free(GPIO_LCDPWR);
 
 
 	i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
 	i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
 				ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
 				ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));

+ 11 - 1
arch/arm/mach-mx3/mach-pcm043.c

@@ -40,6 +40,7 @@
 #include <mach/mx3fb.h>
 #include <mach/mx3fb.h>
 #include <mach/ulpi.h>
 #include <mach/ulpi.h>
 #include <mach/audmux.h>
 #include <mach/audmux.h>
+#include <mach/esdhc.h>
 
 
 #include "devices-imx35.h"
 #include "devices-imx35.h"
 #include "devices.h"
 #include "devices.h"
@@ -217,11 +218,15 @@ static iomux_v3_cfg_t pcm043_pads[] = {
 	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
 	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
 	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
 	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
 	MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
 	MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+	MX35_PAD_ATA_DATA10__GPIO2_23, /* WriteProtect */
+	MX35_PAD_ATA_DATA11__GPIO2_24, /* CardDetect */
 };
 };
 
 
 #define AC97_GPIO_TXFS	IMX_GPIO_NR(2, 31)
 #define AC97_GPIO_TXFS	IMX_GPIO_NR(2, 31)
 #define AC97_GPIO_TXD	IMX_GPIO_NR(2, 28)
 #define AC97_GPIO_TXD	IMX_GPIO_NR(2, 28)
 #define AC97_GPIO_RESET	IMX_GPIO_NR(2, 0)
 #define AC97_GPIO_RESET	IMX_GPIO_NR(2, 0)
+#define SD1_GPIO_WP	IMX_GPIO_NR(2, 23)
+#define SD1_GPIO_CD	IMX_GPIO_NR(2, 24)
 
 
 static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
 static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
 {
 {
@@ -346,6 +351,11 @@ static int __init pcm043_otg_mode(char *options)
 }
 }
 __setup("otg_mode=", pcm043_otg_mode);
 __setup("otg_mode=", pcm043_otg_mode);
 
 
+static struct esdhc_platform_data sd1_pdata = {
+	.wp_gpio = SD1_GPIO_WP,
+	.cd_gpio = SD1_GPIO_CD,
+};
+
 /*
 /*
  * Board specific initialization.
  * Board specific initialization.
  */
  */
@@ -395,7 +405,7 @@ static void __init pcm043_init(void)
 		imx35_add_fsl_usb2_udc(&otg_device_pdata);
 		imx35_add_fsl_usb2_udc(&otg_device_pdata);
 
 
 	imx35_add_flexcan1(NULL);
 	imx35_add_flexcan1(NULL);
-	imx35_add_sdhci_esdhc_imx(0, NULL);
+	imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);
 }
 }
 
 
 static void __init pcm043_timer_init(void)
 static void __init pcm043_timer_init(void)

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

@@ -165,6 +165,7 @@ config MACH_MX53_LOCO
 	select IMX_HAVE_PLATFORM_IMX_I2C
 	select IMX_HAVE_PLATFORM_IMX_I2C
 	select IMX_HAVE_PLATFORM_IMX_UART
 	select IMX_HAVE_PLATFORM_IMX_UART
 	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
 	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+	select IMX_HAVE_PLATFORM_GPIO_KEYS
 	help
 	help
 	  Include support for MX53 LOCO platform. This includes specific
 	  Include support for MX53 LOCO platform. This includes specific
 	  configurations for the board and its peripherals.
 	  configurations for the board and its peripherals.

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

@@ -3,7 +3,7 @@
 #
 #
 
 
 # Object file lists.
 # Object file lists.
-obj-y   := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o
+obj-y   := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o system.o
 obj-$(CONFIG_SOC_IMX50) += mm-mx50.o
 obj-$(CONFIG_SOC_IMX50) += mm-mx50.o
 
 
 obj-$(CONFIG_CPU_FREQ_IMX)    += cpu_op-mx51.o
 obj-$(CONFIG_CPU_FREQ_IMX)    += cpu_op-mx51.o

+ 2 - 3
arch/arm/mach-mx5/board-mx51_babbage.c

@@ -228,13 +228,12 @@ static inline void babbage_fec_reset(void)
 	int ret;
 	int ret;
 
 
 	/* reset FEC PHY */
 	/* reset FEC PHY */
-	ret = gpio_request(BABBAGE_FEC_PHY_RESET, "fec-phy-reset");
+	ret = gpio_request_one(BABBAGE_FEC_PHY_RESET,
+					GPIOF_OUT_INIT_LOW, "fec-phy-reset");
 	if (ret) {
 	if (ret) {
 		printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);
 		printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);
 		return;
 		return;
 	}
 	}
-	gpio_direction_output(BABBAGE_FEC_PHY_RESET, 0);
-	gpio_set_value(BABBAGE_FEC_PHY_RESET, 0);
 	msleep(1);
 	msleep(1);
 	gpio_set_value(BABBAGE_FEC_PHY_RESET, 1);
 	gpio_set_value(BABBAGE_FEC_PHY_RESET, 1);
 }
 }

+ 4 - 5
arch/arm/mach-mx5/board-mx53_evk.c

@@ -34,7 +34,7 @@
 #include <mach/imx-uart.h>
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx53.h>
 #include <mach/iomux-mx53.h>
 
 
-#define SMD_FEC_PHY_RST		IMX_GPIO_NR(7, 6)
+#define MX53_EVK_FEC_PHY_RST	IMX_GPIO_NR(7, 6)
 #define EVK_ECSPI1_CS0		IMX_GPIO_NR(2, 30)
 #define EVK_ECSPI1_CS0		IMX_GPIO_NR(2, 30)
 #define EVK_ECSPI1_CS1		IMX_GPIO_NR(3, 19)
 #define EVK_ECSPI1_CS1		IMX_GPIO_NR(3, 19)
 
 
@@ -82,15 +82,14 @@ static inline void mx53_evk_fec_reset(void)
 	int ret;
 	int ret;
 
 
 	/* reset FEC PHY */
 	/* reset FEC PHY */
-	ret = gpio_request(SMD_FEC_PHY_RST, "fec-phy-reset");
+	ret = gpio_request_one(MX53_EVK_FEC_PHY_RST, GPIOF_OUT_INIT_LOW,
+							"fec-phy-reset");
 	if (ret) {
 	if (ret) {
 		printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);
 		printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);
 		return;
 		return;
 	}
 	}
-	gpio_direction_output(SMD_FEC_PHY_RST, 0);
-	gpio_set_value(SMD_FEC_PHY_RST, 0);
 	msleep(1);
 	msleep(1);
-	gpio_set_value(SMD_FEC_PHY_RST, 1);
+	gpio_set_value(MX53_EVK_FEC_PHY_RST, 1);
 }
 }
 
 
 static struct fec_platform_data mx53_evk_fec_pdata = {
 static struct fec_platform_data mx53_evk_fec_pdata = {

+ 25 - 0
arch/arm/mach-mx5/board-mx53_loco.c

@@ -36,6 +36,9 @@
 #include "crm_regs.h"
 #include "crm_regs.h"
 #include "devices-imx53.h"
 #include "devices-imx53.h"
 
 
+#define MX53_LOCO_POWER			IMX_GPIO_NR(1, 8)
+#define MX53_LOCO_UI1			IMX_GPIO_NR(2, 14)
+#define MX53_LOCO_UI2			IMX_GPIO_NR(2, 15)
 #define LOCO_FEC_PHY_RST		IMX_GPIO_NR(7, 6)
 #define LOCO_FEC_PHY_RST		IMX_GPIO_NR(7, 6)
 
 
 static iomux_v3_cfg_t mx53_loco_pads[] = {
 static iomux_v3_cfg_t mx53_loco_pads[] = {
@@ -180,6 +183,27 @@ static iomux_v3_cfg_t mx53_loco_pads[] = {
 	MX53_PAD_GPIO_8__GPIO1_8,
 	MX53_PAD_GPIO_8__GPIO1_8,
 };
 };
 
 
+#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake)	\
+{								\
+	.gpio		= gpio_num,				\
+	.type		= EV_KEY,				\
+	.code		= ev_code,				\
+	.active_low	= act_low,				\
+	.desc		= "btn " descr,				\
+	.wakeup		= wake,					\
+}
+
+static const struct gpio_keys_button loco_buttons[] __initconst = {
+	GPIO_BUTTON(MX53_LOCO_POWER, KEY_POWER, 1, "power", 0),
+	GPIO_BUTTON(MX53_LOCO_UI1, KEY_VOLUMEUP, 1, "volume-up", 0),
+	GPIO_BUTTON(MX53_LOCO_UI2, KEY_VOLUMEDOWN, 1, "volume-down", 0),
+};
+
+static const struct gpio_keys_platform_data loco_button_data __initconst = {
+	.buttons        = loco_buttons,
+	.nbuttons       = ARRAY_SIZE(loco_buttons),
+};
+
 static inline void mx53_loco_fec_reset(void)
 static inline void mx53_loco_fec_reset(void)
 {
 {
 	int ret;
 	int ret;
@@ -215,6 +239,7 @@ static void __init mx53_loco_board_init(void)
 	imx53_add_imx_i2c(1, &mx53_loco_i2c_data);
 	imx53_add_imx_i2c(1, &mx53_loco_i2c_data);
 	imx53_add_sdhci_esdhc_imx(0, NULL);
 	imx53_add_sdhci_esdhc_imx(0, NULL);
 	imx53_add_sdhci_esdhc_imx(2, NULL);
 	imx53_add_sdhci_esdhc_imx(2, NULL);
+	imx_add_gpio_keys(&loco_button_data);
 }
 }
 
 
 static void __init mx53_loco_timer_init(void)
 static void __init mx53_loco_timer_init(void)

+ 9 - 0
arch/arm/mach-mx5/clock-mx51-mx53.c

@@ -865,6 +865,13 @@ static struct clk aips_tz2_clk = {
 	.disable = _clk_ccgr_disable_inwait,
 	.disable = _clk_ccgr_disable_inwait,
 };
 };
 
 
+static struct clk gpc_dvfs_clk = {
+	.enable_reg = MXC_CCM_CCGR5,
+	.enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+	.enable = _clk_ccgr_enable,
+	.disable = _clk_ccgr_disable,
+};
+
 static struct clk gpt_32k_clk = {
 static struct clk gpt_32k_clk = {
 	.id = 0,
 	.id = 0,
 	.parent = &ckil_clk,
 	.parent = &ckil_clk,
@@ -1448,6 +1455,7 @@ static struct clk_lookup mx51_lookups[] = {
 	_REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk)
 	_REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk)
 	_REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk)
 	_REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk)
 	_REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk)
 	_REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk)
+	_REGISTER_CLOCK(NULL, "gpc_dvfs", gpc_dvfs_clk)
 };
 };
 
 
 static struct clk_lookup mx53_lookups[] = {
 static struct clk_lookup mx53_lookups[] = {
@@ -1511,6 +1519,7 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
 	clk_enable(&iim_clk);
 	clk_enable(&iim_clk);
 	mx51_revision();
 	mx51_revision();
 	clk_disable(&iim_clk);
 	clk_disable(&iim_clk);
+	mx51_display_revision();
 
 
 	/* move usb_phy_clk to 24MHz */
 	/* move usb_phy_clk to 24MHz */
 	clk_set_parent(&usb_phy1_clk, &osc_clk);
 	clk_set_parent(&usb_phy1_clk, &osc_clk);

+ 59 - 0
arch/arm/mach-mx5/cpu.c

@@ -21,6 +21,7 @@
 static int cpu_silicon_rev = -1;
 static int cpu_silicon_rev = -1;
 
 
 #define IIM_SREV 0x24
 #define IIM_SREV 0x24
+#define MX50_HW_ADADIG_DIGPROG	0xB0
 
 
 static int get_mx51_srev(void)
 static int get_mx51_srev(void)
 {
 {
@@ -51,6 +52,26 @@ int mx51_revision(void)
 }
 }
 EXPORT_SYMBOL(mx51_revision);
 EXPORT_SYMBOL(mx51_revision);
 
 
+void mx51_display_revision(void)
+{
+	int rev;
+	char *srev;
+	rev = mx51_revision();
+
+	switch (rev) {
+	case IMX_CHIP_REVISION_2_0:
+		srev = IMX_CHIP_REVISION_2_0_STRING;
+		break;
+	case IMX_CHIP_REVISION_3_0:
+		srev = IMX_CHIP_REVISION_3_0_STRING;
+		break;
+	default:
+		srev = IMX_CHIP_REVISION_UNKNOWN_STRING;
+	}
+	printk(KERN_INFO "CPU identified as i.MX51, silicon rev %s\n", srev);
+}
+EXPORT_SYMBOL(mx51_display_revision);
+
 #ifdef CONFIG_NEON
 #ifdef CONFIG_NEON
 
 
 /*
 /*
@@ -107,6 +128,44 @@ int mx53_revision(void)
 }
 }
 EXPORT_SYMBOL(mx53_revision);
 EXPORT_SYMBOL(mx53_revision);
 
 
+static int get_mx50_srev(void)
+{
+	void __iomem *anatop = ioremap(MX50_ANATOP_BASE_ADDR, SZ_8K);
+	u32 rev;
+
+	if (!anatop) {
+		cpu_silicon_rev = -EINVAL;
+		return 0;
+	}
+
+	rev = readl(anatop + MX50_HW_ADADIG_DIGPROG);
+	rev &= 0xff;
+
+	iounmap(anatop);
+	if (rev == 0x0)
+		return IMX_CHIP_REVISION_1_0;
+	else if (rev == 0x1)
+		return IMX_CHIP_REVISION_1_1;
+	return 0;
+}
+
+/*
+ * Returns:
+ *	the silicon revision of the cpu
+ *	-EINVAL - not a mx50
+ */
+int mx50_revision(void)
+{
+	if (!cpu_is_mx50())
+		return -EINVAL;
+
+	if (cpu_silicon_rev == -1)
+		cpu_silicon_rev = get_mx50_srev();
+
+	return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx50_revision);
+
 static int __init post_cpu_init(void)
 static int __init post_cpu_init(void)
 {
 {
 	unsigned int reg;
 	unsigned int reg;

+ 4 - 0
arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c

@@ -67,6 +67,10 @@ static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
 	MX51_PAD_SD1_DATA1__SD1_DATA1,
 	MX51_PAD_SD1_DATA1__SD1_DATA1,
 	MX51_PAD_SD1_DATA2__SD1_DATA2,
 	MX51_PAD_SD1_DATA2__SD1_DATA2,
 	MX51_PAD_SD1_DATA3__SD1_DATA3,
 	MX51_PAD_SD1_DATA3__SD1_DATA3,
+	/* SD1 CD */
+	_MX51_PAD_GPIO1_0__SD1_CD | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
+			PAD_CTL_PKE | PAD_CTL_SRE_FAST |
+			PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),
 };
 };
 
 
 #define GPIO_LED1	IMX_GPIO_NR(3, 30)
 #define GPIO_LED1	IMX_GPIO_NR(3, 30)

+ 0 - 1
arch/arm/mach-mx5/mx51_efika.c

@@ -42,7 +42,6 @@
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/mach/time.h>
-#include <asm/mach-types.h>
 
 
 #include "devices-imx51.h"
 #include "devices-imx51.h"
 #include "devices.h"
 #include "devices.h"

+ 84 - 0
arch/arm/mach-mx5/system.c

@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include "crm_regs.h"
+
+/* set cpu low power mode before WFI instruction. This function is called
+  * mx5 because it can be used for mx50, mx51, and mx53.*/
+void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
+{
+	u32 plat_lpc, arm_srpgcr, ccm_clpcr;
+	u32 empgc0, empgc1;
+	int stop_mode = 0;
+
+	/* always allow platform to issue a deep sleep mode request */
+	plat_lpc = __raw_readl(MXC_CORTEXA8_PLAT_LPC) &
+	    ~(MXC_CORTEXA8_PLAT_LPC_DSM);
+	ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK);
+	arm_srpgcr = __raw_readl(MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR);
+	empgc0 = __raw_readl(MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR);
+	empgc1 = __raw_readl(MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR);
+
+	switch (mode) {
+	case WAIT_CLOCKED:
+		break;
+	case WAIT_UNCLOCKED:
+		ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
+		break;
+	case WAIT_UNCLOCKED_POWER_OFF:
+	case STOP_POWER_OFF:
+		plat_lpc |= MXC_CORTEXA8_PLAT_LPC_DSM
+			    | MXC_CORTEXA8_PLAT_LPC_DBG_DSM;
+		if (mode == WAIT_UNCLOCKED_POWER_OFF) {
+			ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
+			ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY;
+			ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
+			stop_mode = 0;
+		} else {
+			ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
+			ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET;
+			ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
+			ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
+			stop_mode = 1;
+		}
+		arm_srpgcr |= MXC_SRPGCR_PCR;
+
+		if (tzic_enable_wake(1) != 0)
+			return;
+		break;
+	case STOP_POWER_ON:
+		ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
+		break;
+	default:
+		printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode);
+		return;
+	}
+
+	__raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC);
+	__raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
+	__raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR);
+
+	/* Enable NEON SRPG for all but MX50TO1.0. */
+	if (mx50_revision() != IMX_CHIP_REVISION_1_0)
+		__raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR);
+
+	if (stop_mode) {
+		empgc0 |= MXC_SRPGCR_PCR;
+		empgc1 |= MXC_SRPGCR_PCR;
+
+		__raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR);
+		__raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR);
+	}
+}

+ 2 - 0
arch/arm/mach-mxs/Kconfig

@@ -22,6 +22,7 @@ config MACH_MX23EVK
 	select SOC_IMX23
 	select SOC_IMX23
 	select MXS_HAVE_AMBA_DUART
 	select MXS_HAVE_AMBA_DUART
 	select MXS_HAVE_PLATFORM_AUART
 	select MXS_HAVE_PLATFORM_AUART
+	select MXS_HAVE_PLATFORM_MXS_MMC
 	select MXS_HAVE_PLATFORM_MXSFB
 	select MXS_HAVE_PLATFORM_MXSFB
 	default y
 	default y
 	help
 	help
@@ -35,6 +36,7 @@ config MACH_MX28EVK
 	select MXS_HAVE_PLATFORM_AUART
 	select MXS_HAVE_PLATFORM_AUART
 	select MXS_HAVE_PLATFORM_FEC
 	select MXS_HAVE_PLATFORM_FEC
 	select MXS_HAVE_PLATFORM_FLEXCAN
 	select MXS_HAVE_PLATFORM_FLEXCAN
+	select MXS_HAVE_PLATFORM_MXS_MMC
 	select MXS_HAVE_PLATFORM_MXSFB
 	select MXS_HAVE_PLATFORM_MXSFB
 	select MXS_OCOTP
 	select MXS_OCOTP
 	default y
 	default y

+ 15 - 0
arch/arm/mach-mxs/clock-mx23.c

@@ -521,6 +521,15 @@ static int clk_misc_init(void)
 	__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
 	__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
 			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
 			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
 
 
+	/*
+	 * 480 MHz seems too high to be ssp clock source directly,
+	 * so set frac to get a 288 MHz ref_io.
+	 */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+	reg &= ~BM_CLKCTRL_FRAC_IOFRAC;
+	reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -528,6 +537,12 @@ int __init mx23_clocks_init(void)
 {
 {
 	clk_misc_init();
 	clk_misc_init();
 
 
+	/*
+	 * source ssp clock from ref_io than ref_xtal,
+	 * as ref_xtal only provides 24 MHz as maximum.
+	 */
+	clk_set_parent(&ssp_clk, &ref_io_clk);
+
 	clk_enable(&cpu_clk);
 	clk_enable(&cpu_clk);
 	clk_enable(&hbus_clk);
 	clk_enable(&hbus_clk);
 	clk_enable(&xbus_clk);
 	clk_enable(&xbus_clk);

+ 18 - 0
arch/arm/mach-mxs/clock-mx28.c

@@ -618,6 +618,8 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("pll2", NULL, pll2_clk)
 	_REGISTER_CLOCK("pll2", NULL, pll2_clk)
 	_REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
 	_REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
 	_REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
 	_REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
+	_REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk)
+	_REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
 	_REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
 	_REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
 	_REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
 	_REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
 	_REGISTER_CLOCK(NULL, "usb0", usb0_clk)
 	_REGISTER_CLOCK(NULL, "usb0", usb0_clk)
@@ -737,6 +739,15 @@ static int clk_misc_init(void)
 	reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
 	reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
 	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
 	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
 
 
+	/*
+	 * 480 MHz seems too high to be ssp clock source directly,
+	 * so set frac0 to get a 288 MHz ref_io0.
+	 */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
+	reg &= ~BM_CLKCTRL_FRAC0_IO0FRAC;
+	reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -744,6 +755,13 @@ int __init mx28_clocks_init(void)
 {
 {
 	clk_misc_init();
 	clk_misc_init();
 
 
+	/*
+	 * source ssp clock from ref_io0 than ref_xtal,
+	 * as ref_xtal only provides 24 MHz as maximum.
+	 */
+	clk_set_parent(&ssp0_clk, &ref_io0_clk);
+	clk_set_parent(&ssp1_clk, &ref_io0_clk);
+
 	clk_enable(&cpu_clk);
 	clk_enable(&cpu_clk);
 	clk_enable(&hbus_clk);
 	clk_enable(&hbus_clk);
 	clk_enable(&xbus_clk);
 	clk_enable(&xbus_clk);

+ 4 - 0
arch/arm/mach-mxs/devices-mx23.h

@@ -21,6 +21,10 @@ extern const struct mxs_auart_data mx23_auart_data[] __initconst;
 #define mx23_add_auart0()		mx23_add_auart(0)
 #define mx23_add_auart0()		mx23_add_auart(0)
 #define mx23_add_auart1()		mx23_add_auart(1)
 #define mx23_add_auart1()		mx23_add_auart(1)
 
 
+extern const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst;
+#define mx23_add_mxs_mmc(id, pdata) \
+	mxs_add_mxs_mmc(&mx23_mxs_mmc_data[id], pdata)
+
 #define mx23_add_mxs_pwm(id)		mxs_add_mxs_pwm(MX23_PWM_BASE_ADDR, id)
 #define mx23_add_mxs_pwm(id)		mxs_add_mxs_pwm(MX23_PWM_BASE_ADDR, id)
 
 
 struct platform_device *__init mx23_add_mxsfb(
 struct platform_device *__init mx23_add_mxsfb(

+ 4 - 0
arch/arm/mach-mxs/devices-mx28.h

@@ -37,6 +37,10 @@ extern const struct mxs_flexcan_data mx28_flexcan_data[] __initconst;
 extern const struct mxs_i2c_data mx28_mxs_i2c_data[] __initconst;
 extern const struct mxs_i2c_data mx28_mxs_i2c_data[] __initconst;
 #define mx28_add_mxs_i2c(id)		mxs_add_mxs_i2c(&mx28_mxs_i2c_data[id])
 #define mx28_add_mxs_i2c(id)		mxs_add_mxs_i2c(&mx28_mxs_i2c_data[id])
 
 
+extern const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst;
+#define mx28_add_mxs_mmc(id, pdata) \
+	mxs_add_mxs_mmc(&mx28_mxs_mmc_data[id], pdata)
+
 #define mx28_add_mxs_pwm(id)		mxs_add_mxs_pwm(MX28_PWM_BASE_ADDR, id)
 #define mx28_add_mxs_pwm(id)		mxs_add_mxs_pwm(MX28_PWM_BASE_ADDR, id)
 
 
 struct platform_device *__init mx28_add_mxsfb(
 struct platform_device *__init mx28_add_mxsfb(

+ 3 - 0
arch/arm/mach-mxs/devices/Kconfig

@@ -15,6 +15,9 @@ config MXS_HAVE_PLATFORM_FLEXCAN
 config MXS_HAVE_PLATFORM_MXS_I2C
 config MXS_HAVE_PLATFORM_MXS_I2C
 	bool
 	bool
 
 
+config MXS_HAVE_PLATFORM_MXS_MMC
+	bool
+
 config MXS_HAVE_PLATFORM_MXS_PWM
 config MXS_HAVE_PLATFORM_MXS_PWM
 	bool
 	bool
 
 

+ 1 - 0
arch/arm/mach-mxs/devices/Makefile

@@ -4,5 +4,6 @@ obj-y += platform-dma.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_I2C) += platform-mxs-i2c.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_I2C) += platform-mxs-i2c.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_MMC) += platform-mxs-mmc.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_PWM) += platform-mxs-pwm.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_PWM) += platform-mxs-pwm.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXSFB) += platform-mxsfb.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXSFB) += platform-mxsfb.o

+ 73 - 0
arch/arm/mach-mxs/devices/platform-mxs-mmc.c

@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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/compiler.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define mxs_mxs_mmc_data_entry_single(soc, _id, hwid)			\
+	{								\
+		.id = _id,						\
+		.iobase = soc ## _SSP ## hwid ## _BASE_ADDR,		\
+		.dma = soc ## _DMA_SSP ## hwid,				\
+		.irq_err = soc ## _INT_SSP ## hwid ## _ERROR,		\
+		.irq_dma = soc ## _INT_SSP ## hwid ## _DMA,		\
+	}
+
+#define mxs_mxs_mmc_data_entry(soc, _id, hwid)				\
+	[_id] = mxs_mxs_mmc_data_entry_single(soc, _id, hwid)
+
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = {
+	mxs_mxs_mmc_data_entry(MX23, 0, 1),
+	mxs_mxs_mmc_data_entry(MX23, 1, 2),
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = {
+	mxs_mxs_mmc_data_entry(MX28, 0, 0),
+	mxs_mxs_mmc_data_entry(MX28, 1, 1),
+};
+#endif
+
+struct platform_device *__init mxs_add_mxs_mmc(
+		const struct mxs_mxs_mmc_data *data,
+		const struct mxs_mmc_platform_data *pdata)
+{
+	struct resource res[] = {
+		{
+			.start	= data->iobase,
+			.end	= data->iobase + SZ_8K - 1,
+			.flags	= IORESOURCE_MEM,
+		}, {
+			.start	= data->dma,
+			.end	= data->dma,
+			.flags	= IORESOURCE_DMA,
+		}, {
+			.start	= data->irq_err,
+			.end	= data->irq_err,
+			.flags	= IORESOURCE_IRQ,
+		}, {
+			.start	= data->irq_dma,
+			.end	= data->irq_dma,
+			.flags	= IORESOURCE_IRQ,
+		},
+	};
+
+	return mxs_add_platform_device("mxs-mmc", data->id,
+			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}

+ 13 - 0
arch/arm/mach-mxs/include/mach/devices-common.h

@@ -73,6 +73,19 @@ struct mxs_i2c_data {
 };
 };
 struct platform_device * __init mxs_add_mxs_i2c(const struct mxs_i2c_data *data);
 struct platform_device * __init mxs_add_mxs_i2c(const struct mxs_i2c_data *data);
 
 
+/* mmc */
+#include <mach/mmc.h>
+struct mxs_mxs_mmc_data {
+	int id;
+	resource_size_t iobase;
+	resource_size_t dma;
+	resource_size_t irq_err;
+	resource_size_t irq_dma;
+};
+struct platform_device *__init mxs_add_mxs_mmc(
+		const struct mxs_mxs_mmc_data *data,
+		const struct mxs_mmc_platform_data *pdata);
+
 /* pwm */
 /* pwm */
 struct platform_device *__init mxs_add_mxs_pwm(
 struct platform_device *__init mxs_add_mxs_pwm(
 		resource_size_t iobase, int id);
 		resource_size_t iobase, int id);

+ 44 - 0
arch/arm/mach-mxs/mach-mx23evk.c

@@ -28,6 +28,8 @@
 
 
 #define MX23EVK_LCD_ENABLE	MXS_GPIO_NR(1, 18)
 #define MX23EVK_LCD_ENABLE	MXS_GPIO_NR(1, 18)
 #define MX23EVK_BL_ENABLE	MXS_GPIO_NR(1, 28)
 #define MX23EVK_BL_ENABLE	MXS_GPIO_NR(1, 28)
+#define MX23EVK_MMC0_WRITE_PROTECT	MXS_GPIO_NR(1, 30)
+#define MX23EVK_MMC0_SLOT_POWER		MXS_GPIO_NR(1, 29)
 
 
 static const iomux_cfg_t mx23evk_pads[] __initconst = {
 static const iomux_cfg_t mx23evk_pads[] __initconst = {
 	/* duart */
 	/* duart */
@@ -73,6 +75,36 @@ static const iomux_cfg_t mx23evk_pads[] __initconst = {
 	MX23_PAD_LCD_RESET__GPIO_1_18 | MXS_PAD_CTRL,
 	MX23_PAD_LCD_RESET__GPIO_1_18 | MXS_PAD_CTRL,
 	/* backlight control */
 	/* backlight control */
 	MX23_PAD_PWM2__GPIO_1_28 | MXS_PAD_CTRL,
 	MX23_PAD_PWM2__GPIO_1_28 | MXS_PAD_CTRL,
+
+	/* mmc */
+	MX23_PAD_SSP1_DATA0__SSP1_DATA0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DATA1__SSP1_DATA1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DATA2__SSP1_DATA2 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DATA3__SSP1_DATA3 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_GPMI_D08__SSP1_DATA4 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_GPMI_D09__SSP1_DATA5 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_GPMI_D10__SSP1_DATA6 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_GPMI_D11__SSP1_DATA7 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_CMD__SSP1_CMD |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DETECT__SSP1_DETECT |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX23_PAD_SSP1_SCK__SSP1_SCK |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* write protect */
+	MX23_PAD_PWM4__GPIO_1_30 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* slot power enable */
+	MX23_PAD_PWM3__GPIO_1_29 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
 };
 };
 
 
 /* mxsfb (lcdif) */
 /* mxsfb (lcdif) */
@@ -101,6 +133,11 @@ static const struct mxsfb_platform_data mx23evk_mxsfb_pdata __initconst = {
 	.ld_intf_width	= STMLCDIF_24BIT,
 	.ld_intf_width	= STMLCDIF_24BIT,
 };
 };
 
 
+static struct mxs_mmc_platform_data mx23evk_mmc_pdata __initdata = {
+	.wp_gpio = MX23EVK_MMC0_WRITE_PROTECT,
+	.flags = SLOTF_8_BIT_CAPABLE,
+};
+
 static void __init mx23evk_init(void)
 static void __init mx23evk_init(void)
 {
 {
 	int ret;
 	int ret;
@@ -110,6 +147,13 @@ static void __init mx23evk_init(void)
 	mx23_add_duart();
 	mx23_add_duart();
 	mx23_add_auart0();
 	mx23_add_auart0();
 
 
+	/* power on mmc slot by writing 0 to the gpio */
+	ret = gpio_request_one(MX23EVK_MMC0_SLOT_POWER, GPIOF_DIR_OUT,
+			       "mmc0-slot-power");
+	if (ret)
+		pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret);
+	mx23_add_mxs_mmc(0, &mx23evk_mmc_pdata);
+
 	ret = gpio_request_one(MX23EVK_LCD_ENABLE, GPIOF_DIR_OUT, "lcd-enable");
 	ret = gpio_request_one(MX23EVK_LCD_ENABLE, GPIOF_DIR_OUT, "lcd-enable");
 	if (ret)
 	if (ret)
 		pr_warn("failed to request gpio lcd-enable: %d\n", ret);
 		pr_warn("failed to request gpio lcd-enable: %d\n", ret);

+ 89 - 0
arch/arm/mach-mxs/mach-mx28evk.c

@@ -34,6 +34,11 @@
 #define MX28EVK_LCD_ENABLE	MXS_GPIO_NR(3, 30)
 #define MX28EVK_LCD_ENABLE	MXS_GPIO_NR(3, 30)
 #define MX28EVK_FEC_PHY_RESET	MXS_GPIO_NR(4, 13)
 #define MX28EVK_FEC_PHY_RESET	MXS_GPIO_NR(4, 13)
 
 
+#define MX28EVK_MMC0_WRITE_PROTECT	MXS_GPIO_NR(2, 12)
+#define MX28EVK_MMC1_WRITE_PROTECT	MXS_GPIO_NR(0, 28)
+#define MX28EVK_MMC0_SLOT_POWER		MXS_GPIO_NR(3, 28)
+#define MX28EVK_MMC1_SLOT_POWER		MXS_GPIO_NR(3, 29)
+
 static const iomux_cfg_t mx28evk_pads[] __initconst = {
 static const iomux_cfg_t mx28evk_pads[] __initconst = {
 	/* duart */
 	/* duart */
 	MX28_PAD_PWM0__DUART_RX | MXS_PAD_CTRL,
 	MX28_PAD_PWM0__DUART_RX | MXS_PAD_CTRL,
@@ -115,6 +120,65 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
 	MX28_PAD_LCD_RESET__GPIO_3_30 | MXS_PAD_CTRL,
 	MX28_PAD_LCD_RESET__GPIO_3_30 | MXS_PAD_CTRL,
 	/* backlight control */
 	/* backlight control */
 	MX28_PAD_PWM2__GPIO_3_18 | MXS_PAD_CTRL,
 	MX28_PAD_PWM2__GPIO_3_18 | MXS_PAD_CTRL,
+	/* mmc0 */
+	MX28_PAD_SSP0_DATA0__SSP0_D0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA1__SSP0_D1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA2__SSP0_D2 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA3__SSP0_D3 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA4__SSP0_D4 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA5__SSP0_D5 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA6__SSP0_D6 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA7__SSP0_D7 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_CMD__SSP0_CMD |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX28_PAD_SSP0_SCK__SSP0_SCK |
+		(MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* write protect */
+	MX28_PAD_SSP1_SCK__GPIO_2_12 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* slot power enable */
+	MX28_PAD_PWM3__GPIO_3_28 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+
+	/* mmc1 */
+	MX28_PAD_GPMI_D00__SSP1_D0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D01__SSP1_D1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D02__SSP1_D2 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D03__SSP1_D3 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D04__SSP1_D4 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D05__SSP1_D5 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D06__SSP1_D6 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D07__SSP1_D7 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_RDY1__SSP1_CMD |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX28_PAD_GPMI_WRN__SSP1_SCK |
+		(MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* write protect */
+	MX28_PAD_GPMI_RESETN__GPIO_0_28 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* slot power enable */
+	MX28_PAD_PWM4__GPIO_3_29 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
 };
 };
 
 
 /* fec */
 /* fec */
@@ -258,6 +322,18 @@ static const struct mxsfb_platform_data mx28evk_mxsfb_pdata __initconst = {
 	.ld_intf_width	= STMLCDIF_24BIT,
 	.ld_intf_width	= STMLCDIF_24BIT,
 };
 };
 
 
+static struct mxs_mmc_platform_data mx28evk_mmc_pdata[] __initdata = {
+	{
+		/* mmc0 */
+		.wp_gpio = MX28EVK_MMC0_WRITE_PROTECT,
+		.flags = SLOTF_8_BIT_CAPABLE,
+	}, {
+		/* mmc1 */
+		.wp_gpio = MX28EVK_MMC1_WRITE_PROTECT,
+		.flags = SLOTF_8_BIT_CAPABLE,
+	},
+};
+
 static void __init mx28evk_init(void)
 static void __init mx28evk_init(void)
 {
 {
 	int ret;
 	int ret;
@@ -297,6 +373,19 @@ static void __init mx28evk_init(void)
 		gpio_set_value(MX28EVK_BL_ENABLE, 1);
 		gpio_set_value(MX28EVK_BL_ENABLE, 1);
 
 
 	mx28_add_mxsfb(&mx28evk_mxsfb_pdata);
 	mx28_add_mxsfb(&mx28evk_mxsfb_pdata);
+
+	/* power on mmc slot by writing 0 to the gpio */
+	ret = gpio_request_one(MX28EVK_MMC0_SLOT_POWER, GPIOF_DIR_OUT,
+			       "mmc0-slot-power");
+	if (ret)
+		pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret);
+	mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]);
+
+	ret = gpio_request_one(MX28EVK_MMC1_SLOT_POWER, GPIOF_DIR_OUT,
+			       "mmc1-slot-power");
+	if (ret)
+		pr_warn("failed to request gpio mmc1-slot-power: %d\n", ret);
+	mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]);
 }
 }
 
 
 static void __init mx28evk_timer_init(void)
 static void __init mx28evk_timer_init(void)

+ 35 - 6
arch/arm/mach-mxs/module-tx28.c

@@ -45,7 +45,7 @@ static const iomux_cfg_t tx28_fec_gpio_pads[] __initconst = {
 };
 };
 
 
 #define FEC_MODE (MXS_PAD_8MA | MXS_PAD_PULLUP | MXS_PAD_3V3)
 #define FEC_MODE (MXS_PAD_8MA | MXS_PAD_PULLUP | MXS_PAD_3V3)
-static const iomux_cfg_t tx28_fec_pads[] __initconst = {
+static const iomux_cfg_t tx28_fec0_pads[] __initconst = {
 	MX28_PAD_ENET0_MDC__ENET0_MDC | FEC_MODE,
 	MX28_PAD_ENET0_MDC__ENET0_MDC | FEC_MODE,
 	MX28_PAD_ENET0_MDIO__ENET0_MDIO | FEC_MODE,
 	MX28_PAD_ENET0_MDIO__ENET0_MDIO | FEC_MODE,
 	MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | FEC_MODE,
 	MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | FEC_MODE,
@@ -57,7 +57,20 @@ static const iomux_cfg_t tx28_fec_pads[] __initconst = {
 	MX28_PAD_ENET_CLK__CLKCTRL_ENET | FEC_MODE,
 	MX28_PAD_ENET_CLK__CLKCTRL_ENET | FEC_MODE,
 };
 };
 
 
-static const struct fec_platform_data tx28_fec_data __initconst = {
+static const iomux_cfg_t tx28_fec1_pads[] __initconst = {
+	MX28_PAD_ENET0_RXD2__ENET1_RXD0,
+	MX28_PAD_ENET0_RXD3__ENET1_RXD1,
+	MX28_PAD_ENET0_TXD2__ENET1_TXD0,
+	MX28_PAD_ENET0_TXD3__ENET1_TXD1,
+	MX28_PAD_ENET0_COL__ENET1_TX_EN,
+	MX28_PAD_ENET0_CRS__ENET1_RX_EN,
+};
+
+static struct fec_platform_data tx28_fec0_data = {
+	.phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static struct fec_platform_data tx28_fec1_data = {
 	.phy = PHY_INTERFACE_MODE_RMII,
 	.phy = PHY_INTERFACE_MODE_RMII,
 };
 };
 
 
@@ -108,15 +121,15 @@ int __init tx28_add_fec0(void)
 	pr_debug("%s: Deasserting FEC PHY RESET\n", __func__);
 	pr_debug("%s: Deasserting FEC PHY RESET\n", __func__);
 	gpio_set_value(TX28_FEC_PHY_RESET, 1);
 	gpio_set_value(TX28_FEC_PHY_RESET, 1);
 
 
-	ret = mxs_iomux_setup_multiple_pads(tx28_fec_pads,
-			ARRAY_SIZE(tx28_fec_pads));
+	ret = mxs_iomux_setup_multiple_pads(tx28_fec0_pads,
+			ARRAY_SIZE(tx28_fec0_pads));
 	if (ret) {
 	if (ret) {
 		pr_debug("%s: mxs_iomux_setup_multiple_pads() failed with rc: %d\n",
 		pr_debug("%s: mxs_iomux_setup_multiple_pads() failed with rc: %d\n",
 				__func__, ret);
 				__func__, ret);
 		goto free_gpios;
 		goto free_gpios;
 	}
 	}
-	pr_debug("%s: Registering FEC device\n", __func__);
-	mx28_add_fec(0, &tx28_fec_data);
+	pr_debug("%s: Registering FEC0 device\n", __func__);
+	mx28_add_fec(0, &tx28_fec0_data);
 	return 0;
 	return 0;
 
 
 free_gpios:
 free_gpios:
@@ -129,3 +142,19 @@ free_gpios:
 
 
 	return ret;
 	return ret;
 }
 }
+
+int __init tx28_add_fec1(void)
+{
+	int ret;
+
+	ret = mxs_iomux_setup_multiple_pads(tx28_fec1_pads,
+			ARRAY_SIZE(tx28_fec1_pads));
+	if (ret) {
+		pr_debug("%s: mxs_iomux_setup_multiple_pads() failed with rc: %d\n",
+				__func__, ret);
+		return ret;
+	}
+	pr_debug("%s: Registering FEC1 device\n", __func__);
+	mx28_add_fec(1, &tx28_fec1_data);
+	return 0;
+}

+ 1 - 0
arch/arm/mach-mxs/module-tx28.h

@@ -7,3 +7,4 @@
  * Free Software Foundation.
  * Free Software Foundation.
  */
  */
 int __init tx28_add_fec0(void);
 int __init tx28_add_fec0(void);
+int __init tx28_add_fec1(void);

+ 9 - 9
arch/arm/mach-orion5x/ts78xx-setup.c

@@ -402,7 +402,7 @@ static void ts78xx_fpga_supports(void)
 		/* enable devices if magic matches */
 		/* enable devices if magic matches */
 		switch ((ts78xx_fpga.id >> 8) & 0xffffff) {
 		switch ((ts78xx_fpga.id >> 8) & 0xffffff) {
 		case TS7800_FPGA_MAGIC:
 		case TS7800_FPGA_MAGIC:
-			printk(KERN_WARNING "TS-7800 FPGA: unrecognized revision 0x%.2x\n",
+			pr_warning("TS-7800 FPGA: unrecognized revision 0x%.2x\n",
 					ts78xx_fpga.id & 0xff);
 					ts78xx_fpga.id & 0xff);
 			ts78xx_fpga.supports.ts_rtc.present = 1;
 			ts78xx_fpga.supports.ts_rtc.present = 1;
 			ts78xx_fpga.supports.ts_nand.present = 1;
 			ts78xx_fpga.supports.ts_nand.present = 1;
@@ -423,7 +423,7 @@ static int ts78xx_fpga_load_devices(void)
 	if (ts78xx_fpga.supports.ts_rtc.present == 1) {
 	if (ts78xx_fpga.supports.ts_rtc.present == 1) {
 		tmp = ts78xx_ts_rtc_load();
 		tmp = ts78xx_ts_rtc_load();
 		if (tmp) {
 		if (tmp) {
-			printk(KERN_INFO "TS-78xx: RTC not registered\n");
+			pr_info("TS-78xx: RTC not registered\n");
 			ts78xx_fpga.supports.ts_rtc.present = 0;
 			ts78xx_fpga.supports.ts_rtc.present = 0;
 		}
 		}
 		ret |= tmp;
 		ret |= tmp;
@@ -431,7 +431,7 @@ static int ts78xx_fpga_load_devices(void)
 	if (ts78xx_fpga.supports.ts_nand.present == 1) {
 	if (ts78xx_fpga.supports.ts_nand.present == 1) {
 		tmp = ts78xx_ts_nand_load();
 		tmp = ts78xx_ts_nand_load();
 		if (tmp) {
 		if (tmp) {
-			printk(KERN_INFO "TS-78xx: NAND not registered\n");
+			pr_info("TS-78xx: NAND not registered\n");
 			ts78xx_fpga.supports.ts_nand.present = 0;
 			ts78xx_fpga.supports.ts_nand.present = 0;
 		}
 		}
 		ret |= tmp;
 		ret |= tmp;
@@ -439,7 +439,7 @@ static int ts78xx_fpga_load_devices(void)
 	if (ts78xx_fpga.supports.ts_rng.present == 1) {
 	if (ts78xx_fpga.supports.ts_rng.present == 1) {
 		tmp = ts78xx_ts_rng_load();
 		tmp = ts78xx_ts_rng_load();
 		if (tmp) {
 		if (tmp) {
-			printk(KERN_INFO "TS-78xx: RNG not registered\n");
+			pr_info("TS-78xx: RNG not registered\n");
 			ts78xx_fpga.supports.ts_rng.present = 0;
 			ts78xx_fpga.supports.ts_rng.present = 0;
 		}
 		}
 		ret |= tmp;
 		ret |= tmp;
@@ -466,7 +466,7 @@ static int ts78xx_fpga_load(void)
 {
 {
 	ts78xx_fpga.id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
 	ts78xx_fpga.id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
 
 
-	printk(KERN_INFO "TS-78xx FPGA: magic=0x%.6x, rev=0x%.2x\n",
+	pr_info("TS-78xx FPGA: magic=0x%.6x, rev=0x%.2x\n",
 			(ts78xx_fpga.id >> 8) & 0xffffff,
 			(ts78xx_fpga.id >> 8) & 0xffffff,
 			ts78xx_fpga.id & 0xff);
 			ts78xx_fpga.id & 0xff);
 
 
@@ -494,7 +494,7 @@ static int ts78xx_fpga_unload(void)
 	 * UrJTAG SVN since r1381 can be used to reprogram the FPGA
 	 * UrJTAG SVN since r1381 can be used to reprogram the FPGA
 	 */
 	 */
 	if (ts78xx_fpga.id != fpga_id) {
 	if (ts78xx_fpga.id != fpga_id) {
-		printk(KERN_ERR	"TS-78xx FPGA: magic/rev mismatch\n"
+		pr_err("TS-78xx FPGA: magic/rev mismatch\n"
 			"TS-78xx FPGA: was 0x%.6x/%.2x but now 0x%.6x/%.2x\n",
 			"TS-78xx FPGA: was 0x%.6x/%.2x but now 0x%.6x/%.2x\n",
 			(ts78xx_fpga.id >> 8) & 0xffffff, ts78xx_fpga.id & 0xff,
 			(ts78xx_fpga.id >> 8) & 0xffffff, ts78xx_fpga.id & 0xff,
 			(fpga_id >> 8) & 0xffffff, fpga_id & 0xff);
 			(fpga_id >> 8) & 0xffffff, fpga_id & 0xff);
@@ -525,7 +525,7 @@ static ssize_t ts78xx_fpga_store(struct kobject *kobj,
 	int value, ret;
 	int value, ret;
 
 
 	if (ts78xx_fpga.state < 0) {
 	if (ts78xx_fpga.state < 0) {
-		printk(KERN_ERR "TS-78xx FPGA: borked, you must powercycle asap\n");
+		pr_err("TS-78xx FPGA: borked, you must powercycle asap\n");
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
 
 
@@ -534,7 +534,7 @@ static ssize_t ts78xx_fpga_store(struct kobject *kobj,
 	else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
 	else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
 		value = 0;
 		value = 0;
 	else {
 	else {
-		printk(KERN_ERR "ts78xx_fpga_store: Invalid value\n");
+		pr_err("ts78xx_fpga_store: Invalid value\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -616,7 +616,7 @@ static void __init ts78xx_init(void)
 	ret = ts78xx_fpga_load();
 	ret = ts78xx_fpga_load();
 	ret = sysfs_create_file(power_kobj, &ts78xx_fpga_attr.attr);
 	ret = sysfs_create_file(power_kobj, &ts78xx_fpga_attr.attr);
 	if (ret)
 	if (ret)
-		printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
+		pr_err("sysfs_create_file failed: %d\n", ret);
 }
 }
 
 
 MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")
 MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")

+ 4 - 4
arch/arm/mach-pxa/am200epd.c

@@ -128,8 +128,8 @@ static int am200_init_gpio_regs(struct metronomefb_par *par)
 	return 0;
 	return 0;
 
 
 err_req_gpio:
 err_req_gpio:
-	while (i > 0)
-		gpio_free(gpios[i--]);
+	while (--i >= 0)
+		gpio_free(gpios[i]);
 
 
 	return err;
 	return err;
 }
 }
@@ -194,7 +194,7 @@ static struct notifier_block am200_fb_notif = {
 };
 };
 
 
 /* this gets called as part of our init. these steps must be done now so
 /* this gets called as part of our init. these steps must be done now so
- * that we can use set_pxa_fb_info */
+ * that we can use pxa_set_fb_info */
 static void __init am200_presetup_fb(void)
 static void __init am200_presetup_fb(void)
 {
 {
 	int fw;
 	int fw;
@@ -249,7 +249,7 @@ static void __init am200_presetup_fb(void)
 	/* we divide since we told the LCD controller we're 16bpp */
 	/* we divide since we told the LCD controller we're 16bpp */
 	am200_fb_info.modes->xres /= 2;
 	am200_fb_info.modes->xres /= 2;
 
 
-	set_pxa_fb_info(&am200_fb_info);
+	pxa_set_fb_info(NULL, &am200_fb_info);
 
 
 }
 }
 
 

+ 7 - 6
arch/arm/mach-pxa/am300epd.c

@@ -125,10 +125,7 @@ static int am300_init_gpio_regs(struct broadsheetfb_par *par)
 		if (err) {
 		if (err) {
 			dev_err(&am300_device->dev, "failed requesting "
 			dev_err(&am300_device->dev, "failed requesting "
 				"gpio %d, err=%d\n", i, err);
 				"gpio %d, err=%d\n", i, err);
-			while (i >= DB0_GPIO_PIN)
-				gpio_free(i--);
-			i = ARRAY_SIZE(gpios) - 1;
-			goto err_req_gpio;
+			goto err_req_gpio2;
 		}
 		}
 	}
 	}
 
 
@@ -159,9 +156,13 @@ static int am300_init_gpio_regs(struct broadsheetfb_par *par)
 
 
 	return 0;
 	return 0;
 
 
+err_req_gpio2:
+	while (--i >= DB0_GPIO_PIN)
+		gpio_free(i);
+	i = ARRAY_SIZE(gpios);
 err_req_gpio:
 err_req_gpio:
-	while (i > 0)
-		gpio_free(gpios[i--]);
+	while (--i >= 0)
+		gpio_free(gpios[i]);
 
 
 	return err;
 	return err;
 }
 }

+ 1 - 1
arch/arm/mach-pxa/balloon3.c

@@ -263,7 +263,7 @@ static void __init balloon3_lcd_init(void)
 	}
 	}
 
 
 	balloon3_lcd_screen.pxafb_backlight_power = balloon3_backlight_power;
 	balloon3_lcd_screen.pxafb_backlight_power = balloon3_backlight_power;
-	set_pxa_fb_info(&balloon3_lcd_screen);
+	pxa_set_fb_info(NULL, &balloon3_lcd_screen);
 	return;
 	return;
 
 
 err2:
 err2:

+ 1 - 1
arch/arm/mach-pxa/cm-x2xx.c

@@ -379,7 +379,7 @@ __setup("monitor=", cmx2xx_set_display);
 
 
 static void __init cmx2xx_init_display(void)
 static void __init cmx2xx_init_display(void)
 {
 {
-	set_pxa_fb_info(cmx2xx_display);
+	pxa_set_fb_info(NULL, cmx2xx_display);
 }
 }
 #else
 #else
 static inline void cmx2xx_init_display(void) {}
 static inline void cmx2xx_init_display(void) {}

+ 1 - 1
arch/arm/mach-pxa/cm-x300.c

@@ -296,7 +296,7 @@ static struct pxafb_mach_info cm_x300_lcd = {
 
 
 static void __init cm_x300_init_lcd(void)
 static void __init cm_x300_init_lcd(void)
 {
 {
-	set_pxa_fb_info(&cm_x300_lcd);
+	pxa_set_fb_info(NULL, &cm_x300_lcd);
 }
 }
 #else
 #else
 static inline void cm_x300_init_lcd(void) {}
 static inline void cm_x300_init_lcd(void) {}

+ 1 - 1
arch/arm/mach-pxa/colibri-pxa270-income.c

@@ -175,7 +175,7 @@ static struct pxafb_mach_info income_lcd_screen = {
 
 
 static void __init income_lcd_init(void)
 static void __init income_lcd_init(void)
 {
 {
-	set_pxa_fb_info(&income_lcd_screen);
+	pxa_set_fb_info(NULL, &income_lcd_screen);
 }
 }
 #else
 #else
 static inline void income_lcd_init(void) {}
 static inline void income_lcd_init(void) {}

+ 1 - 1
arch/arm/mach-pxa/colibri-pxa3xx.c

@@ -105,7 +105,7 @@ void __init colibri_pxa3xx_init_lcd(int bl_pin)
 	lcd_bl_pin = bl_pin;
 	lcd_bl_pin = bl_pin;
 	gpio_request(bl_pin, "lcd backlight");
 	gpio_request(bl_pin, "lcd backlight");
 	gpio_direction_output(bl_pin, 0);
 	gpio_direction_output(bl_pin, 0);
-	set_pxa_fb_info(&sharp_lq43_info);
+	pxa_set_fb_info(NULL, &sharp_lq43_info);
 }
 }
 #endif
 #endif
 
 

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

@@ -462,7 +462,6 @@ static struct pxaficp_platform_data corgi_ficp_platform_data = {
  * USB Device Controller
  * USB Device Controller
  */
  */
 static struct pxa2xx_udc_mach_info udc_info __initdata = {
 static struct pxa2xx_udc_mach_info udc_info __initdata = {
-	.gpio_vbus		= -1,
 	/* no connect GPIO; corgi can't tell connection status */
 	/* no connect GPIO; corgi can't tell connection status */
 	.gpio_pullup		= CORGI_GPIO_USB_PULLUP,
 	.gpio_pullup		= CORGI_GPIO_USB_PULLUP,
 };
 };

+ 2 - 7
arch/arm/mach-pxa/devices.c

@@ -90,7 +90,6 @@ void __init pxa_set_mci_info(struct pxamci_platform_data *info)
 
 
 static struct pxa2xx_udc_mach_info pxa_udc_info = {
 static struct pxa2xx_udc_mach_info pxa_udc_info = {
 	.gpio_pullup = -1,
 	.gpio_pullup = -1,
-	.gpio_vbus   = -1,
 };
 };
 
 
 void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
 void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
@@ -188,16 +187,12 @@ struct platform_device pxa_device_fb = {
 	.resource	= pxafb_resources,
 	.resource	= pxafb_resources,
 };
 };
 
 
-void __init set_pxa_fb_info(struct pxafb_mach_info *info)
+void __init pxa_set_fb_info(struct device *parent, struct pxafb_mach_info *info)
 {
 {
+	pxa_device_fb.dev.parent = parent;
 	pxa_register_device(&pxa_device_fb, info);
 	pxa_register_device(&pxa_device_fb, info);
 }
 }
 
 
-void __init set_pxa_fb_parent(struct device *parent_dev)
-{
-	pxa_device_fb.dev.parent = parent_dev;
-}
-
 static struct resource pxa_resource_ffuart[] = {
 static struct resource pxa_resource_ffuart[] = {
 	{
 	{
 		.start	= 0x40100000,
 		.start	= 0x40100000,

+ 1 - 1
arch/arm/mach-pxa/em-x270.c

@@ -689,7 +689,7 @@ static struct pxafb_mach_info em_x270_lcd = {
 
 
 static void __init em_x270_init_lcd(void)
 static void __init em_x270_init_lcd(void)
 {
 {
-	set_pxa_fb_info(&em_x270_lcd);
+	pxa_set_fb_info(NULL, &em_x270_lcd);
 }
 }
 #else
 #else
 static inline void em_x270_init_lcd(void) {}
 static inline void em_x270_init_lcd(void) {}

+ 27 - 9
arch/arm/mach-pxa/eseries.c

@@ -20,6 +20,7 @@
 #include <linux/mfd/t7l66xb.h>
 #include <linux/mfd/t7l66xb.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/partitions.h>
+#include <linux/usb/gpio_vbus.h>
 
 
 #include <video/w100fb.h>
 #include <video/w100fb.h>
 
 
@@ -51,12 +52,20 @@ void __init eseries_fixup(struct machine_desc *desc,
 		mi->bank[0].size = (64*1024*1024);
 		mi->bank[0].size = (64*1024*1024);
 }
 }
 
 
-struct pxa2xx_udc_mach_info e7xx_udc_mach_info = {
+struct gpio_vbus_mach_info e7xx_udc_info = {
 	.gpio_vbus   = GPIO_E7XX_USB_DISC,
 	.gpio_vbus   = GPIO_E7XX_USB_DISC,
 	.gpio_pullup = GPIO_E7XX_USB_PULLUP,
 	.gpio_pullup = GPIO_E7XX_USB_PULLUP,
 	.gpio_pullup_inverted = 1
 	.gpio_pullup_inverted = 1
 };
 };
 
 
+static struct platform_device e7xx_gpio_vbus = {
+	.name	= "gpio-vbus",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &e7xx_udc_info,
+	},
+};
+
 struct pxaficp_platform_data e7xx_ficp_platform_data = {
 struct pxaficp_platform_data e7xx_ficp_platform_data = {
 	.gpio_pwdown		= GPIO_E7XX_IR_OFF,
 	.gpio_pwdown		= GPIO_E7XX_IR_OFF,
 	.transceiver_cap	= IR_SIRMODE | IR_OFF,
 	.transceiver_cap	= IR_SIRMODE | IR_OFF,
@@ -165,6 +174,7 @@ static struct platform_device e330_tc6387xb_device = {
 
 
 static struct platform_device *e330_devices[] __initdata = {
 static struct platform_device *e330_devices[] __initdata = {
 	&e330_tc6387xb_device,
 	&e330_tc6387xb_device,
+	&e7xx_gpio_vbus,
 };
 };
 
 
 static void __init e330_init(void)
 static void __init e330_init(void)
@@ -175,7 +185,6 @@ static void __init e330_init(void)
 	eseries_register_clks();
 	eseries_register_clks();
 	eseries_get_tmio_gpios();
 	eseries_get_tmio_gpios();
 	platform_add_devices(ARRAY_AND_SIZE(e330_devices));
 	platform_add_devices(ARRAY_AND_SIZE(e330_devices));
-	pxa_set_udc_info(&e7xx_udc_mach_info);
 }
 }
 
 
 MACHINE_START(E330, "Toshiba e330")
 MACHINE_START(E330, "Toshiba e330")
@@ -214,6 +223,7 @@ static struct platform_device e350_t7l66xb_device = {
 
 
 static struct platform_device *e350_devices[] __initdata = {
 static struct platform_device *e350_devices[] __initdata = {
 	&e350_t7l66xb_device,
 	&e350_t7l66xb_device,
+	&e7xx_gpio_vbus,
 };
 };
 
 
 static void __init e350_init(void)
 static void __init e350_init(void)
@@ -224,7 +234,6 @@ static void __init e350_init(void)
 	eseries_register_clks();
 	eseries_register_clks();
 	eseries_get_tmio_gpios();
 	eseries_get_tmio_gpios();
 	platform_add_devices(ARRAY_AND_SIZE(e350_devices));
 	platform_add_devices(ARRAY_AND_SIZE(e350_devices));
-	pxa_set_udc_info(&e7xx_udc_mach_info);
 }
 }
 
 
 MACHINE_START(E350, "Toshiba e350")
 MACHINE_START(E350, "Toshiba e350")
@@ -333,6 +342,7 @@ static struct platform_device e400_t7l66xb_device = {
 
 
 static struct platform_device *e400_devices[] __initdata = {
 static struct platform_device *e400_devices[] __initdata = {
 	&e400_t7l66xb_device,
 	&e400_t7l66xb_device,
+	&e7xx_gpio_vbus,
 };
 };
 
 
 static void __init e400_init(void)
 static void __init e400_init(void)
@@ -344,9 +354,8 @@ static void __init e400_init(void)
 	/* Fixme - e400 may have a switched clock */
 	/* Fixme - e400 may have a switched clock */
 	eseries_register_clks();
 	eseries_register_clks();
 	eseries_get_tmio_gpios();
 	eseries_get_tmio_gpios();
-	set_pxa_fb_info(&e400_pxafb_mach_info);
+	pxa_set_fb_info(NULL, &e400_pxafb_mach_info);
 	platform_add_devices(ARRAY_AND_SIZE(e400_devices));
 	platform_add_devices(ARRAY_AND_SIZE(e400_devices));
-	pxa_set_udc_info(&e7xx_udc_mach_info);
 }
 }
 
 
 MACHINE_START(E400, "Toshiba e400")
 MACHINE_START(E400, "Toshiba e400")
@@ -519,6 +528,7 @@ static struct platform_device e740_t7l66xb_device = {
 static struct platform_device *e740_devices[] __initdata = {
 static struct platform_device *e740_devices[] __initdata = {
 	&e740_fb_device,
 	&e740_fb_device,
 	&e740_t7l66xb_device,
 	&e740_t7l66xb_device,
+	&e7xx_gpio_vbus,
 };
 };
 
 
 static void __init e740_init(void)
 static void __init e740_init(void)
@@ -532,7 +542,6 @@ static void __init e740_init(void)
 			"UDCCLK", &pxa25x_device_udc.dev),
 			"UDCCLK", &pxa25x_device_udc.dev),
 	eseries_get_tmio_gpios();
 	eseries_get_tmio_gpios();
 	platform_add_devices(ARRAY_AND_SIZE(e740_devices));
 	platform_add_devices(ARRAY_AND_SIZE(e740_devices));
-	pxa_set_udc_info(&e7xx_udc_mach_info);
 	pxa_set_ac97_info(NULL);
 	pxa_set_ac97_info(NULL);
 	pxa_set_ficp_info(&e7xx_ficp_platform_data);
 	pxa_set_ficp_info(&e7xx_ficp_platform_data);
 }
 }
@@ -711,6 +720,7 @@ static struct platform_device e750_tc6393xb_device = {
 static struct platform_device *e750_devices[] __initdata = {
 static struct platform_device *e750_devices[] __initdata = {
 	&e750_fb_device,
 	&e750_fb_device,
 	&e750_tc6393xb_device,
 	&e750_tc6393xb_device,
+	&e7xx_gpio_vbus,
 };
 };
 
 
 static void __init e750_init(void)
 static void __init e750_init(void)
@@ -723,7 +733,6 @@ static void __init e750_init(void)
 			"GPIO11_CLK", NULL),
 			"GPIO11_CLK", NULL),
 	eseries_get_tmio_gpios();
 	eseries_get_tmio_gpios();
 	platform_add_devices(ARRAY_AND_SIZE(e750_devices));
 	platform_add_devices(ARRAY_AND_SIZE(e750_devices));
-	pxa_set_udc_info(&e7xx_udc_mach_info);
 	pxa_set_ac97_info(NULL);
 	pxa_set_ac97_info(NULL);
 	pxa_set_ficp_info(&e7xx_ficp_platform_data);
 	pxa_set_ficp_info(&e7xx_ficp_platform_data);
 }
 }
@@ -873,12 +882,21 @@ static struct platform_device e800_fb_device = {
 
 
 /* --------------------------- UDC definitions --------------------------- */
 /* --------------------------- UDC definitions --------------------------- */
 
 
-static struct pxa2xx_udc_mach_info e800_udc_mach_info = {
+static struct gpio_vbus_mach_info e800_udc_info = {
 	.gpio_vbus   = GPIO_E800_USB_DISC,
 	.gpio_vbus   = GPIO_E800_USB_DISC,
 	.gpio_pullup = GPIO_E800_USB_PULLUP,
 	.gpio_pullup = GPIO_E800_USB_PULLUP,
 	.gpio_pullup_inverted = 1
 	.gpio_pullup_inverted = 1
 };
 };
 
 
+static struct platform_device e800_gpio_vbus = {
+	.name	= "gpio-vbus",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &e800_udc_info,
+	},
+};
+
+
 /* ----------------- e800 tc6393xb parameters ------------------ */
 /* ----------------- e800 tc6393xb parameters ------------------ */
 
 
 static struct tc6393xb_platform_data e800_tc6393xb_info = {
 static struct tc6393xb_platform_data e800_tc6393xb_info = {
@@ -907,6 +925,7 @@ static struct platform_device e800_tc6393xb_device = {
 static struct platform_device *e800_devices[] __initdata = {
 static struct platform_device *e800_devices[] __initdata = {
 	&e800_fb_device,
 	&e800_fb_device,
 	&e800_tc6393xb_device,
 	&e800_tc6393xb_device,
+	&e800_gpio_vbus,
 };
 };
 
 
 static void __init e800_init(void)
 static void __init e800_init(void)
@@ -919,7 +938,6 @@ static void __init e800_init(void)
 			"GPIO11_CLK", NULL),
 			"GPIO11_CLK", NULL),
 	eseries_get_tmio_gpios();
 	eseries_get_tmio_gpios();
 	platform_add_devices(ARRAY_AND_SIZE(e800_devices));
 	platform_add_devices(ARRAY_AND_SIZE(e800_devices));
-	pxa_set_udc_info(&e800_udc_mach_info);
 	pxa_set_ac97_info(NULL);
 	pxa_set_ac97_info(NULL);
 }
 }
 
 

+ 6 - 6
arch/arm/mach-pxa/ezx.c

@@ -783,7 +783,7 @@ static void __init a780_init(void)
 
 
 	pxa_set_i2c_info(NULL);
 	pxa_set_i2c_info(NULL);
 
 
-	set_pxa_fb_info(&ezx_fb_info_1);
+	pxa_set_fb_info(NULL, &ezx_fb_info_1);
 
 
 	pxa_set_keypad_info(&a780_keypad_platform_data);
 	pxa_set_keypad_info(&a780_keypad_platform_data);
 
 
@@ -853,7 +853,7 @@ static void __init e680_init(void)
 	pxa_set_i2c_info(NULL);
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(e680_i2c_board_info));
 	i2c_register_board_info(0, ARRAY_AND_SIZE(e680_i2c_board_info));
 
 
-	set_pxa_fb_info(&ezx_fb_info_1);
+	pxa_set_fb_info(NULL, &ezx_fb_info_1);
 
 
 	pxa_set_keypad_info(&e680_keypad_platform_data);
 	pxa_set_keypad_info(&e680_keypad_platform_data);
 
 
@@ -918,7 +918,7 @@ static void __init a1200_init(void)
 	pxa_set_i2c_info(NULL);
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(a1200_i2c_board_info));
 	i2c_register_board_info(0, ARRAY_AND_SIZE(a1200_i2c_board_info));
 
 
-	set_pxa_fb_info(&ezx_fb_info_2);
+	pxa_set_fb_info(NULL, &ezx_fb_info_2);
 
 
 	pxa_set_keypad_info(&a1200_keypad_platform_data);
 	pxa_set_keypad_info(&a1200_keypad_platform_data);
 
 
@@ -1103,7 +1103,7 @@ static void __init a910_init(void)
 	pxa_set_i2c_info(NULL);
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(a910_i2c_board_info));
 	i2c_register_board_info(0, ARRAY_AND_SIZE(a910_i2c_board_info));
 
 
-	set_pxa_fb_info(&ezx_fb_info_2);
+	pxa_set_fb_info(NULL, &ezx_fb_info_2);
 
 
 	pxa_set_keypad_info(&a910_keypad_platform_data);
 	pxa_set_keypad_info(&a910_keypad_platform_data);
 
 
@@ -1173,7 +1173,7 @@ static void __init e6_init(void)
 	pxa_set_i2c_info(NULL);
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(e6_i2c_board_info));
 	i2c_register_board_info(0, ARRAY_AND_SIZE(e6_i2c_board_info));
 
 
-	set_pxa_fb_info(&ezx_fb_info_2);
+	pxa_set_fb_info(NULL, &ezx_fb_info_2);
 
 
 	pxa_set_keypad_info(&e6_keypad_platform_data);
 	pxa_set_keypad_info(&e6_keypad_platform_data);
 
 
@@ -1212,7 +1212,7 @@ static void __init e2_init(void)
 	pxa_set_i2c_info(NULL);
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(e2_i2c_board_info));
 	i2c_register_board_info(0, ARRAY_AND_SIZE(e2_i2c_board_info));
 
 
-	set_pxa_fb_info(&ezx_fb_info_2);
+	pxa_set_fb_info(NULL, &ezx_fb_info_2);
 
 
 	pxa_set_keypad_info(&e2_keypad_platform_data);
 	pxa_set_keypad_info(&e2_keypad_platform_data);
 
 

+ 11 - 2
arch/arm/mach-pxa/gumstix.c

@@ -26,6 +26,7 @@
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
+#include <linux/usb/gpio_vbus.h>
 
 
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/memory.h>
 #include <asm/memory.h>
@@ -106,14 +107,22 @@ static void __init gumstix_mmc_init(void)
 #endif
 #endif
 
 
 #ifdef CONFIG_USB_GADGET_PXA25X
 #ifdef CONFIG_USB_GADGET_PXA25X
-static struct pxa2xx_udc_mach_info gumstix_udc_info __initdata = {
+static struct gpio_vbus_mach_info gumstix_udc_info = {
 	.gpio_vbus		= GPIO_GUMSTIX_USB_GPIOn,
 	.gpio_vbus		= GPIO_GUMSTIX_USB_GPIOn,
 	.gpio_pullup		= GPIO_GUMSTIX_USB_GPIOx,
 	.gpio_pullup		= GPIO_GUMSTIX_USB_GPIOx,
 };
 };
 
 
+static struct platform_device gumstix_gpio_vbus = {
+	.name	= "gpio-vbus",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &gumstix_udc_info,
+	},
+};
+
 static void __init gumstix_udc_init(void)
 static void __init gumstix_udc_init(void)
 {
 {
-	pxa_set_udc_info(&gumstix_udc_info);
+	platform_device_register(&gumstix_gpio_vbus);
 }
 }
 #else
 #else
 static void gumstix_udc_init(void)
 static void gumstix_udc_init(void)

+ 1 - 1
arch/arm/mach-pxa/idp.c

@@ -167,7 +167,7 @@ static void __init idp_init(void)
 
 
 	platform_device_register(&smc91x_device);
 	platform_device_register(&smc91x_device);
 	//platform_device_register(&mst_audio_device);
 	//platform_device_register(&mst_audio_device);
-	set_pxa_fb_info(&sharp_lm8v31);
+	pxa_set_fb_info(NULL, &sharp_lm8v31);
 	pxa_set_mci_info(&idp_mci_platform_data);
 	pxa_set_mci_info(&idp_mci_platform_data);
 }
 }
 
 

+ 5 - 0
arch/arm/mach-pxa/include/mach/palmz72.h

@@ -44,6 +44,11 @@
 #define GPIO_NR_PALMZ72_BT_POWER		17
 #define GPIO_NR_PALMZ72_BT_POWER		17
 #define GPIO_NR_PALMZ72_BT_RESET		83
 #define GPIO_NR_PALMZ72_BT_RESET		83
 
 
+/* Camera */
+#define GPIO_NR_PALMZ72_CAM_PWDN		56
+#define GPIO_NR_PALMZ72_CAM_RESET		57
+#define GPIO_NR_PALMZ72_CAM_POWER		91
+
 /** Initial values **/
 /** Initial values **/
 
 
 /* Battery */
 /* Battery */

+ 2 - 2
arch/arm/mach-pxa/include/mach/pxafb.h

@@ -154,8 +154,8 @@ struct pxafb_mach_info {
 	void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
 	void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
 	void (*smart_update)(struct fb_info *);
 	void (*smart_update)(struct fb_info *);
 };
 };
-void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info);
-void set_pxa_fb_parent(struct device *parent_dev);
+
+void pxa_set_fb_info(struct device *, struct pxafb_mach_info *);
 unsigned long pxafb_get_hsync_time(struct device *dev);
 unsigned long pxafb_get_hsync_time(struct device *dev);
 
 
 extern int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int);
 extern int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int);

+ 1 - 2
arch/arm/mach-pxa/include/mach/z2.h

@@ -25,8 +25,7 @@
 #define	GPIO98_ZIPITZ2_LID_BUTTON	98
 #define	GPIO98_ZIPITZ2_LID_BUTTON	98
 
 
 /* Libertas GSPI8686 WiFi */
 /* Libertas GSPI8686 WiFi */
-#define	GPIO14_ZIPITZ2_WIFI_RESET	14
-#define	GPIO15_ZIPITZ2_WIFI_POWER	15
+#define	GPIO14_ZIPITZ2_WIFI_POWER	14
 #define	GPIO24_ZIPITZ2_WIFI_CS		24
 #define	GPIO24_ZIPITZ2_WIFI_CS		24
 #define	GPIO36_ZIPITZ2_WIFI_IRQ		36
 #define	GPIO36_ZIPITZ2_WIFI_IRQ		36
 
 

+ 1 - 1
arch/arm/mach-pxa/littleton.c

@@ -185,7 +185,7 @@ static struct pxafb_mach_info littleton_lcd_info = {
 
 
 static void littleton_init_lcd(void)
 static void littleton_init_lcd(void)
 {
 {
-	set_pxa_fb_info(&littleton_lcd_info);
+	pxa_set_fb_info(NULL, &littleton_lcd_info);
 }
 }
 #else
 #else
 static inline void littleton_init_lcd(void) {};
 static inline void littleton_init_lcd(void) {};

+ 1 - 1
arch/arm/mach-pxa/lpd270.c

@@ -480,7 +480,7 @@ static void __init lpd270_init(void)
 	pxa_set_ac97_info(NULL);
 	pxa_set_ac97_info(NULL);
 
 
 	if (lpd270_lcd_to_use != NULL)
 	if (lpd270_lcd_to_use != NULL)
-		set_pxa_fb_info(lpd270_lcd_to_use);
+		pxa_set_fb_info(NULL, lpd270_lcd_to_use);
 
 
 	pxa_set_ohci_info(&lpd270_ohci_platform_data);
 	pxa_set_ohci_info(&lpd270_ohci_platform_data);
 }
 }

+ 1 - 1
arch/arm/mach-pxa/lubbock.c

@@ -521,7 +521,7 @@ static void __init lubbock_init(void)
 
 
 	clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL);
 	clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL);
 	pxa_set_udc_info(&udc_info);
 	pxa_set_udc_info(&udc_info);
-	set_pxa_fb_info(&sharp_lm8v31);
+	pxa_set_fb_info(NULL, &sharp_lm8v31);
 	pxa_set_mci_info(&lubbock_mci_platform_data);
 	pxa_set_mci_info(&lubbock_mci_platform_data);
 	pxa_set_ficp_info(&lubbock_ficp_platform_data);
 	pxa_set_ficp_info(&lubbock_ficp_platform_data);
 	pxa_set_ac97_info(NULL);
 	pxa_set_ac97_info(NULL);

+ 1 - 1
arch/arm/mach-pxa/magician.c

@@ -757,7 +757,7 @@ static void __init magician_init(void)
 		gpio_direction_output(GPIO104_MAGICIAN_LCD_POWER_1, 0);
 		gpio_direction_output(GPIO104_MAGICIAN_LCD_POWER_1, 0);
 		gpio_direction_output(GPIO105_MAGICIAN_LCD_POWER_2, 0);
 		gpio_direction_output(GPIO105_MAGICIAN_LCD_POWER_2, 0);
 		gpio_direction_output(GPIO106_MAGICIAN_LCD_POWER_3, 0);
 		gpio_direction_output(GPIO106_MAGICIAN_LCD_POWER_3, 0);
-		set_pxa_fb_info(lcd_select ? &samsung_info : &toppoly_info);
+		pxa_set_fb_info(NULL, lcd_select ? &samsung_info : &toppoly_info);
 	} else
 	} else
 		pr_err("LCD detection: CPLD mapping failed\n");
 		pr_err("LCD detection: CPLD mapping failed\n");
 }
 }

+ 1 - 1
arch/arm/mach-pxa/mainstone.c

@@ -592,7 +592,7 @@ static void __init mainstone_init(void)
 	else
 	else
 		mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode;
 		mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode;
 
 
-	set_pxa_fb_info(&mainstone_pxafb_info);
+	pxa_set_fb_info(NULL, &mainstone_pxafb_info);
 	mainstone_backlight_register();
 	mainstone_backlight_register();
 
 
 	pxa_set_mci_info(&mainstone_mci_platform_data);
 	pxa_set_mci_info(&mainstone_mci_platform_data);

+ 1 - 1
arch/arm/mach-pxa/mioa701.c

@@ -795,7 +795,7 @@ static void __init mioa701_machine_init(void)
 	pxa_set_stuart_info(NULL);
 	pxa_set_stuart_info(NULL);
 	mio_gpio_request(ARRAY_AND_SIZE(global_gpios));
 	mio_gpio_request(ARRAY_AND_SIZE(global_gpios));
 	bootstrap_init();
 	bootstrap_init();
-	set_pxa_fb_info(&mioa701_pxafb_info);
+	pxa_set_fb_info(NULL, &mioa701_pxafb_info);
 	pxa_set_mci_info(&mioa701_mci_info);
 	pxa_set_mci_info(&mioa701_mci_info);
 	pxa_set_keypad_info(&mioa701_keypad_info);
 	pxa_set_keypad_info(&mioa701_keypad_info);
 	pxa_set_udc_info(&mioa701_udc_info);
 	pxa_set_udc_info(&mioa701_udc_info);

+ 2 - 3
arch/arm/mach-pxa/palm27x.c

@@ -1,8 +1,7 @@
 /*
 /*
  * Common code for Palm LD, T5, TX, Z72
  * Common code for Palm LD, T5, TX, Z72
  *
  *
- * Copyright (C) 2010
- * Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com>
  *
  *
  * This program is free software; you can redistribute it and/or modify
  * 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
  * it under the terms of the GNU General Public License version 2 as
@@ -158,7 +157,7 @@ void __init palm27x_lcd_init(int power, struct pxafb_mode_info *mode)
 		palm27x_lcd_screen.pxafb_lcd_power = palm27x_lcd_ctl;
 		palm27x_lcd_screen.pxafb_lcd_power = palm27x_lcd_ctl;
 	}
 	}
 
 
-	set_pxa_fb_info(&palm27x_lcd_screen);
+	pxa_set_fb_info(NULL, &palm27x_lcd_screen);
 }
 }
 #endif
 #endif
 
 

+ 1 - 1
arch/arm/mach-pxa/palmtc.c

@@ -507,7 +507,7 @@ static struct pxafb_mach_info palmtc_lcd_screen = {
 
 
 static void __init palmtc_lcd_init(void)
 static void __init palmtc_lcd_init(void)
 {
 {
-	set_pxa_fb_info(&palmtc_lcd_screen);
+	pxa_set_fb_info(NULL, &palmtc_lcd_screen);
 }
 }
 #else
 #else
 static inline void palmtc_lcd_init(void) {}
 static inline void palmtc_lcd_init(void) {}

+ 8 - 25
arch/arm/mach-pxa/palmte2.c

@@ -136,30 +136,14 @@ static struct platform_device palmte2_pxa_keys = {
 /******************************************************************************
 /******************************************************************************
  * Backlight
  * Backlight
  ******************************************************************************/
  ******************************************************************************/
+static struct gpio palmte_bl_gpios[] = {
+	{ GPIO_NR_PALMTE2_BL_POWER, GPIOF_INIT_LOW, "Backlight power" },
+	{ GPIO_NR_PALMTE2_LCD_POWER, GPIOF_INIT_LOW, "LCD power" },
+};
+
 static int palmte2_backlight_init(struct device *dev)
 static int palmte2_backlight_init(struct device *dev)
 {
 {
-	int ret;
-
-	ret = gpio_request(GPIO_NR_PALMTE2_BL_POWER, "BL POWER");
-	if (ret)
-		goto err;
-	ret = gpio_direction_output(GPIO_NR_PALMTE2_BL_POWER, 0);
-	if (ret)
-		goto err2;
-	ret = gpio_request(GPIO_NR_PALMTE2_LCD_POWER, "LCD POWER");
-	if (ret)
-		goto err2;
-	ret = gpio_direction_output(GPIO_NR_PALMTE2_LCD_POWER, 0);
-	if (ret)
-		goto err3;
-
-	return 0;
-err3:
-	gpio_free(GPIO_NR_PALMTE2_LCD_POWER);
-err2:
-	gpio_free(GPIO_NR_PALMTE2_BL_POWER);
-err:
-	return ret;
+	return gpio_request_array(ARRAY_AND_SIZE(palmte_bl_gpios));
 }
 }
 
 
 static int palmte2_backlight_notify(struct device *dev, int brightness)
 static int palmte2_backlight_notify(struct device *dev, int brightness)
@@ -171,8 +155,7 @@ static int palmte2_backlight_notify(struct device *dev, int brightness)
 
 
 static void palmte2_backlight_exit(struct device *dev)
 static void palmte2_backlight_exit(struct device *dev)
 {
 {
-	gpio_free(GPIO_NR_PALMTE2_BL_POWER);
-	gpio_free(GPIO_NR_PALMTE2_LCD_POWER);
+	gpio_free_array(ARRAY_AND_SIZE(palmte_bl_gpios));
 }
 }
 
 
 static struct platform_pwm_backlight_data palmte2_backlight_data = {
 static struct platform_pwm_backlight_data palmte2_backlight_data = {
@@ -363,7 +346,7 @@ static void __init palmte2_init(void)
 	pxa_set_btuart_info(NULL);
 	pxa_set_btuart_info(NULL);
 	pxa_set_stuart_info(NULL);
 	pxa_set_stuart_info(NULL);
 
 
-	set_pxa_fb_info(&palmte2_lcd_screen);
+	pxa_set_fb_info(NULL, &palmte2_lcd_screen);
 	pxa_set_mci_info(&palmte2_mci_platform_data);
 	pxa_set_mci_info(&palmte2_mci_platform_data);
 	palmte2_udc_init();
 	palmte2_udc_init();
 	pxa_set_ac97_info(&palmte2_ac97_pdata);
 	pxa_set_ac97_info(&palmte2_ac97_pdata);

+ 127 - 0
arch/arm/mach-pxa/palmz72.c

@@ -30,6 +30,7 @@
 #include <linux/wm97xx.h>
 #include <linux/wm97xx.h>
 #include <linux/power_supply.h>
 #include <linux/power_supply.h>
 #include <linux/usb/gpio_vbus.h>
 #include <linux/usb/gpio_vbus.h>
+#include <linux/i2c-gpio.h>
 
 
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/arch.h>
@@ -47,6 +48,9 @@
 #include <mach/palm27x.h>
 #include <mach/palm27x.h>
 
 
 #include <mach/pm.h>
 #include <mach/pm.h>
+#include <mach/camera.h>
+
+#include <media/soc_camera.h>
 
 
 #include "generic.h"
 #include "generic.h"
 #include "devices.h"
 #include "devices.h"
@@ -103,6 +107,28 @@ static unsigned long palmz72_pin_config[] __initdata = {
 	GPIO22_GPIO,	/* LCD border color */
 	GPIO22_GPIO,	/* LCD border color */
 	GPIO96_GPIO,	/* lcd power */
 	GPIO96_GPIO,	/* lcd power */
 
 
+	/* PXA Camera */
+	GPIO81_CIF_DD_0,
+	GPIO48_CIF_DD_5,
+	GPIO50_CIF_DD_3,
+	GPIO51_CIF_DD_2,
+	GPIO52_CIF_DD_4,
+	GPIO53_CIF_MCLK,
+	GPIO54_CIF_PCLK,
+	GPIO55_CIF_DD_1,
+	GPIO84_CIF_FV,
+	GPIO85_CIF_LV,
+	GPIO93_CIF_DD_6,
+	GPIO108_CIF_DD_7,
+
+	GPIO56_GPIO,	/* OV9640 Powerdown */
+	GPIO57_GPIO,	/* OV9640 Reset */
+	GPIO91_GPIO,	/* OV9640 Power */
+
+	/* I2C */
+	GPIO117_GPIO,	/* I2C_SCL */
+	GPIO118_GPIO,	/* I2C_SDA */
+
 	/* Misc. */
 	/* Misc. */
 	GPIO0_GPIO	| WAKEUP_ON_LEVEL_HIGH,	/* power detect */
 	GPIO0_GPIO	| WAKEUP_ON_LEVEL_HIGH,	/* power detect */
 	GPIO88_GPIO,				/* green led */
 	GPIO88_GPIO,				/* green led */
@@ -253,6 +279,106 @@ static int __init palmz72_pm_init(void)
 device_initcall(palmz72_pm_init);
 device_initcall(palmz72_pm_init);
 #endif
 #endif
 
 
+/******************************************************************************
+ * SoC Camera
+ ******************************************************************************/
+#if defined(CONFIG_SOC_CAMERA_OV9640) || \
+	defined(CONFIG_SOC_CAMERA_OV9640_MODULE)
+static struct pxacamera_platform_data palmz72_pxacamera_platform_data = {
+	.flags		= PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
+			PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+	.mclk_10khz	= 2600,
+};
+
+/* Board I2C devices. */
+static struct i2c_board_info palmz72_i2c_device[] = {
+	{
+		I2C_BOARD_INFO("ov9640", 0x30),
+	}
+};
+
+static int palmz72_camera_power(struct device *dev, int power)
+{
+	gpio_set_value(GPIO_NR_PALMZ72_CAM_PWDN, !power);
+	mdelay(50);
+	return 0;
+}
+
+static int palmz72_camera_reset(struct device *dev)
+{
+	gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 1);
+	mdelay(50);
+	gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 0);
+	mdelay(50);
+	return 0;
+}
+
+static struct soc_camera_link palmz72_iclink = {
+	.bus_id		= 0, /* Match id in pxa27x_device_camera in device.c */
+	.board_info	= &palmz72_i2c_device[0],
+	.i2c_adapter_id	= 0,
+	.module_name	= "ov96xx",
+	.power		= &palmz72_camera_power,
+	.reset		= &palmz72_camera_reset,
+	.flags		= SOCAM_DATAWIDTH_8,
+};
+
+static struct i2c_gpio_platform_data palmz72_i2c_bus_data = {
+	.sda_pin	= 118,
+	.scl_pin	= 117,
+	.udelay		= 10,
+	.timeout	= 100,
+};
+
+static struct platform_device palmz72_i2c_bus_device = {
+	.name		= "i2c-gpio",
+	.id		= 0, /* we use this as a replacement for i2c-pxa */
+	.dev		= {
+		.platform_data	= &palmz72_i2c_bus_data,
+	}
+};
+
+static struct platform_device palmz72_camera = {
+	.name	= "soc-camera-pdrv",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &palmz72_iclink,
+	},
+};
+
+/* Here we request the camera GPIOs and configure them. We power up the camera
+ * module, deassert the reset pin, but put it into powerdown (low to no power
+ * consumption) mode. This allows us to later bring the module up fast. */
+static struct gpio palmz72_camera_gpios[] = {
+	{ GPIO_NR_PALMZ72_CAM_POWER,	GPIOF_INIT_HIGH,"Camera DVDD" },
+	{ GPIO_NR_PALMZ72_CAM_RESET,	GPIOF_INIT_LOW,	"Camera RESET" },
+	{ GPIO_NR_PALMZ72_CAM_PWDN,	GPIOF_INIT_LOW,	"Camera PWDN" },
+};
+
+static inline void __init palmz72_cam_gpio_init(void)
+{
+	int ret;
+
+	ret = gpio_request_array(ARRAY_AND_SIZE(palmz72_camera_gpios));
+	if (!ret)
+		gpio_free_array(ARRAY_AND_SIZE(palmz72_camera_gpios));
+	else
+		printk(KERN_ERR "Camera GPIO init failed!\n");
+
+	return;
+}
+
+static void __init palmz72_camera_init(void)
+{
+	palmz72_cam_gpio_init();
+	pxa_set_camera_info(&palmz72_pxacamera_platform_data);
+	platform_device_register(&palmz72_i2c_bus_device);
+	platform_device_register(&palmz72_camera);
+}
+#else
+static inline void palmz72_camera_init(void) {}
+#endif
+
 /******************************************************************************
 /******************************************************************************
  * Machine init
  * Machine init
  ******************************************************************************/
  ******************************************************************************/
@@ -276,6 +402,7 @@ static void __init palmz72_init(void)
 	palm27x_pmic_init();
 	palm27x_pmic_init();
 	palmz72_kpc_init();
 	palmz72_kpc_init();
 	palmz72_leds_init();
 	palmz72_leds_init();
+	palmz72_camera_init();
 }
 }
 
 
 MACHINE_START(PALMZ72, "Palm Zire72")
 MACHINE_START(PALMZ72, "Palm Zire72")

+ 1 - 1
arch/arm/mach-pxa/pcm990-baseboard.c

@@ -515,7 +515,7 @@ void __init pcm990_baseboard_init(void)
 	pcm990_init_irq();
 	pcm990_init_irq();
 
 
 #ifndef CONFIG_PCM990_DISPLAY_NONE
 #ifndef CONFIG_PCM990_DISPLAY_NONE
-	set_pxa_fb_info(&pcm990_fbinfo);
+	pxa_set_fb_info(NULL, &pcm990_fbinfo);
 #endif
 #endif
 	platform_device_register(&pcm990_backlight_device);
 	platform_device_register(&pcm990_backlight_device);
 
 

+ 1 - 2
arch/arm/mach-pxa/poodle.c

@@ -445,8 +445,7 @@ static void __init poodle_init(void)
 	if (ret)
 	if (ret)
 		pr_warning("poodle: Unable to register LoCoMo device\n");
 		pr_warning("poodle: Unable to register LoCoMo device\n");
 
 
-	set_pxa_fb_parent(&poodle_locomo_device.dev);
-	set_pxa_fb_info(&poodle_fb_info);
+	pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info);
 	pxa_set_udc_info(&udc_info);
 	pxa_set_udc_info(&udc_info);
 	pxa_set_mci_info(&poodle_mci_platform_data);
 	pxa_set_mci_info(&poodle_mci_platform_data);
 	pxa_set_ficp_info(&poodle_ficp_platform_data);
 	pxa_set_ficp_info(&poodle_ficp_platform_data);

+ 1 - 1
arch/arm/mach-pxa/raumfeld.c

@@ -597,7 +597,7 @@ static void __init raumfeld_lcd_init(void)
 {
 {
 	int ret;
 	int ret;
 
 
-	set_pxa_fb_info(&raumfeld_sharp_lcd_info);
+	pxa_set_fb_info(NULL, &raumfeld_sharp_lcd_info);
 
 
 	/* Earlier devices had the backlight regulator controlled
 	/* Earlier devices had the backlight regulator controlled
 	 * via PWM, later versions use another controller for that */
 	 * via PWM, later versions use another controller for that */

+ 1 - 1
arch/arm/mach-pxa/saar.c

@@ -473,7 +473,7 @@ static struct pxafb_mach_info saar_lcd_info = {
 
 
 static void __init saar_init_lcd(void)
 static void __init saar_init_lcd(void)
 {
 {
-	set_pxa_fb_info(&saar_lcd_info);
+	pxa_set_fb_info(NULL, &saar_lcd_info);
 }
 }
 #else
 #else
 static inline void saar_init_lcd(void) {}
 static inline void saar_init_lcd(void) {}

+ 1 - 1
arch/arm/mach-pxa/spitz.c

@@ -724,7 +724,7 @@ static struct pxafb_mach_info spitz_pxafb_info = {
 
 
 static void __init spitz_lcd_init(void)
 static void __init spitz_lcd_init(void)
 {
 {
-	set_pxa_fb_info(&spitz_pxafb_info);
+	pxa_set_fb_info(NULL, &spitz_pxafb_info);
 }
 }
 #else
 #else
 static inline void spitz_lcd_init(void) {}
 static inline void spitz_lcd_init(void) {}

+ 1 - 1
arch/arm/mach-pxa/tavorevb.c

@@ -466,7 +466,7 @@ static void __init tavorevb_init_lcd(void)
 {
 {
 	platform_device_register(&tavorevb_backlight_devices[0]);
 	platform_device_register(&tavorevb_backlight_devices[0]);
 	platform_device_register(&tavorevb_backlight_devices[1]);
 	platform_device_register(&tavorevb_backlight_devices[1]);
-	set_pxa_fb_info(&tavorevb_lcd_info);
+	pxa_set_fb_info(NULL, &tavorevb_lcd_info);
 }
 }
 #else
 #else
 static inline void tavorevb_init_lcd(void) {}
 static inline void tavorevb_init_lcd(void) {}

+ 2 - 3
arch/arm/mach-pxa/time.c

@@ -100,7 +100,6 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
 static struct clock_event_device ckevt_pxa_osmr0 = {
 static struct clock_event_device ckevt_pxa_osmr0 = {
 	.name		= "osmr0",
 	.name		= "osmr0",
 	.features	= CLOCK_EVT_FEAT_ONESHOT,
 	.features	= CLOCK_EVT_FEAT_ONESHOT,
-	.shift		= 32,
 	.rating		= 200,
 	.rating		= 200,
 	.set_next_event	= pxa_osmr0_set_next_event,
 	.set_next_event	= pxa_osmr0_set_next_event,
 	.set_mode	= pxa_osmr0_set_mode,
 	.set_mode	= pxa_osmr0_set_mode,
@@ -135,8 +134,8 @@ static void __init pxa_timer_init(void)
 
 
 	init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate);
 	init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate);
 
 
-	ckevt_pxa_osmr0.mult =
-		div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift);
+	clocksource_calc_mult_shift(&cksrc_pxa_oscr0, clock_tick_rate, 4);
+	clockevents_calc_mult_shift(&ckevt_pxa_osmr0, clock_tick_rate, 4);
 	ckevt_pxa_osmr0.max_delta_ns =
 	ckevt_pxa_osmr0.max_delta_ns =
 		clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
 		clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
 	ckevt_pxa_osmr0.min_delta_ns =
 	ckevt_pxa_osmr0.min_delta_ns =

+ 11 - 2
arch/arm/mach-pxa/tosa.c

@@ -35,6 +35,7 @@
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/i2c/pxa-i2c.h>
 #include <linux/i2c/pxa-i2c.h>
+#include <linux/usb/gpio_vbus.h>
 
 
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
@@ -240,12 +241,20 @@ static struct scoop_pcmcia_config tosa_pcmcia_config = {
 /*
 /*
  * USB Device Controller
  * USB Device Controller
  */
  */
-static struct pxa2xx_udc_mach_info udc_info __initdata = {
+static struct gpio_vbus_mach_info tosa_udc_info = {
 	.gpio_pullup		= TOSA_GPIO_USB_PULLUP,
 	.gpio_pullup		= TOSA_GPIO_USB_PULLUP,
 	.gpio_vbus		= TOSA_GPIO_USB_IN,
 	.gpio_vbus		= TOSA_GPIO_USB_IN,
 	.gpio_vbus_inverted	= 1,
 	.gpio_vbus_inverted	= 1,
 };
 };
 
 
+static struct platform_device tosa_gpio_vbus = {
+	.name	= "gpio-vbus",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &tosa_udc_info,
+	},
+};
+
 /*
 /*
  * MMC/SD Device
  * MMC/SD Device
  */
  */
@@ -891,6 +900,7 @@ static struct platform_device *devices[] __initdata = {
 	&tosa_bt_device,
 	&tosa_bt_device,
 	&sharpsl_rom_device,
 	&sharpsl_rom_device,
 	&wm9712_device,
 	&wm9712_device,
+	&tosa_gpio_vbus,
 };
 };
 
 
 static void tosa_poweroff(void)
 static void tosa_poweroff(void)
@@ -937,7 +947,6 @@ static void __init tosa_init(void)
 	dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16);
 	dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16);
 
 
 	pxa_set_mci_info(&tosa_mci_platform_data);
 	pxa_set_mci_info(&tosa_mci_platform_data);
-	pxa_set_udc_info(&udc_info);
 	pxa_set_ficp_info(&tosa_ficp_platform_data);
 	pxa_set_ficp_info(&tosa_ficp_platform_data);
 	pxa_set_i2c_info(NULL);
 	pxa_set_i2c_info(NULL);
 	pxa_set_ac97_info(NULL);
 	pxa_set_ac97_info(NULL);

+ 2 - 2
arch/arm/mach-pxa/trizeps4.c

@@ -516,9 +516,9 @@ static void __init trizeps4_init(void)
 	pxa_set_stuart_info(NULL);
 	pxa_set_stuart_info(NULL);
 
 
 	if (0)	/* dont know how to determine LCD */
 	if (0)	/* dont know how to determine LCD */
-		set_pxa_fb_info(&sharp_lcd);
+		pxa_set_fb_info(NULL, &sharp_lcd);
 	else
 	else
-		set_pxa_fb_info(&toshiba_lcd);
+		pxa_set_fb_info(NULL, &toshiba_lcd);
 
 
 	pxa_set_mci_info(&trizeps4_mci_platform_data);
 	pxa_set_mci_info(&trizeps4_mci_platform_data);
 #ifndef STATUS_LEDS_ON_STUART_PINS
 #ifndef STATUS_LEDS_ON_STUART_PINS

+ 1 - 1
arch/arm/mach-pxa/viper.c

@@ -932,7 +932,7 @@ static void __init viper_init(void)
 	/* Wake-up serial console */
 	/* Wake-up serial console */
 	viper_init_serial_gpio();
 	viper_init_serial_gpio();
 
 
-	set_pxa_fb_info(&fb_info);
+	pxa_set_fb_info(NULL, &fb_info);
 
 
 	/* v1 hardware cannot use the datacs line */
 	/* v1 hardware cannot use the datacs line */
 	version = viper_hw_version();
 	version = viper_hw_version();

+ 1 - 1
arch/arm/mach-pxa/vpac270.c

@@ -572,7 +572,7 @@ static void __init vpac270_lcd_init(void)
 	}
 	}
 
 
 	vpac270_lcd_screen.pxafb_lcd_power = vpac270_lcd_power;
 	vpac270_lcd_screen.pxafb_lcd_power = vpac270_lcd_power;
-	set_pxa_fb_info(&vpac270_lcd_screen);
+	pxa_set_fb_info(NULL, &vpac270_lcd_screen);
 	return;
 	return;
 
 
 err2:
 err2:

+ 38 - 39
arch/arm/mach-pxa/z2.c

@@ -91,13 +91,13 @@ static unsigned long z2_pin_config[] = {
 	GPIO47_STUART_TXD,
 	GPIO47_STUART_TXD,
 
 
 	/* Keypad */
 	/* Keypad */
-	GPIO100_KP_MKIN_0	| WAKEUP_ON_LEVEL_HIGH,
-	GPIO101_KP_MKIN_1	| WAKEUP_ON_LEVEL_HIGH,
-	GPIO102_KP_MKIN_2	| WAKEUP_ON_LEVEL_HIGH,
-	GPIO34_KP_MKIN_3	| WAKEUP_ON_LEVEL_HIGH,
-	GPIO38_KP_MKIN_4	| WAKEUP_ON_LEVEL_HIGH,
-	GPIO16_KP_MKIN_5	| WAKEUP_ON_LEVEL_HIGH,
-	GPIO17_KP_MKIN_6	| WAKEUP_ON_LEVEL_HIGH,
+	GPIO100_KP_MKIN_0,
+	GPIO101_KP_MKIN_1,
+	GPIO102_KP_MKIN_2,
+	GPIO34_KP_MKIN_3,
+	GPIO38_KP_MKIN_4,
+	GPIO16_KP_MKIN_5,
+	GPIO17_KP_MKIN_6,
 	GPIO103_KP_MKOUT_0,
 	GPIO103_KP_MKOUT_0,
 	GPIO104_KP_MKOUT_1,
 	GPIO104_KP_MKOUT_1,
 	GPIO105_KP_MKOUT_2,
 	GPIO105_KP_MKOUT_2,
@@ -138,8 +138,7 @@ static unsigned long z2_pin_config[] = {
 	GPIO1_GPIO,		/* Power button */
 	GPIO1_GPIO,		/* Power button */
 	GPIO37_GPIO,		/* Headphone detect */
 	GPIO37_GPIO,		/* Headphone detect */
 	GPIO98_GPIO,		/* Lid switch */
 	GPIO98_GPIO,		/* Lid switch */
-	GPIO14_GPIO,		/* WiFi Reset */
-	GPIO15_GPIO,		/* WiFi Power */
+	GPIO14_GPIO,		/* WiFi Power */
 	GPIO24_GPIO,		/* WiFi CS */
 	GPIO24_GPIO,		/* WiFi CS */
 	GPIO36_GPIO,		/* WiFi IRQ */
 	GPIO36_GPIO,		/* WiFi IRQ */
 	GPIO88_GPIO,		/* LCD CS */
 	GPIO88_GPIO,		/* LCD CS */
@@ -204,7 +203,7 @@ static struct platform_pwm_backlight_data z2_backlight_data[] = {
 		/* Keypad Backlight */
 		/* Keypad Backlight */
 		.pwm_id		= 1,
 		.pwm_id		= 1,
 		.max_brightness	= 1023,
 		.max_brightness	= 1023,
-		.dft_brightness	= 512,
+		.dft_brightness	= 0,
 		.pwm_period_ns	= 1260320,
 		.pwm_period_ns	= 1260320,
 	},
 	},
 	[1] = {
 	[1] = {
@@ -271,7 +270,7 @@ static struct pxafb_mach_info z2_lcd_screen = {
 
 
 static void __init z2_lcd_init(void)
 static void __init z2_lcd_init(void)
 {
 {
-	set_pxa_fb_info(&z2_lcd_screen);
+	pxa_set_fb_info(NULL, &z2_lcd_screen);
 }
 }
 #else
 #else
 static inline void z2_lcd_init(void) {}
 static inline void z2_lcd_init(void) {}
@@ -309,12 +308,12 @@ struct gpio_led z2_gpio_leds[] = {
 	.active_low		= 1,
 	.active_low		= 1,
 }, {
 }, {
 	.name			= "z2:green:charged",
 	.name			= "z2:green:charged",
-	.default_trigger	= "none",
+	.default_trigger	= "mmc0",
 	.gpio			= GPIO85_ZIPITZ2_LED_CHARGED,
 	.gpio			= GPIO85_ZIPITZ2_LED_CHARGED,
 	.active_low		= 1,
 	.active_low		= 1,
 }, {
 }, {
 	.name			= "z2:amber:charging",
 	.name			= "z2:amber:charging",
-	.default_trigger	= "none",
+	.default_trigger	= "Z2-charging-or-full",
 	.gpio			= GPIO83_ZIPITZ2_LED_CHARGING,
 	.gpio			= GPIO83_ZIPITZ2_LED_CHARGING,
 	.active_low		= 1,
 	.active_low		= 1,
 },
 },
@@ -427,8 +426,22 @@ static inline void z2_mkp_init(void) {}
  ******************************************************************************/
  ******************************************************************************/
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 static struct gpio_keys_button z2_pxa_buttons[] = {
 static struct gpio_keys_button z2_pxa_buttons[] = {
-	{KEY_POWER, GPIO1_ZIPITZ2_POWER_BUTTON, 0, "Power Button" },
-	{KEY_CLOSE, GPIO98_ZIPITZ2_LID_BUTTON, 0, "Lid Button" },
+	{
+		.code		= KEY_POWER,
+		.gpio		= GPIO1_ZIPITZ2_POWER_BUTTON,
+		.active_low	= 0,
+		.desc		= "Power Button",
+		.wakeup		= 1,
+		.type		= EV_KEY,
+	},
+	{
+		.code		= SW_LID,
+		.gpio		= GPIO98_ZIPITZ2_LID_BUTTON,
+		.active_low	= 1,
+		.desc		= "Lid Switch",
+		.wakeup		= 0,
+		.type		= EV_SW,
+	},
 };
 };
 
 
 static struct gpio_keys_platform_data z2_pxa_keys_data = {
 static struct gpio_keys_platform_data z2_pxa_keys_data = {
@@ -461,9 +474,9 @@ static struct z2_battery_info batt_chip_info = {
 	.batt_I2C_addr	= 0x55,
 	.batt_I2C_addr	= 0x55,
 	.batt_I2C_reg	= 2,
 	.batt_I2C_reg	= 2,
 	.charge_gpio	= GPIO0_ZIPITZ2_AC_DETECT,
 	.charge_gpio	= GPIO0_ZIPITZ2_AC_DETECT,
-	.min_voltage	= 2400000,
-	.max_voltage	= 3700000,
-	.batt_div	= 69,
+	.min_voltage	= 3475000,
+	.max_voltage	= 4190000,
+	.batt_div	= 59,
 	.batt_mult	= 1000000,
 	.batt_mult	= 1000000,
 	.batt_tech	= POWER_SUPPLY_TECHNOLOGY_LION,
 	.batt_tech	= POWER_SUPPLY_TECHNOLOGY_LION,
 	.batt_name	= "Z2",
 	.batt_name	= "Z2",
@@ -497,26 +510,16 @@ static int z2_lbs_spi_setup(struct spi_device *spi)
 {
 {
 	int ret = 0;
 	int ret = 0;
 
 
-	ret = gpio_request(GPIO15_ZIPITZ2_WIFI_POWER, "WiFi Power");
+	ret = gpio_request(GPIO14_ZIPITZ2_WIFI_POWER, "WiFi Power");
 	if (ret)
 	if (ret)
 		goto err;
 		goto err;
 
 
-	ret = gpio_direction_output(GPIO15_ZIPITZ2_WIFI_POWER, 1);
+	ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_POWER, 1);
 	if (ret)
 	if (ret)
 		goto err2;
 		goto err2;
 
 
-	ret = gpio_request(GPIO14_ZIPITZ2_WIFI_RESET, "WiFi Reset");
-	if (ret)
-		goto err2;
-
-	ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_RESET, 0);
-	if (ret)
-		goto err3;
-
-	/* Reset the card */
+	/* Wait until card is powered on */
 	mdelay(180);
 	mdelay(180);
-	gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 1);
-	mdelay(20);
 
 
 	spi->bits_per_word = 16;
 	spi->bits_per_word = 16;
 	spi->mode = SPI_MODE_2,
 	spi->mode = SPI_MODE_2,
@@ -525,22 +528,18 @@ static int z2_lbs_spi_setup(struct spi_device *spi)
 
 
 	return 0;
 	return 0;
 
 
-err3:
-	gpio_free(GPIO14_ZIPITZ2_WIFI_RESET);
 err2:
 err2:
-	gpio_free(GPIO15_ZIPITZ2_WIFI_POWER);
+	gpio_free(GPIO14_ZIPITZ2_WIFI_POWER);
 err:
 err:
 	return ret;
 	return ret;
 };
 };
 
 
 static int z2_lbs_spi_teardown(struct spi_device *spi)
 static int z2_lbs_spi_teardown(struct spi_device *spi)
 {
 {
-	gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 0);
-	gpio_set_value(GPIO15_ZIPITZ2_WIFI_POWER, 0);
-	gpio_free(GPIO14_ZIPITZ2_WIFI_RESET);
-	gpio_free(GPIO15_ZIPITZ2_WIFI_POWER);
-	return 0;
+	gpio_set_value(GPIO14_ZIPITZ2_WIFI_POWER, 0);
+	gpio_free(GPIO14_ZIPITZ2_WIFI_POWER);
 
 
+	return 0;
 };
 };
 
 
 static struct pxa2xx_spi_chip z2_lbs_chip_info = {
 static struct pxa2xx_spi_chip z2_lbs_chip_info = {

+ 1 - 1
arch/arm/mach-pxa/zeus.c

@@ -847,7 +847,7 @@ static void __init zeus_init(void)
 	if (zeus_setup_fb_gpios())
 	if (zeus_setup_fb_gpios())
 		pr_err("Failed to setup fb gpios\n");
 		pr_err("Failed to setup fb gpios\n");
 	else
 	else
-		set_pxa_fb_info(&zeus_fb_info);
+		pxa_set_fb_info(NULL, &zeus_fb_info);
 
 
 	pxa_set_mci_info(&zeus_mci_platform_data);
 	pxa_set_mci_info(&zeus_mci_platform_data);
 	pxa_set_udc_info(&zeus_udc_info);
 	pxa_set_udc_info(&zeus_udc_info);

+ 2 - 2
arch/arm/mach-pxa/zylonite.c

@@ -208,7 +208,7 @@ static void __init zylonite_init_lcd(void)
 	platform_device_register(&zylonite_backlight_device);
 	platform_device_register(&zylonite_backlight_device);
 
 
 	if (lcd_id & 0x20) {
 	if (lcd_id & 0x20) {
-		set_pxa_fb_info(&zylonite_sharp_lcd_info);
+		pxa_set_fb_info(NULL, &zylonite_sharp_lcd_info);
 		return;
 		return;
 	}
 	}
 
 
@@ -220,7 +220,7 @@ static void __init zylonite_init_lcd(void)
 	else
 	else
 		zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode;
 		zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode;
 
 
-	set_pxa_fb_info(&zylonite_toshiba_lcd_info);
+	pxa_set_fb_info(NULL, &zylonite_toshiba_lcd_info);
 }
 }
 #else
 #else
 static inline void zylonite_init_lcd(void) {}
 static inline void zylonite_init_lcd(void) {}

+ 1 - 1
arch/arm/mach-realview/realview_eb.c

@@ -348,7 +348,7 @@ static void __init gic_init_irq(void)
 
 
 #ifndef CONFIG_REALVIEW_EB_ARM11MP_REVB
 #ifndef CONFIG_REALVIEW_EB_ARM11MP_REVB
 		/* board GIC, secondary */
 		/* board GIC, secondary */
-		gic_init(1, 64, __io_address(REALVIEW_EB_GIC_DIST_BASE),
+		gic_init(1, 96, __io_address(REALVIEW_EB_GIC_DIST_BASE),
 			 __io_address(REALVIEW_EB_GIC_CPU_BASE));
 			 __io_address(REALVIEW_EB_GIC_CPU_BASE));
 		gic_cascade_irq(1, IRQ_EB11MP_EB_IRQ1);
 		gic_cascade_irq(1, IRQ_EB11MP_EB_IRQ1);
 #endif
 #endif

+ 1 - 1
arch/arm/plat-mxc/devices/platform-fec.c

@@ -53,7 +53,7 @@ struct platform_device *__init imx_add_fec(
 	struct resource res[] = {
 	struct resource res[] = {
 		{
 		{
 			.start = data->iobase,
 			.start = data->iobase,
-			.end = data->iobase + SZ_4K,
+			.end = data->iobase + SZ_4K - 1,
 			.flags = IORESOURCE_MEM,
 			.flags = IORESOURCE_MEM,
 		}, {
 		}, {
 			.start = data->irq,
 			.start = data->irq,

+ 1 - 1
arch/arm/plat-mxc/devices/platform-imxdi_rtc.c

@@ -27,7 +27,7 @@ struct platform_device *__init imx_add_imxdi_rtc(
 	struct resource res[] = {
 	struct resource res[] = {
 		{
 		{
 			.start = data->iobase,
 			.start = data->iobase,
-			.end = data->iobase + SZ_16K,
+			.end = data->iobase + SZ_16K - 1,
 			.flags = IORESOURCE_MEM,
 			.flags = IORESOURCE_MEM,
 		}, {
 		}, {
 			.start = data->irq,
 			.start = data->irq,

+ 9 - 1
arch/arm/plat-mxc/include/mach/audmux.h

@@ -15,6 +15,14 @@
 #define MX31_AUDMUX_PORT5_SSI_PINS_5	4
 #define MX31_AUDMUX_PORT5_SSI_PINS_5	4
 #define MX31_AUDMUX_PORT6_SSI_PINS_6	5
 #define MX31_AUDMUX_PORT6_SSI_PINS_6	5
 
 
+#define MX51_AUDMUX_PORT1_SSI0		0
+#define MX51_AUDMUX_PORT2_SSI1		1
+#define MX51_AUDMUX_PORT3		2
+#define MX51_AUDMUX_PORT4		3
+#define MX51_AUDMUX_PORT5		4
+#define MX51_AUDMUX_PORT6		5
+#define MX51_AUDMUX_PORT7		6
+
 /* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
 /* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
 #define MXC_AUDMUX_V1_PCR_INMMASK(x)	((x) & 0xff)
 #define MXC_AUDMUX_V1_PCR_INMMASK(x)	((x) & 0xff)
 #define MXC_AUDMUX_V1_PCR_INMEN		(1 << 8)
 #define MXC_AUDMUX_V1_PCR_INMEN		(1 << 8)
@@ -28,7 +36,7 @@
 #define MXC_AUDMUX_V1_PCR_TCLKDIR	(1 << 30)
 #define MXC_AUDMUX_V1_PCR_TCLKDIR	(1 << 30)
 #define MXC_AUDMUX_V1_PCR_TFSDIR	(1 << 31)
 #define MXC_AUDMUX_V1_PCR_TFSDIR	(1 << 31)
 
 
-/* Register definitions for the i.MX25/31/35 Digital Audio Multiplexer */
+/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */
 #define MXC_AUDMUX_V2_PTCR_TFSDIR	(1 << 31)
 #define MXC_AUDMUX_V2_PTCR_TFSDIR	(1 << 31)
 #define MXC_AUDMUX_V2_PTCR_TFSEL(x)	(((x) & 0xf) << 27)
 #define MXC_AUDMUX_V2_PTCR_TFSEL(x)	(((x) & 0xf) << 27)
 #define MXC_AUDMUX_V2_PTCR_TCLKDIR	(1 << 26)
 #define MXC_AUDMUX_V2_PTCR_TCLKDIR	(1 << 26)

+ 6 - 6
arch/arm/plat-mxc/include/mach/iomux-mx2x.h

@@ -90,12 +90,12 @@
 #define PC31_PF_SSI3_CLK	(GPIO_PORTC | GPIO_PF | GPIO_IN | 31)
 #define PC31_PF_SSI3_CLK	(GPIO_PORTC | GPIO_PF | GPIO_IN | 31)
 #define PD17_PF_I2C_DATA	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 17)
 #define PD17_PF_I2C_DATA	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 17)
 #define PD18_PF_I2C_CLK		(GPIO_PORTD | GPIO_PF | GPIO_OUT | 18)
 #define PD18_PF_I2C_CLK		(GPIO_PORTD | GPIO_PF | GPIO_OUT | 18)
-#define PD19_PF_CSPI2_SS2	(GPIO_PORTD | GPIO_PF | 19)
-#define PD20_PF_CSPI2_SS1	(GPIO_PORTD | GPIO_PF | 20)
-#define PD21_PF_CSPI2_SS0	(GPIO_PORTD | GPIO_PF | 21)
-#define PD22_PF_CSPI2_SCLK	(GPIO_PORTD | GPIO_PF | 22)
-#define PD23_PF_CSPI2_MISO	(GPIO_PORTD | GPIO_PF | 23)
-#define PD24_PF_CSPI2_MOSI	(GPIO_PORTD | GPIO_PF | 24)
+#define PD19_PF_CSPI2_SS2	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 19)
+#define PD20_PF_CSPI2_SS1	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 20)
+#define PD21_PF_CSPI2_SS0	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 21)
+#define PD22_PF_CSPI2_SCLK	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 22)
+#define PD23_PF_CSPI2_MISO	(GPIO_PORTD | GPIO_PF | GPIO_IN | 23)
+#define PD24_PF_CSPI2_MOSI	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 24)
 #define PD25_PF_CSPI1_RDY	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 25)
 #define PD25_PF_CSPI1_RDY	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 25)
 #define PD26_PF_CSPI1_SS2	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 26)
 #define PD26_PF_CSPI1_SS2	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 26)
 #define PD27_PF_CSPI1_SS1	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 27)
 #define PD27_PF_CSPI1_SS1	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 27)

+ 4 - 0
arch/arm/plat-mxc/include/mach/mx50.h

@@ -282,4 +282,8 @@
 #define MX50_INT_APBHDMA_CHAN6	116
 #define MX50_INT_APBHDMA_CHAN6	116
 #define MX50_INT_APBHDMA_CHAN7	117
 #define MX50_INT_APBHDMA_CHAN7	117
 
 
+#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
+extern int mx50_revision(void);
+#endif
+
 #endif /* ifndef __MACH_MX50_H__ */
 #endif /* ifndef __MACH_MX50_H__ */

+ 1 - 0
arch/arm/plat-mxc/include/mach/mx51.h

@@ -347,6 +347,7 @@
 
 
 #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
 #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
 extern int mx51_revision(void);
 extern int mx51_revision(void);
+extern void mx51_display_revision(void);
 #endif
 #endif
 
 
 /* tape-out 1 defines */
 /* tape-out 1 defines */

+ 23 - 0
arch/arm/plat-mxc/include/mach/mxc.h

@@ -51,6 +51,20 @@
 #define IMX_CHIP_REVISION_3_3		0x33
 #define IMX_CHIP_REVISION_3_3		0x33
 #define IMX_CHIP_REVISION_UNKNOWN	0xff
 #define IMX_CHIP_REVISION_UNKNOWN	0xff
 
 
+#define IMX_CHIP_REVISION_1_0_STRING		"1.0"
+#define IMX_CHIP_REVISION_1_1_STRING		"1.1"
+#define IMX_CHIP_REVISION_1_2_STRING		"1.2"
+#define IMX_CHIP_REVISION_1_3_STRING		"1.3"
+#define IMX_CHIP_REVISION_2_0_STRING		"2.0"
+#define IMX_CHIP_REVISION_2_1_STRING		"2.1"
+#define IMX_CHIP_REVISION_2_2_STRING		"2.2"
+#define IMX_CHIP_REVISION_2_3_STRING		"2.3"
+#define IMX_CHIP_REVISION_3_0_STRING		"3.0"
+#define IMX_CHIP_REVISION_3_1_STRING		"3.1"
+#define IMX_CHIP_REVISION_3_2_STRING		"3.2"
+#define IMX_CHIP_REVISION_3_3_STRING		"3.3"
+#define IMX_CHIP_REVISION_UNKNOWN_STRING	"unknown"
+
 #ifndef __ASSEMBLY__
 #ifndef __ASSEMBLY__
 extern unsigned int __mxc_cpu_type;
 extern unsigned int __mxc_cpu_type;
 #endif
 #endif
@@ -181,6 +195,15 @@ struct cpu_op {
 	u32 cpu_rate;
 	u32 cpu_rate;
 };
 };
 
 
+int tzic_enable_wake(int is_idle);
+enum mxc_cpu_pwr_mode {
+	WAIT_CLOCKED,		/* wfi only */
+	WAIT_UNCLOCKED,		/* WAIT */
+	WAIT_UNCLOCKED_POWER_OFF,	/* WAIT + SRPG */
+	STOP_POWER_ON,		/* just STOP */
+	STOP_POWER_OFF,		/* STOP + SRPG */
+};
+
 extern struct cpu_op *(*get_cpu_op)(int *op);
 extern struct cpu_op *(*get_cpu_op)(int *op);
 #endif
 #endif
 
 

+ 5 - 1
arch/arm/plat-mxc/include/mach/system.h

@@ -20,6 +20,8 @@
 #include <mach/hardware.h>
 #include <mach/hardware.h>
 #include <mach/common.h>
 #include <mach/common.h>
 
 
+extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
+
 static inline void arch_idle(void)
 static inline void arch_idle(void)
 {
 {
 #ifdef CONFIG_ARCH_MXC91231
 #ifdef CONFIG_ARCH_MXC91231
@@ -54,7 +56,9 @@ static inline void arch_idle(void)
 			"orr %0, %0, #0x00000004\n"
 			"orr %0, %0, #0x00000004\n"
 			"mcr p15, 0, %0, c1, c0, 0\n"
 			"mcr p15, 0, %0, c1, c0, 0\n"
 			: "=r" (reg));
 			: "=r" (reg));
-	} else
+	} else if (cpu_is_mx51())
+		mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+	else
 		cpu_do_idle();
 		cpu_do_idle();
 }
 }
 
 

+ 24 - 1
arch/arm/plat-mxc/time.c

@@ -27,6 +27,7 @@
 #include <linux/clk.h>
 #include <linux/clk.h>
 
 
 #include <mach/hardware.h>
 #include <mach/hardware.h>
+#include <asm/sched_clock.h>
 #include <asm/mach/time.h>
 #include <asm/mach/time.h>
 #include <mach/common.h>
 #include <mach/common.h>
 
 
@@ -105,6 +106,11 @@ static void gpt_irq_acknowledge(void)
 		__raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
 		__raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
 }
 }
 
 
+static cycle_t dummy_get_cycles(struct clocksource *cs)
+{
+	return 0;
+}
+
 static cycle_t mx1_2_get_cycles(struct clocksource *cs)
 static cycle_t mx1_2_get_cycles(struct clocksource *cs)
 {
 {
 	return __raw_readl(timer_base + MX1_2_TCN);
 	return __raw_readl(timer_base + MX1_2_TCN);
@@ -118,18 +124,35 @@ static cycle_t v2_get_cycles(struct clocksource *cs)
 static struct clocksource clocksource_mxc = {
 static struct clocksource clocksource_mxc = {
 	.name 		= "mxc_timer1",
 	.name 		= "mxc_timer1",
 	.rating		= 200,
 	.rating		= 200,
-	.read		= mx1_2_get_cycles,
+	.read		= dummy_get_cycles,
 	.mask		= CLOCKSOURCE_MASK(32),
 	.mask		= CLOCKSOURCE_MASK(32),
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 };
 
 
+static DEFINE_CLOCK_DATA(cd);
+unsigned long long notrace sched_clock(void)
+{
+	cycle_t cyc = clocksource_mxc.read(&clocksource_mxc);
+
+	return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace mxc_update_sched_clock(void)
+{
+	cycle_t cyc = clocksource_mxc.read(&clocksource_mxc);
+	update_sched_clock(&cd, cyc, (u32)~0);
+}
+
 static int __init mxc_clocksource_init(struct clk *timer_clk)
 static int __init mxc_clocksource_init(struct clk *timer_clk)
 {
 {
 	unsigned int c = clk_get_rate(timer_clk);
 	unsigned int c = clk_get_rate(timer_clk);
 
 
 	if (timer_is_v2())
 	if (timer_is_v2())
 		clocksource_mxc.read = v2_get_cycles;
 		clocksource_mxc.read = v2_get_cycles;
+	else
+		clocksource_mxc.read = mx1_2_get_cycles;
 
 
+	init_sched_clock(&cd, mxc_update_sched_clock, 32, c);
 	clocksource_register_hz(&clocksource_mxc, c);
 	clocksource_register_hz(&clocksource_mxc, c);
 
 
 	return 0;
 	return 0;

+ 22 - 21
drivers/ata/pata_palmld.c

@@ -33,6 +33,11 @@
 
 
 #define DRV_NAME "pata_palmld"
 #define DRV_NAME "pata_palmld"
 
 
+static struct gpio palmld_hdd_gpios[] = {
+	{ GPIO_NR_PALMLD_IDE_PWEN,	GPIOF_INIT_HIGH,	"HDD Power" },
+	{ GPIO_NR_PALMLD_IDE_RESET,	GPIOF_INIT_LOW,		"HDD Reset" },
+};
+
 static struct scsi_host_template palmld_sht = {
 static struct scsi_host_template palmld_sht = {
 	ATA_PIO_SHT(DRV_NAME),
 	ATA_PIO_SHT(DRV_NAME),
 };
 };
@@ -52,28 +57,23 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev)
 
 
 	/* allocate host */
 	/* allocate host */
 	host = ata_host_alloc(&pdev->dev, 1);
 	host = ata_host_alloc(&pdev->dev, 1);
-	if (!host)
-		return -ENOMEM;
+	if (!host) {
+		ret = -ENOMEM;
+		goto err1;
+	}
 
 
 	/* remap drive's physical memory address */
 	/* remap drive's physical memory address */
 	mem = devm_ioremap(&pdev->dev, PALMLD_IDE_PHYS, 0x1000);
 	mem = devm_ioremap(&pdev->dev, PALMLD_IDE_PHYS, 0x1000);
-	if (!mem)
-		return -ENOMEM;
+	if (!mem) {
+		ret = -ENOMEM;
+		goto err1;
+	}
 
 
 	/* request and activate power GPIO, IRQ GPIO */
 	/* request and activate power GPIO, IRQ GPIO */
-	ret = gpio_request(GPIO_NR_PALMLD_IDE_PWEN, "HDD PWR");
+	ret = gpio_request_array(palmld_hdd_gpios,
+				ARRAY_SIZE(palmld_hdd_gpios));
 	if (ret)
 	if (ret)
 		goto err1;
 		goto err1;
-	ret = gpio_direction_output(GPIO_NR_PALMLD_IDE_PWEN, 1);
-	if (ret)
-		goto err2;
-
-	ret = gpio_request(GPIO_NR_PALMLD_IDE_RESET, "HDD RST");
-	if (ret)
-		goto err2;
-	ret = gpio_direction_output(GPIO_NR_PALMLD_IDE_RESET, 0);
-	if (ret)
-		goto err3;
 
 
 	/* reset the drive */
 	/* reset the drive */
 	gpio_set_value(GPIO_NR_PALMLD_IDE_RESET, 0);
 	gpio_set_value(GPIO_NR_PALMLD_IDE_RESET, 0);
@@ -96,13 +96,15 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev)
 	ata_sff_std_ports(&ap->ioaddr);
 	ata_sff_std_ports(&ap->ioaddr);
 
 
 	/* activate host */
 	/* activate host */
-	return ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING,
+	ret = ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING,
 					&palmld_sht);
 					&palmld_sht);
+	if (ret)
+		goto err2;
+
+	return ret;
 
 
-err3:
-	gpio_free(GPIO_NR_PALMLD_IDE_RESET);
 err2:
 err2:
-	gpio_free(GPIO_NR_PALMLD_IDE_PWEN);
+	gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios));
 err1:
 err1:
 	return ret;
 	return ret;
 }
 }
@@ -116,8 +118,7 @@ static __devexit int palmld_pata_remove(struct platform_device *dev)
 	/* power down the HDD */
 	/* power down the HDD */
 	gpio_set_value(GPIO_NR_PALMLD_IDE_PWEN, 0);
 	gpio_set_value(GPIO_NR_PALMLD_IDE_PWEN, 0);
 
 
-	gpio_free(GPIO_NR_PALMLD_IDE_RESET);
-	gpio_free(GPIO_NR_PALMLD_IDE_PWEN);
+	gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios));
 
 
 	return 0;
 	return 0;
 }
 }

+ 49 - 84
drivers/pcmcia/pxa2xx_colibri.c

@@ -34,14 +34,24 @@
 #define	COLIBRI320_DETECT_GPIO	81
 #define	COLIBRI320_DETECT_GPIO	81
 #define	COLIBRI320_READY_GPIO	29
 #define	COLIBRI320_READY_GPIO	29
 
 
-static struct {
-	int	reset_gpio;
-	int	ppen_gpio;
-	int	bvd1_gpio;
-	int	bvd2_gpio;
-	int	detect_gpio;
-	int	ready_gpio;
-} colibri_pcmcia_gpio;
+enum {
+	DETECT = 0,
+	READY = 1,
+	BVD1 = 2,
+	BVD2 = 3,
+	PPEN = 4,
+	RESET = 5,
+};
+
+/* Contents of this array are configured on-the-fly in init function */
+static struct gpio colibri_pcmcia_gpios[] = {
+	{ 0,	GPIOF_IN,	"PCMCIA Detect" },
+	{ 0,	GPIOF_IN,	"PCMCIA Ready" },
+	{ 0,	GPIOF_IN,	"PCMCIA BVD1" },
+	{ 0,	GPIOF_IN,	"PCMCIA BVD2" },
+	{ 0,	GPIOF_INIT_LOW,	"PCMCIA PPEN" },
+	{ 0,	GPIOF_INIT_HIGH,"PCMCIA Reset" },
+};
 
 
 static struct pcmcia_irqs colibri_irqs[] = {
 static struct pcmcia_irqs colibri_irqs[] = {
 	{
 	{
@@ -54,88 +64,42 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 {
 	int ret;
 	int ret;
 
 
-	ret = gpio_request(colibri_pcmcia_gpio.detect_gpio, "DETECT");
+	ret = gpio_request_array(colibri_pcmcia_gpios,
+				ARRAY_SIZE(colibri_pcmcia_gpios));
 	if (ret)
 	if (ret)
 		goto err1;
 		goto err1;
-	ret = gpio_direction_input(colibri_pcmcia_gpio.detect_gpio);
-	if (ret)
-		goto err2;
-
-	ret = gpio_request(colibri_pcmcia_gpio.ready_gpio, "READY");
-	if (ret)
-		goto err2;
-	ret = gpio_direction_input(colibri_pcmcia_gpio.ready_gpio);
-	if (ret)
-		goto err3;
 
 
-	ret = gpio_request(colibri_pcmcia_gpio.bvd1_gpio, "BVD1");
-	if (ret)
-		goto err3;
-	ret = gpio_direction_input(colibri_pcmcia_gpio.bvd1_gpio);
-	if (ret)
-		goto err4;
+	colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio);
+	skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio);
 
 
-	ret = gpio_request(colibri_pcmcia_gpio.bvd2_gpio, "BVD2");
-	if (ret)
-		goto err4;
-	ret = gpio_direction_input(colibri_pcmcia_gpio.bvd2_gpio);
-	if (ret)
-		goto err5;
-
-	ret = gpio_request(colibri_pcmcia_gpio.ppen_gpio, "PPEN");
-	if (ret)
-		goto err5;
-	ret = gpio_direction_output(colibri_pcmcia_gpio.ppen_gpio, 0);
-	if (ret)
-		goto err6;
-
-	ret = gpio_request(colibri_pcmcia_gpio.reset_gpio, "RESET");
-	if (ret)
-		goto err6;
-	ret = gpio_direction_output(colibri_pcmcia_gpio.reset_gpio, 1);
+	ret = soc_pcmcia_request_irqs(skt, colibri_irqs,
+					ARRAY_SIZE(colibri_irqs));
 	if (ret)
 	if (ret)
-		goto err7;
-
-	colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpio.detect_gpio);
-	skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpio.ready_gpio);
+		goto err2;
 
 
-	return soc_pcmcia_request_irqs(skt, colibri_irqs,
-					ARRAY_SIZE(colibri_irqs));
+	return ret;
 
 
-err7:
-	gpio_free(colibri_pcmcia_gpio.detect_gpio);
-err6:
-	gpio_free(colibri_pcmcia_gpio.ready_gpio);
-err5:
-	gpio_free(colibri_pcmcia_gpio.bvd1_gpio);
-err4:
-	gpio_free(colibri_pcmcia_gpio.bvd2_gpio);
-err3:
-	gpio_free(colibri_pcmcia_gpio.reset_gpio);
 err2:
 err2:
-	gpio_free(colibri_pcmcia_gpio.ppen_gpio);
+	gpio_free_array(colibri_pcmcia_gpios,
+			ARRAY_SIZE(colibri_pcmcia_gpios));
 err1:
 err1:
 	return ret;
 	return ret;
 }
 }
 
 
 static void colibri_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 static void colibri_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
 {
-	gpio_free(colibri_pcmcia_gpio.detect_gpio);
-	gpio_free(colibri_pcmcia_gpio.ready_gpio);
-	gpio_free(colibri_pcmcia_gpio.bvd1_gpio);
-	gpio_free(colibri_pcmcia_gpio.bvd2_gpio);
-	gpio_free(colibri_pcmcia_gpio.reset_gpio);
-	gpio_free(colibri_pcmcia_gpio.ppen_gpio);
+	gpio_free_array(colibri_pcmcia_gpios,
+			ARRAY_SIZE(colibri_pcmcia_gpios));
 }
 }
 
 
 static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 					struct pcmcia_state *state)
 					struct pcmcia_state *state)
 {
 {
 
 
-	state->detect = !!gpio_get_value(colibri_pcmcia_gpio.detect_gpio);
-	state->ready  = !!gpio_get_value(colibri_pcmcia_gpio.ready_gpio);
-	state->bvd1   = !!gpio_get_value(colibri_pcmcia_gpio.bvd1_gpio);
-	state->bvd2   = !!gpio_get_value(colibri_pcmcia_gpio.bvd2_gpio);
+	state->detect = !!gpio_get_value(colibri_pcmcia_gpios[DETECT].gpio);
+	state->ready  = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio);
+	state->bvd1   = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio);
+	state->bvd2   = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio);
 	state->wrprot = 0;
 	state->wrprot = 0;
 	state->vs_3v  = 1;
 	state->vs_3v  = 1;
 	state->vs_Xv  = 0;
 	state->vs_Xv  = 0;
@@ -145,9 +109,10 @@ static int
 colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 				const socket_state_t *state)
 				const socket_state_t *state)
 {
 {
-	gpio_set_value(colibri_pcmcia_gpio.ppen_gpio,
+	gpio_set_value(colibri_pcmcia_gpios[PPEN].gpio,
 			!(state->Vcc == 33 && state->Vpp < 50));
 			!(state->Vcc == 33 && state->Vpp < 50));
-	gpio_set_value(colibri_pcmcia_gpio.reset_gpio, state->flags & SS_RESET);
+	gpio_set_value(colibri_pcmcia_gpios[RESET].gpio,
+			state->flags & SS_RESET);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -190,20 +155,20 @@ static int __init colibri_pcmcia_init(void)
 
 
 	/* Colibri PXA270 */
 	/* Colibri PXA270 */
 	if (machine_is_colibri()) {
 	if (machine_is_colibri()) {
-		colibri_pcmcia_gpio.reset_gpio	= COLIBRI270_RESET_GPIO;
-		colibri_pcmcia_gpio.ppen_gpio	= COLIBRI270_PPEN_GPIO;
-		colibri_pcmcia_gpio.bvd1_gpio	= COLIBRI270_BVD1_GPIO;
-		colibri_pcmcia_gpio.bvd2_gpio	= COLIBRI270_BVD2_GPIO;
-		colibri_pcmcia_gpio.detect_gpio	= COLIBRI270_DETECT_GPIO;
-		colibri_pcmcia_gpio.ready_gpio	= COLIBRI270_READY_GPIO;
+		colibri_pcmcia_gpios[RESET].gpio	= COLIBRI270_RESET_GPIO;
+		colibri_pcmcia_gpios[PPEN].gpio		= COLIBRI270_PPEN_GPIO;
+		colibri_pcmcia_gpios[BVD1].gpio		= COLIBRI270_BVD1_GPIO;
+		colibri_pcmcia_gpios[BVD2].gpio		= COLIBRI270_BVD2_GPIO;
+		colibri_pcmcia_gpios[DETECT].gpio	= COLIBRI270_DETECT_GPIO;
+		colibri_pcmcia_gpios[READY].gpio	= COLIBRI270_READY_GPIO;
 	/* Colibri PXA320 */
 	/* Colibri PXA320 */
 	} else if (machine_is_colibri320()) {
 	} else if (machine_is_colibri320()) {
-		colibri_pcmcia_gpio.reset_gpio	= COLIBRI320_RESET_GPIO;
-		colibri_pcmcia_gpio.ppen_gpio	= COLIBRI320_PPEN_GPIO;
-		colibri_pcmcia_gpio.bvd1_gpio	= COLIBRI320_BVD1_GPIO;
-		colibri_pcmcia_gpio.bvd2_gpio	= COLIBRI320_BVD2_GPIO;
-		colibri_pcmcia_gpio.detect_gpio	= COLIBRI320_DETECT_GPIO;
-		colibri_pcmcia_gpio.ready_gpio	= COLIBRI320_READY_GPIO;
+		colibri_pcmcia_gpios[RESET].gpio	= COLIBRI320_RESET_GPIO;
+		colibri_pcmcia_gpios[PPEN].gpio		= COLIBRI320_PPEN_GPIO;
+		colibri_pcmcia_gpios[BVD1].gpio		= COLIBRI320_BVD1_GPIO;
+		colibri_pcmcia_gpios[BVD2].gpio		= COLIBRI320_BVD2_GPIO;
+		colibri_pcmcia_gpios[DETECT].gpio	= COLIBRI320_DETECT_GPIO;
+		colibri_pcmcia_gpios[READY].gpio	= COLIBRI320_READY_GPIO;
 	}
 	}
 
 
 	ret = platform_device_add_data(colibri_pcmcia_device,
 	ret = platform_device_add_data(colibri_pcmcia_device,

+ 10 - 32
drivers/pcmcia/pxa2xx_palmld.c

@@ -4,7 +4,7 @@
  * Driver for Palm LifeDrive PCMCIA
  * Driver for Palm LifeDrive PCMCIA
  *
  *
  * Copyright (C) 2006 Alex Osborne <ato@meshy.org>
  * Copyright (C) 2006 Alex Osborne <ato@meshy.org>
- * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com>
  *
  *
  * This program is free software; you can redistribute it and/or modify
  * 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
  * it under the terms of the GNU General Public License version 2 as
@@ -20,49 +20,27 @@
 #include <mach/palmld.h>
 #include <mach/palmld.h>
 #include "soc_common.h"
 #include "soc_common.h"
 
 
+static struct gpio palmld_pcmcia_gpios[] = {
+	{ GPIO_NR_PALMLD_PCMCIA_POWER,	GPIOF_INIT_LOW,	"PCMCIA Power" },
+	{ GPIO_NR_PALMLD_PCMCIA_RESET,	GPIOF_INIT_HIGH,"PCMCIA Reset" },
+	{ GPIO_NR_PALMLD_PCMCIA_READY,	GPIOF_IN,	"PCMCIA Ready" },
+};
+
 static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 {
 	int ret;
 	int ret;
 
 
-	ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_POWER, "PCMCIA PWR");
-	if (ret)
-		goto err1;
-	ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_POWER, 0);
-	if (ret)
-		goto err2;
-
-	ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_RESET, "PCMCIA RST");
-	if (ret)
-		goto err2;
-	ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_RESET, 1);
-	if (ret)
-		goto err3;
-
-	ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_READY, "PCMCIA RDY");
-	if (ret)
-		goto err3;
-	ret = gpio_direction_input(GPIO_NR_PALMLD_PCMCIA_READY);
-	if (ret)
-		goto err4;
+	ret = gpio_request_array(palmld_pcmcia_gpios,
+				ARRAY_SIZE(palmld_pcmcia_gpios));
 
 
 	skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
 	skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
-	return 0;
 
 
-err4:
-	gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
-err3:
-	gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
-err2:
-	gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
-err1:
 	return ret;
 	return ret;
 }
 }
 
 
 static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
 {
-	gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
-	gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
-	gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
+	gpio_free_array(palmld_pcmcia_gpios, ARRAY_SIZE(palmld_pcmcia_gpios));
 }
 }
 
 
 static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,

+ 13 - 62
drivers/pcmcia/pxa2xx_palmtc.c

@@ -4,7 +4,7 @@
  * Driver for Palm Tungsten|C PCMCIA
  * Driver for Palm Tungsten|C PCMCIA
  *
  *
  * Copyright (C) 2008 Alex Osborne <ato@meshy.org>
  * Copyright (C) 2008 Alex Osborne <ato@meshy.org>
- * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2009-2011 Marek Vasut <marek.vasut@gmail.com>
  *
  *
  * This program is free software; you can redistribute it and/or modify
  * 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
  * it under the terms of the GNU General Public License version 2 as
@@ -21,79 +21,30 @@
 #include <mach/palmtc.h>
 #include <mach/palmtc.h>
 #include "soc_common.h"
 #include "soc_common.h"
 
 
+static struct gpio palmtc_pcmcia_gpios[] = {
+	{ GPIO_NR_PALMTC_PCMCIA_POWER1,	GPIOF_INIT_LOW,	"PCMCIA Power 1" },
+	{ GPIO_NR_PALMTC_PCMCIA_POWER2,	GPIOF_INIT_LOW,	"PCMCIA Power 2" },
+	{ GPIO_NR_PALMTC_PCMCIA_POWER3,	GPIOF_INIT_LOW,	"PCMCIA Power 3" },
+	{ GPIO_NR_PALMTC_PCMCIA_RESET,	GPIOF_INIT_HIGH,"PCMCIA Reset" },
+	{ GPIO_NR_PALMTC_PCMCIA_READY,	GPIOF_IN,	"PCMCIA Ready" },
+	{ GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN,	"PCMCIA Power Ready" },
+};
+
 static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 {
 	int ret;
 	int ret;
 
 
-	ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER1, "PCMCIA PWR1");
-	if (ret)
-		goto err1;
-	ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER1, 0);
-	if (ret)
-		goto err2;
-
-	ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER2, "PCMCIA PWR2");
-	if (ret)
-		goto err2;
-	ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER2, 0);
-	if (ret)
-		goto err3;
-
-	ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER3, "PCMCIA PWR3");
-	if (ret)
-		goto err3;
-	ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER3, 0);
-	if (ret)
-		goto err4;
-
-	ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_RESET, "PCMCIA RST");
-	if (ret)
-		goto err4;
-	ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_RESET, 1);
-	if (ret)
-		goto err5;
-
-	ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_READY, "PCMCIA RDY");
-	if (ret)
-		goto err5;
-	ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_READY);
-	if (ret)
-		goto err6;
-
-	ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_PWRREADY, "PCMCIA PWRRDY");
-	if (ret)
-		goto err6;
-	ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_PWRREADY);
-	if (ret)
-		goto err7;
+	ret = gpio_request_array(palmtc_pcmcia_gpios,
+				ARRAY_SIZE(palmtc_pcmcia_gpios));
 
 
 	skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY);
 	skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY);
-	return 0;
 
 
-err7:
-	gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY);
-err6:
-	gpio_free(GPIO_NR_PALMTC_PCMCIA_READY);
-err5:
-	gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET);
-err4:
-	gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3);
-err3:
-	gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2);
-err2:
-	gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1);
-err1:
 	return ret;
 	return ret;
 }
 }
 
 
 static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
 {
-	gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY);
-	gpio_free(GPIO_NR_PALMTC_PCMCIA_READY);
-	gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET);
-	gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3);
-	gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2);
-	gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1);
+	gpio_free_array(palmtc_pcmcia_gpios, ARRAY_SIZE(palmtc_pcmcia_gpios));
 }
 }
 
 
 static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt,

+ 12 - 45
drivers/pcmcia/pxa2xx_palmtx.c

@@ -3,7 +3,7 @@
  *
  *
  * Driver for Palm T|X PCMCIA
  * Driver for Palm T|X PCMCIA
  *
  *
- * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com>
  *
  *
  * This program is free software; you can redistribute it and/or modify
  * 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
  * it under the terms of the GNU General Public License version 2 as
@@ -13,67 +13,34 @@
 
 
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
 
 
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
-
-#include <mach/gpio.h>
 #include <mach/palmtx.h>
 #include <mach/palmtx.h>
-
 #include "soc_common.h"
 #include "soc_common.h"
 
 
+static struct gpio palmtx_pcmcia_gpios[] = {
+	{ GPIO_NR_PALMTX_PCMCIA_POWER1,	GPIOF_INIT_LOW,	"PCMCIA Power 1" },
+	{ GPIO_NR_PALMTX_PCMCIA_POWER2,	GPIOF_INIT_LOW,	"PCMCIA Power 2" },
+	{ GPIO_NR_PALMTX_PCMCIA_RESET,	GPIOF_INIT_HIGH,"PCMCIA Reset" },
+	{ GPIO_NR_PALMTX_PCMCIA_READY,	GPIOF_IN,	"PCMCIA Ready" },
+};
+
 static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 {
 	int ret;
 	int ret;
 
 
-	ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER1, "PCMCIA PWR1");
-	if (ret)
-		goto err1;
-	ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER1, 0);
-	if (ret)
-		goto err2;
-
-	ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER2, "PCMCIA PWR2");
-	if (ret)
-		goto err2;
-	ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER2, 0);
-	if (ret)
-		goto err3;
-
-	ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_RESET, "PCMCIA RST");
-	if (ret)
-		goto err3;
-	ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_RESET, 1);
-	if (ret)
-		goto err4;
-
-	ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_READY, "PCMCIA RDY");
-	if (ret)
-		goto err4;
-	ret = gpio_direction_input(GPIO_NR_PALMTX_PCMCIA_READY);
-	if (ret)
-		goto err5;
+	ret = gpio_request_array(palmtx_pcmcia_gpios,
+				ARRAY_SIZE(palmtx_pcmcia_gpios));
 
 
 	skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
 	skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
-	return 0;
 
 
-err5:
-	gpio_free(GPIO_NR_PALMTX_PCMCIA_READY);
-err4:
-	gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET);
-err3:
-	gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2);
-err2:
-	gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1);
-err1:
 	return ret;
 	return ret;
 }
 }
 
 
 static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
 {
-	gpio_free(GPIO_NR_PALMTX_PCMCIA_READY);
-	gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET);
-	gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2);
-	gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1);
+	gpio_free_array(palmtx_pcmcia_gpios, ARRAY_SIZE(palmtx_pcmcia_gpios));
 }
 }
 
 
 static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt,

+ 30 - 80
drivers/pcmcia/pxa2xx_vpac270.c

@@ -3,8 +3,7 @@
  *
  *
  * Driver for Voipac PXA270 PCMCIA and CF sockets
  * Driver for Voipac PXA270 PCMCIA and CF sockets
  *
  *
- * Copyright (C) 2010
- * Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com>
  *
  *
  * This program is free software; you can redistribute it and/or modify
  * 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
  * it under the terms of the GNU General Public License version 2 as
@@ -22,6 +21,19 @@
 
 
 #include "soc_common.h"
 #include "soc_common.h"
 
 
+static struct gpio vpac270_pcmcia_gpios[] = {
+	{ GPIO84_VPAC270_PCMCIA_CD,	GPIOF_IN,	"PCMCIA Card Detect" },
+	{ GPIO35_VPAC270_PCMCIA_RDY,	GPIOF_IN,	"PCMCIA Ready" },
+	{ GPIO107_VPAC270_PCMCIA_PPEN,	GPIOF_INIT_LOW,	"PCMCIA PPEN" },
+	{ GPIO11_VPAC270_PCMCIA_RESET,	GPIOF_INIT_LOW,	"PCMCIA Reset" },
+};
+
+static struct gpio vpac270_cf_gpios[] = {
+	{ GPIO17_VPAC270_CF_CD,		GPIOF_IN,	"CF Card Detect" },
+	{ GPIO12_VPAC270_CF_RDY,	GPIOF_IN,	"CF Ready" },
+	{ GPIO16_VPAC270_CF_RESET,	GPIOF_INIT_LOW,	"CF Reset" },
+};
+
 static struct pcmcia_irqs cd_irqs[] = {
 static struct pcmcia_irqs cd_irqs[] = {
 	{
 	{
 		.sock = 0,
 		.sock = 0,
@@ -40,96 +52,34 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 	int ret;
 	int ret;
 
 
 	if (skt->nr == 0) {
 	if (skt->nr == 0) {
-		ret = gpio_request(GPIO84_VPAC270_PCMCIA_CD, "PCMCIA CD");
-		if (ret)
-			goto err1;
-		ret = gpio_direction_input(GPIO84_VPAC270_PCMCIA_CD);
-		if (ret)
-			goto err2;
-
-		ret = gpio_request(GPIO35_VPAC270_PCMCIA_RDY, "PCMCIA RDY");
-		if (ret)
-			goto err2;
-		ret = gpio_direction_input(GPIO35_VPAC270_PCMCIA_RDY);
-		if (ret)
-			goto err3;
-
-		ret = gpio_request(GPIO107_VPAC270_PCMCIA_PPEN, "PCMCIA PPEN");
-		if (ret)
-			goto err3;
-		ret = gpio_direction_output(GPIO107_VPAC270_PCMCIA_PPEN, 0);
-		if (ret)
-			goto err4;
-
-		ret = gpio_request(GPIO11_VPAC270_PCMCIA_RESET, "PCMCIA RESET");
-		if (ret)
-			goto err4;
-		ret = gpio_direction_output(GPIO11_VPAC270_PCMCIA_RESET, 0);
-		if (ret)
-			goto err5;
+		ret = gpio_request_array(vpac270_pcmcia_gpios,
+				ARRAY_SIZE(vpac270_pcmcia_gpios));
 
 
 		skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY);
 		skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY);
 
 
-		return soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1);
-
-err5:
-		gpio_free(GPIO11_VPAC270_PCMCIA_RESET);
-err4:
-		gpio_free(GPIO107_VPAC270_PCMCIA_PPEN);
-err3:
-		gpio_free(GPIO35_VPAC270_PCMCIA_RDY);
-err2:
-		gpio_free(GPIO84_VPAC270_PCMCIA_CD);
-err1:
-		return ret;
-
+		if (!ret)
+			ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1);
 	} else {
 	} else {
-		ret = gpio_request(GPIO17_VPAC270_CF_CD, "CF CD");
-		if (ret)
-			goto err6;
-		ret = gpio_direction_input(GPIO17_VPAC270_CF_CD);
-		if (ret)
-			goto err7;
-
-		ret = gpio_request(GPIO12_VPAC270_CF_RDY, "CF RDY");
-		if (ret)
-			goto err7;
-		ret = gpio_direction_input(GPIO12_VPAC270_CF_RDY);
-		if (ret)
-			goto err8;
-
-		ret = gpio_request(GPIO16_VPAC270_CF_RESET, "CF RESET");
-		if (ret)
-			goto err8;
-		ret = gpio_direction_output(GPIO16_VPAC270_CF_RESET, 0);
-		if (ret)
-			goto err9;
+		ret = gpio_request_array(vpac270_cf_gpios,
+				ARRAY_SIZE(vpac270_cf_gpios));
 
 
 		skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY);
 		skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY);
 
 
-		return soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1);
-
-err9:
-		gpio_free(GPIO16_VPAC270_CF_RESET);
-err8:
-		gpio_free(GPIO12_VPAC270_CF_RDY);
-err7:
-		gpio_free(GPIO17_VPAC270_CF_CD);
-err6:
-		return ret;
-
+		if (!ret)
+			ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1);
 	}
 	}
+
+	return ret;
 }
 }
 
 
 static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
 {
-	gpio_free(GPIO11_VPAC270_PCMCIA_RESET);
-	gpio_free(GPIO107_VPAC270_PCMCIA_PPEN);
-	gpio_free(GPIO35_VPAC270_PCMCIA_RDY);
-	gpio_free(GPIO84_VPAC270_PCMCIA_CD);
-	gpio_free(GPIO16_VPAC270_CF_RESET);
-	gpio_free(GPIO12_VPAC270_CF_RDY);
-	gpio_free(GPIO17_VPAC270_CF_CD);
+	if (skt->nr == 0)
+		gpio_request_array(vpac270_pcmcia_gpios,
+					ARRAY_SIZE(vpac270_pcmcia_gpios));
+	else
+		gpio_request_array(vpac270_cf_gpios,
+					ARRAY_SIZE(vpac270_cf_gpios));
 }
 }
 
 
 static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,

+ 7 - 69
drivers/usb/gadget/pxa25x_udc.c

@@ -139,24 +139,6 @@ static const char ep0name [] = "ep0";
 static void pxa25x_ep_fifo_flush (struct usb_ep *ep);
 static void pxa25x_ep_fifo_flush (struct usb_ep *ep);
 static void nuke (struct pxa25x_ep *, int status);
 static void nuke (struct pxa25x_ep *, int status);
 
 
-/* one GPIO should be used to detect VBUS from the host */
-static int is_vbus_present(void)
-{
-	struct pxa2xx_udc_mach_info		*mach = the_controller->mach;
-
-	if (gpio_is_valid(mach->gpio_vbus)) {
-		int value = gpio_get_value(mach->gpio_vbus);
-
-		if (mach->gpio_vbus_inverted)
-			return !value;
-		else
-			return !!value;
-	}
-	if (mach->udc_is_connected)
-		return mach->udc_is_connected();
-	return 1;
-}
-
 /* one GPIO should control a D+ pullup, so host sees this device (or not) */
 /* one GPIO should control a D+ pullup, so host sees this device (or not) */
 static void pullup_off(void)
 static void pullup_off(void)
 {
 {
@@ -1055,7 +1037,7 @@ udc_seq_show(struct seq_file *m, void *_d)
 		"%s version: %s\nGadget driver: %s\nHost %s\n\n",
 		"%s version: %s\nGadget driver: %s\nHost %s\n\n",
 		driver_name, DRIVER_VERSION SIZE_STR "(pio)",
 		driver_name, DRIVER_VERSION SIZE_STR "(pio)",
 		dev->driver ? dev->driver->driver.name : "(none)",
 		dev->driver ? dev->driver->driver.name : "(none)",
-		is_vbus_present() ? "full speed" : "disconnected");
+		dev->gadget.speed == USB_SPEED_FULL ? "full speed" : "disconnected");
 
 
 	/* registers for device and ep0 */
 	/* registers for device and ep0 */
 	seq_printf(m,
 	seq_printf(m,
@@ -1094,7 +1076,7 @@ udc_seq_show(struct seq_file *m, void *_d)
 			(tmp & UDCCFR_ACM) ? " acm" : "");
 			(tmp & UDCCFR_ACM) ? " acm" : "");
 	}
 	}
 
 
-	if (!is_vbus_present() || !dev->driver)
+	if (dev->gadget.speed != USB_SPEED_FULL || !dev->driver)
 		goto done;
 		goto done;
 
 
 	seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n",
 	seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n",
@@ -1435,14 +1417,6 @@ lubbock_vbus_irq(int irq, void *_dev)
 
 
 #endif
 #endif
 
 
-static irqreturn_t udc_vbus_irq(int irq, void *_dev)
-{
-	struct pxa25x_udc	*dev = _dev;
-
-	pxa25x_udc_vbus_session(&dev->gadget, is_vbus_present());
-	return IRQ_HANDLED;
-}
-
 
 
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
 
 
@@ -1766,12 +1740,9 @@ pxa25x_udc_irq(int irq, void *_dev)
 		if (unlikely(udccr & UDCCR_SUSIR)) {
 		if (unlikely(udccr & UDCCR_SUSIR)) {
 			udc_ack_int_UDCCR(UDCCR_SUSIR);
 			udc_ack_int_UDCCR(UDCCR_SUSIR);
 			handled = 1;
 			handled = 1;
-			DBG(DBG_VERBOSE, "USB suspend%s\n", is_vbus_present()
-				? "" : "+disconnect");
+			DBG(DBG_VERBOSE, "USB suspend\n");
 
 
-			if (!is_vbus_present())
-				stop_activity(dev, dev->driver);
-			else if (dev->gadget.speed != USB_SPEED_UNKNOWN
+			if (dev->gadget.speed != USB_SPEED_UNKNOWN
 					&& dev->driver
 					&& dev->driver
 					&& dev->driver->suspend)
 					&& dev->driver->suspend)
 				dev->driver->suspend(&dev->gadget);
 				dev->driver->suspend(&dev->gadget);
@@ -1786,8 +1757,7 @@ pxa25x_udc_irq(int irq, void *_dev)
 
 
 			if (dev->gadget.speed != USB_SPEED_UNKNOWN
 			if (dev->gadget.speed != USB_SPEED_UNKNOWN
 					&& dev->driver
 					&& dev->driver
-					&& dev->driver->resume
-					&& is_vbus_present())
+					&& dev->driver->resume)
 				dev->driver->resume(&dev->gadget);
 				dev->driver->resume(&dev->gadget);
 		}
 		}
 
 
@@ -2137,7 +2107,7 @@ static struct pxa25x_udc memory = {
 static int __init pxa25x_udc_probe(struct platform_device *pdev)
 static int __init pxa25x_udc_probe(struct platform_device *pdev)
 {
 {
 	struct pxa25x_udc *dev = &memory;
 	struct pxa25x_udc *dev = &memory;
-	int retval, vbus_irq, irq;
+	int retval, irq;
 	u32 chiprev;
 	u32 chiprev;
 
 
 	/* insist on Intel/ARM/XScale */
 	/* insist on Intel/ARM/XScale */
@@ -2199,19 +2169,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
 
 
 	dev->transceiver = otg_get_transceiver();
 	dev->transceiver = otg_get_transceiver();
 
 
-	if (gpio_is_valid(dev->mach->gpio_vbus)) {
-		if ((retval = gpio_request(dev->mach->gpio_vbus,
-				"pxa25x_udc GPIO VBUS"))) {
-			dev_dbg(&pdev->dev,
-				"can't get vbus gpio %d, err: %d\n",
-				dev->mach->gpio_vbus, retval);
-			goto err_gpio_vbus;
-		}
-		gpio_direction_input(dev->mach->gpio_vbus);
-		vbus_irq = gpio_to_irq(dev->mach->gpio_vbus);
-	} else
-		vbus_irq = 0;
-
 	if (gpio_is_valid(dev->mach->gpio_pullup)) {
 	if (gpio_is_valid(dev->mach->gpio_pullup)) {
 		if ((retval = gpio_request(dev->mach->gpio_pullup,
 		if ((retval = gpio_request(dev->mach->gpio_pullup,
 				"pca25x_udc GPIO PULLUP"))) {
 				"pca25x_udc GPIO PULLUP"))) {
@@ -2237,7 +2194,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
 	udc_disable(dev);
 	udc_disable(dev);
 	udc_reinit(dev);
 	udc_reinit(dev);
 
 
-	dev->vbus = !!is_vbus_present();
+	dev->vbus = 0;
 
 
 	/* irq setup after old hardware state is cleaned up */
 	/* irq setup after old hardware state is cleaned up */
 	retval = request_irq(irq, pxa25x_udc_irq,
 	retval = request_irq(irq, pxa25x_udc_irq,
@@ -2273,22 +2230,10 @@ lubbock_fail0:
 		}
 		}
 	} else
 	} else
 #endif
 #endif
-	if (vbus_irq) {
-		retval = request_irq(vbus_irq, udc_vbus_irq,
-				IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
-				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-				driver_name, dev);
-		if (retval != 0) {
-			pr_err("%s: can't get irq %i, err %d\n",
-				driver_name, vbus_irq, retval);
-			goto err_vbus_irq;
-		}
-	}
 	create_debug_files(dev);
 	create_debug_files(dev);
 
 
 	return 0;
 	return 0;
 
 
- err_vbus_irq:
 #ifdef	CONFIG_ARCH_LUBBOCK
 #ifdef	CONFIG_ARCH_LUBBOCK
 	free_irq(LUBBOCK_USB_DISC_IRQ, dev);
 	free_irq(LUBBOCK_USB_DISC_IRQ, dev);
  err_irq_lub:
  err_irq_lub:
@@ -2298,9 +2243,6 @@ lubbock_fail0:
 	if (gpio_is_valid(dev->mach->gpio_pullup))
 	if (gpio_is_valid(dev->mach->gpio_pullup))
 		gpio_free(dev->mach->gpio_pullup);
 		gpio_free(dev->mach->gpio_pullup);
  err_gpio_pullup:
  err_gpio_pullup:
-	if (gpio_is_valid(dev->mach->gpio_vbus))
-		gpio_free(dev->mach->gpio_vbus);
- err_gpio_vbus:
 	if (dev->transceiver) {
 	if (dev->transceiver) {
 		otg_put_transceiver(dev->transceiver);
 		otg_put_transceiver(dev->transceiver);
 		dev->transceiver = NULL;
 		dev->transceiver = NULL;
@@ -2337,10 +2279,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)
 		free_irq(LUBBOCK_USB_IRQ, dev);
 		free_irq(LUBBOCK_USB_IRQ, dev);
 	}
 	}
 #endif
 #endif
-	if (gpio_is_valid(dev->mach->gpio_vbus)) {
-		free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev);
-		gpio_free(dev->mach->gpio_vbus);
-	}
 	if (gpio_is_valid(dev->mach->gpio_pullup))
 	if (gpio_is_valid(dev->mach->gpio_pullup))
 		gpio_free(dev->mach->gpio_pullup);
 		gpio_free(dev->mach->gpio_pullup);
 
 

+ 89 - 47
drivers/video/pxafb.c

@@ -627,7 +627,12 @@ static void overlay1fb_enable(struct pxafb_layer *ofb)
 
 
 static void overlay1fb_disable(struct pxafb_layer *ofb)
 static void overlay1fb_disable(struct pxafb_layer *ofb)
 {
 {
-	uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
+	uint32_t lccr5;
+
+	if (!(lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN))
+		return;
+
+	lccr5 = lcd_readl(ofb->fbi, LCCR5);
 
 
 	lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
 	lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
 
 
@@ -685,7 +690,12 @@ static void overlay2fb_enable(struct pxafb_layer *ofb)
 
 
 static void overlay2fb_disable(struct pxafb_layer *ofb)
 static void overlay2fb_disable(struct pxafb_layer *ofb)
 {
 {
-	uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
+	uint32_t lccr5;
+
+	if (!(lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN))
+		return;
+
+	lccr5 = lcd_readl(ofb->fbi, LCCR5);
 
 
 	lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
 	lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
 
 
@@ -720,12 +730,10 @@ static int overlayfb_open(struct fb_info *info, int user)
 	if (user == 0)
 	if (user == 0)
 		return -ENODEV;
 		return -ENODEV;
 
 
-	/* allow only one user at a time */
-	if (atomic_inc_and_test(&ofb->usage))
-		return -EBUSY;
+	if (ofb->usage++ == 0)
+		/* unblank the base framebuffer */
+		fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
 
 
-	/* unblank the base framebuffer */
-	fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -733,12 +741,15 @@ static int overlayfb_release(struct fb_info *info, int user)
 {
 {
 	struct pxafb_layer *ofb = (struct pxafb_layer*) info;
 	struct pxafb_layer *ofb = (struct pxafb_layer*) info;
 
 
-	atomic_dec(&ofb->usage);
-	ofb->ops->disable(ofb);
+	if (ofb->usage == 1) {
+		ofb->ops->disable(ofb);
+		ofb->fb.var.height	= -1;
+		ofb->fb.var.width	= -1;
+		ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0;
+		ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0;
 
 
-	free_pages_exact(ofb->video_mem, ofb->video_mem_size);
-	ofb->video_mem = NULL;
-	ofb->video_mem_size = 0;
+		ofb->usage--;
+	}
 	return 0;
 	return 0;
 }
 }
 
 
@@ -750,7 +761,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var,
 	int xpos, ypos, pfor, bpp;
 	int xpos, ypos, pfor, bpp;
 
 
 	xpos = NONSTD_TO_XPOS(var->nonstd);
 	xpos = NONSTD_TO_XPOS(var->nonstd);
-	ypos = NONSTD_TO_XPOS(var->nonstd);
+	ypos = NONSTD_TO_YPOS(var->nonstd);
 	pfor = NONSTD_TO_PFOR(var->nonstd);
 	pfor = NONSTD_TO_PFOR(var->nonstd);
 
 
 	bpp = pxafb_var_to_bpp(var);
 	bpp = pxafb_var_to_bpp(var);
@@ -794,7 +805,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var,
 	return 0;
 	return 0;
 }
 }
 
 
-static int overlayfb_map_video_memory(struct pxafb_layer *ofb)
+static int overlayfb_check_video_memory(struct pxafb_layer *ofb)
 {
 {
 	struct fb_var_screeninfo *var = &ofb->fb.var;
 	struct fb_var_screeninfo *var = &ofb->fb.var;
 	int pfor = NONSTD_TO_PFOR(var->nonstd);
 	int pfor = NONSTD_TO_PFOR(var->nonstd);
@@ -812,27 +823,11 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb)
 
 
 	size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual);
 	size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual);
 
 
-	/* don't re-allocate if the original video memory is enough */
 	if (ofb->video_mem) {
 	if (ofb->video_mem) {
 		if (ofb->video_mem_size >= size)
 		if (ofb->video_mem_size >= size)
 			return 0;
 			return 0;
-
-		free_pages_exact(ofb->video_mem, ofb->video_mem_size);
 	}
 	}
-
-	ofb->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
-	if (ofb->video_mem == NULL)
-		return -ENOMEM;
-
-	ofb->video_mem_phys = virt_to_phys(ofb->video_mem);
-	ofb->video_mem_size = size;
-
-	mutex_lock(&ofb->fb.mm_lock);
-	ofb->fb.fix.smem_start	= ofb->video_mem_phys;
-	ofb->fb.fix.smem_len	= ofb->fb.fix.line_length * var->yres_virtual;
-	mutex_unlock(&ofb->fb.mm_lock);
-	ofb->fb.screen_base	= ofb->video_mem;
-	return 0;
+	return -EINVAL;
 }
 }
 
 
 static int overlayfb_set_par(struct fb_info *info)
 static int overlayfb_set_par(struct fb_info *info)
@@ -841,13 +836,13 @@ static int overlayfb_set_par(struct fb_info *info)
 	struct fb_var_screeninfo *var = &info->var;
 	struct fb_var_screeninfo *var = &info->var;
 	int xpos, ypos, pfor, bpp, ret;
 	int xpos, ypos, pfor, bpp, ret;
 
 
-	ret = overlayfb_map_video_memory(ofb);
+	ret = overlayfb_check_video_memory(ofb);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
 	bpp  = pxafb_var_to_bpp(var);
 	bpp  = pxafb_var_to_bpp(var);
 	xpos = NONSTD_TO_XPOS(var->nonstd);
 	xpos = NONSTD_TO_XPOS(var->nonstd);
-	ypos = NONSTD_TO_XPOS(var->nonstd);
+	ypos = NONSTD_TO_YPOS(var->nonstd);
 	pfor = NONSTD_TO_PFOR(var->nonstd);
 	pfor = NONSTD_TO_PFOR(var->nonstd);
 
 
 	ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) |
 	ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) |
@@ -891,7 +886,7 @@ static void __devinit init_pxafb_overlay(struct pxafb_info *fbi,
 
 
 	ofb->id = id;
 	ofb->id = id;
 	ofb->ops = &ofb_ops[id];
 	ofb->ops = &ofb_ops[id];
-	atomic_set(&ofb->usage, 0);
+	ofb->usage = 0;
 	ofb->fbi = fbi;
 	ofb->fbi = fbi;
 	init_completion(&ofb->branch_done);
 	init_completion(&ofb->branch_done);
 }
 }
@@ -904,29 +899,60 @@ static inline int pxafb_overlay_supported(void)
 	return 0;
 	return 0;
 }
 }
 
 
-static int __devinit pxafb_overlay_init(struct pxafb_info *fbi)
+static int __devinit pxafb_overlay_map_video_memory(struct pxafb_info *pxafb,
+	struct pxafb_layer *ofb)
+{
+	/* We assume that user will use at most video_mem_size for overlay fb,
+	 * anyway, it's useless to use 16bpp main plane and 24bpp overlay
+	 */
+	ofb->video_mem = alloc_pages_exact(PAGE_ALIGN(pxafb->video_mem_size),
+		GFP_KERNEL | __GFP_ZERO);
+	if (ofb->video_mem == NULL)
+		return -ENOMEM;
+
+	ofb->video_mem_phys = virt_to_phys(ofb->video_mem);
+	ofb->video_mem_size = PAGE_ALIGN(pxafb->video_mem_size);
+
+	mutex_lock(&ofb->fb.mm_lock);
+	ofb->fb.fix.smem_start	= ofb->video_mem_phys;
+	ofb->fb.fix.smem_len	= pxafb->video_mem_size;
+	mutex_unlock(&ofb->fb.mm_lock);
+
+	ofb->fb.screen_base	= ofb->video_mem;
+
+	return 0;
+}
+
+static void __devinit pxafb_overlay_init(struct pxafb_info *fbi)
 {
 {
 	int i, ret;
 	int i, ret;
 
 
 	if (!pxafb_overlay_supported())
 	if (!pxafb_overlay_supported())
-		return 0;
+		return;
 
 
 	for (i = 0; i < 2; i++) {
 	for (i = 0; i < 2; i++) {
-		init_pxafb_overlay(fbi, &fbi->overlay[i], i);
-		ret = register_framebuffer(&fbi->overlay[i].fb);
+		struct pxafb_layer *ofb = &fbi->overlay[i];
+		init_pxafb_overlay(fbi, ofb, i);
+		ret = register_framebuffer(&ofb->fb);
 		if (ret) {
 		if (ret) {
 			dev_err(fbi->dev, "failed to register overlay %d\n", i);
 			dev_err(fbi->dev, "failed to register overlay %d\n", i);
-			return ret;
+			continue;
 		}
 		}
+		ret = pxafb_overlay_map_video_memory(fbi, ofb);
+		if (ret) {
+			dev_err(fbi->dev,
+				"failed to map video memory for overlay %d\n",
+				i);
+			unregister_framebuffer(&ofb->fb);
+			continue;
+		}
+		ofb->registered = 1;
 	}
 	}
 
 
 	/* mask all IU/BS/EOF/SOF interrupts */
 	/* mask all IU/BS/EOF/SOF interrupts */
 	lcd_writel(fbi, LCCR5, ~0);
 	lcd_writel(fbi, LCCR5, ~0);
 
 
-	/* place overlay(s) on top of base */
-	fbi->lccr0 |= LCCR0_OUC;
 	pr_info("PXA Overlay driver loaded successfully!\n");
 	pr_info("PXA Overlay driver loaded successfully!\n");
-	return 0;
 }
 }
 
 
 static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi)
 static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi)
@@ -936,8 +962,15 @@ static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi)
 	if (!pxafb_overlay_supported())
 	if (!pxafb_overlay_supported())
 		return;
 		return;
 
 
-	for (i = 0; i < 2; i++)
-		unregister_framebuffer(&fbi->overlay[i].fb);
+	for (i = 0; i < 2; i++) {
+		struct pxafb_layer *ofb = &fbi->overlay[i];
+		if (ofb->registered) {
+			if (ofb->video_mem)
+				free_pages_exact(ofb->video_mem,
+					ofb->video_mem_size);
+			unregister_framebuffer(&ofb->fb);
+		}
+	}
 }
 }
 #else
 #else
 static inline void pxafb_overlay_init(struct pxafb_info *fbi) {}
 static inline void pxafb_overlay_init(struct pxafb_info *fbi) {}
@@ -1368,7 +1401,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
 	    (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||
 	    (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||
 	    (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) ||
 	    (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) ||
 	    (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) ||
 	    (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) ||
-	    (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))
+	    ((fbi->lccr0 & LCCR0_SDS) &&
+	    (lcd_readl(fbi, FDADR1) != fbi->fdadr[1])))
 		pxafb_schedule_work(fbi, C_REENABLE);
 		pxafb_schedule_work(fbi, C_REENABLE);
 
 
 	return 0;
 	return 0;
@@ -1420,7 +1454,8 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
 	lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
 	lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
 
 
 	lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
 	lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
-	lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
+	if (fbi->lccr0 & LCCR0_SDS)
+		lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
 	lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
 	lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
 }
 }
 
 
@@ -1613,7 +1648,8 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data)
 
 
 	switch (val) {
 	switch (val) {
 	case CPUFREQ_PRECHANGE:
 	case CPUFREQ_PRECHANGE:
-		set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE);
+		if (!fbi->overlay[0].usage && !fbi->overlay[1].usage)
+			set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE);
 		break;
 		break;
 
 
 	case CPUFREQ_POSTCHANGE:
 	case CPUFREQ_POSTCHANGE:
@@ -1806,6 +1842,12 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
 
 
 	pxafb_decode_mach_info(fbi, inf);
 	pxafb_decode_mach_info(fbi, inf);
 
 
+#ifdef CONFIG_FB_PXA_OVERLAY
+	/* place overlay(s) on top of base */
+	if (pxafb_overlay_supported())
+		fbi->lccr0 |= LCCR0_OUC;
+#endif
+
 	init_waitqueue_head(&fbi->ctrlr_wait);
 	init_waitqueue_head(&fbi->ctrlr_wait);
 	INIT_WORK(&fbi->task, pxafb_task);
 	INIT_WORK(&fbi->task, pxafb_task);
 	mutex_init(&fbi->ctrlr_lock);
 	mutex_init(&fbi->ctrlr_lock);

Some files were not shown because too many files changed in this diff