浏览代码

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

* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (35 commits)
  ARM: Update (and cut down) mach-types
  ARM: 6771/1: vexpress: add support for multiple core tiles
  ARM: 6797/1: hw_breakpoint: Fix newlines in WARNings
  ARM: 6751/1: vexpress: select applicable errata workarounds in Kconfig
  ARM: 6753/1: omap4: Enable ARM local timers with OMAP4430 es1.0 exception
  ARM: 6759/1: smp: Select local timers vs broadcast timer support runtime
  ARM: pgtable: add pud-level code
  ARM: 6673/1: LPAE: use phys_addr_t instead of unsigned long for start of membanks
  ARM: Use long long format when printing meminfo physical addresses
  ARM: integrator: add Integrator/CP sched_clock support
  ARM: realview/vexpress: consolidate SMP bringup code
  ARM: realview/vexpress: consolidate localtimer support
  ARM: integrator/versatile: consolidate FPGA IRQ handling code
  ARM: rationalize versatile family Kconfig/Makefile
  ARM: realview: remove old AMBA device DMA definitions
  ARM: versatile: remove old AMBA device DMA definitions
  ARM: vexpress: use new init_early for clock tree and sched_clock init
  ARM: realview: use new init_early for clock tree and sched_clock init
  ARM: versatile: use new init_early for clock tree and sched_clock init
  ARM: integrator: use new init_early for clock tree init
  ...
Linus Torvalds 14 年之前
父节点
当前提交
2f284c8463
共有 68 个文件被更改,包括 1149 次插入3537 次删除
  1. 7 3
      arch/arm/Kconfig
  2. 7 1
      arch/arm/include/asm/localtimer.h
  3. 8 6
      arch/arm/include/asm/outercache.h
  4. 2 1
      arch/arm/include/asm/pgtable.h
  5. 1 1
      arch/arm/include/asm/setup.h
  6. 7 7
      arch/arm/kernel/hw_breakpoint.c
  7. 4 3
      arch/arm/kernel/setup.c
  8. 3 4
      arch/arm/kernel/smp.c
  9. 3 3
      arch/arm/kernel/traps.c
  10. 6 1
      arch/arm/lib/uaccess_with_memcpy.c
  11. 2 1
      arch/arm/mach-exynos4/localtimer.c
  12. 1 0
      arch/arm/mach-integrator/Kconfig
  13. 1 0
      arch/arm/mach-integrator/common.h
  14. 5 2
      arch/arm/mach-integrator/core.c
  15. 5 0
      arch/arm/mach-integrator/impd1.c
  16. 2 2
      arch/arm/mach-integrator/include/mach/cm.h
  17. 14 30
      arch/arm/mach-integrator/integrator_ap.c
  18. 64 175
      arch/arm/mach-integrator/integrator_cp.c
  19. 2 1
      arch/arm/mach-msm/timer.c
  20. 1 0
      arch/arm/mach-omap2/Kconfig
  21. 6 1
      arch/arm/mach-omap2/timer-mpu.c
  22. 1 2
      arch/arm/mach-realview/Makefile
  23. 40 193
      arch/arm/mach-realview/core.c
  24. 1 1
      arch/arm/mach-realview/core.h
  25. 0 40
      arch/arm/mach-realview/headsmp.S
  26. 0 26
      arch/arm/mach-realview/localtimer.c
  27. 3 95
      arch/arm/mach-realview/platsmp.c
  28. 1 21
      arch/arm/mach-realview/realview_eb.c
  29. 1 21
      arch/arm/mach-realview/realview_pb1176.c
  30. 1 21
      arch/arm/mach-realview/realview_pb11mp.c
  31. 1 21
      arch/arm/mach-realview/realview_pba8.c
  32. 1 21
      arch/arm/mach-realview/realview_pbx.c
  33. 2 1
      arch/arm/mach-shmobile/localtimer.c
  34. 2 1
      arch/arm/mach-tegra/localtimer.c
  35. 2 1
      arch/arm/mach-ux500/localtimer.c
  36. 64 231
      arch/arm/mach-versatile/core.c
  37. 1 1
      arch/arm/mach-versatile/core.h
  38. 1 1
      arch/arm/mach-versatile/include/mach/hardware.h
  39. 1 0
      arch/arm/mach-versatile/versatile_ab.c
  40. 1 5
      arch/arm/mach-versatile/versatile_pb.c
  41. 3 0
      arch/arm/mach-vexpress/Kconfig
  42. 1 2
      arch/arm/mach-vexpress/Makefile
  43. 0 5
      arch/arm/mach-vexpress/core.h
  44. 44 63
      arch/arm/mach-vexpress/ct-ca9x4.c
  45. 2 0
      arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
  46. 22 0
      arch/arm/mach-vexpress/include/mach/motherboard.h
  47. 4 121
      arch/arm/mach-vexpress/platsmp.c
  48. 80 10
      arch/arm/mach-vexpress/v2m.c
  49. 10 1
      arch/arm/mm/dma-mapping.c
  50. 6 1
      arch/arm/mm/fault-armv.c
  51. 31 8
      arch/arm/mm/fault.c
  52. 29 6
      arch/arm/mm/idmap.c
  53. 3 3
      arch/arm/mm/init.c
  54. 1 1
      arch/arm/mm/mm.h
  55. 44 27
      arch/arm/mm/mmu.c
  56. 20 4
      arch/arm/mm/pgd.c
  57. 17 0
      arch/arm/plat-versatile/Kconfig
  58. 6 7
      arch/arm/plat-versatile/Makefile
  59. 182 0
      arch/arm/plat-versatile/clcd.c
  60. 72 0
      arch/arm/plat-versatile/fpga-irq.c
  61. 4 4
      arch/arm/plat-versatile/headsmp.S
  62. 9 0
      arch/arm/plat-versatile/include/plat/clcd.h
  63. 12 0
      arch/arm/plat-versatile/include/plat/fpga-irq.h
  64. 3 2
      arch/arm/plat-versatile/localtimer.c
  65. 104 0
      arch/arm/plat-versatile/platsmp.c
  66. 6 2293
      arch/arm/tools/mach-types
  67. 90 13
      drivers/video/amba-clcd.c
  68. 69 21
      include/linux/amba/clcd.h

+ 7 - 3
arch/arm/Kconfig

@@ -235,6 +235,7 @@ config ARCH_INTEGRATOR
 	select ICST
 	select ICST
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_CLOCKEVENTS
 	select PLAT_VERSATILE
 	select PLAT_VERSATILE
+	select PLAT_VERSATILE_FPGA_IRQ
 	help
 	help
 	  Support for ARM's Integrator platform.
 	  Support for ARM's Integrator platform.
 
 
@@ -242,11 +243,11 @@ config ARCH_REALVIEW
 	bool "ARM Ltd. RealView family"
 	bool "ARM Ltd. RealView family"
 	select ARM_AMBA
 	select ARM_AMBA
 	select CLKDEV_LOOKUP
 	select CLKDEV_LOOKUP
-	select HAVE_SCHED_CLOCK
 	select ICST
 	select ICST
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_CLOCKEVENTS
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select PLAT_VERSATILE
 	select PLAT_VERSATILE
+	select PLAT_VERSATILE_CLCD
 	select ARM_TIMER_SP804
 	select ARM_TIMER_SP804
 	select GPIO_PL061 if GPIOLIB
 	select GPIO_PL061 if GPIOLIB
 	help
 	help
@@ -257,11 +258,12 @@ config ARCH_VERSATILE
 	select ARM_AMBA
 	select ARM_AMBA
 	select ARM_VIC
 	select ARM_VIC
 	select CLKDEV_LOOKUP
 	select CLKDEV_LOOKUP
-	select HAVE_SCHED_CLOCK
 	select ICST
 	select ICST
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_CLOCKEVENTS
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select PLAT_VERSATILE
 	select PLAT_VERSATILE
+	select PLAT_VERSATILE_CLCD
+	select PLAT_VERSATILE_FPGA_IRQ
 	select ARM_TIMER_SP804
 	select ARM_TIMER_SP804
 	help
 	help
 	  This enables support for ARM Ltd Versatile board.
 	  This enables support for ARM Ltd Versatile board.
@@ -274,9 +276,10 @@ config ARCH_VEXPRESS
 	select CLKDEV_LOOKUP
 	select CLKDEV_LOOKUP
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CLK
 	select HAVE_CLK
-	select HAVE_SCHED_CLOCK
+	select HAVE_PATA_PLATFORM
 	select ICST
 	select ICST
 	select PLAT_VERSATILE
 	select PLAT_VERSATILE
+	select PLAT_VERSATILE_CLCD
 	help
 	help
 	  This enables support for the ARM Ltd Versatile Express boards.
 	  This enables support for the ARM Ltd Versatile Express boards.
 
 
@@ -1011,6 +1014,7 @@ source "arch/arm/mach-ux500/Kconfig"
 source "arch/arm/mach-versatile/Kconfig"
 source "arch/arm/mach-versatile/Kconfig"
 
 
 source "arch/arm/mach-vexpress/Kconfig"
 source "arch/arm/mach-vexpress/Kconfig"
+source "arch/arm/plat-versatile/Kconfig"
 
 
 source "arch/arm/mach-vt8500/Kconfig"
 source "arch/arm/mach-vt8500/Kconfig"
 
 

+ 7 - 1
arch/arm/include/asm/localtimer.h

@@ -44,8 +44,14 @@ int local_timer_ack(void);
 /*
 /*
  * Setup a local timer interrupt for a CPU.
  * Setup a local timer interrupt for a CPU.
  */
  */
-void local_timer_setup(struct clock_event_device *);
+int local_timer_setup(struct clock_event_device *);
 
 
+#else
+
+static inline int local_timer_setup(struct clock_event_device *evt)
+{
+	return -ENXIO;
+}
 #endif
 #endif
 
 
 #endif
 #endif

+ 8 - 6
arch/arm/include/asm/outercache.h

@@ -21,6 +21,8 @@
 #ifndef __ASM_OUTERCACHE_H
 #ifndef __ASM_OUTERCACHE_H
 #define __ASM_OUTERCACHE_H
 #define __ASM_OUTERCACHE_H
 
 
+#include <linux/types.h>
+
 struct outer_cache_fns {
 struct outer_cache_fns {
 	void (*inv_range)(unsigned long, unsigned long);
 	void (*inv_range)(unsigned long, unsigned long);
 	void (*clean_range)(unsigned long, unsigned long);
 	void (*clean_range)(unsigned long, unsigned long);
@@ -38,17 +40,17 @@ struct outer_cache_fns {
 
 
 extern struct outer_cache_fns outer_cache;
 extern struct outer_cache_fns outer_cache;
 
 
-static inline void outer_inv_range(unsigned long start, unsigned long end)
+static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
 {
 {
 	if (outer_cache.inv_range)
 	if (outer_cache.inv_range)
 		outer_cache.inv_range(start, end);
 		outer_cache.inv_range(start, end);
 }
 }
-static inline void outer_clean_range(unsigned long start, unsigned long end)
+static inline void outer_clean_range(phys_addr_t start, phys_addr_t end)
 {
 {
 	if (outer_cache.clean_range)
 	if (outer_cache.clean_range)
 		outer_cache.clean_range(start, end);
 		outer_cache.clean_range(start, end);
 }
 }
-static inline void outer_flush_range(unsigned long start, unsigned long end)
+static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
 {
 {
 	if (outer_cache.flush_range)
 	if (outer_cache.flush_range)
 		outer_cache.flush_range(start, end);
 		outer_cache.flush_range(start, end);
@@ -74,11 +76,11 @@ static inline void outer_disable(void)
 
 
 #else
 #else
 
 
-static inline void outer_inv_range(unsigned long start, unsigned long end)
+static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
 { }
 { }
-static inline void outer_clean_range(unsigned long start, unsigned long end)
+static inline void outer_clean_range(phys_addr_t start, phys_addr_t end)
 { }
 { }
-static inline void outer_flush_range(unsigned long start, unsigned long end)
+static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
 { }
 { }
 static inline void outer_flush_all(void) { }
 static inline void outer_flush_all(void) { }
 static inline void outer_inv_all(void) { }
 static inline void outer_inv_all(void) { }

+ 2 - 1
arch/arm/include/asm/pgtable.h

@@ -301,6 +301,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 #define pgd_present(pgd)	(1)
 #define pgd_present(pgd)	(1)
 #define pgd_clear(pgdp)		do { } while (0)
 #define pgd_clear(pgdp)		do { } while (0)
 #define set_pgd(pgd,pgdp)	do { } while (0)
 #define set_pgd(pgd,pgdp)	do { } while (0)
+#define set_pud(pud,pudp)	do { } while (0)
 
 
 
 
 /* Find an entry in the second-level page table.. */
 /* Find an entry in the second-level page table.. */
@@ -351,7 +352,7 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
 #define pte_unmap(pte)			__pte_unmap(pte)
 #define pte_unmap(pte)			__pte_unmap(pte)
 
 
 #define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
 #define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
-#define pfn_pte(pfn,prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#define pfn_pte(pfn,prot)	__pte(__pfn_to_phys(pfn) | pgprot_val(prot))
 
 
 #define pte_page(pte)		pfn_to_page(pte_pfn(pte))
 #define pte_page(pte)		pfn_to_page(pte_pfn(pte))
 #define mk_pte(page,prot)	pfn_pte(page_to_pfn(page), prot)
 #define mk_pte(page,prot)	pfn_pte(page_to_pfn(page), prot)

+ 1 - 1
arch/arm/include/asm/setup.h

@@ -195,7 +195,7 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn }
 #define NR_BANKS 8
 #define NR_BANKS 8
 
 
 struct membank {
 struct membank {
-	unsigned long start;
+	phys_addr_t start;
 	unsigned long size;
 	unsigned long size;
 	unsigned int highmem;
 	unsigned int highmem;
 };
 };

+ 7 - 7
arch/arm/kernel/hw_breakpoint.c

@@ -238,8 +238,8 @@ static int enable_monitor_mode(void)
 	ARM_DBG_READ(c1, 0, dscr);
 	ARM_DBG_READ(c1, 0, dscr);
 
 
 	/* Ensure that halting mode is disabled. */
 	/* Ensure that halting mode is disabled. */
-	if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, "halting debug mode enabled."
-				"Unable to access hardware resources.")) {
+	if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN,
+			"halting debug mode enabled. Unable to access hardware resources.\n")) {
 		ret = -EPERM;
 		ret = -EPERM;
 		goto out;
 		goto out;
 	}
 	}
@@ -377,7 +377,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
 		}
 		}
 	}
 	}
 
 
-	if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot")) {
+	if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) {
 		ret = -EBUSY;
 		ret = -EBUSY;
 		goto out;
 		goto out;
 	}
 	}
@@ -423,7 +423,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
 		}
 		}
 	}
 	}
 
 
-	if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot"))
+	if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n"))
 		return;
 		return;
 
 
 	/* Reset the control register. */
 	/* Reset the control register. */
@@ -635,7 +635,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
 	if (WARN_ONCE(!bp->overflow_handler &&
 	if (WARN_ONCE(!bp->overflow_handler &&
 		(arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps()
 		(arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps()
 		 || !bp->hw.bp_target),
 		 || !bp->hw.bp_target),
-			"overflow handler required but none found")) {
+			"overflow handler required but none found\n")) {
 		ret = -EINVAL;
 		ret = -EINVAL;
 	}
 	}
 out:
 out:
@@ -936,8 +936,8 @@ static int __init arch_hw_breakpoint_init(void)
 	ARM_DBG_READ(c1, 0, dscr);
 	ARM_DBG_READ(c1, 0, dscr);
 	if (dscr & ARM_DSCR_HDBGEN) {
 	if (dscr & ARM_DSCR_HDBGEN) {
 		max_watchpoint_len = 4;
 		max_watchpoint_len = 4;
-		pr_warning("halting debug mode enabled. Assuming maximum "
-			   "watchpoint size of %u bytes.", max_watchpoint_len);
+		pr_warning("halting debug mode enabled. Assuming maximum watchpoint size of %u bytes.\n",
+			   max_watchpoint_len);
 	} else {
 	} else {
 		/* Work out the maximum supported watchpoint length. */
 		/* Work out the maximum supported watchpoint length. */
 		max_watchpoint_len = get_max_wp_len();
 		max_watchpoint_len = get_max_wp_len();

+ 4 - 3
arch/arm/kernel/setup.c

@@ -466,13 +466,13 @@ static struct machine_desc * __init setup_machine(unsigned int nr)
 		/* can't use cpu_relax() here as it may require MMU setup */;
 		/* can't use cpu_relax() here as it may require MMU setup */;
 }
 }
 
 
-static int __init arm_add_memory(unsigned long start, unsigned long size)
+static int __init arm_add_memory(phys_addr_t start, unsigned long size)
 {
 {
 	struct membank *bank = &meminfo.bank[meminfo.nr_banks];
 	struct membank *bank = &meminfo.bank[meminfo.nr_banks];
 
 
 	if (meminfo.nr_banks >= NR_BANKS) {
 	if (meminfo.nr_banks >= NR_BANKS) {
 		printk(KERN_CRIT "NR_BANKS too low, "
 		printk(KERN_CRIT "NR_BANKS too low, "
-			"ignoring memory at %#lx\n", start);
+			"ignoring memory at 0x%08llx\n", (long long)start);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -502,7 +502,8 @@ static int __init arm_add_memory(unsigned long start, unsigned long size)
 static int __init early_mem(char *p)
 static int __init early_mem(char *p)
 {
 {
 	static int usermem __initdata = 0;
 	static int usermem __initdata = 0;
-	unsigned long size, start;
+	unsigned long size;
+	phys_addr_t start;
 	char *endp;
 	char *endp;
 
 
 	/*
 	/*

+ 3 - 4
arch/arm/kernel/smp.c

@@ -474,13 +474,12 @@ static void smp_timer_broadcast(const struct cpumask *mask)
 #define smp_timer_broadcast	NULL
 #define smp_timer_broadcast	NULL
 #endif
 #endif
 
 
-#ifndef CONFIG_LOCAL_TIMERS
 static void broadcast_timer_set_mode(enum clock_event_mode mode,
 static void broadcast_timer_set_mode(enum clock_event_mode mode,
 	struct clock_event_device *evt)
 	struct clock_event_device *evt)
 {
 {
 }
 }
 
 
-static void local_timer_setup(struct clock_event_device *evt)
+static void broadcast_timer_setup(struct clock_event_device *evt)
 {
 {
 	evt->name	= "dummy_timer";
 	evt->name	= "dummy_timer";
 	evt->features	= CLOCK_EVT_FEAT_ONESHOT |
 	evt->features	= CLOCK_EVT_FEAT_ONESHOT |
@@ -492,7 +491,6 @@ static void local_timer_setup(struct clock_event_device *evt)
 
 
 	clockevents_register_device(evt);
 	clockevents_register_device(evt);
 }
 }
-#endif
 
 
 void __cpuinit percpu_timer_setup(void)
 void __cpuinit percpu_timer_setup(void)
 {
 {
@@ -502,7 +500,8 @@ void __cpuinit percpu_timer_setup(void)
 	evt->cpumask = cpumask_of(cpu);
 	evt->cpumask = cpumask_of(cpu);
 	evt->broadcast = smp_timer_broadcast;
 	evt->broadcast = smp_timer_broadcast;
 
 
-	local_timer_setup(evt);
+	if (local_timer_setup(evt))
+		broadcast_timer_setup(evt);
 }
 }
 
 
 #ifdef CONFIG_HOTPLUG_CPU
 #ifdef CONFIG_HOTPLUG_CPU

+ 3 - 3
arch/arm/kernel/traps.c

@@ -712,17 +712,17 @@ EXPORT_SYMBOL(__readwrite_bug);
 
 
 void __pte_error(const char *file, int line, pte_t pte)
 void __pte_error(const char *file, int line, pte_t pte)
 {
 {
-	printk("%s:%d: bad pte %08lx.\n", file, line, pte_val(pte));
+	printk("%s:%d: bad pte %08llx.\n", file, line, (long long)pte_val(pte));
 }
 }
 
 
 void __pmd_error(const char *file, int line, pmd_t pmd)
 void __pmd_error(const char *file, int line, pmd_t pmd)
 {
 {
-	printk("%s:%d: bad pmd %08lx.\n", file, line, pmd_val(pmd));
+	printk("%s:%d: bad pmd %08llx.\n", file, line, (long long)pmd_val(pmd));
 }
 }
 
 
 void __pgd_error(const char *file, int line, pgd_t pgd)
 void __pgd_error(const char *file, int line, pgd_t pgd)
 {
 {
-	printk("%s:%d: bad pgd %08lx.\n", file, line, pgd_val(pgd));
+	printk("%s:%d: bad pgd %08llx.\n", file, line, (long long)pgd_val(pgd));
 }
 }
 
 
 asmlinkage void __div0(void)
 asmlinkage void __div0(void)

+ 6 - 1
arch/arm/lib/uaccess_with_memcpy.c

@@ -27,13 +27,18 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp)
 	pgd_t *pgd;
 	pgd_t *pgd;
 	pmd_t *pmd;
 	pmd_t *pmd;
 	pte_t *pte;
 	pte_t *pte;
+	pud_t *pud;
 	spinlock_t *ptl;
 	spinlock_t *ptl;
 
 
 	pgd = pgd_offset(current->mm, addr);
 	pgd = pgd_offset(current->mm, addr);
 	if (unlikely(pgd_none(*pgd) || pgd_bad(*pgd)))
 	if (unlikely(pgd_none(*pgd) || pgd_bad(*pgd)))
 		return 0;
 		return 0;
 
 
-	pmd = pmd_offset(pgd, addr);
+	pud = pud_offset(pgd, addr);
+	if (unlikely(pud_none(*pud) || pud_bad(*pud)))
+		return 0;
+
+	pmd = pmd_offset(pud, addr);
 	if (unlikely(pmd_none(*pmd) || pmd_bad(*pmd)))
 	if (unlikely(pmd_none(*pmd) || pmd_bad(*pmd)))
 		return 0;
 		return 0;
 
 

+ 2 - 1
arch/arm/mach-exynos4/localtimer.c

@@ -18,8 +18,9 @@
 /*
 /*
  * Setup the local clock events for a CPU.
  * Setup the local clock events for a CPU.
  */
  */
-void __cpuinit local_timer_setup(struct clock_event_device *evt)
+int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
 {
 	evt->irq = IRQ_LOCALTIMER;
 	evt->irq = IRQ_LOCALTIMER;
 	twd_timer_setup(evt);
 	twd_timer_setup(evt);
+	return 0;
 }
 }

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

@@ -13,6 +13,7 @@ config ARCH_INTEGRATOR_CP
 	bool "Support Integrator/CP platform"
 	bool "Support Integrator/CP platform"
 	select ARCH_CINTEGRATOR
 	select ARCH_CINTEGRATOR
 	select ARM_TIMER_SP804
 	select ARM_TIMER_SP804
+	select PLAT_VERSATILE_CLCD
 	help
 	help
 	  Include support for the ARM(R) Integrator CP platform.
 	  Include support for the ARM(R) Integrator CP platform.
 
 

+ 1 - 0
arch/arm/mach-integrator/common.h

@@ -1 +1,2 @@
+void integrator_init_early(void);
 void integrator_reserve(void);
 void integrator_reserve(void);

+ 5 - 2
arch/arm/mach-integrator/core.c

@@ -144,12 +144,15 @@ static struct clk_lookup lookups[] = {
 	}
 	}
 };
 };
 
 
+void __init integrator_init_early(void)
+{
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+}
+
 static int __init integrator_init(void)
 static int __init integrator_init(void)
 {
 {
 	int i;
 	int i;
 
 
-	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 		struct amba_device *d = amba_devs[i];
 		struct amba_device *d = amba_devs[i];
 		amba_device_register(d, &iomem_resource);
 		amba_device_register(d, &iomem_resource);

+ 5 - 0
arch/arm/mach-integrator/impd1.c

@@ -121,6 +121,7 @@ static struct clcd_panel vga = {
 	.height		= -1,
 	.height		= -1,
 	.tim2		= TIM2_BCD | TIM2_IPC,
 	.tim2		= TIM2_BCD | TIM2_IPC,
 	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
 	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+	.caps		= CLCD_CAP_5551,
 	.connector	= IMPD1_CTRL_DISP_VGA,
 	.connector	= IMPD1_CTRL_DISP_VGA,
 	.bpp		= 16,
 	.bpp		= 16,
 	.grayscale	= 0,
 	.grayscale	= 0,
@@ -149,6 +150,7 @@ static struct clcd_panel svga = {
 	.tim2		= TIM2_BCD,
 	.tim2		= TIM2_BCD,
 	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
 	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
 	.connector	= IMPD1_CTRL_DISP_VGA,
 	.connector	= IMPD1_CTRL_DISP_VGA,
+	.caps		= CLCD_CAP_5551,
 	.bpp		= 16,
 	.bpp		= 16,
 	.grayscale	= 0,
 	.grayscale	= 0,
 };
 };
@@ -175,6 +177,7 @@ static struct clcd_panel prospector = {
 	.height		= -1,
 	.height		= -1,
 	.tim2		= TIM2_BCD,
 	.tim2		= TIM2_BCD,
 	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
 	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+	.caps		= CLCD_CAP_5551,
 	.fixedtimings	= 1,
 	.fixedtimings	= 1,
 	.connector	= IMPD1_CTRL_DISP_LCD,
 	.connector	= IMPD1_CTRL_DISP_LCD,
 	.bpp		= 16,
 	.bpp		= 16,
@@ -206,6 +209,7 @@ static struct clcd_panel ltm10c209 = {
 	.height		= -1,
 	.height		= -1,
 	.tim2		= TIM2_BCD,
 	.tim2		= TIM2_BCD,
 	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
 	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+	.caps		= CLCD_CAP_5551,
 	.fixedtimings	= 1,
 	.fixedtimings	= 1,
 	.connector	= IMPD1_CTRL_DISP_LCD,
 	.connector	= IMPD1_CTRL_DISP_LCD,
 	.bpp		= 16,
 	.bpp		= 16,
@@ -279,6 +283,7 @@ static void impd1fb_clcd_remove(struct clcd_fb *fb)
 
 
 static struct clcd_board impd1_clcd_data = {
 static struct clcd_board impd1_clcd_data = {
 	.name		= "IM-PD/1",
 	.name		= "IM-PD/1",
+	.caps		= CLCD_CAP_5551 | CLCD_CAP_888,
 	.check		= clcdfb_check,
 	.check		= clcdfb_check,
 	.decode		= clcdfb_decode,
 	.decode		= clcdfb_decode,
 	.disable	= impd1fb_clcd_disable,
 	.disable	= impd1fb_clcd_disable,

+ 2 - 2
arch/arm/mach-integrator/include/mach/cm.h

@@ -24,9 +24,9 @@ void cm_control(u32, u32);
 #define CM_CTRL_LCDBIASDN		(1 << 10)
 #define CM_CTRL_LCDBIASDN		(1 << 10)
 #define CM_CTRL_LCDMUXSEL_MASK		(7 << 11)
 #define CM_CTRL_LCDMUXSEL_MASK		(7 << 11)
 #define CM_CTRL_LCDMUXSEL_GENLCD	(1 << 11)
 #define CM_CTRL_LCDMUXSEL_GENLCD	(1 << 11)
-#define CM_CTRL_LCDMUXSEL_VGA_16BPP	(2 << 11)
+#define CM_CTRL_LCDMUXSEL_VGA565_TFT555	(2 << 11)
 #define CM_CTRL_LCDMUXSEL_SHARPLCD	(3 << 11)
 #define CM_CTRL_LCDMUXSEL_SHARPLCD	(3 << 11)
-#define CM_CTRL_LCDMUXSEL_VGA_8421BPP	(4 << 11)
+#define CM_CTRL_LCDMUXSEL_VGA555_TFT555	(4 << 11)
 #define CM_CTRL_LCDEN0			(1 << 14)
 #define CM_CTRL_LCDEN0			(1 << 14)
 #define CM_CTRL_LCDEN1			(1 << 15)
 #define CM_CTRL_LCDEN1			(1 << 15)
 #define CM_CTRL_STATIC1			(1 << 16)
 #define CM_CTRL_STATIC1			(1 << 16)

+ 14 - 30
arch/arm/mach-integrator/integrator_ap.c

@@ -48,6 +48,8 @@
 #include <asm/mach/map.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 #include <asm/mach/time.h>
 
 
+#include <plat/fpga-irq.h>
+
 #include "common.h"
 #include "common.h"
 
 
 /* 
 /* 
@@ -57,10 +59,10 @@
  * Setup a VA for the Integrator interrupt controller (for header #0,
  * Setup a VA for the Integrator interrupt controller (for header #0,
  * just for now).
  * just for now).
  */
  */
-#define VA_IC_BASE	IO_ADDRESS(INTEGRATOR_IC_BASE) 
-#define VA_SC_BASE	IO_ADDRESS(INTEGRATOR_SC_BASE)
-#define VA_EBI_BASE	IO_ADDRESS(INTEGRATOR_EBI_BASE)
-#define VA_CMIC_BASE	IO_ADDRESS(INTEGRATOR_HDR_IC)
+#define VA_IC_BASE	__io_address(INTEGRATOR_IC_BASE)
+#define VA_SC_BASE	__io_address(INTEGRATOR_SC_BASE)
+#define VA_EBI_BASE	__io_address(INTEGRATOR_EBI_BASE)
+#define VA_CMIC_BASE	__io_address(INTEGRATOR_HDR_IC)
 
 
 /*
 /*
  * Logical      Physical
  * Logical      Physical
@@ -156,27 +158,14 @@ static void __init ap_map_io(void)
 
 
 #define INTEGRATOR_SC_VALID_INT	0x003fffff
 #define INTEGRATOR_SC_VALID_INT	0x003fffff
 
 
-static void sc_mask_irq(struct irq_data *d)
-{
-	writel(1 << d->irq, VA_IC_BASE + IRQ_ENABLE_CLEAR);
-}
-
-static void sc_unmask_irq(struct irq_data *d)
-{
-	writel(1 << d->irq, VA_IC_BASE + IRQ_ENABLE_SET);
-}
-
-static struct irq_chip sc_chip = {
-	.name		= "SC",
-	.irq_ack	= sc_mask_irq,
-	.irq_mask	= sc_mask_irq,
-	.irq_unmask	= sc_unmask_irq,
+static struct fpga_irq_data sc_irq_data = {
+	.base		= VA_IC_BASE,
+	.irq_start	= 0,
+	.chip.name	= "SC",
 };
 };
 
 
 static void __init ap_init_irq(void)
 static void __init ap_init_irq(void)
 {
 {
-	unsigned int i;
-
 	/* Disable all interrupts initially. */
 	/* Disable all interrupts initially. */
 	/* Do the core module ones */
 	/* Do the core module ones */
 	writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
 	writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
@@ -185,13 +174,7 @@ static void __init ap_init_irq(void)
 	writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
 	writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
 	writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
 	writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
 
 
-	for (i = 0; i < NR_IRQS; i++) {
-		if (((1 << i) & INTEGRATOR_SC_VALID_INT) != 0) {
-			set_irq_chip(i, &sc_chip);
-			set_irq_handler(i, handle_level_irq);
-			set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-		}
-	}
+	fpga_irq_init(-1, INTEGRATOR_SC_VALID_INT, &sc_irq_data);
 }
 }
 
 
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM
@@ -282,7 +265,7 @@ static void ap_flash_exit(void)
 
 
 static void ap_flash_set_vpp(int on)
 static void ap_flash_set_vpp(int on)
 {
 {
-	unsigned long reg = on ? SC_CTRLS : SC_CTRLC;
+	void __iomem *reg = on ? SC_CTRLS : SC_CTRLC;
 
 
 	writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
 	writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
 }
 }
@@ -499,8 +482,9 @@ static struct sys_timer ap_timer = {
 MACHINE_START(INTEGRATOR, "ARM-Integrator")
 MACHINE_START(INTEGRATOR, "ARM-Integrator")
 	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
 	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
 	.boot_params	= 0x00000100,
 	.boot_params	= 0x00000100,
-	.map_io		= ap_map_io,
 	.reserve	= integrator_reserve,
 	.reserve	= integrator_reserve,
+	.map_io		= ap_map_io,
+	.init_early	= integrator_init_early,
 	.init_irq	= ap_init_irq,
 	.init_irq	= ap_init_irq,
 	.timer		= &ap_timer,
 	.timer		= &ap_timer,
 	.init_machine	= ap_init,
 	.init_machine	= ap_init,

+ 64 - 175
arch/arm/mach-integrator/integrator_cp.c

@@ -42,6 +42,10 @@
 
 
 #include <asm/hardware/timer-sp.h>
 #include <asm/hardware/timer-sp.h>
 
 
+#include <plat/clcd.h>
+#include <plat/fpga-irq.h>
+#include <plat/sched_clock.h>
+
 #include "common.h"
 #include "common.h"
 
 
 #define INTCP_PA_FLASH_BASE		0x24000000
 #define INTCP_PA_FLASH_BASE		0x24000000
@@ -49,9 +53,9 @@
 
 
 #define INTCP_PA_CLCD_BASE		0xc0000000
 #define INTCP_PA_CLCD_BASE		0xc0000000
 
 
-#define INTCP_VA_CIC_BASE		IO_ADDRESS(INTEGRATOR_HDR_BASE + 0x40)
-#define INTCP_VA_PIC_BASE		IO_ADDRESS(INTEGRATOR_IC_BASE)
-#define INTCP_VA_SIC_BASE		IO_ADDRESS(INTEGRATOR_CP_SIC_BASE)
+#define INTCP_VA_CIC_BASE		__io_address(INTEGRATOR_HDR_BASE + 0x40)
+#define INTCP_VA_PIC_BASE		__io_address(INTEGRATOR_IC_BASE)
+#define INTCP_VA_SIC_BASE		__io_address(INTEGRATOR_CP_SIC_BASE)
 
 
 #define INTCP_ETH_SIZE			0x10
 #define INTCP_ETH_SIZE			0x10
 
 
@@ -139,129 +143,48 @@ static void __init intcp_map_io(void)
 	iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
 	iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
 }
 }
 
 
-#define cic_writel	__raw_writel
-#define cic_readl	__raw_readl
-#define pic_writel	__raw_writel
-#define pic_readl	__raw_readl
-#define sic_writel	__raw_writel
-#define sic_readl	__raw_readl
-
-static void cic_mask_irq(struct irq_data *d)
-{
-	unsigned int irq = d->irq - IRQ_CIC_START;
-	cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
-}
-
-static void cic_unmask_irq(struct irq_data *d)
-{
-	unsigned int irq = d->irq - IRQ_CIC_START;
-	cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_SET);
-}
-
-static struct irq_chip cic_chip = {
-	.name		= "CIC",
-	.irq_ack	= cic_mask_irq,
-	.irq_mask	= cic_mask_irq,
-	.irq_unmask	= cic_unmask_irq,
+static struct fpga_irq_data cic_irq_data = {
+	.base		= INTCP_VA_CIC_BASE,
+	.irq_start	= IRQ_CIC_START,
+	.chip.name	= "CIC",
 };
 };
 
 
-static void pic_mask_irq(struct irq_data *d)
-{
-	unsigned int irq = d->irq - IRQ_PIC_START;
-	pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
-}
-
-static void pic_unmask_irq(struct irq_data *d)
-{
-	unsigned int irq = d->irq - IRQ_PIC_START;
-	pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_SET);
-}
-
-static struct irq_chip pic_chip = {
-	.name		= "PIC",
-	.irq_ack	= pic_mask_irq,
-	.irq_mask	= pic_mask_irq,
-	.irq_unmask	= pic_unmask_irq,
+static struct fpga_irq_data pic_irq_data = {
+	.base		= INTCP_VA_PIC_BASE,
+	.irq_start	= IRQ_PIC_START,
+	.chip.name	= "PIC",
 };
 };
 
 
-static void sic_mask_irq(struct irq_data *d)
-{
-	unsigned int irq = d->irq - IRQ_SIC_START;
-	sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
-}
-
-static void sic_unmask_irq(struct irq_data *d)
-{
-	unsigned int irq = d->irq - IRQ_SIC_START;
-	sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_SET);
-}
-
-static struct irq_chip sic_chip = {
-	.name		= "SIC",
-	.irq_ack	= sic_mask_irq,
-	.irq_mask	= sic_mask_irq,
-	.irq_unmask	= sic_unmask_irq,
+static struct fpga_irq_data sic_irq_data = {
+	.base		= INTCP_VA_SIC_BASE,
+	.irq_start	= IRQ_SIC_START,
+	.chip.name	= "SIC",
 };
 };
 
 
-static void
-sic_handle_irq(unsigned int irq, struct irq_desc *desc)
-{
-	unsigned long status = sic_readl(INTCP_VA_SIC_BASE + IRQ_STATUS);
-
-	if (status == 0) {
-		do_bad_IRQ(irq, desc);
-		return;
-	}
-
-	do {
-		irq = ffs(status) - 1;
-		status &= ~(1 << irq);
-
-		irq += IRQ_SIC_START;
-
-		generic_handle_irq(irq);
-	} while (status);
-}
-
 static void __init intcp_init_irq(void)
 static void __init intcp_init_irq(void)
 {
 {
-	unsigned int i;
+	u32 pic_mask, sic_mask;
+
+	pic_mask = ~((~0u) << (11 - IRQ_PIC_START));
+	pic_mask |= (~((~0u) << (29 - 22))) << 22;
+	sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START));
 
 
 	/*
 	/*
 	 * Disable all interrupt sources
 	 * Disable all interrupt sources
 	 */
 	 */
-	pic_writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
-	pic_writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR);
-
-	for (i = IRQ_PIC_START; i <= IRQ_PIC_END; i++) {
-		if (i == 11)
-			i = 22;
-		if (i == 29)
-			break;
-		set_irq_chip(i, &pic_chip);
-		set_irq_handler(i, handle_level_irq);
-		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-	}
+	writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
+	writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR);
+	writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
+	writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
+	writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
+	writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
 
 
-	cic_writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
-	cic_writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
+	fpga_irq_init(-1, pic_mask, &pic_irq_data);
 
 
-	for (i = IRQ_CIC_START; i <= IRQ_CIC_END; i++) {
-		set_irq_chip(i, &cic_chip);
-		set_irq_handler(i, handle_level_irq);
-		set_irq_flags(i, IRQF_VALID);
-	}
-
-	sic_writel(0x00000fff, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
-	sic_writel(0x00000fff, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
-
-	for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) {
-		set_irq_chip(i, &sic_chip);
-		set_irq_handler(i, handle_level_irq);
-		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-	}
+	fpga_irq_init(-1, ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)),
+		&cic_irq_data);
 
 
-	set_irq_chained_handler(IRQ_CP_CPPLDINT, sic_handle_irq);
+	fpga_irq_init(IRQ_CP_CPPLDINT, sic_mask, &sic_irq_data);
 }
 }
 
 
 /*
 /*
@@ -449,43 +372,21 @@ static struct amba_device aaci_device = {
 /*
 /*
  * CLCD support
  * CLCD support
  */
  */
-static struct clcd_panel vga = {
-	.mode		= {
-		.name		= "VGA",
-		.refresh	= 60,
-		.xres		= 640,
-		.yres		= 480,
-		.pixclock	= 39721,
-		.left_margin	= 40,
-		.right_margin	= 24,
-		.upper_margin	= 32,
-		.lower_margin	= 11,
-		.hsync_len	= 96,
-		.vsync_len	= 2,
-		.sync		= 0,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-	.width		= -1,
-	.height		= -1,
-	.tim2		= TIM2_BCD | TIM2_IPC,
-	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
-	.bpp		= 16,
-	.grayscale	= 0,
-};
-
 /*
 /*
  * Ensure VGA is selected.
  * Ensure VGA is selected.
  */
  */
 static void cp_clcd_enable(struct clcd_fb *fb)
 static void cp_clcd_enable(struct clcd_fb *fb)
 {
 {
-	u32 val;
+	struct fb_var_screeninfo *var = &fb->fb.var;
+	u32 val = CM_CTRL_STATIC1 | CM_CTRL_STATIC2;
 
 
-	if (fb->fb.var.bits_per_pixel <= 8)
-		val = CM_CTRL_LCDMUXSEL_VGA_8421BPP;
+	if (var->bits_per_pixel <= 8 ||
+	    (var->bits_per_pixel == 16 && var->green.length == 5))
+		/* Pseudocolor, RGB555, BGR555 */
+		val |= CM_CTRL_LCDMUXSEL_VGA555_TFT555;
 	else if (fb->fb.var.bits_per_pixel <= 16)
 	else if (fb->fb.var.bits_per_pixel <= 16)
-		val = CM_CTRL_LCDMUXSEL_VGA_16BPP
-			| CM_CTRL_LCDEN0 | CM_CTRL_LCDEN1
-			| CM_CTRL_STATIC1 | CM_CTRL_STATIC2;
+		/* truecolor RGB565 */
+		val |= CM_CTRL_LCDMUXSEL_VGA565_TFT555;
 	else
 	else
 		val = 0; /* no idea for this, don't trust the docs */
 		val = 0; /* no idea for this, don't trust the docs */
 
 
@@ -498,49 +399,24 @@ static void cp_clcd_enable(struct clcd_fb *fb)
 		   CM_CTRL_n24BITEN, val);
 		   CM_CTRL_n24BITEN, val);
 }
 }
 
 
-static unsigned long framesize = SZ_1M;
-
 static int cp_clcd_setup(struct clcd_fb *fb)
 static int cp_clcd_setup(struct clcd_fb *fb)
 {
 {
-	dma_addr_t dma;
-
-	fb->panel = &vga;
-
-	fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
-						    &dma, GFP_KERNEL);
-	if (!fb->fb.screen_base) {
-		printk(KERN_ERR "CLCD: unable to map framebuffer\n");
-		return -ENOMEM;
-	}
-
-	fb->fb.fix.smem_start	= dma;
-	fb->fb.fix.smem_len	= framesize;
-
-	return 0;
-}
-
-static int cp_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
-{
-	return dma_mmap_writecombine(&fb->dev->dev, vma,
-				     fb->fb.screen_base,
-				     fb->fb.fix.smem_start,
-				     fb->fb.fix.smem_len);
-}
+	fb->panel = versatile_clcd_get_panel("VGA");
+	if (!fb->panel)
+		return -EINVAL;
 
 
-static void cp_clcd_remove(struct clcd_fb *fb)
-{
-	dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
-			      fb->fb.screen_base, fb->fb.fix.smem_start);
+	return versatile_clcd_setup_dma(fb, SZ_1M);
 }
 }
 
 
 static struct clcd_board clcd_data = {
 static struct clcd_board clcd_data = {
 	.name		= "Integrator/CP",
 	.name		= "Integrator/CP",
+	.caps		= CLCD_CAP_5551 | CLCD_CAP_RGB565 | CLCD_CAP_888,
 	.check		= clcdfb_check,
 	.check		= clcdfb_check,
 	.decode		= clcdfb_decode,
 	.decode		= clcdfb_decode,
 	.enable		= cp_clcd_enable,
 	.enable		= cp_clcd_enable,
 	.setup		= cp_clcd_setup,
 	.setup		= cp_clcd_setup,
-	.mmap		= cp_clcd_mmap,
-	.remove		= cp_clcd_remove,
+	.mmap		= versatile_clcd_mmap_dma,
+	.remove		= versatile_clcd_remove_dma,
 };
 };
 
 
 static struct amba_device clcd_device = {
 static struct amba_device clcd_device = {
@@ -565,11 +441,23 @@ static struct amba_device *amba_devs[] __initdata = {
 	&clcd_device,
 	&clcd_device,
 };
 };
 
 
+#define REFCOUNTER (__io_address(INTEGRATOR_HDR_BASE) + 0x28)
+
+static void __init intcp_init_early(void)
+{
+	clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups));
+
+	integrator_init_early();
+
+#ifdef CONFIG_PLAT_VERSATILE_SCHED_CLOCK
+	versatile_sched_clock_init(REFCOUNTER, 24000000);
+#endif
+}
+
 static void __init intcp_init(void)
 static void __init intcp_init(void)
 {
 {
 	int i;
 	int i;
 
 
-	clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups));
 	platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
 	platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
 
 
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
@@ -599,8 +487,9 @@ static struct sys_timer cp_timer = {
 MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
 MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
 	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
 	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
 	.boot_params	= 0x00000100,
 	.boot_params	= 0x00000100,
-	.map_io		= intcp_map_io,
 	.reserve	= integrator_reserve,
 	.reserve	= integrator_reserve,
+	.map_io		= intcp_map_io,
+	.init_early	= intcp_init_early,
 	.init_irq	= intcp_init_irq,
 	.init_irq	= intcp_init_irq,
 	.timer		= &cp_timer,
 	.timer		= &cp_timer,
 	.init_machine	= intcp_init,
 	.init_machine	= intcp_init,

+ 2 - 1
arch/arm/mach-msm/timer.c

@@ -263,7 +263,7 @@ static void __init msm_timer_init(void)
 }
 }
 
 
 #ifdef CONFIG_SMP
 #ifdef CONFIG_SMP
-void __cpuinit local_timer_setup(struct clock_event_device *evt)
+int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
 {
 	struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER];
 	struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER];
 
 
@@ -295,6 +295,7 @@ void __cpuinit local_timer_setup(struct clock_event_device *evt)
 	gic_enable_ppi(clock->irq.irq);
 	gic_enable_ppi(clock->irq.irq);
 
 
 	clockevents_register_device(evt);
 	clockevents_register_device(evt);
+	return 0;
 }
 }
 
 
 inline int local_timer_ack(void)
 inline int local_timer_ack(void)

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

@@ -44,6 +44,7 @@ config ARCH_OMAP4
 	depends on ARCH_OMAP2PLUS
 	depends on ARCH_OMAP2PLUS
 	select CPU_V7
 	select CPU_V7
 	select ARM_GIC
 	select ARM_GIC
+	select LOCAL_TIMERS if SMP
 	select PL310_ERRATA_588369
 	select PL310_ERRATA_588369
 	select PL310_ERRATA_727915
 	select PL310_ERRATA_727915
 	select ARM_ERRATA_720789
 	select ARM_ERRATA_720789

+ 6 - 1
arch/arm/mach-omap2/timer-mpu.c

@@ -26,9 +26,14 @@
 /*
 /*
  * Setup the local clock events for a CPU.
  * Setup the local clock events for a CPU.
  */
  */
-void __cpuinit local_timer_setup(struct clock_event_device *evt)
+int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
 {
+	/* Local timers are not supprted on OMAP4430 ES1.0 */
+	if (omap_rev() == OMAP4430_REV_ES1_0)
+		return -ENXIO;
+
 	evt->irq = OMAP44XX_IRQ_LOCALTIMER;
 	evt->irq = OMAP44XX_IRQ_LOCALTIMER;
 	twd_timer_setup(evt);
 	twd_timer_setup(evt);
+	return 0;
 }
 }
 
 

+ 1 - 2
arch/arm/mach-realview/Makefile

@@ -8,6 +8,5 @@ obj-$(CONFIG_MACH_REALVIEW_PB11MP)	+= realview_pb11mp.o
 obj-$(CONFIG_MACH_REALVIEW_PB1176)	+= realview_pb1176.o
 obj-$(CONFIG_MACH_REALVIEW_PB1176)	+= realview_pb1176.o
 obj-$(CONFIG_MACH_REALVIEW_PBA8)	+= realview_pba8.o
 obj-$(CONFIG_MACH_REALVIEW_PBA8)	+= realview_pba8.o
 obj-$(CONFIG_MACH_REALVIEW_PBX)		+= realview_pbx.o
 obj-$(CONFIG_MACH_REALVIEW_PBX)		+= realview_pbx.o
-obj-$(CONFIG_SMP)			+= platsmp.o headsmp.o
+obj-$(CONFIG_SMP)			+= platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= hotplug.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= hotplug.o
-obj-$(CONFIG_LOCAL_TIMERS)		+= localtimer.o

+ 40 - 193
arch/arm/mach-realview/core.c

@@ -51,6 +51,7 @@
 #include <mach/irqs.h>
 #include <mach/irqs.h>
 #include <asm/hardware/timer-sp.h>
 #include <asm/hardware/timer-sp.h>
 
 
+#include <plat/clcd.h>
 #include <plat/sched_clock.h>
 #include <plat/sched_clock.h>
 
 
 #include "core.h"
 #include "core.h"
@@ -359,18 +360,19 @@ static struct clk_lookup lookups[] = {
 	}
 	}
 };
 };
 
 
-static int __init clk_init(void)
+void __init realview_init_early(void)
 {
 {
+	void __iomem *sys = __io_address(REALVIEW_SYS_BASE);
+
 	if (machine_is_realview_pb1176())
 	if (machine_is_realview_pb1176())
-		oscvco_clk.vcoreg = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC0_OFFSET;
+		oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC0_OFFSET;
 	else
 	else
-		oscvco_clk.vcoreg = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET;
+		oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC4_OFFSET;
 
 
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 
-	return 0;
+	versatile_sched_clock_init(sys + REALVIEW_SYS_24MHz_OFFSET, 24000000);
 }
 }
-core_initcall(clk_init);
 
 
 /*
 /*
  * CLCD support.
  * CLCD support.
@@ -385,157 +387,6 @@ core_initcall(clk_init);
 #define SYS_CLCD_ID_SANYO_2_5	(0x07 << 8)
 #define SYS_CLCD_ID_SANYO_2_5	(0x07 << 8)
 #define SYS_CLCD_ID_VGA		(0x1f << 8)
 #define SYS_CLCD_ID_VGA		(0x1f << 8)
 
 
-static struct clcd_panel vga = {
-	.mode		= {
-		.name		= "VGA",
-		.refresh	= 60,
-		.xres		= 640,
-		.yres		= 480,
-		.pixclock	= 39721,
-		.left_margin	= 40,
-		.right_margin	= 24,
-		.upper_margin	= 32,
-		.lower_margin	= 11,
-		.hsync_len	= 96,
-		.vsync_len	= 2,
-		.sync		= 0,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-	.width		= -1,
-	.height		= -1,
-	.tim2		= TIM2_BCD | TIM2_IPC,
-	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
-	.bpp		= 16,
-};
-
-static struct clcd_panel xvga = {
-	.mode		= {
-		.name		= "XVGA",
-		.refresh	= 60,
-		.xres		= 1024,
-		.yres		= 768,
-		.pixclock	= 15748,
-		.left_margin	= 152,
-		.right_margin	= 48,
-		.upper_margin	= 23,
-		.lower_margin	= 3,
-		.hsync_len	= 104,
-		.vsync_len	= 4,
-		.sync		= 0,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-	.width		= -1,
-	.height		= -1,
-	.tim2		= TIM2_BCD | TIM2_IPC,
-	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
-	.bpp		= 16,
-};
-
-static struct clcd_panel sanyo_3_8_in = {
-	.mode		= {
-		.name		= "Sanyo QVGA",
-		.refresh	= 116,
-		.xres		= 320,
-		.yres		= 240,
-		.pixclock	= 100000,
-		.left_margin	= 6,
-		.right_margin	= 6,
-		.upper_margin	= 5,
-		.lower_margin	= 5,
-		.hsync_len	= 6,
-		.vsync_len	= 6,
-		.sync		= 0,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-	.width		= -1,
-	.height		= -1,
-	.tim2		= TIM2_BCD,
-	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
-	.bpp		= 16,
-};
-
-static struct clcd_panel sanyo_2_5_in = {
-	.mode		= {
-		.name		= "Sanyo QVGA Portrait",
-		.refresh	= 116,
-		.xres		= 240,
-		.yres		= 320,
-		.pixclock	= 100000,
-		.left_margin	= 20,
-		.right_margin	= 10,
-		.upper_margin	= 2,
-		.lower_margin	= 2,
-		.hsync_len	= 10,
-		.vsync_len	= 2,
-		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-	.width		= -1,
-	.height		= -1,
-	.tim2		= TIM2_IVS | TIM2_IHS | TIM2_IPC,
-	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
-	.bpp		= 16,
-};
-
-static struct clcd_panel epson_2_2_in = {
-	.mode		= {
-		.name		= "Epson QCIF",
-		.refresh	= 390,
-		.xres		= 176,
-		.yres		= 220,
-		.pixclock	= 62500,
-		.left_margin	= 3,
-		.right_margin	= 2,
-		.upper_margin	= 1,
-		.lower_margin	= 0,
-		.hsync_len	= 3,
-		.vsync_len	= 2,
-		.sync		= 0,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-	.width		= -1,
-	.height		= -1,
-	.tim2		= TIM2_BCD | TIM2_IPC,
-	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
-	.bpp		= 16,
-};
-
-/*
- * Detect which LCD panel is connected, and return the appropriate
- * clcd_panel structure.  Note: we do not have any information on
- * the required timings for the 8.4in panel, so we presently assume
- * VGA timings.
- */
-static struct clcd_panel *realview_clcd_panel(void)
-{
-	void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
-	struct clcd_panel *vga_panel;
-	struct clcd_panel *panel;
-	u32 val;
-
-	if (machine_is_realview_eb())
-		vga_panel = &vga;
-	else
-		vga_panel = &xvga;
-
-	val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
-	if (val == SYS_CLCD_ID_SANYO_3_8)
-		panel = &sanyo_3_8_in;
-	else if (val == SYS_CLCD_ID_SANYO_2_5)
-		panel = &sanyo_2_5_in;
-	else if (val == SYS_CLCD_ID_EPSON_2_2)
-		panel = &epson_2_2_in;
-	else if (val == SYS_CLCD_ID_VGA)
-		panel = vga_panel;
-	else {
-		printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
-			val);
-		panel = vga_panel;
-	}
-
-	return panel;
-}
-
 /*
 /*
  * Disable all display connectors on the interface module.
  * Disable all display connectors on the interface module.
  */
  */
@@ -565,56 +416,60 @@ static void realview_clcd_enable(struct clcd_fb *fb)
 	writel(val, sys_clcd);
 	writel(val, sys_clcd);
 }
 }
 
 
+/*
+ * Detect which LCD panel is connected, and return the appropriate
+ * clcd_panel structure.  Note: we do not have any information on
+ * the required timings for the 8.4in panel, so we presently assume
+ * VGA timings.
+ */
 static int realview_clcd_setup(struct clcd_fb *fb)
 static int realview_clcd_setup(struct clcd_fb *fb)
 {
 {
+	void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
+	const char *panel_name, *vga_panel_name;
 	unsigned long framesize;
 	unsigned long framesize;
-	dma_addr_t dma;
+	u32 val;
 
 
-	if (machine_is_realview_eb())
+	if (machine_is_realview_eb()) {
 		/* VGA, 16bpp */
 		/* VGA, 16bpp */
 		framesize = 640 * 480 * 2;
 		framesize = 640 * 480 * 2;
-	else
+		vga_panel_name = "VGA";
+	} else {
 		/* XVGA, 16bpp */
 		/* XVGA, 16bpp */
 		framesize = 1024 * 768 * 2;
 		framesize = 1024 * 768 * 2;
-
-	fb->panel		= realview_clcd_panel();
-
-	fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
-						    &dma, GFP_KERNEL | GFP_DMA);
-	if (!fb->fb.screen_base) {
-		printk(KERN_ERR "CLCD: unable to map framebuffer\n");
-		return -ENOMEM;
+		vga_panel_name = "XVGA";
 	}
 	}
 
 
-	fb->fb.fix.smem_start	= dma;
-	fb->fb.fix.smem_len	= framesize;
-
-	return 0;
-}
+	val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
+	if (val == SYS_CLCD_ID_SANYO_3_8)
+		panel_name = "Sanyo TM38QV67A02A";
+	else if (val == SYS_CLCD_ID_SANYO_2_5)
+		panel_name = "Sanyo QVGA Portrait";
+	else if (val == SYS_CLCD_ID_EPSON_2_2)
+		panel_name = "Epson L2F50113T00";
+	else if (val == SYS_CLCD_ID_VGA)
+		panel_name = vga_panel_name;
+	else {
+		pr_err("CLCD: unknown LCD panel ID 0x%08x, using VGA\n", val);
+		panel_name = vga_panel_name;
+	}
 
 
-static int realview_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
-{
-	return dma_mmap_writecombine(&fb->dev->dev, vma,
-				     fb->fb.screen_base,
-				     fb->fb.fix.smem_start,
-				     fb->fb.fix.smem_len);
-}
+	fb->panel = versatile_clcd_get_panel(panel_name);
+	if (!fb->panel)
+		return -EINVAL;
 
 
-static void realview_clcd_remove(struct clcd_fb *fb)
-{
-	dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
-			      fb->fb.screen_base, fb->fb.fix.smem_start);
+	return versatile_clcd_setup_dma(fb, framesize);
 }
 }
 
 
 struct clcd_board clcd_plat_data = {
 struct clcd_board clcd_plat_data = {
 	.name		= "RealView",
 	.name		= "RealView",
+	.caps		= CLCD_CAP_ALL,
 	.check		= clcdfb_check,
 	.check		= clcdfb_check,
 	.decode		= clcdfb_decode,
 	.decode		= clcdfb_decode,
 	.disable	= realview_clcd_disable,
 	.disable	= realview_clcd_disable,
 	.enable		= realview_clcd_enable,
 	.enable		= realview_clcd_enable,
 	.setup		= realview_clcd_setup,
 	.setup		= realview_clcd_setup,
-	.mmap		= realview_clcd_mmap,
-	.remove		= realview_clcd_remove,
+	.mmap		= versatile_clcd_mmap_dma,
+	.remove		= versatile_clcd_remove_dma,
 };
 };
 
 
 #ifdef CONFIG_LEDS
 #ifdef CONFIG_LEDS
@@ -655,12 +510,6 @@ void realview_leds_event(led_event_t ledevt)
 }
 }
 #endif	/* CONFIG_LEDS */
 #endif	/* CONFIG_LEDS */
 
 
-/*
- * The sched_clock counter
- */
-#define REFCOUNTER		(__io_address(REALVIEW_SYS_BASE) + \
-				 REALVIEW_SYS_24MHz_OFFSET)
-
 /*
 /*
  * Where is the timer (VA)?
  * Where is the timer (VA)?
  */
  */
@@ -676,8 +525,6 @@ void __init realview_timer_init(unsigned int timer_irq)
 {
 {
 	u32 val;
 	u32 val;
 
 
-	versatile_sched_clock_init(REFCOUNTER, 24000000);
-
 	/* 
 	/* 
 	 * set clock frequency: 
 	 * set clock frequency: 
 	 *	REALVIEW_REFCLK is 32KHz
 	 *	REALVIEW_REFCLK is 32KHz

+ 1 - 1
arch/arm/mach-realview/core.h

@@ -42,7 +42,6 @@ static struct amba_device name##_device = {			\
 	},							\
 	},							\
 	.dma_mask	= ~0,					\
 	.dma_mask	= ~0,					\
 	.irq		= base##_IRQ,				\
 	.irq		= base##_IRQ,				\
-	/* .dma		= base##_DMA,*/				\
 }
 }
 
 
 struct machine_desc;
 struct machine_desc;
@@ -63,6 +62,7 @@ extern void realview_timer_init(unsigned int timer_irq);
 extern int realview_flash_register(struct resource *res, u32 num);
 extern int realview_flash_register(struct resource *res, u32 num);
 extern int realview_eth_register(const char *name, struct resource *res);
 extern int realview_eth_register(const char *name, struct resource *res);
 extern int realview_usb_register(struct resource *res);
 extern int realview_usb_register(struct resource *res);
+extern void realview_init_early(void);
 extern void realview_fixup(struct machine_desc *mdesc, struct tag *tags,
 extern void realview_fixup(struct machine_desc *mdesc, struct tag *tags,
 			   char **from, struct meminfo *meminfo);
 			   char **from, struct meminfo *meminfo);
 extern void (*realview_reset)(char);
 extern void (*realview_reset)(char);

+ 0 - 40
arch/arm/mach-realview/headsmp.S

@@ -1,40 +0,0 @@
-/*
- *  linux/arch/arm/mach-realview/headsmp.S
- *
- *  Copyright (c) 2003 ARM Limited
- *  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/linkage.h>
-#include <linux/init.h>
-
-	__INIT
-
-/*
- * Realview specific entry point for secondary CPUs.  This provides
- * a "holding pen" into which all secondary cores are held until we're
- * ready for them to initialise.
- */
-ENTRY(realview_secondary_startup)
-	mrc	p15, 0, r0, c0, c0, 5
-	and	r0, r0, #15
-	adr	r4, 1f
-	ldmia	r4, {r5, r6}
-	sub	r4, r4, r5
-	add	r6, r6, r4
-pen:	ldr	r7, [r6]
-	cmp	r7, r0
-	bne	pen
-
-	/*
-	 * we've been released from the holding pen: secondary_stack
-	 * should now contain the SVC stack for this core
-	 */
-	b	secondary_startup
-
-	.align
-1:	.long	.
-	.long	pen_release

+ 0 - 26
arch/arm/mach-realview/localtimer.c

@@ -1,26 +0,0 @@
-/*
- *  linux/arch/arm/mach-realview/localtimer.c
- *
- *  Copyright (C) 2002 ARM Ltd.
- *  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/init.h>
-#include <linux/smp.h>
-#include <linux/clockchips.h>
-
-#include <asm/irq.h>
-#include <asm/smp_twd.h>
-#include <asm/localtimer.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-void __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-	evt->irq = IRQ_LOCALTIMER;
-	twd_timer_setup(evt);
-}

+ 3 - 95
arch/arm/mach-realview/platsmp.c

@@ -10,44 +10,21 @@
  */
  */
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/jiffies.h>
 #include <linux/smp.h>
 #include <linux/smp.h>
 #include <linux/io.h>
 #include <linux/io.h>
 
 
-#include <asm/cacheflush.h>
 #include <mach/hardware.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
+#include <asm/smp_scu.h>
 #include <asm/unified.h>
 #include <asm/unified.h>
 
 
 #include <mach/board-eb.h>
 #include <mach/board-eb.h>
 #include <mach/board-pb11mp.h>
 #include <mach/board-pb11mp.h>
 #include <mach/board-pbx.h>
 #include <mach/board-pbx.h>
-#include <asm/smp_scu.h>
 
 
 #include "core.h"
 #include "core.h"
 
 
-extern void realview_secondary_startup(void);
-
-/*
- * control for which core is the next to come out of the secondary
- * boot "holding pen"
- */
-volatile int __cpuinitdata pen_release = -1;
-
-/*
- * Write pen_release in a way that is guaranteed to be visible to all
- * observers, irrespective of whether they're taking part in coherency
- * or not.  This is necessary for the hotplug code to work reliably.
- */
-static void __cpuinit write_pen_release(int val)
-{
-	pen_release = val;
-	smp_wmb();
-	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
-	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
-}
+extern void versatile_secondary_startup(void);
 
 
 static void __iomem *scu_base_addr(void)
 static void __iomem *scu_base_addr(void)
 {
 {
@@ -62,75 +39,6 @@ static void __iomem *scu_base_addr(void)
 		return (void __iomem *)0;
 		return (void __iomem *)0;
 }
 }
 
 
-static DEFINE_SPINLOCK(boot_lock);
-
-void __cpuinit platform_secondary_init(unsigned int cpu)
-{
-	/*
-	 * if any interrupts are already enabled for the primary
-	 * core (e.g. timer irq), then they will not have been enabled
-	 * for us: do so
-	 */
-	gic_secondary_init(0);
-
-	/*
-	 * let the primary processor know we're out of the
-	 * pen, then head off into the C entry point
-	 */
-	write_pen_release(-1);
-
-	/*
-	 * Synchronise with the boot thread.
-	 */
-	spin_lock(&boot_lock);
-	spin_unlock(&boot_lock);
-}
-
-int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
-{
-	unsigned long timeout;
-
-	/*
-	 * set synchronisation state between this boot processor
-	 * and the secondary one
-	 */
-	spin_lock(&boot_lock);
-
-	/*
-	 * The secondary processor is waiting to be released from
-	 * the holding pen - release it, then wait for it to flag
-	 * that it has been released by resetting pen_release.
-	 *
-	 * Note that "pen_release" is the hardware CPU ID, whereas
-	 * "cpu" is Linux's internal ID.
-	 */
-	write_pen_release(cpu);
-
-	/*
-	 * Send the secondary CPU a soft interrupt, thereby causing
-	 * the boot monitor to read the system wide flags register,
-	 * and branch to the address found there.
-	 */
-	smp_cross_call(cpumask_of(cpu), 1);
-
-	timeout = jiffies + (1 * HZ);
-	while (time_before(jiffies, timeout)) {
-		smp_rmb();
-		if (pen_release == -1)
-			break;
-
-		udelay(10);
-	}
-
-	/*
-	 * now the secondary core is starting up let it run its
-	 * calibrations, then wait for it to finish
-	 */
-	spin_unlock(&boot_lock);
-
-	return pen_release != -1 ? -ENOSYS : 0;
-}
-
 /*
 /*
  * Initialise the CPU possible map early - this describes the CPUs
  * Initialise the CPU possible map early - this describes the CPUs
  * which may be present or become present in the system.
  * which may be present or become present in the system.
@@ -174,6 +82,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 	 * until it receives a soft interrupt, and then the
 	 * until it receives a soft interrupt, and then the
 	 * secondary CPU branches to this address.
 	 * secondary CPU branches to this address.
 	 */
 	 */
-	__raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
+	__raw_writel(BSYM(virt_to_phys(versatile_secondary_startup)),
 		     __io_address(REALVIEW_SYS_FLAGSSET));
 		     __io_address(REALVIEW_SYS_FLAGSSET));
 }
 }

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

@@ -144,60 +144,39 @@ static struct pl022_ssp_controller ssp0_plat_data = {
  * These devices are connected via the core APB bridge
  * These devices are connected via the core APB bridge
  */
  */
 #define GPIO2_IRQ	{ IRQ_EB_GPIO2, NO_IRQ }
 #define GPIO2_IRQ	{ IRQ_EB_GPIO2, NO_IRQ }
-#define GPIO2_DMA	{ 0, 0 }
 #define GPIO3_IRQ	{ IRQ_EB_GPIO3, NO_IRQ }
 #define GPIO3_IRQ	{ IRQ_EB_GPIO3, NO_IRQ }
-#define GPIO3_DMA	{ 0, 0 }
 
 
 #define AACI_IRQ	{ IRQ_EB_AACI, NO_IRQ }
 #define AACI_IRQ	{ IRQ_EB_AACI, NO_IRQ }
-#define AACI_DMA	{ 0x80, 0x81 }
 #define MMCI0_IRQ	{ IRQ_EB_MMCI0A, IRQ_EB_MMCI0B }
 #define MMCI0_IRQ	{ IRQ_EB_MMCI0A, IRQ_EB_MMCI0B }
-#define MMCI0_DMA	{ 0x84, 0 }
 #define KMI0_IRQ	{ IRQ_EB_KMI0, NO_IRQ }
 #define KMI0_IRQ	{ IRQ_EB_KMI0, NO_IRQ }
-#define KMI0_DMA	{ 0, 0 }
 #define KMI1_IRQ	{ IRQ_EB_KMI1, NO_IRQ }
 #define KMI1_IRQ	{ IRQ_EB_KMI1, NO_IRQ }
-#define KMI1_DMA	{ 0, 0 }
 
 
 /*
 /*
  * These devices are connected directly to the multi-layer AHB switch
  * These devices are connected directly to the multi-layer AHB switch
  */
  */
 #define EB_SMC_IRQ	{ NO_IRQ, NO_IRQ }
 #define EB_SMC_IRQ	{ NO_IRQ, NO_IRQ }
-#define EB_SMC_DMA	{ 0, 0 }
 #define MPMC_IRQ	{ NO_IRQ, NO_IRQ }
 #define MPMC_IRQ	{ NO_IRQ, NO_IRQ }
-#define MPMC_DMA	{ 0, 0 }
 #define EB_CLCD_IRQ	{ IRQ_EB_CLCD, NO_IRQ }
 #define EB_CLCD_IRQ	{ IRQ_EB_CLCD, NO_IRQ }
-#define EB_CLCD_DMA	{ 0, 0 }
 #define DMAC_IRQ	{ IRQ_EB_DMA, NO_IRQ }
 #define DMAC_IRQ	{ IRQ_EB_DMA, NO_IRQ }
-#define DMAC_DMA	{ 0, 0 }
 
 
 /*
 /*
  * These devices are connected via the core APB bridge
  * These devices are connected via the core APB bridge
  */
  */
 #define SCTL_IRQ	{ NO_IRQ, NO_IRQ }
 #define SCTL_IRQ	{ NO_IRQ, NO_IRQ }
-#define SCTL_DMA	{ 0, 0 }
 #define EB_WATCHDOG_IRQ	{ IRQ_EB_WDOG, NO_IRQ }
 #define EB_WATCHDOG_IRQ	{ IRQ_EB_WDOG, NO_IRQ }
-#define EB_WATCHDOG_DMA	{ 0, 0 }
 #define EB_GPIO0_IRQ	{ IRQ_EB_GPIO0, NO_IRQ }
 #define EB_GPIO0_IRQ	{ IRQ_EB_GPIO0, NO_IRQ }
-#define EB_GPIO0_DMA	{ 0, 0 }
 #define GPIO1_IRQ	{ IRQ_EB_GPIO1, NO_IRQ }
 #define GPIO1_IRQ	{ IRQ_EB_GPIO1, NO_IRQ }
-#define GPIO1_DMA	{ 0, 0 }
 #define EB_RTC_IRQ	{ IRQ_EB_RTC, NO_IRQ }
 #define EB_RTC_IRQ	{ IRQ_EB_RTC, NO_IRQ }
-#define EB_RTC_DMA	{ 0, 0 }
 
 
 /*
 /*
  * These devices are connected via the DMA APB bridge
  * These devices are connected via the DMA APB bridge
  */
  */
 #define SCI_IRQ		{ IRQ_EB_SCI, NO_IRQ }
 #define SCI_IRQ		{ IRQ_EB_SCI, NO_IRQ }
-#define SCI_DMA		{ 7, 6 }
 #define EB_UART0_IRQ	{ IRQ_EB_UART0, NO_IRQ }
 #define EB_UART0_IRQ	{ IRQ_EB_UART0, NO_IRQ }
-#define EB_UART0_DMA	{ 15, 14 }
 #define EB_UART1_IRQ	{ IRQ_EB_UART1, NO_IRQ }
 #define EB_UART1_IRQ	{ IRQ_EB_UART1, NO_IRQ }
-#define EB_UART1_DMA	{ 13, 12 }
 #define EB_UART2_IRQ	{ IRQ_EB_UART2, NO_IRQ }
 #define EB_UART2_IRQ	{ IRQ_EB_UART2, NO_IRQ }
-#define EB_UART2_DMA	{ 11, 10 }
 #define EB_UART3_IRQ	{ IRQ_EB_UART3, NO_IRQ }
 #define EB_UART3_IRQ	{ IRQ_EB_UART3, NO_IRQ }
-#define EB_UART3_DMA	{ 0x86, 0x87 }
 #define EB_SSP_IRQ	{ IRQ_EB_SSP, NO_IRQ }
 #define EB_SSP_IRQ	{ IRQ_EB_SSP, NO_IRQ }
-#define EB_SSP_DMA	{ 9, 8 }
 
 
 /* FPGA Primecells */
 /* FPGA Primecells */
 AMBA_DEVICE(aaci,  "fpga:aaci",  AACI,     NULL);
 AMBA_DEVICE(aaci,  "fpga:aaci",  AACI,     NULL);
@@ -487,6 +466,7 @@ MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
 	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100,
 	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100,
 	.fixup		= realview_fixup,
 	.fixup		= realview_fixup,
 	.map_io		= realview_eb_map_io,
 	.map_io		= realview_eb_map_io,
+	.init_early	= realview_init_early,
 	.init_irq	= gic_init_irq,
 	.init_irq	= gic_init_irq,
 	.timer		= &realview_eb_timer,
 	.timer		= &realview_eb_timer,
 	.init_machine	= realview_eb_init,
 	.init_machine	= realview_eb_init,

+ 1 - 21
arch/arm/mach-realview/realview_pb1176.c

@@ -134,47 +134,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
  * RealView PB1176 AMBA devices
  * RealView PB1176 AMBA devices
  */
  */
 #define GPIO2_IRQ	{ IRQ_PB1176_GPIO2, NO_IRQ }
 #define GPIO2_IRQ	{ IRQ_PB1176_GPIO2, NO_IRQ }
-#define GPIO2_DMA	{ 0, 0 }
 #define GPIO3_IRQ	{ IRQ_PB1176_GPIO3, NO_IRQ }
 #define GPIO3_IRQ	{ IRQ_PB1176_GPIO3, NO_IRQ }
-#define GPIO3_DMA	{ 0, 0 }
 #define AACI_IRQ	{ IRQ_PB1176_AACI, NO_IRQ }
 #define AACI_IRQ	{ IRQ_PB1176_AACI, NO_IRQ }
-#define AACI_DMA	{ 0x80, 0x81 }
 #define MMCI0_IRQ	{ IRQ_PB1176_MMCI0A, IRQ_PB1176_MMCI0B }
 #define MMCI0_IRQ	{ IRQ_PB1176_MMCI0A, IRQ_PB1176_MMCI0B }
-#define MMCI0_DMA	{ 0x84, 0 }
 #define KMI0_IRQ	{ IRQ_PB1176_KMI0, NO_IRQ }
 #define KMI0_IRQ	{ IRQ_PB1176_KMI0, NO_IRQ }
-#define KMI0_DMA	{ 0, 0 }
 #define KMI1_IRQ	{ IRQ_PB1176_KMI1, NO_IRQ }
 #define KMI1_IRQ	{ IRQ_PB1176_KMI1, NO_IRQ }
-#define KMI1_DMA	{ 0, 0 }
 #define PB1176_SMC_IRQ	{ NO_IRQ, NO_IRQ }
 #define PB1176_SMC_IRQ	{ NO_IRQ, NO_IRQ }
-#define PB1176_SMC_DMA	{ 0, 0 }
 #define MPMC_IRQ	{ NO_IRQ, NO_IRQ }
 #define MPMC_IRQ	{ NO_IRQ, NO_IRQ }
-#define MPMC_DMA	{ 0, 0 }
 #define PB1176_CLCD_IRQ	{ IRQ_DC1176_CLCD, NO_IRQ }
 #define PB1176_CLCD_IRQ	{ IRQ_DC1176_CLCD, NO_IRQ }
-#define PB1176_CLCD_DMA	{ 0, 0 }
 #define SCTL_IRQ	{ NO_IRQ, NO_IRQ }
 #define SCTL_IRQ	{ NO_IRQ, NO_IRQ }
-#define SCTL_DMA	{ 0, 0 }
 #define PB1176_WATCHDOG_IRQ	{ IRQ_DC1176_WATCHDOG, NO_IRQ }
 #define PB1176_WATCHDOG_IRQ	{ IRQ_DC1176_WATCHDOG, NO_IRQ }
-#define PB1176_WATCHDOG_DMA	{ 0, 0 }
 #define PB1176_GPIO0_IRQ	{ IRQ_PB1176_GPIO0, NO_IRQ }
 #define PB1176_GPIO0_IRQ	{ IRQ_PB1176_GPIO0, NO_IRQ }
-#define PB1176_GPIO0_DMA	{ 0, 0 }
 #define GPIO1_IRQ	{ IRQ_PB1176_GPIO1, NO_IRQ }
 #define GPIO1_IRQ	{ IRQ_PB1176_GPIO1, NO_IRQ }
-#define GPIO1_DMA	{ 0, 0 }
 #define PB1176_RTC_IRQ	{ IRQ_DC1176_RTC, NO_IRQ }
 #define PB1176_RTC_IRQ	{ IRQ_DC1176_RTC, NO_IRQ }
-#define PB1176_RTC_DMA	{ 0, 0 }
 #define SCI_IRQ		{ IRQ_PB1176_SCI, NO_IRQ }
 #define SCI_IRQ		{ IRQ_PB1176_SCI, NO_IRQ }
-#define SCI_DMA		{ 7, 6 }
 #define PB1176_UART0_IRQ	{ IRQ_DC1176_UART0, NO_IRQ }
 #define PB1176_UART0_IRQ	{ IRQ_DC1176_UART0, NO_IRQ }
-#define PB1176_UART0_DMA	{ 15, 14 }
 #define PB1176_UART1_IRQ	{ IRQ_DC1176_UART1, NO_IRQ }
 #define PB1176_UART1_IRQ	{ IRQ_DC1176_UART1, NO_IRQ }
-#define PB1176_UART1_DMA	{ 13, 12 }
 #define PB1176_UART2_IRQ	{ IRQ_DC1176_UART2, NO_IRQ }
 #define PB1176_UART2_IRQ	{ IRQ_DC1176_UART2, NO_IRQ }
-#define PB1176_UART2_DMA	{ 11, 10 }
 #define PB1176_UART3_IRQ	{ IRQ_DC1176_UART3, NO_IRQ }
 #define PB1176_UART3_IRQ	{ IRQ_DC1176_UART3, NO_IRQ }
-#define PB1176_UART3_DMA	{ 0x86, 0x87 }
 #define PB1176_UART4_IRQ	{ IRQ_PB1176_UART4, NO_IRQ }
 #define PB1176_UART4_IRQ	{ IRQ_PB1176_UART4, NO_IRQ }
-#define PB1176_UART4_DMA	{ 0, 0 }
 #define PB1176_SSP_IRQ		{ IRQ_DC1176_SSP, NO_IRQ }
 #define PB1176_SSP_IRQ		{ IRQ_DC1176_SSP, NO_IRQ }
-#define PB1176_SSP_DMA		{ 9, 8 }
 
 
 /* FPGA Primecells */
 /* FPGA Primecells */
 AMBA_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
 AMBA_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
@@ -382,6 +361,7 @@ MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
 	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100,
 	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100,
 	.fixup		= realview_pb1176_fixup,
 	.fixup		= realview_pb1176_fixup,
 	.map_io		= realview_pb1176_map_io,
 	.map_io		= realview_pb1176_map_io,
+	.init_early	= realview_init_early,
 	.init_irq	= gic_init_irq,
 	.init_irq	= gic_init_irq,
 	.timer		= &realview_pb1176_timer,
 	.timer		= &realview_pb1176_timer,
 	.init_machine	= realview_pb1176_init,
 	.init_machine	= realview_pb1176_init,

+ 1 - 21
arch/arm/mach-realview/realview_pb11mp.c

@@ -136,47 +136,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
  */
  */
 
 
 #define GPIO2_IRQ		{ IRQ_PB11MP_GPIO2, NO_IRQ }
 #define GPIO2_IRQ		{ IRQ_PB11MP_GPIO2, NO_IRQ }
-#define GPIO2_DMA		{ 0, 0 }
 #define GPIO3_IRQ		{ IRQ_PB11MP_GPIO3, NO_IRQ }
 #define GPIO3_IRQ		{ IRQ_PB11MP_GPIO3, NO_IRQ }
-#define GPIO3_DMA		{ 0, 0 }
 #define AACI_IRQ		{ IRQ_TC11MP_AACI, NO_IRQ }
 #define AACI_IRQ		{ IRQ_TC11MP_AACI, NO_IRQ }
-#define AACI_DMA		{ 0x80, 0x81 }
 #define MMCI0_IRQ		{ IRQ_TC11MP_MMCI0A, IRQ_TC11MP_MMCI0B }
 #define MMCI0_IRQ		{ IRQ_TC11MP_MMCI0A, IRQ_TC11MP_MMCI0B }
-#define MMCI0_DMA		{ 0x84, 0 }
 #define KMI0_IRQ		{ IRQ_TC11MP_KMI0, NO_IRQ }
 #define KMI0_IRQ		{ IRQ_TC11MP_KMI0, NO_IRQ }
-#define KMI0_DMA		{ 0, 0 }
 #define KMI1_IRQ		{ IRQ_TC11MP_KMI1, NO_IRQ }
 #define KMI1_IRQ		{ IRQ_TC11MP_KMI1, NO_IRQ }
-#define KMI1_DMA		{ 0, 0 }
 #define PB11MP_SMC_IRQ		{ NO_IRQ, NO_IRQ }
 #define PB11MP_SMC_IRQ		{ NO_IRQ, NO_IRQ }
-#define PB11MP_SMC_DMA		{ 0, 0 }
 #define MPMC_IRQ		{ NO_IRQ, NO_IRQ }
 #define MPMC_IRQ		{ NO_IRQ, NO_IRQ }
-#define MPMC_DMA		{ 0, 0 }
 #define PB11MP_CLCD_IRQ		{ IRQ_PB11MP_CLCD, NO_IRQ }
 #define PB11MP_CLCD_IRQ		{ IRQ_PB11MP_CLCD, NO_IRQ }
-#define PB11MP_CLCD_DMA		{ 0, 0 }
 #define DMAC_IRQ		{ IRQ_PB11MP_DMAC, NO_IRQ }
 #define DMAC_IRQ		{ IRQ_PB11MP_DMAC, NO_IRQ }
-#define DMAC_DMA		{ 0, 0 }
 #define SCTL_IRQ		{ NO_IRQ, NO_IRQ }
 #define SCTL_IRQ		{ NO_IRQ, NO_IRQ }
-#define SCTL_DMA		{ 0, 0 }
 #define PB11MP_WATCHDOG_IRQ	{ IRQ_PB11MP_WATCHDOG, NO_IRQ }
 #define PB11MP_WATCHDOG_IRQ	{ IRQ_PB11MP_WATCHDOG, NO_IRQ }
-#define PB11MP_WATCHDOG_DMA	{ 0, 0 }
 #define PB11MP_GPIO0_IRQ	{ IRQ_PB11MP_GPIO0, NO_IRQ }
 #define PB11MP_GPIO0_IRQ	{ IRQ_PB11MP_GPIO0, NO_IRQ }
-#define PB11MP_GPIO0_DMA	{ 0, 0 }
 #define GPIO1_IRQ		{ IRQ_PB11MP_GPIO1, NO_IRQ }
 #define GPIO1_IRQ		{ IRQ_PB11MP_GPIO1, NO_IRQ }
-#define GPIO1_DMA		{ 0, 0 }
 #define PB11MP_RTC_IRQ		{ IRQ_TC11MP_RTC, NO_IRQ }
 #define PB11MP_RTC_IRQ		{ IRQ_TC11MP_RTC, NO_IRQ }
-#define PB11MP_RTC_DMA		{ 0, 0 }
 #define SCI_IRQ			{ IRQ_PB11MP_SCI, NO_IRQ }
 #define SCI_IRQ			{ IRQ_PB11MP_SCI, NO_IRQ }
-#define SCI_DMA			{ 7, 6 }
 #define PB11MP_UART0_IRQ	{ IRQ_TC11MP_UART0, NO_IRQ }
 #define PB11MP_UART0_IRQ	{ IRQ_TC11MP_UART0, NO_IRQ }
-#define PB11MP_UART0_DMA	{ 15, 14 }
 #define PB11MP_UART1_IRQ	{ IRQ_TC11MP_UART1, NO_IRQ }
 #define PB11MP_UART1_IRQ	{ IRQ_TC11MP_UART1, NO_IRQ }
-#define PB11MP_UART1_DMA	{ 13, 12 }
 #define PB11MP_UART2_IRQ	{ IRQ_PB11MP_UART2, NO_IRQ }
 #define PB11MP_UART2_IRQ	{ IRQ_PB11MP_UART2, NO_IRQ }
-#define PB11MP_UART2_DMA	{ 11, 10 }
 #define PB11MP_UART3_IRQ	{ IRQ_PB11MP_UART3, NO_IRQ }
 #define PB11MP_UART3_IRQ	{ IRQ_PB11MP_UART3, NO_IRQ }
-#define PB11MP_UART3_DMA	{ 0x86, 0x87 }
 #define PB11MP_SSP_IRQ		{ IRQ_PB11MP_SSP, NO_IRQ }
 #define PB11MP_SSP_IRQ		{ IRQ_PB11MP_SSP, NO_IRQ }
-#define PB11MP_SSP_DMA		{ 9, 8 }
 
 
 /* FPGA Primecells */
 /* FPGA Primecells */
 AMBA_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
 AMBA_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
@@ -384,6 +363,7 @@ MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
 	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100,
 	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100,
 	.fixup		= realview_fixup,
 	.fixup		= realview_fixup,
 	.map_io		= realview_pb11mp_map_io,
 	.map_io		= realview_pb11mp_map_io,
+	.init_early	= realview_init_early,
 	.init_irq	= gic_init_irq,
 	.init_irq	= gic_init_irq,
 	.timer		= &realview_pb11mp_timer,
 	.timer		= &realview_pb11mp_timer,
 	.init_machine	= realview_pb11mp_init,
 	.init_machine	= realview_pb11mp_init,

+ 1 - 21
arch/arm/mach-realview/realview_pba8.c

@@ -126,47 +126,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
  */
  */
 
 
 #define GPIO2_IRQ		{ IRQ_PBA8_GPIO2, NO_IRQ }
 #define GPIO2_IRQ		{ IRQ_PBA8_GPIO2, NO_IRQ }
-#define GPIO2_DMA		{ 0, 0 }
 #define GPIO3_IRQ		{ IRQ_PBA8_GPIO3, NO_IRQ }
 #define GPIO3_IRQ		{ IRQ_PBA8_GPIO3, NO_IRQ }
-#define GPIO3_DMA		{ 0, 0 }
 #define AACI_IRQ		{ IRQ_PBA8_AACI, NO_IRQ }
 #define AACI_IRQ		{ IRQ_PBA8_AACI, NO_IRQ }
-#define AACI_DMA		{ 0x80, 0x81 }
 #define MMCI0_IRQ		{ IRQ_PBA8_MMCI0A, IRQ_PBA8_MMCI0B }
 #define MMCI0_IRQ		{ IRQ_PBA8_MMCI0A, IRQ_PBA8_MMCI0B }
-#define MMCI0_DMA		{ 0x84, 0 }
 #define KMI0_IRQ		{ IRQ_PBA8_KMI0, NO_IRQ }
 #define KMI0_IRQ		{ IRQ_PBA8_KMI0, NO_IRQ }
-#define KMI0_DMA		{ 0, 0 }
 #define KMI1_IRQ		{ IRQ_PBA8_KMI1, NO_IRQ }
 #define KMI1_IRQ		{ IRQ_PBA8_KMI1, NO_IRQ }
-#define KMI1_DMA		{ 0, 0 }
 #define PBA8_SMC_IRQ		{ NO_IRQ, NO_IRQ }
 #define PBA8_SMC_IRQ		{ NO_IRQ, NO_IRQ }
-#define PBA8_SMC_DMA		{ 0, 0 }
 #define MPMC_IRQ		{ NO_IRQ, NO_IRQ }
 #define MPMC_IRQ		{ NO_IRQ, NO_IRQ }
-#define MPMC_DMA		{ 0, 0 }
 #define PBA8_CLCD_IRQ		{ IRQ_PBA8_CLCD, NO_IRQ }
 #define PBA8_CLCD_IRQ		{ IRQ_PBA8_CLCD, NO_IRQ }
-#define PBA8_CLCD_DMA		{ 0, 0 }
 #define DMAC_IRQ		{ IRQ_PBA8_DMAC, NO_IRQ }
 #define DMAC_IRQ		{ IRQ_PBA8_DMAC, NO_IRQ }
-#define DMAC_DMA		{ 0, 0 }
 #define SCTL_IRQ		{ NO_IRQ, NO_IRQ }
 #define SCTL_IRQ		{ NO_IRQ, NO_IRQ }
-#define SCTL_DMA		{ 0, 0 }
 #define PBA8_WATCHDOG_IRQ	{ IRQ_PBA8_WATCHDOG, NO_IRQ }
 #define PBA8_WATCHDOG_IRQ	{ IRQ_PBA8_WATCHDOG, NO_IRQ }
-#define PBA8_WATCHDOG_DMA	{ 0, 0 }
 #define PBA8_GPIO0_IRQ		{ IRQ_PBA8_GPIO0, NO_IRQ }
 #define PBA8_GPIO0_IRQ		{ IRQ_PBA8_GPIO0, NO_IRQ }
-#define PBA8_GPIO0_DMA		{ 0, 0 }
 #define GPIO1_IRQ		{ IRQ_PBA8_GPIO1, NO_IRQ }
 #define GPIO1_IRQ		{ IRQ_PBA8_GPIO1, NO_IRQ }
-#define GPIO1_DMA		{ 0, 0 }
 #define PBA8_RTC_IRQ		{ IRQ_PBA8_RTC, NO_IRQ }
 #define PBA8_RTC_IRQ		{ IRQ_PBA8_RTC, NO_IRQ }
-#define PBA8_RTC_DMA		{ 0, 0 }
 #define SCI_IRQ			{ IRQ_PBA8_SCI, NO_IRQ }
 #define SCI_IRQ			{ IRQ_PBA8_SCI, NO_IRQ }
-#define SCI_DMA			{ 7, 6 }
 #define PBA8_UART0_IRQ		{ IRQ_PBA8_UART0, NO_IRQ }
 #define PBA8_UART0_IRQ		{ IRQ_PBA8_UART0, NO_IRQ }
-#define PBA8_UART0_DMA		{ 15, 14 }
 #define PBA8_UART1_IRQ		{ IRQ_PBA8_UART1, NO_IRQ }
 #define PBA8_UART1_IRQ		{ IRQ_PBA8_UART1, NO_IRQ }
-#define PBA8_UART1_DMA		{ 13, 12 }
 #define PBA8_UART2_IRQ		{ IRQ_PBA8_UART2, NO_IRQ }
 #define PBA8_UART2_IRQ		{ IRQ_PBA8_UART2, NO_IRQ }
-#define PBA8_UART2_DMA		{ 11, 10 }
 #define PBA8_UART3_IRQ		{ IRQ_PBA8_UART3, NO_IRQ }
 #define PBA8_UART3_IRQ		{ IRQ_PBA8_UART3, NO_IRQ }
-#define PBA8_UART3_DMA		{ 0x86, 0x87 }
 #define PBA8_SSP_IRQ		{ IRQ_PBA8_SSP, NO_IRQ }
 #define PBA8_SSP_IRQ		{ IRQ_PBA8_SSP, NO_IRQ }
-#define PBA8_SSP_DMA		{ 9, 8 }
 
 
 /* FPGA Primecells */
 /* FPGA Primecells */
 AMBA_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
 AMBA_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
@@ -334,6 +313,7 @@ MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
 	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100,
 	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100,
 	.fixup		= realview_fixup,
 	.fixup		= realview_fixup,
 	.map_io		= realview_pba8_map_io,
 	.map_io		= realview_pba8_map_io,
+	.init_early	= realview_init_early,
 	.init_irq	= gic_init_irq,
 	.init_irq	= gic_init_irq,
 	.timer		= &realview_pba8_timer,
 	.timer		= &realview_pba8_timer,
 	.init_machine	= realview_pba8_init,
 	.init_machine	= realview_pba8_init,

+ 1 - 21
arch/arm/mach-realview/realview_pbx.c

@@ -148,47 +148,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
  */
  */
 
 
 #define GPIO2_IRQ		{ IRQ_PBX_GPIO2, NO_IRQ }
 #define GPIO2_IRQ		{ IRQ_PBX_GPIO2, NO_IRQ }
-#define GPIO2_DMA		{ 0, 0 }
 #define GPIO3_IRQ		{ IRQ_PBX_GPIO3, NO_IRQ }
 #define GPIO3_IRQ		{ IRQ_PBX_GPIO3, NO_IRQ }
-#define GPIO3_DMA		{ 0, 0 }
 #define AACI_IRQ		{ IRQ_PBX_AACI, NO_IRQ }
 #define AACI_IRQ		{ IRQ_PBX_AACI, NO_IRQ }
-#define AACI_DMA		{ 0x80, 0x81 }
 #define MMCI0_IRQ		{ IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B }
 #define MMCI0_IRQ		{ IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B }
-#define MMCI0_DMA		{ 0x84, 0 }
 #define KMI0_IRQ		{ IRQ_PBX_KMI0, NO_IRQ }
 #define KMI0_IRQ		{ IRQ_PBX_KMI0, NO_IRQ }
-#define KMI0_DMA		{ 0, 0 }
 #define KMI1_IRQ		{ IRQ_PBX_KMI1, NO_IRQ }
 #define KMI1_IRQ		{ IRQ_PBX_KMI1, NO_IRQ }
-#define KMI1_DMA		{ 0, 0 }
 #define PBX_SMC_IRQ		{ NO_IRQ, NO_IRQ }
 #define PBX_SMC_IRQ		{ NO_IRQ, NO_IRQ }
-#define PBX_SMC_DMA		{ 0, 0 }
 #define MPMC_IRQ		{ NO_IRQ, NO_IRQ }
 #define MPMC_IRQ		{ NO_IRQ, NO_IRQ }
-#define MPMC_DMA		{ 0, 0 }
 #define PBX_CLCD_IRQ		{ IRQ_PBX_CLCD, NO_IRQ }
 #define PBX_CLCD_IRQ		{ IRQ_PBX_CLCD, NO_IRQ }
-#define PBX_CLCD_DMA		{ 0, 0 }
 #define DMAC_IRQ		{ IRQ_PBX_DMAC, NO_IRQ }
 #define DMAC_IRQ		{ IRQ_PBX_DMAC, NO_IRQ }
-#define DMAC_DMA		{ 0, 0 }
 #define SCTL_IRQ		{ NO_IRQ, NO_IRQ }
 #define SCTL_IRQ		{ NO_IRQ, NO_IRQ }
-#define SCTL_DMA		{ 0, 0 }
 #define PBX_WATCHDOG_IRQ	{ IRQ_PBX_WATCHDOG, NO_IRQ }
 #define PBX_WATCHDOG_IRQ	{ IRQ_PBX_WATCHDOG, NO_IRQ }
-#define PBX_WATCHDOG_DMA	{ 0, 0 }
 #define PBX_GPIO0_IRQ		{ IRQ_PBX_GPIO0, NO_IRQ }
 #define PBX_GPIO0_IRQ		{ IRQ_PBX_GPIO0, NO_IRQ }
-#define PBX_GPIO0_DMA		{ 0, 0 }
 #define GPIO1_IRQ		{ IRQ_PBX_GPIO1, NO_IRQ }
 #define GPIO1_IRQ		{ IRQ_PBX_GPIO1, NO_IRQ }
-#define GPIO1_DMA		{ 0, 0 }
 #define PBX_RTC_IRQ		{ IRQ_PBX_RTC, NO_IRQ }
 #define PBX_RTC_IRQ		{ IRQ_PBX_RTC, NO_IRQ }
-#define PBX_RTC_DMA		{ 0, 0 }
 #define SCI_IRQ			{ IRQ_PBX_SCI, NO_IRQ }
 #define SCI_IRQ			{ IRQ_PBX_SCI, NO_IRQ }
-#define SCI_DMA			{ 7, 6 }
 #define PBX_UART0_IRQ		{ IRQ_PBX_UART0, NO_IRQ }
 #define PBX_UART0_IRQ		{ IRQ_PBX_UART0, NO_IRQ }
-#define PBX_UART0_DMA		{ 15, 14 }
 #define PBX_UART1_IRQ		{ IRQ_PBX_UART1, NO_IRQ }
 #define PBX_UART1_IRQ		{ IRQ_PBX_UART1, NO_IRQ }
-#define PBX_UART1_DMA		{ 13, 12 }
 #define PBX_UART2_IRQ		{ IRQ_PBX_UART2, NO_IRQ }
 #define PBX_UART2_IRQ		{ IRQ_PBX_UART2, NO_IRQ }
-#define PBX_UART2_DMA		{ 11, 10 }
 #define PBX_UART3_IRQ		{ IRQ_PBX_UART3, NO_IRQ }
 #define PBX_UART3_IRQ		{ IRQ_PBX_UART3, NO_IRQ }
-#define PBX_UART3_DMA		{ 0x86, 0x87 }
 #define PBX_SSP_IRQ		{ IRQ_PBX_SSP, NO_IRQ }
 #define PBX_SSP_IRQ		{ IRQ_PBX_SSP, NO_IRQ }
-#define PBX_SSP_DMA		{ 9, 8 }
 
 
 /* FPGA Primecells */
 /* FPGA Primecells */
 AMBA_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
 AMBA_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
@@ -417,6 +396,7 @@ MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
 	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100,
 	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100,
 	.fixup		= realview_pbx_fixup,
 	.fixup		= realview_pbx_fixup,
 	.map_io		= realview_pbx_map_io,
 	.map_io		= realview_pbx_map_io,
+	.init_early	= realview_init_early,
 	.init_irq	= gic_init_irq,
 	.init_irq	= gic_init_irq,
 	.timer		= &realview_pbx_timer,
 	.timer		= &realview_pbx_timer,
 	.init_machine	= realview_pbx_init,
 	.init_machine	= realview_pbx_init,

+ 2 - 1
arch/arm/mach-shmobile/localtimer.c

@@ -18,8 +18,9 @@
 /*
 /*
  * Setup the local clock events for a CPU.
  * Setup the local clock events for a CPU.
  */
  */
-void __cpuinit local_timer_setup(struct clock_event_device *evt)
+int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
 {
 	evt->irq = 29;
 	evt->irq = 29;
 	twd_timer_setup(evt);
 	twd_timer_setup(evt);
+	return 0;
 }
 }

+ 2 - 1
arch/arm/mach-tegra/localtimer.c

@@ -18,8 +18,9 @@
 /*
 /*
  * Setup the local clock events for a CPU.
  * Setup the local clock events for a CPU.
  */
  */
-void __cpuinit local_timer_setup(struct clock_event_device *evt)
+int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
 {
 	evt->irq = IRQ_LOCALTIMER;
 	evt->irq = IRQ_LOCALTIMER;
 	twd_timer_setup(evt);
 	twd_timer_setup(evt);
+	return 0;
 }
 }

+ 2 - 1
arch/arm/mach-ux500/localtimer.c

@@ -21,8 +21,9 @@
 /*
 /*
  * Setup the local clock events for a CPU.
  * Setup the local clock events for a CPU.
  */
  */
-void __cpuinit local_timer_setup(struct clock_event_device *evt)
+int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
 {
 	evt->irq = IRQ_LOCALTIMER;
 	evt->irq = IRQ_LOCALTIMER;
 	twd_timer_setup(evt);
 	twd_timer_setup(evt);
+	return 0;
 }
 }

+ 64 - 231
arch/arm/mach-versatile/core.c

@@ -50,6 +50,8 @@
 #include <mach/platform.h>
 #include <mach/platform.h>
 #include <asm/hardware/timer-sp.h>
 #include <asm/hardware/timer-sp.h>
 
 
+#include <plat/clcd.h>
+#include <plat/fpga-irq.h>
 #include <plat/sched_clock.h>
 #include <plat/sched_clock.h>
 
 
 #include "core.h"
 #include "core.h"
@@ -63,47 +65,12 @@
 #define VA_VIC_BASE		__io_address(VERSATILE_VIC_BASE)
 #define VA_VIC_BASE		__io_address(VERSATILE_VIC_BASE)
 #define VA_SIC_BASE		__io_address(VERSATILE_SIC_BASE)
 #define VA_SIC_BASE		__io_address(VERSATILE_SIC_BASE)
 
 
-static void sic_mask_irq(struct irq_data *d)
-{
-	unsigned int irq = d->irq - IRQ_SIC_START;
-
-	writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
-}
-
-static void sic_unmask_irq(struct irq_data *d)
-{
-	unsigned int irq = d->irq - IRQ_SIC_START;
-
-	writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_SET);
-}
-
-static struct irq_chip sic_chip = {
-	.name		= "SIC",
-	.irq_ack	= sic_mask_irq,
-	.irq_mask	= sic_mask_irq,
-	.irq_unmask	= sic_unmask_irq,
+static struct fpga_irq_data sic_irq = {
+	.base		= VA_SIC_BASE,
+	.irq_start	= IRQ_SIC_START,
+	.chip.name	= "SIC",
 };
 };
 
 
-static void
-sic_handle_irq(unsigned int irq, struct irq_desc *desc)
-{
-	unsigned long status = readl(VA_SIC_BASE + SIC_IRQ_STATUS);
-
-	if (status == 0) {
-		do_bad_IRQ(irq, desc);
-		return;
-	}
-
-	do {
-		irq = ffs(status) - 1;
-		status &= ~(1 << irq);
-
-		irq += IRQ_SIC_START;
-
-		generic_handle_irq(irq);
-	} while (status);
-}
-
 #if 1
 #if 1
 #define IRQ_MMCI0A	IRQ_VICSOURCE22
 #define IRQ_MMCI0A	IRQ_VICSOURCE22
 #define IRQ_AACI	IRQ_VICSOURCE24
 #define IRQ_AACI	IRQ_VICSOURCE24
@@ -118,22 +85,11 @@ sic_handle_irq(unsigned int irq, struct irq_desc *desc)
 
 
 void __init versatile_init_irq(void)
 void __init versatile_init_irq(void)
 {
 {
-	unsigned int i;
-
 	vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0);
 	vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0);
 
 
-	set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq);
-
-	/* Do second interrupt controller */
 	writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
 	writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
 
 
-	for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) {
-		if ((PIC_MASK & (1 << (i - IRQ_SIC_START))) == 0) {
-			set_irq_chip(i, &sic_chip);
-			set_irq_handler(i, handle_level_irq);
-			set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-		}
-	}
+	fpga_irq_init(IRQ_VICSOURCE31, ~PIC_MASK, &sic_irq);
 
 
 	/*
 	/*
 	 * Interrupts on secondary controller from 0 to 8 are routed to
 	 * Interrupts on secondary controller from 0 to 8 are routed to
@@ -476,127 +432,7 @@ static struct clk_lookup lookups[] = {
 #define SYS_CLCD_ID_SANYO_2_5	(0x07 << 8)
 #define SYS_CLCD_ID_SANYO_2_5	(0x07 << 8)
 #define SYS_CLCD_ID_VGA		(0x1f << 8)
 #define SYS_CLCD_ID_VGA		(0x1f << 8)
 
 
-static struct clcd_panel vga = {
-	.mode		= {
-		.name		= "VGA",
-		.refresh	= 60,
-		.xres		= 640,
-		.yres		= 480,
-		.pixclock	= 39721,
-		.left_margin	= 40,
-		.right_margin	= 24,
-		.upper_margin	= 32,
-		.lower_margin	= 11,
-		.hsync_len	= 96,
-		.vsync_len	= 2,
-		.sync		= 0,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-	.width		= -1,
-	.height		= -1,
-	.tim2		= TIM2_BCD | TIM2_IPC,
-	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
-	.bpp		= 16,
-};
-
-static struct clcd_panel sanyo_3_8_in = {
-	.mode		= {
-		.name		= "Sanyo QVGA",
-		.refresh	= 116,
-		.xres		= 320,
-		.yres		= 240,
-		.pixclock	= 100000,
-		.left_margin	= 6,
-		.right_margin	= 6,
-		.upper_margin	= 5,
-		.lower_margin	= 5,
-		.hsync_len	= 6,
-		.vsync_len	= 6,
-		.sync		= 0,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-	.width		= -1,
-	.height		= -1,
-	.tim2		= TIM2_BCD,
-	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
-	.bpp		= 16,
-};
-
-static struct clcd_panel sanyo_2_5_in = {
-	.mode		= {
-		.name		= "Sanyo QVGA Portrait",
-		.refresh	= 116,
-		.xres		= 240,
-		.yres		= 320,
-		.pixclock	= 100000,
-		.left_margin	= 20,
-		.right_margin	= 10,
-		.upper_margin	= 2,
-		.lower_margin	= 2,
-		.hsync_len	= 10,
-		.vsync_len	= 2,
-		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-	.width		= -1,
-	.height		= -1,
-	.tim2		= TIM2_IVS | TIM2_IHS | TIM2_IPC,
-	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
-	.bpp		= 16,
-};
-
-static struct clcd_panel epson_2_2_in = {
-	.mode		= {
-		.name		= "Epson QCIF",
-		.refresh	= 390,
-		.xres		= 176,
-		.yres		= 220,
-		.pixclock	= 62500,
-		.left_margin	= 3,
-		.right_margin	= 2,
-		.upper_margin	= 1,
-		.lower_margin	= 0,
-		.hsync_len	= 3,
-		.vsync_len	= 2,
-		.sync		= 0,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-	.width		= -1,
-	.height		= -1,
-	.tim2		= TIM2_BCD | TIM2_IPC,
-	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
-	.bpp		= 16,
-};
-
-/*
- * Detect which LCD panel is connected, and return the appropriate
- * clcd_panel structure.  Note: we do not have any information on
- * the required timings for the 8.4in panel, so we presently assume
- * VGA timings.
- */
-static struct clcd_panel *versatile_clcd_panel(void)
-{
-	void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
-	struct clcd_panel *panel = &vga;
-	u32 val;
-
-	val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
-	if (val == SYS_CLCD_ID_SANYO_3_8)
-		panel = &sanyo_3_8_in;
-	else if (val == SYS_CLCD_ID_SANYO_2_5)
-		panel = &sanyo_2_5_in;
-	else if (val == SYS_CLCD_ID_EPSON_2_2)
-		panel = &epson_2_2_in;
-	else if (val == SYS_CLCD_ID_VGA)
-		panel = &vga;
-	else {
-		printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
-			val);
-		panel = &vga;
-	}
-
-	return panel;
-}
+static bool is_sanyo_2_5_lcd;
 
 
 /*
 /*
  * Disable all display connectors on the interface module.
  * Disable all display connectors on the interface module.
@@ -614,7 +450,7 @@ static void versatile_clcd_disable(struct clcd_fb *fb)
 	/*
 	/*
 	 * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off
 	 * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off
 	 */
 	 */
-	if (machine_is_versatile_ab() && fb->panel == &sanyo_2_5_in) {
+	if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) {
 		void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
 		void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
 		unsigned long ctrl;
 		unsigned long ctrl;
 
 
@@ -630,18 +466,22 @@ static void versatile_clcd_disable(struct clcd_fb *fb)
  */
  */
 static void versatile_clcd_enable(struct clcd_fb *fb)
 static void versatile_clcd_enable(struct clcd_fb *fb)
 {
 {
+	struct fb_var_screeninfo *var = &fb->fb.var;
 	void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
 	void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
 	u32 val;
 	u32 val;
 
 
 	val = readl(sys_clcd);
 	val = readl(sys_clcd);
 	val &= ~SYS_CLCD_MODE_MASK;
 	val &= ~SYS_CLCD_MODE_MASK;
 
 
-	switch (fb->fb.var.green.length) {
+	switch (var->green.length) {
 	case 5:
 	case 5:
 		val |= SYS_CLCD_MODE_5551;
 		val |= SYS_CLCD_MODE_5551;
 		break;
 		break;
 	case 6:
 	case 6:
-		val |= SYS_CLCD_MODE_565_RLSB;
+		if (var->red.offset == 0)
+			val |= SYS_CLCD_MODE_565_RLSB;
+		else
+			val |= SYS_CLCD_MODE_565_BLSB;
 		break;
 		break;
 	case 8:
 	case 8:
 		val |= SYS_CLCD_MODE_888;
 		val |= SYS_CLCD_MODE_888;
@@ -663,7 +503,7 @@ static void versatile_clcd_enable(struct clcd_fb *fb)
 	/*
 	/*
 	 * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on
 	 * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on
 	 */
 	 */
-	if (machine_is_versatile_ab() && fb->panel == &sanyo_2_5_in) {
+	if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) {
 		void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
 		void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
 		unsigned long ctrl;
 		unsigned long ctrl;
 
 
@@ -674,50 +514,62 @@ static void versatile_clcd_enable(struct clcd_fb *fb)
 #endif
 #endif
 }
 }
 
 
-static unsigned long framesize = SZ_1M;
-
+/*
+ * Detect which LCD panel is connected, and return the appropriate
+ * clcd_panel structure.  Note: we do not have any information on
+ * the required timings for the 8.4in panel, so we presently assume
+ * VGA timings.
+ */
 static int versatile_clcd_setup(struct clcd_fb *fb)
 static int versatile_clcd_setup(struct clcd_fb *fb)
 {
 {
-	dma_addr_t dma;
+	void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
+	const char *panel_name;
+	u32 val;
 
 
-	fb->panel		= versatile_clcd_panel();
+	is_sanyo_2_5_lcd = false;
 
 
-	fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
-						    &dma, GFP_KERNEL);
-	if (!fb->fb.screen_base) {
-		printk(KERN_ERR "CLCD: unable to map framebuffer\n");
-		return -ENOMEM;
+	val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
+	if (val == SYS_CLCD_ID_SANYO_3_8)
+		panel_name = "Sanyo TM38QV67A02A";
+	else if (val == SYS_CLCD_ID_SANYO_2_5) {
+		panel_name = "Sanyo QVGA Portrait";
+		is_sanyo_2_5_lcd = true;
+	} else if (val == SYS_CLCD_ID_EPSON_2_2)
+		panel_name = "Epson L2F50113T00";
+	else if (val == SYS_CLCD_ID_VGA)
+		panel_name = "VGA";
+	else {
+		printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
+			val);
+		panel_name = "VGA";
 	}
 	}
 
 
-	fb->fb.fix.smem_start	= dma;
-	fb->fb.fix.smem_len	= framesize;
+	fb->panel = versatile_clcd_get_panel(panel_name);
+	if (!fb->panel)
+		return -EINVAL;
 
 
-	return 0;
+	return versatile_clcd_setup_dma(fb, SZ_1M);
 }
 }
 
 
-static int versatile_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+static void versatile_clcd_decode(struct clcd_fb *fb, struct clcd_regs *regs)
 {
 {
-	return dma_mmap_writecombine(&fb->dev->dev, vma,
-				     fb->fb.screen_base,
-				     fb->fb.fix.smem_start,
-				     fb->fb.fix.smem_len);
-}
+	clcdfb_decode(fb, regs);
 
 
-static void versatile_clcd_remove(struct clcd_fb *fb)
-{
-	dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
-			      fb->fb.screen_base, fb->fb.fix.smem_start);
+	/* Always clear BGR for RGB565: we do the routing externally */
+	if (fb->fb.var.green.length == 6)
+		regs->cntl &= ~CNTL_BGR;
 }
 }
 
 
 static struct clcd_board clcd_plat_data = {
 static struct clcd_board clcd_plat_data = {
 	.name		= "Versatile",
 	.name		= "Versatile",
+	.caps		= CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
 	.check		= clcdfb_check,
 	.check		= clcdfb_check,
-	.decode		= clcdfb_decode,
+	.decode		= versatile_clcd_decode,
 	.disable	= versatile_clcd_disable,
 	.disable	= versatile_clcd_disable,
 	.enable		= versatile_clcd_enable,
 	.enable		= versatile_clcd_enable,
 	.setup		= versatile_clcd_setup,
 	.setup		= versatile_clcd_setup,
-	.mmap		= versatile_clcd_mmap,
-	.remove		= versatile_clcd_remove,
+	.mmap		= versatile_clcd_mmap_dma,
+	.remove		= versatile_clcd_remove_dma,
 };
 };
 
 
 static struct pl061_platform_data gpio0_plat_data = {
 static struct pl061_platform_data gpio0_plat_data = {
@@ -737,53 +589,35 @@ static struct pl022_ssp_controller ssp0_plat_data = {
 };
 };
 
 
 #define AACI_IRQ	{ IRQ_AACI, NO_IRQ }
 #define AACI_IRQ	{ IRQ_AACI, NO_IRQ }
-#define AACI_DMA	{ 0x80, 0x81 }
 #define MMCI0_IRQ	{ IRQ_MMCI0A,IRQ_SIC_MMCI0B }
 #define MMCI0_IRQ	{ IRQ_MMCI0A,IRQ_SIC_MMCI0B }
-#define MMCI0_DMA	{ 0x84, 0 }
 #define KMI0_IRQ	{ IRQ_SIC_KMI0, NO_IRQ }
 #define KMI0_IRQ	{ IRQ_SIC_KMI0, NO_IRQ }
-#define KMI0_DMA	{ 0, 0 }
 #define KMI1_IRQ	{ IRQ_SIC_KMI1, NO_IRQ }
 #define KMI1_IRQ	{ IRQ_SIC_KMI1, NO_IRQ }
-#define KMI1_DMA	{ 0, 0 }
 
 
 /*
 /*
  * These devices are connected directly to the multi-layer AHB switch
  * These devices are connected directly to the multi-layer AHB switch
  */
  */
 #define SMC_IRQ		{ NO_IRQ, NO_IRQ }
 #define SMC_IRQ		{ NO_IRQ, NO_IRQ }
-#define SMC_DMA		{ 0, 0 }
 #define MPMC_IRQ	{ NO_IRQ, NO_IRQ }
 #define MPMC_IRQ	{ NO_IRQ, NO_IRQ }
-#define MPMC_DMA	{ 0, 0 }
 #define CLCD_IRQ	{ IRQ_CLCDINT, NO_IRQ }
 #define CLCD_IRQ	{ IRQ_CLCDINT, NO_IRQ }
-#define CLCD_DMA	{ 0, 0 }
 #define DMAC_IRQ	{ IRQ_DMAINT, NO_IRQ }
 #define DMAC_IRQ	{ IRQ_DMAINT, NO_IRQ }
-#define DMAC_DMA	{ 0, 0 }
 
 
 /*
 /*
  * These devices are connected via the core APB bridge
  * These devices are connected via the core APB bridge
  */
  */
 #define SCTL_IRQ	{ NO_IRQ, NO_IRQ }
 #define SCTL_IRQ	{ NO_IRQ, NO_IRQ }
-#define SCTL_DMA	{ 0, 0 }
 #define WATCHDOG_IRQ	{ IRQ_WDOGINT, NO_IRQ }
 #define WATCHDOG_IRQ	{ IRQ_WDOGINT, NO_IRQ }
-#define WATCHDOG_DMA	{ 0, 0 }
 #define GPIO0_IRQ	{ IRQ_GPIOINT0, NO_IRQ }
 #define GPIO0_IRQ	{ IRQ_GPIOINT0, NO_IRQ }
-#define GPIO0_DMA	{ 0, 0 }
 #define GPIO1_IRQ	{ IRQ_GPIOINT1, NO_IRQ }
 #define GPIO1_IRQ	{ IRQ_GPIOINT1, NO_IRQ }
-#define GPIO1_DMA	{ 0, 0 }
 #define RTC_IRQ		{ IRQ_RTCINT, NO_IRQ }
 #define RTC_IRQ		{ IRQ_RTCINT, NO_IRQ }
-#define RTC_DMA		{ 0, 0 }
 
 
 /*
 /*
  * These devices are connected via the DMA APB bridge
  * These devices are connected via the DMA APB bridge
  */
  */
 #define SCI_IRQ		{ IRQ_SCIINT, NO_IRQ }
 #define SCI_IRQ		{ IRQ_SCIINT, NO_IRQ }
-#define SCI_DMA		{ 7, 6 }
 #define UART0_IRQ	{ IRQ_UARTINT0, NO_IRQ }
 #define UART0_IRQ	{ IRQ_UARTINT0, NO_IRQ }
-#define UART0_DMA	{ 15, 14 }
 #define UART1_IRQ	{ IRQ_UARTINT1, NO_IRQ }
 #define UART1_IRQ	{ IRQ_UARTINT1, NO_IRQ }
-#define UART1_DMA	{ 13, 12 }
 #define UART2_IRQ	{ IRQ_UARTINT2, NO_IRQ }
 #define UART2_IRQ	{ IRQ_UARTINT2, NO_IRQ }
-#define UART2_DMA	{ 11, 10 }
 #define SSP_IRQ		{ IRQ_SSPINT, NO_IRQ }
 #define SSP_IRQ		{ IRQ_SSPINT, NO_IRQ }
-#define SSP_DMA		{ 9, 8 }
 
 
 /* FPGA Primecells */
 /* FPGA Primecells */
 AMBA_DEVICE(aaci,  "fpga:04", AACI,     NULL);
 AMBA_DEVICE(aaci,  "fpga:04", AACI,     NULL);
@@ -865,14 +699,21 @@ static void versatile_leds_event(led_event_t ledevt)
 }
 }
 #endif	/* CONFIG_LEDS */
 #endif	/* CONFIG_LEDS */
 
 
-void __init versatile_init(void)
+/* Early initializations */
+void __init versatile_init_early(void)
 {
 {
-	int i;
-
-	osc4_clk.vcoreg	= __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSCCLCD_OFFSET;
+	void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
 
 
+	osc4_clk.vcoreg	= sys + VERSATILE_SYS_OSCCLCD_OFFSET;
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 
+	versatile_sched_clock_init(sys + VERSATILE_SYS_24MHz_OFFSET, 24000000);
+}
+
+void __init versatile_init(void)
+{
+	int i;
+
 	platform_device_register(&versatile_flash_device);
 	platform_device_register(&versatile_flash_device);
 	platform_device_register(&versatile_i2c_device);
 	platform_device_register(&versatile_i2c_device);
 	platform_device_register(&smc91x_device);
 	platform_device_register(&smc91x_device);
@@ -888,12 +729,6 @@ void __init versatile_init(void)
 #endif
 #endif
 }
 }
 
 
-/*
- * The sched_clock counter
- */
-#define REFCOUNTER		(__io_address(VERSATILE_SYS_BASE) + \
-				 VERSATILE_SYS_24MHz_OFFSET)
-
 /*
 /*
  * Where is the timer (VA)?
  * Where is the timer (VA)?
  */
  */
@@ -909,8 +744,6 @@ static void __init versatile_timer_init(void)
 {
 {
 	u32 val;
 	u32 val;
 
 
-	versatile_sched_clock_init(REFCOUNTER, 24000000);
-
 	/* 
 	/* 
 	 * set clock frequency: 
 	 * set clock frequency: 
 	 *	VERSATILE_REFCLK is 32KHz
 	 *	VERSATILE_REFCLK is 32KHz

+ 1 - 1
arch/arm/mach-versatile/core.h

@@ -25,6 +25,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/bus.h>
 
 
 extern void __init versatile_init(void);
 extern void __init versatile_init(void);
+extern void __init versatile_init_early(void);
 extern void __init versatile_init_irq(void);
 extern void __init versatile_init_irq(void);
 extern void __init versatile_map_io(void);
 extern void __init versatile_map_io(void);
 extern struct sys_timer versatile_timer;
 extern struct sys_timer versatile_timer;
@@ -44,7 +45,6 @@ static struct amba_device name##_device = {			\
 	},							\
 	},							\
 	.dma_mask	= ~0,					\
 	.dma_mask	= ~0,					\
 	.irq		= base##_IRQ,				\
 	.irq		= base##_IRQ,				\
-	/* .dma		= base##_DMA,*/				\
 }
 }
 
 
 #endif
 #endif

+ 1 - 1
arch/arm/mach-versatile/include/mach/hardware.h

@@ -39,6 +39,6 @@
 /* macro to get at IO space when running virtually */
 /* macro to get at IO space when running virtually */
 #define IO_ADDRESS(x)		(((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
 #define IO_ADDRESS(x)		(((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
 
 
-#define __io_address(n)		__io(IO_ADDRESS(n))
+#define __io_address(n)		((void __iomem __force *)IO_ADDRESS(n))
 
 
 #endif
 #endif

+ 1 - 0
arch/arm/mach-versatile/versatile_ab.c

@@ -37,6 +37,7 @@ MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
 	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
 	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
 	.boot_params	= 0x00000100,
 	.boot_params	= 0x00000100,
 	.map_io		= versatile_map_io,
 	.map_io		= versatile_map_io,
+	.init_early	= versatile_init_early,
 	.init_irq	= versatile_init_irq,
 	.init_irq	= versatile_init_irq,
 	.timer		= &versatile_timer,
 	.timer		= &versatile_timer,
 	.init_machine	= versatile_init,
 	.init_machine	= versatile_init,

+ 1 - 5
arch/arm/mach-versatile/versatile_pb.c

@@ -59,19 +59,14 @@ static struct pl061_platform_data gpio3_plat_data = {
 };
 };
 
 
 #define UART3_IRQ	{ IRQ_SIC_UART3, NO_IRQ }
 #define UART3_IRQ	{ IRQ_SIC_UART3, NO_IRQ }
-#define UART3_DMA	{ 0x86, 0x87 }
 #define SCI1_IRQ	{ IRQ_SIC_SCI3, NO_IRQ }
 #define SCI1_IRQ	{ IRQ_SIC_SCI3, NO_IRQ }
-#define SCI1_DMA	{ 0x88, 0x89 }
 #define MMCI1_IRQ	{ IRQ_MMCI1A, IRQ_SIC_MMCI1B }
 #define MMCI1_IRQ	{ IRQ_MMCI1A, IRQ_SIC_MMCI1B }
-#define MMCI1_DMA	{ 0x85, 0 }
 
 
 /*
 /*
  * These devices are connected via the core APB bridge
  * These devices are connected via the core APB bridge
  */
  */
 #define GPIO2_IRQ	{ IRQ_GPIOINT2, NO_IRQ }
 #define GPIO2_IRQ	{ IRQ_GPIOINT2, NO_IRQ }
-#define GPIO2_DMA	{ 0, 0 }
 #define GPIO3_IRQ	{ IRQ_GPIOINT3, NO_IRQ }
 #define GPIO3_IRQ	{ IRQ_GPIOINT3, NO_IRQ }
-#define GPIO3_DMA	{ 0, 0 }
 
 
 /*
 /*
  * These devices are connected via the DMA APB bridge
  * These devices are connected via the DMA APB bridge
@@ -110,6 +105,7 @@ MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
 	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
 	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
 	.boot_params	= 0x00000100,
 	.boot_params	= 0x00000100,
 	.map_io		= versatile_map_io,
 	.map_io		= versatile_map_io,
+	.init_early	= versatile_init_early,
 	.init_irq	= versatile_init_irq,
 	.init_irq	= versatile_init_irq,
 	.timer		= &versatile_timer,
 	.timer		= &versatile_timer,
 	.init_machine	= versatile_pb_init,
 	.init_machine	= versatile_pb_init,

+ 3 - 0
arch/arm/mach-vexpress/Kconfig

@@ -5,5 +5,8 @@ config ARCH_VEXPRESS_CA9X4
 	bool "Versatile Express Cortex-A9x4 tile"
 	bool "Versatile Express Cortex-A9x4 tile"
 	select CPU_V7
 	select CPU_V7
 	select ARM_GIC
 	select ARM_GIC
+	select ARM_ERRATA_720789
+	select ARM_ERRATA_751472
+	select ARM_ERRATA_753970
 
 
 endmenu
 endmenu

+ 1 - 2
arch/arm/mach-vexpress/Makefile

@@ -4,6 +4,5 @@
 
 
 obj-y					:= v2m.o
 obj-y					:= v2m.o
 obj-$(CONFIG_ARCH_VEXPRESS_CA9X4)	+= ct-ca9x4.o
 obj-$(CONFIG_ARCH_VEXPRESS_CA9X4)	+= ct-ca9x4.o
-obj-$(CONFIG_SMP)			+= platsmp.o headsmp.o
+obj-$(CONFIG_SMP)			+= platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= hotplug.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= hotplug.o
-obj-$(CONFIG_LOCAL_TIMERS)		+= localtimer.o

+ 0 - 5
arch/arm/mach-vexpress/core.h

@@ -17,8 +17,3 @@ struct amba_device name##_device = {		\
 	.irq		= IRQ_##base,		\
 	.irq		= IRQ_##base,		\
 	/* .dma		= DMA_##base,*/		\
 	/* .dma		= DMA_##base,*/		\
 }
 }
-
-struct map_desc;
-
-void v2m_map_io(struct map_desc *tile, size_t num);
-extern struct sys_timer v2m_timer;

+ 44 - 63
arch/arm/mach-vexpress/ct-ca9x4.c

@@ -10,19 +10,17 @@
 #include <linux/amba/clcd.h>
 #include <linux/amba/clcd.h>
 #include <linux/clkdev.h>
 #include <linux/clkdev.h>
 
 
-#include <asm/pgtable.h>
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/gic.h>
-#include <asm/mach-types.h>
 #include <asm/pmu.h>
 #include <asm/pmu.h>
+#include <asm/smp_scu.h>
 #include <asm/smp_twd.h>
 #include <asm/smp_twd.h>
 
 
 #include <mach/ct-ca9x4.h>
 #include <mach/ct-ca9x4.h>
 
 
 #include <asm/hardware/timer-sp.h>
 #include <asm/hardware/timer-sp.h>
 
 
-#include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 #include <asm/mach/time.h>
 
 
@@ -30,6 +28,8 @@
 
 
 #include <mach/motherboard.h>
 #include <mach/motherboard.h>
 
 
+#include <plat/clcd.h>
+
 #define V2M_PA_CS7	0x10000000
 #define V2M_PA_CS7	0x10000000
 
 
 static struct map_desc ct_ca9x4_io_desc[] __initdata = {
 static struct map_desc ct_ca9x4_io_desc[] __initdata = {
@@ -56,7 +56,7 @@ static void __init ct_ca9x4_map_io(void)
 #ifdef CONFIG_LOCAL_TIMERS
 #ifdef CONFIG_LOCAL_TIMERS
 	twd_base = MMIO_P2V(A9_MPCORE_TWD);
 	twd_base = MMIO_P2V(A9_MPCORE_TWD);
 #endif
 #endif
-	v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
+	iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
 }
 }
 
 
 static void __init ct_ca9x4_init_irq(void)
 static void __init ct_ca9x4_init_irq(void)
@@ -80,29 +80,6 @@ static struct sys_timer ct_ca9x4_timer = {
 };
 };
 #endif
 #endif
 
 
-static struct clcd_panel xvga_panel = {
-	.mode		= {
-		.name		= "XVGA",
-		.refresh	= 60,
-		.xres		= 1024,
-		.yres		= 768,
-		.pixclock	= 15384,
-		.left_margin	= 168,
-		.right_margin	= 8,
-		.upper_margin	= 29,
-		.lower_margin	= 3,
-		.hsync_len	= 144,
-		.vsync_len	= 6,
-		.sync		= 0,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-	.width		= -1,
-	.height		= -1,
-	.tim2		= TIM2_BCD | TIM2_IPC,
-	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
-	.bpp		= 16,
-};
-
 static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
 static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
 {
 {
 	v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0);
 	v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0);
@@ -112,42 +89,23 @@ static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
 static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
 static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
 {
 {
 	unsigned long framesize = 1024 * 768 * 2;
 	unsigned long framesize = 1024 * 768 * 2;
-	dma_addr_t dma;
 
 
-	fb->panel = &xvga_panel;
+	fb->panel = versatile_clcd_get_panel("XVGA");
+	if (!fb->panel)
+		return -EINVAL;
 
 
-	fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
-				&dma, GFP_KERNEL);
-	if (!fb->fb.screen_base) {
-		printk(KERN_ERR "CLCD: unable to map frame buffer\n");
-		return -ENOMEM;
-	}
-	fb->fb.fix.smem_start = dma;
-	fb->fb.fix.smem_len = framesize;
-
-	return 0;
-}
-
-static int ct_ca9x4_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
-{
-	return dma_mmap_writecombine(&fb->dev->dev, vma, fb->fb.screen_base,
-		fb->fb.fix.smem_start, fb->fb.fix.smem_len);
-}
-
-static void ct_ca9x4_clcd_remove(struct clcd_fb *fb)
-{
-	dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
-		fb->fb.screen_base, fb->fb.fix.smem_start);
+	return versatile_clcd_setup_dma(fb, framesize);
 }
 }
 
 
 static struct clcd_board ct_ca9x4_clcd_data = {
 static struct clcd_board ct_ca9x4_clcd_data = {
 	.name		= "CT-CA9X4",
 	.name		= "CT-CA9X4",
+	.caps		= CLCD_CAP_5551 | CLCD_CAP_565,
 	.check		= clcdfb_check,
 	.check		= clcdfb_check,
 	.decode		= clcdfb_decode,
 	.decode		= clcdfb_decode,
 	.enable		= ct_ca9x4_clcd_enable,
 	.enable		= ct_ca9x4_clcd_enable,
 	.setup		= ct_ca9x4_clcd_setup,
 	.setup		= ct_ca9x4_clcd_setup,
-	.mmap		= ct_ca9x4_clcd_mmap,
-	.remove		= ct_ca9x4_clcd_remove,
+	.mmap		= versatile_clcd_mmap_dma,
+	.remove		= versatile_clcd_remove_dma,
 };
 };
 
 
 static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
 static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
@@ -220,6 +178,11 @@ static struct platform_device pmu_device = {
 	.resource	= pmu_resources,
 	.resource	= pmu_resources,
 };
 };
 
 
+static void __init ct_ca9x4_init_early(void)
+{
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+}
+
 static void __init ct_ca9x4_init(void)
 static void __init ct_ca9x4_init(void)
 {
 {
 	int i;
 	int i;
@@ -234,22 +197,40 @@ static void __init ct_ca9x4_init(void)
 	l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
 	l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
 #endif
 #endif
 
 
-	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
 	for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
 	for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
 		amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
 		amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
 
 
 	platform_device_register(&pmu_device);
 	platform_device_register(&pmu_device);
 }
 }
 
 
-MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4")
-	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100,
+#ifdef CONFIG_SMP
+static void ct_ca9x4_init_cpu_map(void)
+{
+	int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU));
+
+	for (i = 0; i < ncores; ++i)
+		set_cpu_possible(i, true);
+}
+
+static void ct_ca9x4_smp_enable(unsigned int max_cpus)
+{
+	int i;
+	for (i = 0; i < max_cpus; i++)
+		set_cpu_present(i, true);
+
+	scu_enable(MMIO_P2V(A9_MPCORE_SCU));
+}
+#endif
+
+struct ct_desc ct_ca9x4_desc __initdata = {
+	.id		= V2M_CT_ID_CA9,
+	.name		= "CA9x4",
 	.map_io		= ct_ca9x4_map_io,
 	.map_io		= ct_ca9x4_map_io,
+	.init_early	= ct_ca9x4_init_early,
 	.init_irq	= ct_ca9x4_init_irq,
 	.init_irq	= ct_ca9x4_init_irq,
-#if 0
-	.timer		= &ct_ca9x4_timer,
-#else
-	.timer		= &v2m_timer,
+	.init_tile	= ct_ca9x4_init,
+#ifdef CONFIG_SMP
+	.init_cpu_map	= ct_ca9x4_init_cpu_map,
+	.smp_enable	= ct_ca9x4_smp_enable,
 #endif
 #endif
-	.init_machine	= ct_ca9x4_init,
-MACHINE_END
+};

+ 2 - 0
arch/arm/mach-vexpress/include/mach/ct-ca9x4.h

@@ -45,4 +45,6 @@
 #define IRQ_CT_CA9X4_PMU_CPU2	94
 #define IRQ_CT_CA9X4_PMU_CPU2	94
 #define IRQ_CT_CA9X4_PMU_CPU3	95
 #define IRQ_CT_CA9X4_PMU_CPU3	95
 
 
+extern struct ct_desc ct_ca9x4_desc;
+
 #endif
 #endif

+ 22 - 0
arch/arm/mach-vexpress/include/mach/motherboard.h

@@ -118,4 +118,26 @@
 int v2m_cfg_write(u32 devfn, u32 data);
 int v2m_cfg_write(u32 devfn, u32 data);
 int v2m_cfg_read(u32 devfn, u32 *data);
 int v2m_cfg_read(u32 devfn, u32 *data);
 
 
+/*
+ * Core tile IDs
+ */
+#define V2M_CT_ID_CA9		0x0c000191
+#define V2M_CT_ID_UNSUPPORTED	0xff000191
+#define V2M_CT_ID_MASK		0xff000fff
+
+struct ct_desc {
+	u32			id;
+	const char		*name;
+	void			(*map_io)(void);
+	void			(*init_early)(void);
+	void			(*init_irq)(void);
+	void			(*init_tile)(void);
+#ifdef CONFIG_SMP
+	void			(*init_cpu_map)(void);
+	void			(*smp_enable)(unsigned int);
+#endif
+};
+
+extern struct ct_desc *ct_desc;
+
 #endif
 #endif

+ 4 - 121
arch/arm/mach-vexpress/platsmp.c

@@ -10,114 +10,17 @@
  */
  */
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/jiffies.h>
 #include <linux/smp.h>
 #include <linux/smp.h>
 #include <linux/io.h>
 #include <linux/io.h>
 
 
-#include <asm/cacheflush.h>
-#include <asm/smp_scu.h>
 #include <asm/unified.h>
 #include <asm/unified.h>
 
 
-#include <mach/ct-ca9x4.h>
 #include <mach/motherboard.h>
 #include <mach/motherboard.h>
 #define V2M_PA_CS7 0x10000000
 #define V2M_PA_CS7 0x10000000
 
 
 #include "core.h"
 #include "core.h"
 
 
-extern void vexpress_secondary_startup(void);
-
-/*
- * control for which core is the next to come out of the secondary
- * boot "holding pen"
- */
-volatile int __cpuinitdata pen_release = -1;
-
-/*
- * Write pen_release in a way that is guaranteed to be visible to all
- * observers, irrespective of whether they're taking part in coherency
- * or not.  This is necessary for the hotplug code to work reliably.
- */
-static void __cpuinit write_pen_release(int val)
-{
-	pen_release = val;
-	smp_wmb();
-	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
-	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
-}
-
-static void __iomem *scu_base_addr(void)
-{
-	return MMIO_P2V(A9_MPCORE_SCU);
-}
-
-static DEFINE_SPINLOCK(boot_lock);
-
-void __cpuinit platform_secondary_init(unsigned int cpu)
-{
-	/*
-	 * if any interrupts are already enabled for the primary
-	 * core (e.g. timer irq), then they will not have been enabled
-	 * for us: do so
-	 */
-	gic_secondary_init(0);
-
-	/*
-	 * let the primary processor know we're out of the
-	 * pen, then head off into the C entry point
-	 */
-	write_pen_release(-1);
-
-	/*
-	 * Synchronise with the boot thread.
-	 */
-	spin_lock(&boot_lock);
-	spin_unlock(&boot_lock);
-}
-
-int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
-{
-	unsigned long timeout;
-
-	/*
-	 * Set synchronisation state between this boot processor
-	 * and the secondary one
-	 */
-	spin_lock(&boot_lock);
-
-	/*
-	 * This is really belt and braces; we hold unintended secondary
-	 * CPUs in the holding pen until we're ready for them.  However,
-	 * since we haven't sent them a soft interrupt, they shouldn't
-	 * be there.
-	 */
-	write_pen_release(cpu);
-
-	/*
-	 * Send the secondary CPU a soft interrupt, thereby causing
-	 * the boot monitor to read the system wide flags register,
-	 * and branch to the address found there.
-	 */
-	smp_cross_call(cpumask_of(cpu), 1);
-
-	timeout = jiffies + (1 * HZ);
-	while (time_before(jiffies, timeout)) {
-		smp_rmb();
-		if (pen_release == -1)
-			break;
-
-		udelay(10);
-	}
-
-	/*
-	 * now the secondary core is starting up let it run its
-	 * calibrations, then wait for it to finish
-	 */
-	spin_unlock(&boot_lock);
-
-	return pen_release != -1 ? -ENOSYS : 0;
-}
+extern void versatile_secondary_startup(void);
 
 
 /*
 /*
  * Initialise the CPU possible map early - this describes the CPUs
  * Initialise the CPU possible map early - this describes the CPUs
@@ -125,36 +28,16 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
  */
  */
 void __init smp_init_cpus(void)
 void __init smp_init_cpus(void)
 {
 {
-	void __iomem *scu_base = scu_base_addr();
-	unsigned int i, ncores;
-
-	ncores = scu_base ? scu_get_core_count(scu_base) : 1;
-
-	/* sanity check */
-	if (ncores > NR_CPUS) {
-		printk(KERN_WARNING
-		       "vexpress: no. of cores (%d) greater than configured "
-		       "maximum of %d - clipping\n",
-		       ncores, NR_CPUS);
-		ncores = NR_CPUS;
-	}
-
-	for (i = 0; i < ncores; i++)
-		set_cpu_possible(i, true);
+	ct_desc->init_cpu_map();
 }
 }
 
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
 {
-	int i;
-
 	/*
 	/*
 	 * Initialise the present map, which describes the set of CPUs
 	 * Initialise the present map, which describes the set of CPUs
 	 * actually populated at the present time.
 	 * actually populated at the present time.
 	 */
 	 */
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
-
-	scu_enable(scu_base_addr());
+	ct_desc->smp_enable(max_cpus);
 
 
 	/*
 	/*
 	 * Write the address of secondary startup into the
 	 * Write the address of secondary startup into the
@@ -163,6 +46,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 	 * secondary CPU branches to this address.
 	 * secondary CPU branches to this address.
 	 */
 	 */
 	writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
 	writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
-	writel(BSYM(virt_to_phys(vexpress_secondary_startup)),
+	writel(BSYM(virt_to_phys(versatile_secondary_startup)),
 		MMIO_P2V(V2M_SYS_FLAGSSET));
 		MMIO_P2V(V2M_SYS_FLAGSSET));
 }
 }

+ 80 - 10
arch/arm/mach-vexpress/v2m.c

@@ -7,13 +7,16 @@
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
+#include <linux/ata_platform.h>
 #include <linux/smsc911x.h>
 #include <linux/smsc911x.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
 #include <linux/sysdev.h>
 #include <linux/sysdev.h>
 #include <linux/usb/isp1760.h>
 #include <linux/usb/isp1760.h>
 #include <linux/clkdev.h>
 #include <linux/clkdev.h>
 
 
+#include <asm/mach-types.h>
 #include <asm/sizes.h>
 #include <asm/sizes.h>
+#include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 #include <asm/mach/time.h>
@@ -21,6 +24,7 @@
 #include <asm/hardware/timer-sp.h>
 #include <asm/hardware/timer-sp.h>
 #include <asm/hardware/sp810.h>
 #include <asm/hardware/sp810.h>
 
 
+#include <mach/ct-ca9x4.h>
 #include <mach/motherboard.h>
 #include <mach/motherboard.h>
 
 
 #include <plat/sched_clock.h>
 #include <plat/sched_clock.h>
@@ -42,19 +46,16 @@ static struct map_desc v2m_io_desc[] __initdata = {
 	},
 	},
 };
 };
 
 
-void __init v2m_map_io(struct map_desc *tile, size_t num)
+static void __init v2m_init_early(void)
 {
 {
-	iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
-	iotable_init(tile, num);
+	ct_desc->init_early();
+	versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
 }
 }
 
 
-
 static void __init v2m_timer_init(void)
 static void __init v2m_timer_init(void)
 {
 {
 	u32 scctrl;
 	u32 scctrl;
 
 
-	versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
-
 	/* Select 1MHz TIMCLK as the reference clock for SP804 timers */
 	/* Select 1MHz TIMCLK as the reference clock for SP804 timers */
 	scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL));
 	scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL));
 	scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
 	scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
@@ -68,7 +69,7 @@ static void __init v2m_timer_init(void)
 	sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0);
 	sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0);
 }
 }
 
 
-struct sys_timer v2m_timer = {
+static struct sys_timer v2m_timer = {
 	.init	= v2m_timer_init,
 	.init	= v2m_timer_init,
 };
 };
 
 
@@ -249,6 +250,29 @@ static struct platform_device v2m_flash_device = {
 	.dev.platform_data = &v2m_flash_data,
 	.dev.platform_data = &v2m_flash_data,
 };
 };
 
 
+static struct pata_platform_info v2m_pata_data = {
+	.ioport_shift	= 2,
+};
+
+static struct resource v2m_pata_resources[] = {
+	{
+		.start	= V2M_CF,
+		.end	= V2M_CF + 0xff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= V2M_CF + 0x100,
+		.end	= V2M_CF + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device v2m_cf_device = {
+	.name		= "pata_platform",
+	.id		= -1,
+	.resource	= v2m_pata_resources,
+	.num_resources	= ARRAY_SIZE(v2m_pata_resources),
+	.dev.platform_data = &v2m_pata_data,
+};
 
 
 static unsigned int v2m_mmci_status(struct device *dev)
 static unsigned int v2m_mmci_status(struct device *dev)
 {
 {
@@ -354,7 +378,44 @@ static void v2m_restart(char str, const char *cmd)
 		printk(KERN_EMERG "Unable to reboot\n");
 		printk(KERN_EMERG "Unable to reboot\n");
 }
 }
 
 
-static int __init v2m_init(void)
+struct ct_desc *ct_desc;
+
+static struct ct_desc *ct_descs[] __initdata = {
+#ifdef CONFIG_ARCH_VEXPRESS_CA9X4
+	&ct_ca9x4_desc,
+#endif
+};
+
+static void __init v2m_populate_ct_desc(void)
+{
+	int i;
+	u32 current_tile_id;
+
+	ct_desc = NULL;
+	current_tile_id = readl(MMIO_P2V(V2M_SYS_PROCID0)) & V2M_CT_ID_MASK;
+
+	for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i)
+		if (ct_descs[i]->id == current_tile_id)
+			ct_desc = ct_descs[i];
+
+	if (!ct_desc)
+		panic("vexpress: failed to populate core tile description "
+		      "for tile ID 0x%8x\n", current_tile_id);
+}
+
+static void __init v2m_map_io(void)
+{
+	iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
+	v2m_populate_ct_desc();
+	ct_desc->map_io();
+}
+
+static void __init v2m_init_irq(void)
+{
+	ct_desc->init_irq();
+}
+
+static void __init v2m_init(void)
 {
 {
 	int i;
 	int i;
 
 
@@ -363,6 +424,7 @@ static int __init v2m_init(void)
 	platform_device_register(&v2m_pcie_i2c_device);
 	platform_device_register(&v2m_pcie_i2c_device);
 	platform_device_register(&v2m_ddc_i2c_device);
 	platform_device_register(&v2m_ddc_i2c_device);
 	platform_device_register(&v2m_flash_device);
 	platform_device_register(&v2m_flash_device);
+	platform_device_register(&v2m_cf_device);
 	platform_device_register(&v2m_eth_device);
 	platform_device_register(&v2m_eth_device);
 	platform_device_register(&v2m_usb_device);
 	platform_device_register(&v2m_usb_device);
 
 
@@ -372,6 +434,14 @@ static int __init v2m_init(void)
 	pm_power_off = v2m_power_off;
 	pm_power_off = v2m_power_off;
 	arm_pm_restart = v2m_restart;
 	arm_pm_restart = v2m_restart;
 
 
-	return 0;
+	ct_desc->init_tile();
 }
 }
-arch_initcall(v2m_init);
+
+MACHINE_START(VEXPRESS, "ARM-Versatile Express")
+	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100,
+	.map_io		= v2m_map_io,
+	.init_early	= v2m_init_early,
+	.init_irq	= v2m_init_irq,
+	.timer		= &v2m_timer,
+	.init_machine	= v2m_init,
+MACHINE_END

+ 10 - 1
arch/arm/mm/dma-mapping.c

@@ -149,6 +149,7 @@ static int __init consistent_init(void)
 {
 {
 	int ret = 0;
 	int ret = 0;
 	pgd_t *pgd;
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pmd_t *pmd;
 	pte_t *pte;
 	pte_t *pte;
 	int i = 0;
 	int i = 0;
@@ -156,7 +157,15 @@ static int __init consistent_init(void)
 
 
 	do {
 	do {
 		pgd = pgd_offset(&init_mm, base);
 		pgd = pgd_offset(&init_mm, base);
-		pmd = pmd_alloc(&init_mm, pgd, base);
+
+		pud = pud_alloc(&init_mm, pgd, base);
+		if (!pud) {
+			printk(KERN_ERR "%s: no pud tables\n", __func__);
+			ret = -ENOMEM;
+			break;
+		}
+
+		pmd = pmd_alloc(&init_mm, pud, base);
 		if (!pmd) {
 		if (!pmd) {
 			printk(KERN_ERR "%s: no pmd tables\n", __func__);
 			printk(KERN_ERR "%s: no pmd tables\n", __func__);
 			ret = -ENOMEM;
 			ret = -ENOMEM;

+ 6 - 1
arch/arm/mm/fault-armv.c

@@ -95,6 +95,7 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
 {
 {
 	spinlock_t *ptl;
 	spinlock_t *ptl;
 	pgd_t *pgd;
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pmd_t *pmd;
 	pte_t *pte;
 	pte_t *pte;
 	int ret;
 	int ret;
@@ -103,7 +104,11 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
 	if (pgd_none_or_clear_bad(pgd))
 	if (pgd_none_or_clear_bad(pgd))
 		return 0;
 		return 0;
 
 
-	pmd = pmd_offset(pgd, address);
+	pud = pud_offset(pgd, address);
+	if (pud_none_or_clear_bad(pud))
+		return 0;
+
+	pmd = pmd_offset(pud, address);
 	if (pmd_none_or_clear_bad(pmd))
 	if (pmd_none_or_clear_bad(pmd))
 		return 0;
 		return 0;
 
 

+ 31 - 8
arch/arm/mm/fault.c

@@ -76,9 +76,11 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
 
 
 	printk(KERN_ALERT "pgd = %p\n", mm->pgd);
 	printk(KERN_ALERT "pgd = %p\n", mm->pgd);
 	pgd = pgd_offset(mm, addr);
 	pgd = pgd_offset(mm, addr);
-	printk(KERN_ALERT "[%08lx] *pgd=%08lx", addr, pgd_val(*pgd));
+	printk(KERN_ALERT "[%08lx] *pgd=%08llx",
+			addr, (long long)pgd_val(*pgd));
 
 
 	do {
 	do {
+		pud_t *pud;
 		pmd_t *pmd;
 		pmd_t *pmd;
 		pte_t *pte;
 		pte_t *pte;
 
 
@@ -90,9 +92,21 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
 			break;
 			break;
 		}
 		}
 
 
-		pmd = pmd_offset(pgd, addr);
+		pud = pud_offset(pgd, addr);
+		if (PTRS_PER_PUD != 1)
+			printk(", *pud=%08lx", pud_val(*pud));
+
+		if (pud_none(*pud))
+			break;
+
+		if (pud_bad(*pud)) {
+			printk("(bad)");
+			break;
+		}
+
+		pmd = pmd_offset(pud, addr);
 		if (PTRS_PER_PMD != 1)
 		if (PTRS_PER_PMD != 1)
-			printk(", *pmd=%08lx", pmd_val(*pmd));
+			printk(", *pmd=%08llx", (long long)pmd_val(*pmd));
 
 
 		if (pmd_none(*pmd))
 		if (pmd_none(*pmd))
 			break;
 			break;
@@ -107,8 +121,9 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
 			break;
 			break;
 
 
 		pte = pte_offset_map(pmd, addr);
 		pte = pte_offset_map(pmd, addr);
-		printk(", *pte=%08lx", pte_val(*pte));
-		printk(", *ppte=%08lx", pte_val(pte[PTE_HWTABLE_PTRS]));
+		printk(", *pte=%08llx", (long long)pte_val(*pte));
+		printk(", *ppte=%08llx",
+		       (long long)pte_val(pte[PTE_HWTABLE_PTRS]));
 		pte_unmap(pte);
 		pte_unmap(pte);
 	} while(0);
 	} while(0);
 
 
@@ -388,6 +403,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
 {
 {
 	unsigned int index;
 	unsigned int index;
 	pgd_t *pgd, *pgd_k;
 	pgd_t *pgd, *pgd_k;
+	pud_t *pud, *pud_k;
 	pmd_t *pmd, *pmd_k;
 	pmd_t *pmd, *pmd_k;
 
 
 	if (addr < TASK_SIZE)
 	if (addr < TASK_SIZE)
@@ -406,12 +422,19 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
 
 
 	if (pgd_none(*pgd_k))
 	if (pgd_none(*pgd_k))
 		goto bad_area;
 		goto bad_area;
-
 	if (!pgd_present(*pgd))
 	if (!pgd_present(*pgd))
 		set_pgd(pgd, *pgd_k);
 		set_pgd(pgd, *pgd_k);
 
 
-	pmd_k = pmd_offset(pgd_k, addr);
-	pmd   = pmd_offset(pgd, addr);
+	pud = pud_offset(pgd, addr);
+	pud_k = pud_offset(pgd_k, addr);
+
+	if (pud_none(*pud_k))
+		goto bad_area;
+	if (!pud_present(*pud))
+		set_pud(pud, *pud_k);
+
+	pmd = pmd_offset(pud, addr);
+	pmd_k = pmd_offset(pud_k, addr);
 
 
 	/*
 	/*
 	 * On ARM one Linux PGD entry contains two hardware entries (see page
 	 * On ARM one Linux PGD entry contains two hardware entries (see page

+ 29 - 6
arch/arm/mm/idmap.c

@@ -4,10 +4,10 @@
 #include <asm/pgalloc.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 
 
-static void idmap_add_pmd(pgd_t *pgd, unsigned long addr, unsigned long end,
+static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
 	unsigned long prot)
 	unsigned long prot)
 {
 {
-	pmd_t *pmd = pmd_offset(pgd, addr);
+	pmd_t *pmd = pmd_offset(pud, addr);
 
 
 	addr = (addr & PMD_MASK) | prot;
 	addr = (addr & PMD_MASK) | prot;
 	pmd[0] = __pmd(addr);
 	pmd[0] = __pmd(addr);
@@ -16,6 +16,18 @@ static void idmap_add_pmd(pgd_t *pgd, unsigned long addr, unsigned long end,
 	flush_pmd_entry(pmd);
 	flush_pmd_entry(pmd);
 }
 }
 
 
+static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
+	unsigned long prot)
+{
+	pud_t *pud = pud_offset(pgd, addr);
+	unsigned long next;
+
+	do {
+		next = pud_addr_end(addr, end);
+		idmap_add_pmd(pud, addr, next, prot);
+	} while (pud++, addr = next, addr != end);
+}
+
 void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
 void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
 {
 {
 	unsigned long prot, next;
 	unsigned long prot, next;
@@ -27,17 +39,28 @@ void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
 	pgd += pgd_index(addr);
 	pgd += pgd_index(addr);
 	do {
 	do {
 		next = pgd_addr_end(addr, end);
 		next = pgd_addr_end(addr, end);
-		idmap_add_pmd(pgd, addr, next, prot);
+		idmap_add_pud(pgd, addr, next, prot);
 	} while (pgd++, addr = next, addr != end);
 	} while (pgd++, addr = next, addr != end);
 }
 }
 
 
 #ifdef CONFIG_SMP
 #ifdef CONFIG_SMP
-static void idmap_del_pmd(pgd_t *pgd, unsigned long addr, unsigned long end)
+static void idmap_del_pmd(pud_t *pud, unsigned long addr, unsigned long end)
 {
 {
-	pmd_t *pmd = pmd_offset(pgd, addr);
+	pmd_t *pmd = pmd_offset(pud, addr);
 	pmd_clear(pmd);
 	pmd_clear(pmd);
 }
 }
 
 
+static void idmap_del_pud(pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+	pud_t *pud = pud_offset(pgd, addr);
+	unsigned long next;
+
+	do {
+		next = pud_addr_end(addr, end);
+		idmap_del_pmd(pud, addr, next);
+	} while (pud++, addr = next, addr != end);
+}
+
 void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
 void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
 {
 {
 	unsigned long next;
 	unsigned long next;
@@ -45,7 +68,7 @@ void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
 	pgd += pgd_index(addr);
 	pgd += pgd_index(addr);
 	do {
 	do {
 		next = pgd_addr_end(addr, end);
 		next = pgd_addr_end(addr, end);
-		idmap_del_pmd(pgd, addr, next);
+		idmap_del_pud(pgd, addr, next);
 	} while (pgd++, addr = next, addr != end);
 	} while (pgd++, addr = next, addr != end);
 }
 }
 #endif
 #endif

+ 3 - 3
arch/arm/mm/init.c

@@ -350,7 +350,7 @@ void __init bootmem_init(void)
 	 */
 	 */
 	arm_bootmem_free(min, max_low, max_high);
 	arm_bootmem_free(min, max_low, max_high);
 
 
-	high_memory = __va((max_low << PAGE_SHIFT) - 1) + 1;
+	high_memory = __va(((phys_addr_t)max_low << PAGE_SHIFT) - 1) + 1;
 
 
 	/*
 	/*
 	 * This doesn't seem to be used by the Linux memory manager any
 	 * This doesn't seem to be used by the Linux memory manager any
@@ -398,8 +398,8 @@ free_memmap(unsigned long start_pfn, unsigned long end_pfn)
 	 * Convert to physical addresses, and
 	 * Convert to physical addresses, and
 	 * round start upwards and end downwards.
 	 * round start upwards and end downwards.
 	 */
 	 */
-	pg = PAGE_ALIGN(__pa(start_pg));
-	pgend = __pa(end_pg) & PAGE_MASK;
+	pg = (unsigned long)PAGE_ALIGN(__pa(start_pg));
+	pgend = (unsigned long)__pa(end_pg) & PAGE_MASK;
 
 
 	/*
 	/*
 	 * If there are free pages between these,
 	 * If there are free pages between these,

+ 1 - 1
arch/arm/mm/mm.h

@@ -7,7 +7,7 @@ extern pmd_t *top_pmd;
 
 
 static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
 static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
 {
 {
-	return pmd_offset(pgd, virt);
+	return pmd_offset(pud_offset(pgd, virt), virt);
 }
 }
 
 
 static inline pmd_t *pmd_off_k(unsigned long virt)
 static inline pmd_t *pmd_off_k(unsigned long virt)

+ 44 - 27
arch/arm/mm/mmu.c

@@ -533,7 +533,7 @@ static void __init *early_alloc(unsigned long sz)
 static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot)
 static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot)
 {
 {
 	if (pmd_none(*pmd)) {
 	if (pmd_none(*pmd)) {
-		pte_t *pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t));
+		pte_t *pte = early_alloc(PTE_HWTABLE_OFF + PTE_HWTABLE_SIZE);
 		__pmd_populate(pmd, __pa(pte), prot);
 		__pmd_populate(pmd, __pa(pte), prot);
 	}
 	}
 	BUG_ON(pmd_bad(*pmd));
 	BUG_ON(pmd_bad(*pmd));
@@ -551,11 +551,11 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
 	} while (pte++, addr += PAGE_SIZE, addr != end);
 	} while (pte++, addr += PAGE_SIZE, addr != end);
 }
 }
 
 
-static void __init alloc_init_section(pgd_t *pgd, unsigned long addr,
+static void __init alloc_init_section(pud_t *pud, unsigned long addr,
 				      unsigned long end, phys_addr_t phys,
 				      unsigned long end, phys_addr_t phys,
 				      const struct mem_type *type)
 				      const struct mem_type *type)
 {
 {
-	pmd_t *pmd = pmd_offset(pgd, addr);
+	pmd_t *pmd = pmd_offset(pud, addr);
 
 
 	/*
 	/*
 	 * Try a section mapping - end, addr and phys must all be aligned
 	 * Try a section mapping - end, addr and phys must all be aligned
@@ -584,6 +584,19 @@ static void __init alloc_init_section(pgd_t *pgd, unsigned long addr,
 	}
 	}
 }
 }
 
 
+static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
+	unsigned long phys, const struct mem_type *type)
+{
+	pud_t *pud = pud_offset(pgd, addr);
+	unsigned long next;
+
+	do {
+		next = pud_addr_end(addr, end);
+		alloc_init_section(pud, addr, next, phys, type);
+		phys += next - addr;
+	} while (pud++, addr = next, addr != end);
+}
+
 static void __init create_36bit_mapping(struct map_desc *md,
 static void __init create_36bit_mapping(struct map_desc *md,
 					const struct mem_type *type)
 					const struct mem_type *type)
 {
 {
@@ -592,13 +605,13 @@ static void __init create_36bit_mapping(struct map_desc *md,
 	pgd_t *pgd;
 	pgd_t *pgd;
 
 
 	addr = md->virtual;
 	addr = md->virtual;
-	phys = (unsigned long)__pfn_to_phys(md->pfn);
+	phys = __pfn_to_phys(md->pfn);
 	length = PAGE_ALIGN(md->length);
 	length = PAGE_ALIGN(md->length);
 
 
 	if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) {
 	if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) {
 		printk(KERN_ERR "MM: CPU does not support supersection "
 		printk(KERN_ERR "MM: CPU does not support supersection "
 		       "mapping for 0x%08llx at 0x%08lx\n",
 		       "mapping for 0x%08llx at 0x%08lx\n",
-		       __pfn_to_phys((u64)md->pfn), addr);
+		       (long long)__pfn_to_phys((u64)md->pfn), addr);
 		return;
 		return;
 	}
 	}
 
 
@@ -611,14 +624,14 @@ static void __init create_36bit_mapping(struct map_desc *md,
 	if (type->domain) {
 	if (type->domain) {
 		printk(KERN_ERR "MM: invalid domain in supersection "
 		printk(KERN_ERR "MM: invalid domain in supersection "
 		       "mapping for 0x%08llx at 0x%08lx\n",
 		       "mapping for 0x%08llx at 0x%08lx\n",
-		       __pfn_to_phys((u64)md->pfn), addr);
+		       (long long)__pfn_to_phys((u64)md->pfn), addr);
 		return;
 		return;
 	}
 	}
 
 
 	if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) {
 	if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) {
-		printk(KERN_ERR "MM: cannot create mapping for "
-		       "0x%08llx at 0x%08lx invalid alignment\n",
-		       __pfn_to_phys((u64)md->pfn), addr);
+		printk(KERN_ERR "MM: cannot create mapping for 0x%08llx"
+		       " at 0x%08lx invalid alignment\n",
+		       (long long)__pfn_to_phys((u64)md->pfn), addr);
 		return;
 		return;
 	}
 	}
 
 
@@ -631,7 +644,8 @@ static void __init create_36bit_mapping(struct map_desc *md,
 	pgd = pgd_offset_k(addr);
 	pgd = pgd_offset_k(addr);
 	end = addr + length;
 	end = addr + length;
 	do {
 	do {
-		pmd_t *pmd = pmd_offset(pgd, addr);
+		pud_t *pud = pud_offset(pgd, addr);
+		pmd_t *pmd = pmd_offset(pud, addr);
 		int i;
 		int i;
 
 
 		for (i = 0; i < 16; i++)
 		for (i = 0; i < 16; i++)
@@ -652,22 +666,23 @@ static void __init create_36bit_mapping(struct map_desc *md,
  */
  */
 static void __init create_mapping(struct map_desc *md)
 static void __init create_mapping(struct map_desc *md)
 {
 {
-	unsigned long phys, addr, length, end;
+	unsigned long addr, length, end;
+	phys_addr_t phys;
 	const struct mem_type *type;
 	const struct mem_type *type;
 	pgd_t *pgd;
 	pgd_t *pgd;
 
 
 	if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
 	if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
-		printk(KERN_WARNING "BUG: not creating mapping for "
-		       "0x%08llx at 0x%08lx in user region\n",
-		       __pfn_to_phys((u64)md->pfn), md->virtual);
+		printk(KERN_WARNING "BUG: not creating mapping for 0x%08llx"
+		       " at 0x%08lx in user region\n",
+		       (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
 		return;
 		return;
 	}
 	}
 
 
 	if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
 	if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
 	    md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
 	    md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
-		printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx "
-		       "overlaps vmalloc space\n",
-		       __pfn_to_phys((u64)md->pfn), md->virtual);
+		printk(KERN_WARNING "BUG: mapping for 0x%08llx"
+		       " at 0x%08lx overlaps vmalloc space\n",
+		       (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
 	}
 	}
 
 
 	type = &mem_types[md->type];
 	type = &mem_types[md->type];
@@ -681,13 +696,13 @@ static void __init create_mapping(struct map_desc *md)
 	}
 	}
 
 
 	addr = md->virtual & PAGE_MASK;
 	addr = md->virtual & PAGE_MASK;
-	phys = (unsigned long)__pfn_to_phys(md->pfn);
+	phys = __pfn_to_phys(md->pfn);
 	length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
 	length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
 
 
 	if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) {
 	if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) {
-		printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not "
+		printk(KERN_WARNING "BUG: map for 0x%08llx at 0x%08lx can not "
 		       "be mapped using pages, ignoring.\n",
 		       "be mapped using pages, ignoring.\n",
-		       __pfn_to_phys(md->pfn), addr);
+		       (long long)__pfn_to_phys(md->pfn), addr);
 		return;
 		return;
 	}
 	}
 
 
@@ -696,7 +711,7 @@ static void __init create_mapping(struct map_desc *md)
 	do {
 	do {
 		unsigned long next = pgd_addr_end(addr, end);
 		unsigned long next = pgd_addr_end(addr, end);
 
 
-		alloc_init_section(pgd, addr, next, phys, type);
+		alloc_init_pud(pgd, addr, next, phys, type);
 
 
 		phys += next - addr;
 		phys += next - addr;
 		addr = next;
 		addr = next;
@@ -794,9 +809,10 @@ static void __init sanity_check_meminfo(void)
 		 */
 		 */
 		if (__va(bank->start) >= vmalloc_min ||
 		if (__va(bank->start) >= vmalloc_min ||
 		    __va(bank->start) < (void *)PAGE_OFFSET) {
 		    __va(bank->start) < (void *)PAGE_OFFSET) {
-			printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx "
+			printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx "
 			       "(vmalloc region overlap).\n",
 			       "(vmalloc region overlap).\n",
-			       bank->start, bank->start + bank->size - 1);
+			       (unsigned long long)bank->start,
+			       (unsigned long long)bank->start + bank->size - 1);
 			continue;
 			continue;
 		}
 		}
 
 
@@ -807,10 +823,11 @@ static void __init sanity_check_meminfo(void)
 		if (__va(bank->start + bank->size) > vmalloc_min ||
 		if (__va(bank->start + bank->size) > vmalloc_min ||
 		    __va(bank->start + bank->size) < __va(bank->start)) {
 		    __va(bank->start + bank->size) < __va(bank->start)) {
 			unsigned long newsize = vmalloc_min - __va(bank->start);
 			unsigned long newsize = vmalloc_min - __va(bank->start);
-			printk(KERN_NOTICE "Truncating RAM at %.8lx-%.8lx "
-			       "to -%.8lx (vmalloc region overlap).\n",
-			       bank->start, bank->start + bank->size - 1,
-			       bank->start + newsize - 1);
+			printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
+			       "to -%.8llx (vmalloc region overlap).\n",
+			       (unsigned long long)bank->start,
+			       (unsigned long long)bank->start + bank->size - 1,
+			       (unsigned long long)bank->start + newsize - 1);
 			bank->size = newsize;
 			bank->size = newsize;
 		}
 		}
 #endif
 #endif

+ 20 - 4
arch/arm/mm/pgd.c

@@ -23,6 +23,7 @@
 pgd_t *pgd_alloc(struct mm_struct *mm)
 pgd_t *pgd_alloc(struct mm_struct *mm)
 {
 {
 	pgd_t *new_pgd, *init_pgd;
 	pgd_t *new_pgd, *init_pgd;
+	pud_t *new_pud, *init_pud;
 	pmd_t *new_pmd, *init_pmd;
 	pmd_t *new_pmd, *init_pmd;
 	pte_t *new_pte, *init_pte;
 	pte_t *new_pte, *init_pte;
 
 
@@ -46,7 +47,11 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 		 * On ARM, first page must always be allocated since it
 		 * On ARM, first page must always be allocated since it
 		 * contains the machine vectors.
 		 * contains the machine vectors.
 		 */
 		 */
-		new_pmd = pmd_alloc(mm, new_pgd, 0);
+		new_pud = pud_alloc(mm, new_pgd, 0);
+		if (!new_pud)
+			goto no_pud;
+
+		new_pmd = pmd_alloc(mm, new_pud, 0);
 		if (!new_pmd)
 		if (!new_pmd)
 			goto no_pmd;
 			goto no_pmd;
 
 
@@ -54,7 +59,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 		if (!new_pte)
 		if (!new_pte)
 			goto no_pte;
 			goto no_pte;
 
 
-		init_pmd = pmd_offset(init_pgd, 0);
+		init_pud = pud_offset(init_pgd, 0);
+		init_pmd = pmd_offset(init_pud, 0);
 		init_pte = pte_offset_map(init_pmd, 0);
 		init_pte = pte_offset_map(init_pmd, 0);
 		set_pte_ext(new_pte, *init_pte, 0);
 		set_pte_ext(new_pte, *init_pte, 0);
 		pte_unmap(init_pte);
 		pte_unmap(init_pte);
@@ -66,6 +72,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 no_pte:
 no_pte:
 	pmd_free(mm, new_pmd);
 	pmd_free(mm, new_pmd);
 no_pmd:
 no_pmd:
+	pud_free(mm, new_pud);
+no_pud:
 	free_pages((unsigned long)new_pgd, 2);
 	free_pages((unsigned long)new_pgd, 2);
 no_pgd:
 no_pgd:
 	return NULL;
 	return NULL;
@@ -74,6 +82,7 @@ no_pgd:
 void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
 void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
 {
 {
 	pgd_t *pgd;
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pmd_t *pmd;
 	pgtable_t pte;
 	pgtable_t pte;
 
 
@@ -84,7 +93,11 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
 	if (pgd_none_or_clear_bad(pgd))
 	if (pgd_none_or_clear_bad(pgd))
 		goto no_pgd;
 		goto no_pgd;
 
 
-	pmd = pmd_offset(pgd, 0);
+	pud = pud_offset(pgd, 0);
+	if (pud_none_or_clear_bad(pud))
+		goto no_pud;
+
+	pmd = pmd_offset(pud, 0);
 	if (pmd_none_or_clear_bad(pmd))
 	if (pmd_none_or_clear_bad(pmd))
 		goto no_pmd;
 		goto no_pmd;
 
 
@@ -92,8 +105,11 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
 	pmd_clear(pmd);
 	pmd_clear(pmd);
 	pte_free(mm, pte);
 	pte_free(mm, pte);
 no_pmd:
 no_pmd:
-	pgd_clear(pgd);
+	pud_clear(pud);
 	pmd_free(mm, pmd);
 	pmd_free(mm, pmd);
+no_pud:
+	pgd_clear(pgd);
+	pud_free(mm, pud);
 no_pgd:
 no_pgd:
 	free_pages((unsigned long) pgd_base, 2);
 	free_pages((unsigned long) pgd_base, 2);
 }
 }

+ 17 - 0
arch/arm/plat-versatile/Kconfig

@@ -0,0 +1,17 @@
+if PLAT_VERSATILE
+
+config PLAT_VERSATILE_CLCD
+	bool
+
+config PLAT_VERSATILE_FPGA_IRQ
+	bool
+
+config PLAT_VERSATILE_LEDS
+	def_bool y if LEDS_CLASS
+	depends on ARCH_REALVIEW || ARCH_VERSATILE
+
+config PLAT_VERSATILE_SCHED_CLOCK
+	def_bool y if !ARCH_INTEGRATOR_AP
+	select HAVE_SCHED_CLOCK
+
+endif

+ 6 - 7
arch/arm/plat-versatile/Makefile

@@ -1,8 +1,7 @@
 obj-y	:= clock.o
 obj-y	:= clock.o
-ifneq ($(CONFIG_ARCH_INTEGRATOR),y)
-obj-y	+= sched-clock.o
-endif
-ifeq ($(CONFIG_LEDS_CLASS),y)
-obj-$(CONFIG_ARCH_REALVIEW) += leds.o
-obj-$(CONFIG_ARCH_VERSATILE) += leds.o
-endif
+obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
+obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
+obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
+obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
+obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o
+obj-$(CONFIG_SMP) += headsmp.o platsmp.o

+ 182 - 0
arch/arm/plat-versatile/clcd.c

@@ -0,0 +1,182 @@
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <plat/clcd.h>
+
+static struct clcd_panel vga = {
+	.mode		= {
+		.name		= "VGA",
+		.refresh	= 60,
+		.xres		= 640,
+		.yres		= 480,
+		.pixclock	= 39721,
+		.left_margin	= 40,
+		.right_margin	= 24,
+		.upper_margin	= 32,
+		.lower_margin	= 11,
+		.hsync_len	= 96,
+		.vsync_len	= 2,
+		.sync		= 0,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+	.width		= -1,
+	.height		= -1,
+	.tim2		= TIM2_BCD | TIM2_IPC,
+	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
+	.caps		= CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
+	.bpp		= 16,
+};
+
+static struct clcd_panel xvga = {
+	.mode		= {
+		.name		= "XVGA",
+		.refresh	= 60,
+		.xres		= 1024,
+		.yres		= 768,
+		.pixclock	= 15748,
+		.left_margin	= 152,
+		.right_margin	= 48,
+		.upper_margin	= 23,
+		.lower_margin	= 3,
+		.hsync_len	= 104,
+		.vsync_len	= 4,
+		.sync		= 0,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+	.width		= -1,
+	.height		= -1,
+	.tim2		= TIM2_BCD | TIM2_IPC,
+	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
+	.caps		= CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
+	.bpp		= 16,
+};
+
+/* Sanyo TM38QV67A02A - 3.8 inch QVGA (320x240) Color TFT */
+static struct clcd_panel sanyo_tm38qv67a02a = {
+	.mode		= {
+		.name		= "Sanyo TM38QV67A02A",
+		.refresh	= 116,
+		.xres		= 320,
+		.yres		= 240,
+		.pixclock	= 100000,
+		.left_margin	= 6,
+		.right_margin	= 6,
+		.upper_margin	= 5,
+		.lower_margin	= 5,
+		.hsync_len	= 6,
+		.vsync_len	= 6,
+		.sync		= 0,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+	.width		= -1,
+	.height		= -1,
+	.tim2		= TIM2_BCD,
+	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
+	.caps		= CLCD_CAP_5551,
+	.bpp		= 16,
+};
+
+static struct clcd_panel sanyo_2_5_in = {
+	.mode		= {
+		.name		= "Sanyo QVGA Portrait",
+		.refresh	= 116,
+		.xres		= 240,
+		.yres		= 320,
+		.pixclock	= 100000,
+		.left_margin	= 20,
+		.right_margin	= 10,
+		.upper_margin	= 2,
+		.lower_margin	= 2,
+		.hsync_len	= 10,
+		.vsync_len	= 2,
+		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+	.width		= -1,
+	.height		= -1,
+	.tim2		= TIM2_IVS | TIM2_IHS | TIM2_IPC,
+	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
+	.caps		= CLCD_CAP_5551,
+	.bpp		= 16,
+};
+
+/* Epson L2F50113T00 - 2.2 inch 176x220 Color TFT */
+static struct clcd_panel epson_l2f50113t00 = {
+	.mode		= {
+		.name		= "Epson L2F50113T00",
+		.refresh	= 390,
+		.xres		= 176,
+		.yres		= 220,
+		.pixclock	= 62500,
+		.left_margin	= 3,
+		.right_margin	= 2,
+		.upper_margin	= 1,
+		.lower_margin	= 0,
+		.hsync_len	= 3,
+		.vsync_len	= 2,
+		.sync		= 0,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+	.width		= -1,
+	.height		= -1,
+	.tim2		= TIM2_BCD | TIM2_IPC,
+	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
+	.caps		= CLCD_CAP_5551,
+	.bpp		= 16,
+};
+
+static struct clcd_panel *panels[] = {
+	&vga,
+	&xvga,
+	&sanyo_tm38qv67a02a,
+	&sanyo_2_5_in,
+	&epson_l2f50113t00,
+};
+
+struct clcd_panel *versatile_clcd_get_panel(const char *name)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(panels); i++)
+		if (strcmp(panels[i]->mode.name, name) == 0)
+			break;
+
+	if (i < ARRAY_SIZE(panels))
+		return panels[i];
+
+	pr_err("CLCD: couldn't get parameters for panel %s\n", name);
+
+	return NULL;
+}
+
+int versatile_clcd_setup_dma(struct clcd_fb *fb, unsigned long framesize)
+{
+	dma_addr_t dma;
+
+	fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
+						    &dma, GFP_KERNEL);
+	if (!fb->fb.screen_base) {
+		pr_err("CLCD: unable to map framebuffer\n");
+		return -ENOMEM;
+	}
+
+	fb->fb.fix.smem_start	= dma;
+	fb->fb.fix.smem_len	= framesize;
+
+	return 0;
+}
+
+int versatile_clcd_mmap_dma(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+	return dma_mmap_writecombine(&fb->dev->dev, vma,
+				     fb->fb.screen_base,
+				     fb->fb.fix.smem_start,
+				     fb->fb.fix.smem_len);
+}
+
+void versatile_clcd_remove_dma(struct clcd_fb *fb)
+{
+	dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
+			      fb->fb.screen_base, fb->fb.fix.smem_start);
+}

+ 72 - 0
arch/arm/plat-versatile/fpga-irq.c

@@ -0,0 +1,72 @@
+/*
+ *  Support for Versatile FPGA-based IRQ controllers
+ */
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/mach/irq.h>
+#include <plat/fpga-irq.h>
+
+#define IRQ_STATUS		0x00
+#define IRQ_RAW_STATUS		0x04
+#define IRQ_ENABLE_SET		0x08
+#define IRQ_ENABLE_CLEAR	0x0c
+
+static void fpga_irq_mask(struct irq_data *d)
+{
+	struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
+	u32 mask = 1 << (d->irq - f->irq_start);
+
+	writel(mask, f->base + IRQ_ENABLE_CLEAR);
+}
+
+static void fpga_irq_unmask(struct irq_data *d)
+{
+	struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
+	u32 mask = 1 << (d->irq - f->irq_start);
+
+	writel(mask, f->base + IRQ_ENABLE_SET);
+}
+
+static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc)
+{
+	struct fpga_irq_data *f = get_irq_desc_data(desc);
+	u32 status = readl(f->base + IRQ_STATUS);
+
+	if (status == 0) {
+		do_bad_IRQ(irq, desc);
+		return;
+	}
+
+	do {
+		irq = ffs(status) - 1;
+		status &= ~(1 << irq);
+
+		generic_handle_irq(irq + f->irq_start);
+	} while (status);
+}
+
+void __init fpga_irq_init(int parent_irq, u32 valid, struct fpga_irq_data *f)
+{
+	unsigned int i;
+
+	f->chip.irq_ack = fpga_irq_mask;
+	f->chip.irq_mask = fpga_irq_mask;
+	f->chip.irq_unmask = fpga_irq_unmask;
+
+	if (parent_irq != -1) {
+		set_irq_data(parent_irq, f);
+		set_irq_chained_handler(parent_irq, fpga_irq_handle);
+	}
+
+	for (i = 0; i < 32; i++) {
+		if (valid & (1 << i)) {
+			unsigned int irq = f->irq_start + i;
+
+			set_irq_chip_data(irq, f);
+			set_irq_chip(irq, &f->chip);
+			set_irq_handler(irq, handle_level_irq);
+			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+		}
+	}
+}

+ 4 - 4
arch/arm/mach-vexpress/headsmp.S → arch/arm/plat-versatile/headsmp.S

@@ -1,5 +1,5 @@
 /*
 /*
- *  linux/arch/arm/mach-vexpress/headsmp.S
+ *  linux/arch/arm/plat-versatile/headsmp.S
  *
  *
  *  Copyright (c) 2003 ARM Limited
  *  Copyright (c) 2003 ARM Limited
  *  All Rights Reserved
  *  All Rights Reserved
@@ -14,11 +14,11 @@
 	__INIT
 	__INIT
 
 
 /*
 /*
- * Versatile Express specific entry point for secondary CPUs.  This
- * provides a "holding pen" into which all secondary cores are held
+ * Realview/Versatile Express specific entry point for secondary CPUs.
+ * This provides a "holding pen" into which all secondary cores are held
  * until we're ready for them to initialise.
  * until we're ready for them to initialise.
  */
  */
-ENTRY(vexpress_secondary_startup)
+ENTRY(versatile_secondary_startup)
 	mrc	p15, 0, r0, c0, c0, 5
 	mrc	p15, 0, r0, c0, c0, 5
 	and	r0, r0, #15
 	and	r0, r0, #15
 	adr	r4, 1f
 	adr	r4, 1f

+ 9 - 0
arch/arm/plat-versatile/include/plat/clcd.h

@@ -0,0 +1,9 @@
+#ifndef PLAT_CLCD_H
+#define PLAT_CLCD_H
+
+struct clcd_panel *versatile_clcd_get_panel(const char *);
+int versatile_clcd_setup_dma(struct clcd_fb *, unsigned long);
+int versatile_clcd_mmap_dma(struct clcd_fb *, struct vm_area_struct *);
+void versatile_clcd_remove_dma(struct clcd_fb *);
+
+#endif

+ 12 - 0
arch/arm/plat-versatile/include/plat/fpga-irq.h

@@ -0,0 +1,12 @@
+#ifndef PLAT_FPGA_IRQ_H
+#define PLAT_FPGA_IRQ_H
+
+struct fpga_irq_data {
+	void __iomem *base;
+	unsigned int irq_start;
+	struct irq_chip chip;
+};
+
+void fpga_irq_init(int, u32, struct fpga_irq_data *);
+
+#endif

+ 3 - 2
arch/arm/mach-vexpress/localtimer.c → arch/arm/plat-versatile/localtimer.c

@@ -1,5 +1,5 @@
 /*
 /*
- *  linux/arch/arm/mach-vexpress/localtimer.c
+ *  linux/arch/arm/plat-versatile/localtimer.c
  *
  *
  *  Copyright (C) 2002 ARM Ltd.
  *  Copyright (C) 2002 ARM Ltd.
  *  All Rights Reserved
  *  All Rights Reserved
@@ -19,8 +19,9 @@
 /*
 /*
  * Setup the local clock events for a CPU.
  * Setup the local clock events for a CPU.
  */
  */
-void __cpuinit local_timer_setup(struct clock_event_device *evt)
+int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
 {
 	evt->irq = IRQ_LOCALTIMER;
 	evt->irq = IRQ_LOCALTIMER;
 	twd_timer_setup(evt);
 	twd_timer_setup(evt);
+	return 0;
 }
 }

+ 104 - 0
arch/arm/plat-versatile/platsmp.c

@@ -0,0 +1,104 @@
+/*
+ *  linux/arch/arm/plat-versatile/platsmp.c
+ *
+ *  Copyright (C) 2002 ARM Ltd.
+ *  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/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+volatile int __cpuinitdata pen_release = -1;
+
+/*
+ * Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not.  This is necessary for the hotplug code to work reliably.
+ */
+static void __cpuinit write_pen_release(int val)
+{
+	pen_release = val;
+	smp_wmb();
+	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+	/*
+	 * if any interrupts are already enabled for the primary
+	 * core (e.g. timer irq), then they will not have been enabled
+	 * for us: do so
+	 */
+	gic_secondary_init(0);
+
+	/*
+	 * let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	write_pen_release(-1);
+
+	/*
+	 * Synchronise with the boot thread.
+	 */
+	spin_lock(&boot_lock);
+	spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long timeout;
+
+	/*
+	 * Set synchronisation state between this boot processor
+	 * and the secondary one
+	 */
+	spin_lock(&boot_lock);
+
+	/*
+	 * This is really belt and braces; we hold unintended secondary
+	 * CPUs in the holding pen until we're ready for them.  However,
+	 * since we haven't sent them a soft interrupt, they shouldn't
+	 * be there.
+	 */
+	write_pen_release(cpu);
+
+	/*
+	 * Send the secondary CPU a soft interrupt, thereby causing
+	 * the boot monitor to read the system wide flags register,
+	 * and branch to the address found there.
+	 */
+	smp_cross_call(cpumask_of(cpu), 1);
+
+	timeout = jiffies + (1 * HZ);
+	while (time_before(jiffies, timeout)) {
+		smp_rmb();
+		if (pen_release == -1)
+			break;
+
+		udelay(10);
+	}
+
+	/*
+	 * now the secondary core is starting up let it run its
+	 * calibrations, then wait for it to finish
+	 */
+	spin_unlock(&boot_lock);
+
+	return pen_release != -1 ? -ENOSYS : 0;
+}

文件差异内容过多而无法显示
+ 6 - 2293
arch/arm/tools/mach-types


+ 90 - 13
drivers/video/amba-clcd.c

@@ -120,8 +120,23 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
 static int
 static int
 clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
 clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
 {
 {
+	u32 caps;
 	int ret = 0;
 	int ret = 0;
 
 
+	if (fb->panel->caps && fb->board->caps)
+		caps = fb->panel->caps & fb->board->caps;
+	else {
+		/* Old way of specifying what can be used */
+		caps = fb->panel->cntl & CNTL_BGR ?
+			CLCD_CAP_BGR : CLCD_CAP_RGB;
+		/* But mask out 444 modes as they weren't supported */
+		caps &= ~CLCD_CAP_444;
+	}
+
+	/* Only TFT panels can do RGB888/BGR888 */
+	if (!(fb->panel->cntl & CNTL_LCDTFT))
+		caps &= ~CLCD_CAP_888;
+
 	memset(&var->transp, 0, sizeof(var->transp));
 	memset(&var->transp, 0, sizeof(var->transp));
 
 
 	var->red.msb_right = 0;
 	var->red.msb_right = 0;
@@ -133,6 +148,13 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
 	case 2:
 	case 2:
 	case 4:
 	case 4:
 	case 8:
 	case 8:
+		/* If we can't do 5551, reject */
+		caps &= CLCD_CAP_5551;
+		if (!caps) {
+			ret = -EINVAL;
+			break;
+		}
+
 		var->red.length		= var->bits_per_pixel;
 		var->red.length		= var->bits_per_pixel;
 		var->red.offset		= 0;
 		var->red.offset		= 0;
 		var->green.length	= var->bits_per_pixel;
 		var->green.length	= var->bits_per_pixel;
@@ -140,23 +162,61 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
 		var->blue.length	= var->bits_per_pixel;
 		var->blue.length	= var->bits_per_pixel;
 		var->blue.offset	= 0;
 		var->blue.offset	= 0;
 		break;
 		break;
+
 	case 16:
 	case 16:
-		var->red.length = 5;
-		var->blue.length = 5;
+		/* If we can't do 444, 5551 or 565, reject */
+		if (!(caps & (CLCD_CAP_444 | CLCD_CAP_5551 | CLCD_CAP_565))) {
+			ret = -EINVAL;
+			break;
+		}
+
 		/*
 		/*
-		 * Green length can be 5 or 6 depending whether
-		 * we're operating in RGB555 or RGB565 mode.
+		 * Green length can be 4, 5 or 6 depending whether
+		 * we're operating in 444, 5551 or 565 mode.
 		 */
 		 */
-		if (var->green.length != 5 && var->green.length != 6)
-			var->green.length = 6;
+		if (var->green.length == 4 && caps & CLCD_CAP_444)
+			caps &= CLCD_CAP_444;
+		if (var->green.length == 5 && caps & CLCD_CAP_5551)
+			caps &= CLCD_CAP_5551;
+		else if (var->green.length == 6 && caps & CLCD_CAP_565)
+			caps &= CLCD_CAP_565;
+		else {
+			/*
+			 * PL110 officially only supports RGB555,
+			 * but may be wired up to allow RGB565.
+			 */
+			if (caps & CLCD_CAP_565) {
+				var->green.length = 6;
+				caps &= CLCD_CAP_565;
+			} else if (caps & CLCD_CAP_5551) {
+				var->green.length = 5;
+				caps &= CLCD_CAP_5551;
+			} else {
+				var->green.length = 4;
+				caps &= CLCD_CAP_444;
+			}
+		}
+
+		if (var->green.length >= 5) {
+			var->red.length = 5;
+			var->blue.length = 5;
+		} else {
+			var->red.length = 4;
+			var->blue.length = 4;
+		}
 		break;
 		break;
 	case 32:
 	case 32:
-		if (fb->panel->cntl & CNTL_LCDTFT) {
-			var->red.length		= 8;
-			var->green.length	= 8;
-			var->blue.length	= 8;
+		/* If we can't do 888, reject */
+		caps &= CLCD_CAP_888;
+		if (!caps) {
+			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
+
+		var->red.length = 8;
+		var->green.length = 8;
+		var->blue.length = 8;
+		break;
 	default:
 	default:
 		ret = -EINVAL;
 		ret = -EINVAL;
 		break;
 		break;
@@ -168,7 +228,20 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
 	 * the bitfield length defined above.
 	 * the bitfield length defined above.
 	 */
 	 */
 	if (ret == 0 && var->bits_per_pixel >= 16) {
 	if (ret == 0 && var->bits_per_pixel >= 16) {
-		if (fb->panel->cntl & CNTL_BGR) {
+		bool bgr, rgb;
+
+		bgr = caps & CLCD_CAP_BGR && var->blue.offset == 0;
+		rgb = caps & CLCD_CAP_RGB && var->red.offset == 0;
+
+		if (!bgr && !rgb)
+			/*
+			 * The requested format was not possible, try just
+			 * our capabilities.  One of BGR or RGB must be
+			 * supported.
+			 */
+			bgr = caps & CLCD_CAP_BGR;
+
+		if (bgr) {
 			var->blue.offset = 0;
 			var->blue.offset = 0;
 			var->green.offset = var->blue.offset + var->blue.length;
 			var->green.offset = var->blue.offset + var->blue.length;
 			var->red.offset = var->green.offset + var->green.length;
 			var->red.offset = var->green.offset + var->green.length;
@@ -443,8 +516,8 @@ static int clcdfb_register(struct clcd_fb *fb)
 
 
 	fb_set_var(&fb->fb, &fb->fb.var);
 	fb_set_var(&fb->fb, &fb->fb.var);
 
 
-        printk(KERN_INFO "CLCD: %s hardware, %s display\n",
-               fb->board->name, fb->panel->mode.name);
+	dev_info(&fb->dev->dev, "%s hardware, %s display\n",
+	         fb->board->name, fb->panel->mode.name);
 
 
 	ret = register_framebuffer(&fb->fb);
 	ret = register_framebuffer(&fb->fb);
 	if (ret == 0)
 	if (ret == 0)
@@ -486,6 +559,10 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
 	fb->dev = dev;
 	fb->dev = dev;
 	fb->board = board;
 	fb->board = board;
 
 
+	dev_info(&fb->dev->dev, "PL%03x rev%u at 0x%08llx\n",
+		amba_part(dev), amba_rev(dev),
+		(unsigned long long)dev->res.start);
+
 	ret = fb->board->setup(fb);
 	ret = fb->board->setup(fb);
 	if (ret)
 	if (ret)
 		goto free_fb;
 		goto free_fb;

+ 69 - 21
include/linux/amba/clcd.h

@@ -53,6 +53,7 @@
 #define CNTL_LCDBPP8		(3 << 1)
 #define CNTL_LCDBPP8		(3 << 1)
 #define CNTL_LCDBPP16		(4 << 1)
 #define CNTL_LCDBPP16		(4 << 1)
 #define CNTL_LCDBPP16_565	(6 << 1)
 #define CNTL_LCDBPP16_565	(6 << 1)
+#define CNTL_LCDBPP16_444	(7 << 1)
 #define CNTL_LCDBPP24		(5 << 1)
 #define CNTL_LCDBPP24		(5 << 1)
 #define CNTL_LCDBW		(1 << 4)
 #define CNTL_LCDBW		(1 << 4)
 #define CNTL_LCDTFT		(1 << 5)
 #define CNTL_LCDTFT		(1 << 5)
@@ -66,6 +67,32 @@
 #define CNTL_LDMAFIFOTIME	(1 << 15)
 #define CNTL_LDMAFIFOTIME	(1 << 15)
 #define CNTL_WATERMARK		(1 << 16)
 #define CNTL_WATERMARK		(1 << 16)
 
 
+enum {
+	/* individual formats */
+	CLCD_CAP_RGB444		= (1 << 0),
+	CLCD_CAP_RGB5551	= (1 << 1),
+	CLCD_CAP_RGB565		= (1 << 2),
+	CLCD_CAP_RGB888		= (1 << 3),
+	CLCD_CAP_BGR444		= (1 << 4),
+	CLCD_CAP_BGR5551	= (1 << 5),
+	CLCD_CAP_BGR565		= (1 << 6),
+	CLCD_CAP_BGR888		= (1 << 7),
+
+	/* connection layouts */
+	CLCD_CAP_444		= CLCD_CAP_RGB444 | CLCD_CAP_BGR444,
+	CLCD_CAP_5551		= CLCD_CAP_RGB5551 | CLCD_CAP_BGR5551,
+	CLCD_CAP_565		= CLCD_CAP_RGB565 | CLCD_CAP_BGR565,
+	CLCD_CAP_888		= CLCD_CAP_RGB888 | CLCD_CAP_BGR888,
+
+	/* red/blue ordering */
+	CLCD_CAP_RGB		= CLCD_CAP_RGB444 | CLCD_CAP_RGB5551 |
+				  CLCD_CAP_RGB565 | CLCD_CAP_RGB888,
+	CLCD_CAP_BGR		= CLCD_CAP_BGR444 | CLCD_CAP_BGR5551 |
+				  CLCD_CAP_BGR565 | CLCD_CAP_BGR888,
+
+	CLCD_CAP_ALL		= CLCD_CAP_BGR | CLCD_CAP_RGB,
+};
+
 struct clcd_panel {
 struct clcd_panel {
 	struct fb_videomode	mode;
 	struct fb_videomode	mode;
 	signed short		width;	/* width in mm */
 	signed short		width;	/* width in mm */
@@ -73,6 +100,7 @@ struct clcd_panel {
 	u32			tim2;
 	u32			tim2;
 	u32			tim3;
 	u32			tim3;
 	u32			cntl;
 	u32			cntl;
+	u32			caps;
 	unsigned int		bpp:8,
 	unsigned int		bpp:8,
 				fixedtimings:1,
 				fixedtimings:1,
 				grayscale:1;
 				grayscale:1;
@@ -96,6 +124,11 @@ struct clcd_fb;
 struct clcd_board {
 struct clcd_board {
 	const char *name;
 	const char *name;
 
 
+	/*
+	 * Optional.  Hardware capability flags.
+	 */
+	u32	caps;
+
 	/*
 	/*
 	 * Optional.  Check whether the var structure is acceptable
 	 * Optional.  Check whether the var structure is acceptable
 	 * for this display.
 	 * for this display.
@@ -155,34 +188,35 @@ struct clcd_fb {
 
 
 static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
 static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
 {
 {
+	struct fb_var_screeninfo *var = &fb->fb.var;
 	u32 val, cpl;
 	u32 val, cpl;
 
 
 	/*
 	/*
 	 * Program the CLCD controller registers and start the CLCD
 	 * Program the CLCD controller registers and start the CLCD
 	 */
 	 */
-	val = ((fb->fb.var.xres / 16) - 1) << 2;
-	val |= (fb->fb.var.hsync_len - 1) << 8;
-	val |= (fb->fb.var.right_margin - 1) << 16;
-	val |= (fb->fb.var.left_margin - 1) << 24;
+	val = ((var->xres / 16) - 1) << 2;
+	val |= (var->hsync_len - 1) << 8;
+	val |= (var->right_margin - 1) << 16;
+	val |= (var->left_margin - 1) << 24;
 	regs->tim0 = val;
 	regs->tim0 = val;
 
 
-	val = fb->fb.var.yres;
+	val = var->yres;
 	if (fb->panel->cntl & CNTL_LCDDUAL)
 	if (fb->panel->cntl & CNTL_LCDDUAL)
 		val /= 2;
 		val /= 2;
 	val -= 1;
 	val -= 1;
-	val |= (fb->fb.var.vsync_len - 1) << 10;
-	val |= fb->fb.var.lower_margin << 16;
-	val |= fb->fb.var.upper_margin << 24;
+	val |= (var->vsync_len - 1) << 10;
+	val |= var->lower_margin << 16;
+	val |= var->upper_margin << 24;
 	regs->tim1 = val;
 	regs->tim1 = val;
 
 
 	val = fb->panel->tim2;
 	val = fb->panel->tim2;
-	val |= fb->fb.var.sync & FB_SYNC_HOR_HIGH_ACT  ? 0 : TIM2_IHS;
-	val |= fb->fb.var.sync & FB_SYNC_VERT_HIGH_ACT ? 0 : TIM2_IVS;
+	val |= var->sync & FB_SYNC_HOR_HIGH_ACT  ? 0 : TIM2_IHS;
+	val |= var->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : TIM2_IVS;
 
 
-	cpl = fb->fb.var.xres_virtual;
+	cpl = var->xres_virtual;
 	if (fb->panel->cntl & CNTL_LCDTFT)	  /* TFT */
 	if (fb->panel->cntl & CNTL_LCDTFT)	  /* TFT */
 		/* / 1 */;
 		/* / 1 */;
-	else if (!fb->fb.var.grayscale)		  /* STN color */
+	else if (!var->grayscale)		  /* STN color */
 		cpl = cpl * 8 / 3;
 		cpl = cpl * 8 / 3;
 	else if (fb->panel->cntl & CNTL_LCDMONO8) /* STN monochrome, 8bit */
 	else if (fb->panel->cntl & CNTL_LCDMONO8) /* STN monochrome, 8bit */
 		cpl /= 8;
 		cpl /= 8;
@@ -194,10 +228,22 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
 	regs->tim3 = fb->panel->tim3;
 	regs->tim3 = fb->panel->tim3;
 
 
 	val = fb->panel->cntl;
 	val = fb->panel->cntl;
-	if (fb->fb.var.grayscale)
+	if (var->grayscale)
 		val |= CNTL_LCDBW;
 		val |= CNTL_LCDBW;
 
 
-	switch (fb->fb.var.bits_per_pixel) {
+	if (fb->panel->caps && fb->board->caps &&
+	    var->bits_per_pixel >= 16) {
+		/*
+		 * if board and panel supply capabilities, we can support
+		 * changing BGR/RGB depending on supplied parameters
+		 */
+		if (var->red.offset == 0)
+			val &= ~CNTL_BGR;
+		else
+			val |= CNTL_BGR;
+	}
+
+	switch (var->bits_per_pixel) {
 	case 1:
 	case 1:
 		val |= CNTL_LCDBPP1;
 		val |= CNTL_LCDBPP1;
 		break;
 		break;
@@ -212,15 +258,17 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
 		break;
 		break;
 	case 16:
 	case 16:
 		/*
 		/*
-		 * PL110 cannot choose between 5551 and 565 modes in
-		 * its control register
+		 * PL110 cannot choose between 5551 and 565 modes in its
+		 * control register.  It is possible to use 565 with
+		 * custom external wiring.
 		 */
 		 */
-		if ((fb->dev->periphid & 0x000fffff) == 0x00041110)
+		if (amba_part(fb->dev) == 0x110 ||
+		    var->green.length == 5)
 			val |= CNTL_LCDBPP16;
 			val |= CNTL_LCDBPP16;
-		else if (fb->fb.var.green.length == 5)
-			val |= CNTL_LCDBPP16;
-		else
+		else if (var->green.length == 6)
 			val |= CNTL_LCDBPP16_565;
 			val |= CNTL_LCDBPP16_565;
+		else
+			val |= CNTL_LCDBPP16_444;
 		break;
 		break;
 	case 32:
 	case 32:
 		val |= CNTL_LCDBPP24;
 		val |= CNTL_LCDBPP24;
@@ -228,7 +276,7 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
 	}
 	}
 
 
 	regs->cntl = val;
 	regs->cntl = val;
-	regs->pixclock = fb->fb.var.pixclock;
+	regs->pixclock = var->pixclock;
 }
 }
 
 
 static inline int clcdfb_check(struct clcd_fb *fb, struct fb_var_screeninfo *var)
 static inline int clcdfb_check(struct clcd_fb *fb, struct fb_var_screeninfo *var)

部分文件因为文件数量过多而无法显示