aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig10
-rw-r--r--arch/arm/include/asm/localtimer.h8
-rw-r--r--arch/arm/include/asm/outercache.h14
-rw-r--r--arch/arm/include/asm/pgtable.h3
-rw-r--r--arch/arm/include/asm/setup.h2
-rw-r--r--arch/arm/kernel/hw_breakpoint.c14
-rw-r--r--arch/arm/kernel/setup.c7
-rw-r--r--arch/arm/kernel/smp.c7
-rw-r--r--arch/arm/kernel/traps.c6
-rw-r--r--arch/arm/lib/uaccess_with_memcpy.c7
-rw-r--r--arch/arm/mach-integrator/Kconfig1
-rw-r--r--arch/arm/mach-integrator/common.h1
-rw-r--r--arch/arm/mach-integrator/core.c7
-rw-r--r--arch/arm/mach-integrator/impd1.c5
-rw-r--r--arch/arm/mach-integrator/include/mach/cm.h4
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c44
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c239
-rw-r--r--arch/arm/mach-msm/timer.c3
-rw-r--r--arch/arm/mach-omap2/Kconfig1
-rw-r--r--arch/arm/mach-omap2/timer-mpu.c7
-rw-r--r--arch/arm/mach-realview/Makefile3
-rw-r--r--arch/arm/mach-realview/core.c233
-rw-r--r--arch/arm/mach-realview/core.h2
-rw-r--r--arch/arm/mach-realview/headsmp.S40
-rw-r--r--arch/arm/mach-realview/localtimer.c26
-rw-r--r--arch/arm/mach-realview/platsmp.c98
-rw-r--r--arch/arm/mach-realview/realview_eb.c22
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c22
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c22
-rw-r--r--arch/arm/mach-realview/realview_pba8.c22
-rw-r--r--arch/arm/mach-realview/realview_pbx.c22
-rw-r--r--arch/arm/mach-s5pv310/localtimer.c3
-rw-r--r--arch/arm/mach-shmobile/localtimer.c3
-rw-r--r--arch/arm/mach-tegra/localtimer.c3
-rw-r--r--arch/arm/mach-ux500/localtimer.c3
-rw-r--r--arch/arm/mach-versatile/core.c295
-rw-r--r--arch/arm/mach-versatile/core.h2
-rw-r--r--arch/arm/mach-versatile/include/mach/hardware.h2
-rw-r--r--arch/arm/mach-versatile/versatile_ab.c1
-rw-r--r--arch/arm/mach-versatile/versatile_pb.c6
-rw-r--r--arch/arm/mach-vexpress/Kconfig3
-rw-r--r--arch/arm/mach-vexpress/Makefile3
-rw-r--r--arch/arm/mach-vexpress/core.h1
-rw-r--r--arch/arm/mach-vexpress/ct-ca9x4.c68
-rw-r--r--arch/arm/mach-vexpress/platsmp.c94
-rw-r--r--arch/arm/mach-vexpress/v2m.c31
-rw-r--r--arch/arm/mm/dma-mapping.c11
-rw-r--r--arch/arm/mm/fault-armv.c7
-rw-r--r--arch/arm/mm/fault.c39
-rw-r--r--arch/arm/mm/idmap.c35
-rw-r--r--arch/arm/mm/init.c6
-rw-r--r--arch/arm/mm/mm.h2
-rw-r--r--arch/arm/mm/mmu.c71
-rw-r--r--arch/arm/mm/pgd.c24
-rw-r--r--arch/arm/plat-versatile/Kconfig17
-rw-r--r--arch/arm/plat-versatile/Makefile13
-rw-r--r--arch/arm/plat-versatile/clcd.c182
-rw-r--r--arch/arm/plat-versatile/fpga-irq.c72
-rw-r--r--arch/arm/plat-versatile/headsmp.S (renamed from arch/arm/mach-vexpress/headsmp.S)8
-rw-r--r--arch/arm/plat-versatile/include/plat/clcd.h9
-rw-r--r--arch/arm/plat-versatile/include/plat/fpga-irq.h12
-rw-r--r--arch/arm/plat-versatile/localtimer.c (renamed from arch/arm/mach-vexpress/localtimer.c)5
-rw-r--r--arch/arm/plat-versatile/platsmp.c104
63 files changed, 881 insertions, 1156 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e34bf0272da..f785b49bf1f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -235,6 +235,7 @@ config ARCH_INTEGRATOR
235 select ICST 235 select ICST
236 select GENERIC_CLOCKEVENTS 236 select GENERIC_CLOCKEVENTS
237 select PLAT_VERSATILE 237 select PLAT_VERSATILE
238 select PLAT_VERSATILE_FPGA_IRQ
238 help 239 help
239 Support for ARM's Integrator platform. 240 Support for ARM's Integrator platform.
240 241
@@ -242,11 +243,11 @@ config ARCH_REALVIEW
242 bool "ARM Ltd. RealView family" 243 bool "ARM Ltd. RealView family"
243 select ARM_AMBA 244 select ARM_AMBA
244 select CLKDEV_LOOKUP 245 select CLKDEV_LOOKUP
245 select HAVE_SCHED_CLOCK
246 select ICST 246 select ICST
247 select GENERIC_CLOCKEVENTS 247 select GENERIC_CLOCKEVENTS
248 select ARCH_WANT_OPTIONAL_GPIOLIB 248 select ARCH_WANT_OPTIONAL_GPIOLIB
249 select PLAT_VERSATILE 249 select PLAT_VERSATILE
250 select PLAT_VERSATILE_CLCD
250 select ARM_TIMER_SP804 251 select ARM_TIMER_SP804
251 select GPIO_PL061 if GPIOLIB 252 select GPIO_PL061 if GPIOLIB
252 help 253 help
@@ -257,11 +258,12 @@ config ARCH_VERSATILE
257 select ARM_AMBA 258 select ARM_AMBA
258 select ARM_VIC 259 select ARM_VIC
259 select CLKDEV_LOOKUP 260 select CLKDEV_LOOKUP
260 select HAVE_SCHED_CLOCK
261 select ICST 261 select ICST
262 select GENERIC_CLOCKEVENTS 262 select GENERIC_CLOCKEVENTS
263 select ARCH_WANT_OPTIONAL_GPIOLIB 263 select ARCH_WANT_OPTIONAL_GPIOLIB
264 select PLAT_VERSATILE 264 select PLAT_VERSATILE
265 select PLAT_VERSATILE_CLCD
266 select PLAT_VERSATILE_FPGA_IRQ
265 select ARM_TIMER_SP804 267 select ARM_TIMER_SP804
266 help 268 help
267 This enables support for ARM Ltd Versatile board. 269 This enables support for ARM Ltd Versatile board.
@@ -274,9 +276,10 @@ config ARCH_VEXPRESS
274 select CLKDEV_LOOKUP 276 select CLKDEV_LOOKUP
275 select GENERIC_CLOCKEVENTS 277 select GENERIC_CLOCKEVENTS
276 select HAVE_CLK 278 select HAVE_CLK
277 select HAVE_SCHED_CLOCK 279 select HAVE_PATA_PLATFORM
278 select ICST 280 select ICST
279 select PLAT_VERSATILE 281 select PLAT_VERSATILE
282 select PLAT_VERSATILE_CLCD
280 help 283 help
281 This enables support for the ARM Ltd Versatile Express boards. 284 This enables support for the ARM Ltd Versatile Express boards.
282 285
@@ -1008,6 +1011,7 @@ source "arch/arm/mach-ux500/Kconfig"
1008source "arch/arm/mach-versatile/Kconfig" 1011source "arch/arm/mach-versatile/Kconfig"
1009 1012
1010source "arch/arm/mach-vexpress/Kconfig" 1013source "arch/arm/mach-vexpress/Kconfig"
1014source "arch/arm/plat-versatile/Kconfig"
1011 1015
1012source "arch/arm/mach-vt8500/Kconfig" 1016source "arch/arm/mach-vt8500/Kconfig"
1013 1017
diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
index 6bc63ab498c..080d74f8128 100644
--- a/arch/arm/include/asm/localtimer.h
+++ b/arch/arm/include/asm/localtimer.h
@@ -44,8 +44,14 @@ int local_timer_ack(void);
44/* 44/*
45 * Setup a local timer interrupt for a CPU. 45 * Setup a local timer interrupt for a CPU.
46 */ 46 */
47void local_timer_setup(struct clock_event_device *); 47int local_timer_setup(struct clock_event_device *);
48 48
49#else
50
51static inline int local_timer_setup(struct clock_event_device *evt)
52{
53 return -ENXIO;
54}
49#endif 55#endif
50 56
51#endif 57#endif
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
index 348d513afa9..d8387437ec5 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -21,6 +21,8 @@
21#ifndef __ASM_OUTERCACHE_H 21#ifndef __ASM_OUTERCACHE_H
22#define __ASM_OUTERCACHE_H 22#define __ASM_OUTERCACHE_H
23 23
24#include <linux/types.h>
25
24struct outer_cache_fns { 26struct outer_cache_fns {
25 void (*inv_range)(unsigned long, unsigned long); 27 void (*inv_range)(unsigned long, unsigned long);
26 void (*clean_range)(unsigned long, unsigned long); 28 void (*clean_range)(unsigned long, unsigned long);
@@ -38,17 +40,17 @@ struct outer_cache_fns {
38 40
39extern struct outer_cache_fns outer_cache; 41extern struct outer_cache_fns outer_cache;
40 42
41static inline void outer_inv_range(unsigned long start, unsigned long end) 43static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
42{ 44{
43 if (outer_cache.inv_range) 45 if (outer_cache.inv_range)
44 outer_cache.inv_range(start, end); 46 outer_cache.inv_range(start, end);
45} 47}
46static inline void outer_clean_range(unsigned long start, unsigned long end) 48static inline void outer_clean_range(phys_addr_t start, phys_addr_t end)
47{ 49{
48 if (outer_cache.clean_range) 50 if (outer_cache.clean_range)
49 outer_cache.clean_range(start, end); 51 outer_cache.clean_range(start, end);
50} 52}
51static inline void outer_flush_range(unsigned long start, unsigned long end) 53static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
52{ 54{
53 if (outer_cache.flush_range) 55 if (outer_cache.flush_range)
54 outer_cache.flush_range(start, end); 56 outer_cache.flush_range(start, end);
@@ -74,11 +76,11 @@ static inline void outer_disable(void)
74 76
75#else 77#else
76 78
77static inline void outer_inv_range(unsigned long start, unsigned long end) 79static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
78{ } 80{ }
79static inline void outer_clean_range(unsigned long start, unsigned long end) 81static inline void outer_clean_range(phys_addr_t start, phys_addr_t end)
80{ } 82{ }
81static inline void outer_flush_range(unsigned long start, unsigned long end) 83static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
82{ } 84{ }
83static inline void outer_flush_all(void) { } 85static inline void outer_flush_all(void) { }
84static inline void outer_inv_all(void) { } 86static inline void outer_inv_all(void) { }
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index ebcb6432f45..5750704e027 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -301,6 +301,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
301#define pgd_present(pgd) (1) 301#define pgd_present(pgd) (1)
302#define pgd_clear(pgdp) do { } while (0) 302#define pgd_clear(pgdp) do { } while (0)
303#define set_pgd(pgd,pgdp) do { } while (0) 303#define set_pgd(pgd,pgdp) do { } while (0)
304#define set_pud(pud,pudp) do { } while (0)
304 305
305 306
306/* Find an entry in the second-level page table.. */ 307/* Find an entry in the second-level page table.. */
@@ -351,7 +352,7 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
351#define pte_unmap(pte) __pte_unmap(pte) 352#define pte_unmap(pte) __pte_unmap(pte)
352 353
353#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) 354#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
354#define pfn_pte(pfn,prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) 355#define pfn_pte(pfn,prot) __pte(__pfn_to_phys(pfn) | pgprot_val(prot))
355 356
356#define pte_page(pte) pfn_to_page(pte_pfn(pte)) 357#define pte_page(pte) pfn_to_page(pte_pfn(pte))
357#define mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot) 358#define mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot)
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index da8b52ec49c..95176af3df8 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -195,7 +195,7 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn }
195#define NR_BANKS 8 195#define NR_BANKS 8
196 196
197struct membank { 197struct membank {
198 unsigned long start; 198 phys_addr_t start;
199 unsigned long size; 199 unsigned long size;
200 unsigned int highmem; 200 unsigned int highmem;
201}; 201};
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index 44b84fe6e1b..8dbc126f715 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -238,8 +238,8 @@ static int enable_monitor_mode(void)
238 ARM_DBG_READ(c1, 0, dscr); 238 ARM_DBG_READ(c1, 0, dscr);
239 239
240 /* Ensure that halting mode is disabled. */ 240 /* Ensure that halting mode is disabled. */
241 if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, "halting debug mode enabled." 241 if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN,
242 "Unable to access hardware resources.")) { 242 "halting debug mode enabled. Unable to access hardware resources.\n")) {
243 ret = -EPERM; 243 ret = -EPERM;
244 goto out; 244 goto out;
245 } 245 }
@@ -377,7 +377,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
377 } 377 }
378 } 378 }
379 379
380 if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot")) { 380 if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) {
381 ret = -EBUSY; 381 ret = -EBUSY;
382 goto out; 382 goto out;
383 } 383 }
@@ -423,7 +423,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
423 } 423 }
424 } 424 }
425 425
426 if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot")) 426 if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n"))
427 return; 427 return;
428 428
429 /* Reset the control register. */ 429 /* Reset the control register. */
@@ -635,7 +635,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
635 if (WARN_ONCE(!bp->overflow_handler && 635 if (WARN_ONCE(!bp->overflow_handler &&
636 (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps() 636 (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps()
637 || !bp->hw.bp_target), 637 || !bp->hw.bp_target),
638 "overflow handler required but none found")) { 638 "overflow handler required but none found\n")) {
639 ret = -EINVAL; 639 ret = -EINVAL;
640 } 640 }
641out: 641out:
@@ -936,8 +936,8 @@ static int __init arch_hw_breakpoint_init(void)
936 ARM_DBG_READ(c1, 0, dscr); 936 ARM_DBG_READ(c1, 0, dscr);
937 if (dscr & ARM_DSCR_HDBGEN) { 937 if (dscr & ARM_DSCR_HDBGEN) {
938 max_watchpoint_len = 4; 938 max_watchpoint_len = 4;
939 pr_warning("halting debug mode enabled. Assuming maximum " 939 pr_warning("halting debug mode enabled. Assuming maximum watchpoint size of %u bytes.\n",
940 "watchpoint size of %u bytes.", max_watchpoint_len); 940 max_watchpoint_len);
941 } else { 941 } else {
942 /* Work out the maximum supported watchpoint length. */ 942 /* Work out the maximum supported watchpoint length. */
943 max_watchpoint_len = get_max_wp_len(); 943 max_watchpoint_len = get_max_wp_len();
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index d1da9217427..d149539ccd6 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -466,13 +466,13 @@ static struct machine_desc * __init setup_machine(unsigned int nr)
466 /* can't use cpu_relax() here as it may require MMU setup */; 466 /* can't use cpu_relax() here as it may require MMU setup */;
467} 467}
468 468
469static int __init arm_add_memory(unsigned long start, unsigned long size) 469static int __init arm_add_memory(phys_addr_t start, unsigned long size)
470{ 470{
471 struct membank *bank = &meminfo.bank[meminfo.nr_banks]; 471 struct membank *bank = &meminfo.bank[meminfo.nr_banks];
472 472
473 if (meminfo.nr_banks >= NR_BANKS) { 473 if (meminfo.nr_banks >= NR_BANKS) {
474 printk(KERN_CRIT "NR_BANKS too low, " 474 printk(KERN_CRIT "NR_BANKS too low, "
475 "ignoring memory at %#lx\n", start); 475 "ignoring memory at 0x%08llx\n", (long long)start);
476 return -EINVAL; 476 return -EINVAL;
477 } 477 }
478 478
@@ -502,7 +502,8 @@ static int __init arm_add_memory(unsigned long start, unsigned long size)
502static int __init early_mem(char *p) 502static int __init early_mem(char *p)
503{ 503{
504 static int usermem __initdata = 0; 504 static int usermem __initdata = 0;
505 unsigned long size, start; 505 unsigned long size;
506 phys_addr_t start;
506 char *endp; 507 char *endp;
507 508
508 /* 509 /*
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 4539ebcb089..8fe05ad932e 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -474,13 +474,12 @@ static void smp_timer_broadcast(const struct cpumask *mask)
474#define smp_timer_broadcast NULL 474#define smp_timer_broadcast NULL
475#endif 475#endif
476 476
477#ifndef CONFIG_LOCAL_TIMERS
478static void broadcast_timer_set_mode(enum clock_event_mode mode, 477static void broadcast_timer_set_mode(enum clock_event_mode mode,
479 struct clock_event_device *evt) 478 struct clock_event_device *evt)
480{ 479{
481} 480}
482 481
483static void local_timer_setup(struct clock_event_device *evt) 482static void broadcast_timer_setup(struct clock_event_device *evt)
484{ 483{
485 evt->name = "dummy_timer"; 484 evt->name = "dummy_timer";
486 evt->features = CLOCK_EVT_FEAT_ONESHOT | 485 evt->features = CLOCK_EVT_FEAT_ONESHOT |
@@ -492,7 +491,6 @@ static void local_timer_setup(struct clock_event_device *evt)
492 491
493 clockevents_register_device(evt); 492 clockevents_register_device(evt);
494} 493}
495#endif
496 494
497void __cpuinit percpu_timer_setup(void) 495void __cpuinit percpu_timer_setup(void)
498{ 496{
@@ -502,7 +500,8 @@ void __cpuinit percpu_timer_setup(void)
502 evt->cpumask = cpumask_of(cpu); 500 evt->cpumask = cpumask_of(cpu);
503 evt->broadcast = smp_timer_broadcast; 501 evt->broadcast = smp_timer_broadcast;
504 502
505 local_timer_setup(evt); 503 if (local_timer_setup(evt))
504 broadcast_timer_setup(evt);
506} 505}
507 506
508#ifdef CONFIG_HOTPLUG_CPU 507#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 21ac43f1c2d..f0000e188c8 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -712,17 +712,17 @@ EXPORT_SYMBOL(__readwrite_bug);
712 712
713void __pte_error(const char *file, int line, pte_t pte) 713void __pte_error(const char *file, int line, pte_t pte)
714{ 714{
715 printk("%s:%d: bad pte %08lx.\n", file, line, pte_val(pte)); 715 printk("%s:%d: bad pte %08llx.\n", file, line, (long long)pte_val(pte));
716} 716}
717 717
718void __pmd_error(const char *file, int line, pmd_t pmd) 718void __pmd_error(const char *file, int line, pmd_t pmd)
719{ 719{
720 printk("%s:%d: bad pmd %08lx.\n", file, line, pmd_val(pmd)); 720 printk("%s:%d: bad pmd %08llx.\n", file, line, (long long)pmd_val(pmd));
721} 721}
722 722
723void __pgd_error(const char *file, int line, pgd_t pgd) 723void __pgd_error(const char *file, int line, pgd_t pgd)
724{ 724{
725 printk("%s:%d: bad pgd %08lx.\n", file, line, pgd_val(pgd)); 725 printk("%s:%d: bad pgd %08llx.\n", file, line, (long long)pgd_val(pgd));
726} 726}
727 727
728asmlinkage void __div0(void) 728asmlinkage void __div0(void)
diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
index e2d2f2cd0c4..8b9b13649f8 100644
--- a/arch/arm/lib/uaccess_with_memcpy.c
+++ b/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)
27 pgd_t *pgd; 27 pgd_t *pgd;
28 pmd_t *pmd; 28 pmd_t *pmd;
29 pte_t *pte; 29 pte_t *pte;
30 pud_t *pud;
30 spinlock_t *ptl; 31 spinlock_t *ptl;
31 32
32 pgd = pgd_offset(current->mm, addr); 33 pgd = pgd_offset(current->mm, addr);
33 if (unlikely(pgd_none(*pgd) || pgd_bad(*pgd))) 34 if (unlikely(pgd_none(*pgd) || pgd_bad(*pgd)))
34 return 0; 35 return 0;
35 36
36 pmd = pmd_offset(pgd, addr); 37 pud = pud_offset(pgd, addr);
38 if (unlikely(pud_none(*pud) || pud_bad(*pud)))
39 return 0;
40
41 pmd = pmd_offset(pud, addr);
37 if (unlikely(pmd_none(*pmd) || pmd_bad(*pmd))) 42 if (unlikely(pmd_none(*pmd) || pmd_bad(*pmd)))
38 return 0; 43 return 0;
39 44
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
index 769b0f10c83..d701d32a07f 100644
--- a/arch/arm/mach-integrator/Kconfig
+++ b/arch/arm/mach-integrator/Kconfig
@@ -13,6 +13,7 @@ config ARCH_INTEGRATOR_CP
13 bool "Support Integrator/CP platform" 13 bool "Support Integrator/CP platform"
14 select ARCH_CINTEGRATOR 14 select ARCH_CINTEGRATOR
15 select ARM_TIMER_SP804 15 select ARM_TIMER_SP804
16 select PLAT_VERSATILE_CLCD
16 help 17 help
17 Include support for the ARM(R) Integrator CP platform. 18 Include support for the ARM(R) Integrator CP platform.
18 19
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
index 5f96e1518aa..a08f9b0299d 100644
--- a/arch/arm/mach-integrator/common.h
+++ b/arch/arm/mach-integrator/common.h
@@ -1 +1,2 @@
1void integrator_init_early(void);
1void integrator_reserve(void); 2void integrator_reserve(void);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index b8e884b450d..77315b99568 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -144,12 +144,15 @@ static struct clk_lookup lookups[] = {
144 } 144 }
145}; 145};
146 146
147void __init integrator_init_early(void)
148{
149 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
150}
151
147static int __init integrator_init(void) 152static int __init integrator_init(void)
148{ 153{
149 int i; 154 int i;
150 155
151 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
152
153 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { 156 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
154 struct amba_device *d = amba_devs[i]; 157 struct amba_device *d = amba_devs[i];
155 amba_device_register(d, &iomem_resource); 158 amba_device_register(d, &iomem_resource);
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index 5db574f8ae3..8cbb75a96bd 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -121,6 +121,7 @@ static struct clcd_panel vga = {
121 .height = -1, 121 .height = -1,
122 .tim2 = TIM2_BCD | TIM2_IPC, 122 .tim2 = TIM2_BCD | TIM2_IPC,
123 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), 123 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
124 .caps = CLCD_CAP_5551,
124 .connector = IMPD1_CTRL_DISP_VGA, 125 .connector = IMPD1_CTRL_DISP_VGA,
125 .bpp = 16, 126 .bpp = 16,
126 .grayscale = 0, 127 .grayscale = 0,
@@ -149,6 +150,7 @@ static struct clcd_panel svga = {
149 .tim2 = TIM2_BCD, 150 .tim2 = TIM2_BCD,
150 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), 151 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
151 .connector = IMPD1_CTRL_DISP_VGA, 152 .connector = IMPD1_CTRL_DISP_VGA,
153 .caps = CLCD_CAP_5551,
152 .bpp = 16, 154 .bpp = 16,
153 .grayscale = 0, 155 .grayscale = 0,
154}; 156};
@@ -175,6 +177,7 @@ static struct clcd_panel prospector = {
175 .height = -1, 177 .height = -1,
176 .tim2 = TIM2_BCD, 178 .tim2 = TIM2_BCD,
177 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), 179 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
180 .caps = CLCD_CAP_5551,
178 .fixedtimings = 1, 181 .fixedtimings = 1,
179 .connector = IMPD1_CTRL_DISP_LCD, 182 .connector = IMPD1_CTRL_DISP_LCD,
180 .bpp = 16, 183 .bpp = 16,
@@ -206,6 +209,7 @@ static struct clcd_panel ltm10c209 = {
206 .height = -1, 209 .height = -1,
207 .tim2 = TIM2_BCD, 210 .tim2 = TIM2_BCD,
208 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), 211 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
212 .caps = CLCD_CAP_5551,
209 .fixedtimings = 1, 213 .fixedtimings = 1,
210 .connector = IMPD1_CTRL_DISP_LCD, 214 .connector = IMPD1_CTRL_DISP_LCD,
211 .bpp = 16, 215 .bpp = 16,
@@ -279,6 +283,7 @@ static void impd1fb_clcd_remove(struct clcd_fb *fb)
279 283
280static struct clcd_board impd1_clcd_data = { 284static struct clcd_board impd1_clcd_data = {
281 .name = "IM-PD/1", 285 .name = "IM-PD/1",
286 .caps = CLCD_CAP_5551 | CLCD_CAP_888,
282 .check = clcdfb_check, 287 .check = clcdfb_check,
283 .decode = clcdfb_decode, 288 .decode = clcdfb_decode,
284 .disable = impd1fb_clcd_disable, 289 .disable = impd1fb_clcd_disable,
diff --git a/arch/arm/mach-integrator/include/mach/cm.h b/arch/arm/mach-integrator/include/mach/cm.h
index 1ab353e2359..445d57adb04 100644
--- a/arch/arm/mach-integrator/include/mach/cm.h
+++ b/arch/arm/mach-integrator/include/mach/cm.h
@@ -24,9 +24,9 @@ void cm_control(u32, u32);
24#define CM_CTRL_LCDBIASDN (1 << 10) 24#define CM_CTRL_LCDBIASDN (1 << 10)
25#define CM_CTRL_LCDMUXSEL_MASK (7 << 11) 25#define CM_CTRL_LCDMUXSEL_MASK (7 << 11)
26#define CM_CTRL_LCDMUXSEL_GENLCD (1 << 11) 26#define CM_CTRL_LCDMUXSEL_GENLCD (1 << 11)
27#define CM_CTRL_LCDMUXSEL_VGA_16BPP (2 << 11) 27#define CM_CTRL_LCDMUXSEL_VGA565_TFT555 (2 << 11)
28#define CM_CTRL_LCDMUXSEL_SHARPLCD (3 << 11) 28#define CM_CTRL_LCDMUXSEL_SHARPLCD (3 << 11)
29#define CM_CTRL_LCDMUXSEL_VGA_8421BPP (4 << 11) 29#define CM_CTRL_LCDMUXSEL_VGA555_TFT555 (4 << 11)
30#define CM_CTRL_LCDEN0 (1 << 14) 30#define CM_CTRL_LCDEN0 (1 << 14)
31#define CM_CTRL_LCDEN1 (1 << 15) 31#define CM_CTRL_LCDEN1 (1 << 15)
32#define CM_CTRL_STATIC1 (1 << 16) 32#define CM_CTRL_STATIC1 (1 << 16)
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index b666443b5cb..980803ff348 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -48,6 +48,8 @@
48#include <asm/mach/map.h> 48#include <asm/mach/map.h>
49#include <asm/mach/time.h> 49#include <asm/mach/time.h>
50 50
51#include <plat/fpga-irq.h>
52
51#include "common.h" 53#include "common.h"
52 54
53/* 55/*
@@ -57,10 +59,10 @@
57 * Setup a VA for the Integrator interrupt controller (for header #0, 59 * Setup a VA for the Integrator interrupt controller (for header #0,
58 * just for now). 60 * just for now).
59 */ 61 */
60#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) 62#define VA_IC_BASE __io_address(INTEGRATOR_IC_BASE)
61#define VA_SC_BASE IO_ADDRESS(INTEGRATOR_SC_BASE) 63#define VA_SC_BASE __io_address(INTEGRATOR_SC_BASE)
62#define VA_EBI_BASE IO_ADDRESS(INTEGRATOR_EBI_BASE) 64#define VA_EBI_BASE __io_address(INTEGRATOR_EBI_BASE)
63#define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_IC) 65#define VA_CMIC_BASE __io_address(INTEGRATOR_HDR_IC)
64 66
65/* 67/*
66 * Logical Physical 68 * Logical Physical
@@ -156,27 +158,14 @@ static void __init ap_map_io(void)
156 158
157#define INTEGRATOR_SC_VALID_INT 0x003fffff 159#define INTEGRATOR_SC_VALID_INT 0x003fffff
158 160
159static void sc_mask_irq(struct irq_data *d) 161static struct fpga_irq_data sc_irq_data = {
160{ 162 .base = VA_IC_BASE,
161 writel(1 << d->irq, VA_IC_BASE + IRQ_ENABLE_CLEAR); 163 .irq_start = 0,
162} 164 .chip.name = "SC",
163
164static void sc_unmask_irq(struct irq_data *d)
165{
166 writel(1 << d->irq, VA_IC_BASE + IRQ_ENABLE_SET);
167}
168
169static struct irq_chip sc_chip = {
170 .name = "SC",
171 .irq_ack = sc_mask_irq,
172 .irq_mask = sc_mask_irq,
173 .irq_unmask = sc_unmask_irq,
174}; 165};
175 166
176static void __init ap_init_irq(void) 167static void __init ap_init_irq(void)
177{ 168{
178 unsigned int i;
179
180 /* Disable all interrupts initially. */ 169 /* Disable all interrupts initially. */
181 /* Do the core module ones */ 170 /* Do the core module ones */
182 writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); 171 writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
@@ -185,13 +174,7 @@ static void __init ap_init_irq(void)
185 writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); 174 writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
186 writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); 175 writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
187 176
188 for (i = 0; i < NR_IRQS; i++) { 177 fpga_irq_init(-1, INTEGRATOR_SC_VALID_INT, &sc_irq_data);
189 if (((1 << i) & INTEGRATOR_SC_VALID_INT) != 0) {
190 set_irq_chip(i, &sc_chip);
191 set_irq_handler(i, handle_level_irq);
192 set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
193 }
194 }
195} 178}
196 179
197#ifdef CONFIG_PM 180#ifdef CONFIG_PM
@@ -282,7 +265,7 @@ static void ap_flash_exit(void)
282 265
283static void ap_flash_set_vpp(int on) 266static void ap_flash_set_vpp(int on)
284{ 267{
285 unsigned long reg = on ? SC_CTRLS : SC_CTRLC; 268 void __iomem *reg = on ? SC_CTRLS : SC_CTRLC;
286 269
287 writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg); 270 writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
288} 271}
@@ -499,8 +482,9 @@ static struct sys_timer ap_timer = {
499MACHINE_START(INTEGRATOR, "ARM-Integrator") 482MACHINE_START(INTEGRATOR, "ARM-Integrator")
500 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ 483 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
501 .boot_params = 0x00000100, 484 .boot_params = 0x00000100,
502 .map_io = ap_map_io,
503 .reserve = integrator_reserve, 485 .reserve = integrator_reserve,
486 .map_io = ap_map_io,
487 .init_early = integrator_init_early,
504 .init_irq = ap_init_irq, 488 .init_irq = ap_init_irq,
505 .timer = &ap_timer, 489 .timer = &ap_timer,
506 .init_machine = ap_init, 490 .init_machine = ap_init,
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index e9327da1382..9e3ce26023e 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -42,6 +42,10 @@
42 42
43#include <asm/hardware/timer-sp.h> 43#include <asm/hardware/timer-sp.h>
44 44
45#include <plat/clcd.h>
46#include <plat/fpga-irq.h>
47#include <plat/sched_clock.h>
48
45#include "common.h" 49#include "common.h"
46 50
47#define INTCP_PA_FLASH_BASE 0x24000000 51#define INTCP_PA_FLASH_BASE 0x24000000
@@ -49,9 +53,9 @@
49 53
50#define INTCP_PA_CLCD_BASE 0xc0000000 54#define INTCP_PA_CLCD_BASE 0xc0000000
51 55
52#define INTCP_VA_CIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE + 0x40) 56#define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40)
53#define INTCP_VA_PIC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) 57#define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE)
54#define INTCP_VA_SIC_BASE IO_ADDRESS(INTEGRATOR_CP_SIC_BASE) 58#define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE)
55 59
56#define INTCP_ETH_SIZE 0x10 60#define INTCP_ETH_SIZE 0x10
57 61
@@ -139,129 +143,48 @@ static void __init intcp_map_io(void)
139 iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc)); 143 iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
140} 144}
141 145
142#define cic_writel __raw_writel 146static struct fpga_irq_data cic_irq_data = {
143#define cic_readl __raw_readl 147 .base = INTCP_VA_CIC_BASE,
144#define pic_writel __raw_writel 148 .irq_start = IRQ_CIC_START,
145#define pic_readl __raw_readl 149 .chip.name = "CIC",
146#define sic_writel __raw_writel
147#define sic_readl __raw_readl
148
149static void cic_mask_irq(struct irq_data *d)
150{
151 unsigned int irq = d->irq - IRQ_CIC_START;
152 cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
153}
154
155static void cic_unmask_irq(struct irq_data *d)
156{
157 unsigned int irq = d->irq - IRQ_CIC_START;
158 cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_SET);
159}
160
161static struct irq_chip cic_chip = {
162 .name = "CIC",
163 .irq_ack = cic_mask_irq,
164 .irq_mask = cic_mask_irq,
165 .irq_unmask = cic_unmask_irq,
166}; 150};
167 151
168static void pic_mask_irq(struct irq_data *d) 152static struct fpga_irq_data pic_irq_data = {
169{ 153 .base = INTCP_VA_PIC_BASE,
170 unsigned int irq = d->irq - IRQ_PIC_START; 154 .irq_start = IRQ_PIC_START,
171 pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); 155 .chip.name = "PIC",
172}
173
174static void pic_unmask_irq(struct irq_data *d)
175{
176 unsigned int irq = d->irq - IRQ_PIC_START;
177 pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_SET);
178}
179
180static struct irq_chip pic_chip = {
181 .name = "PIC",
182 .irq_ack = pic_mask_irq,
183 .irq_mask = pic_mask_irq,
184 .irq_unmask = pic_unmask_irq,
185}; 156};
186 157
187static void sic_mask_irq(struct irq_data *d) 158static struct fpga_irq_data sic_irq_data = {
188{ 159 .base = INTCP_VA_SIC_BASE,
189 unsigned int irq = d->irq - IRQ_SIC_START; 160 .irq_start = IRQ_SIC_START,
190 sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); 161 .chip.name = "SIC",
191}
192
193static void sic_unmask_irq(struct irq_data *d)
194{
195 unsigned int irq = d->irq - IRQ_SIC_START;
196 sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_SET);
197}
198
199static struct irq_chip sic_chip = {
200 .name = "SIC",
201 .irq_ack = sic_mask_irq,
202 .irq_mask = sic_mask_irq,
203 .irq_unmask = sic_unmask_irq,
204}; 162};
205 163
206static void
207sic_handle_irq(unsigned int irq, struct irq_desc *desc)
208{
209 unsigned long status = sic_readl(INTCP_VA_SIC_BASE + IRQ_STATUS);
210
211 if (status == 0) {
212 do_bad_IRQ(irq, desc);
213 return;
214 }
215
216 do {
217 irq = ffs(status) - 1;
218 status &= ~(1 << irq);
219
220 irq += IRQ_SIC_START;
221
222 generic_handle_irq(irq);
223 } while (status);
224}
225
226static void __init intcp_init_irq(void) 164static void __init intcp_init_irq(void)
227{ 165{
228 unsigned int i; 166 u32 pic_mask, sic_mask;
167
168 pic_mask = ~((~0u) << (11 - IRQ_PIC_START));
169 pic_mask |= (~((~0u) << (29 - 22))) << 22;
170 sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START));
229 171
230 /* 172 /*
231 * Disable all interrupt sources 173 * Disable all interrupt sources
232 */ 174 */
233 pic_writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); 175 writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
234 pic_writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR); 176 writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR);
235 177 writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
236 for (i = IRQ_PIC_START; i <= IRQ_PIC_END; i++) { 178 writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
237 if (i == 11) 179 writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
238 i = 22; 180 writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
239 if (i == 29)
240 break;
241 set_irq_chip(i, &pic_chip);
242 set_irq_handler(i, handle_level_irq);
243 set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
244 }
245 181
246 cic_writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); 182 fpga_irq_init(-1, pic_mask, &pic_irq_data);
247 cic_writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
248 183
249 for (i = IRQ_CIC_START; i <= IRQ_CIC_END; i++) { 184 fpga_irq_init(-1, ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)),
250 set_irq_chip(i, &cic_chip); 185 &cic_irq_data);
251 set_irq_handler(i, handle_level_irq);
252 set_irq_flags(i, IRQF_VALID);
253 }
254
255 sic_writel(0x00000fff, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
256 sic_writel(0x00000fff, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
257
258 for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) {
259 set_irq_chip(i, &sic_chip);
260 set_irq_handler(i, handle_level_irq);
261 set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
262 }
263 186
264 set_irq_chained_handler(IRQ_CP_CPPLDINT, sic_handle_irq); 187 fpga_irq_init(IRQ_CP_CPPLDINT, sic_mask, &sic_irq_data);
265} 188}
266 189
267/* 190/*
@@ -449,43 +372,21 @@ static struct amba_device aaci_device = {
449/* 372/*
450 * CLCD support 373 * CLCD support
451 */ 374 */
452static struct clcd_panel vga = {
453 .mode = {
454 .name = "VGA",
455 .refresh = 60,
456 .xres = 640,
457 .yres = 480,
458 .pixclock = 39721,
459 .left_margin = 40,
460 .right_margin = 24,
461 .upper_margin = 32,
462 .lower_margin = 11,
463 .hsync_len = 96,
464 .vsync_len = 2,
465 .sync = 0,
466 .vmode = FB_VMODE_NONINTERLACED,
467 },
468 .width = -1,
469 .height = -1,
470 .tim2 = TIM2_BCD | TIM2_IPC,
471 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
472 .bpp = 16,
473 .grayscale = 0,
474};
475
476/* 375/*
477 * Ensure VGA is selected. 376 * Ensure VGA is selected.
478 */ 377 */
479static void cp_clcd_enable(struct clcd_fb *fb) 378static void cp_clcd_enable(struct clcd_fb *fb)
480{ 379{
481 u32 val; 380 struct fb_var_screeninfo *var = &fb->fb.var;
381 u32 val = CM_CTRL_STATIC1 | CM_CTRL_STATIC2;
482 382
483 if (fb->fb.var.bits_per_pixel <= 8) 383 if (var->bits_per_pixel <= 8 ||
484 val = CM_CTRL_LCDMUXSEL_VGA_8421BPP; 384 (var->bits_per_pixel == 16 && var->green.length == 5))
385 /* Pseudocolor, RGB555, BGR555 */
386 val |= CM_CTRL_LCDMUXSEL_VGA555_TFT555;
485 else if (fb->fb.var.bits_per_pixel <= 16) 387 else if (fb->fb.var.bits_per_pixel <= 16)
486 val = CM_CTRL_LCDMUXSEL_VGA_16BPP 388 /* truecolor RGB565 */
487 | CM_CTRL_LCDEN0 | CM_CTRL_LCDEN1 389 val |= CM_CTRL_LCDMUXSEL_VGA565_TFT555;
488 | CM_CTRL_STATIC1 | CM_CTRL_STATIC2;
489 else 390 else
490 val = 0; /* no idea for this, don't trust the docs */ 391 val = 0; /* no idea for this, don't trust the docs */
491 392
@@ -498,49 +399,24 @@ static void cp_clcd_enable(struct clcd_fb *fb)
498 CM_CTRL_n24BITEN, val); 399 CM_CTRL_n24BITEN, val);
499} 400}
500 401
501static unsigned long framesize = SZ_1M;
502
503static int cp_clcd_setup(struct clcd_fb *fb) 402static int cp_clcd_setup(struct clcd_fb *fb)
504{ 403{
505 dma_addr_t dma; 404 fb->panel = versatile_clcd_get_panel("VGA");
506 405 if (!fb->panel)
507 fb->panel = &vga; 406 return -EINVAL;
508
509 fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
510 &dma, GFP_KERNEL);
511 if (!fb->fb.screen_base) {
512 printk(KERN_ERR "CLCD: unable to map framebuffer\n");
513 return -ENOMEM;
514 }
515
516 fb->fb.fix.smem_start = dma;
517 fb->fb.fix.smem_len = framesize;
518
519 return 0;
520}
521
522static int cp_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
523{
524 return dma_mmap_writecombine(&fb->dev->dev, vma,
525 fb->fb.screen_base,
526 fb->fb.fix.smem_start,
527 fb->fb.fix.smem_len);
528}
529 407
530static void cp_clcd_remove(struct clcd_fb *fb) 408 return versatile_clcd_setup_dma(fb, SZ_1M);
531{
532 dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
533 fb->fb.screen_base, fb->fb.fix.smem_start);
534} 409}
535 410
536static struct clcd_board clcd_data = { 411static struct clcd_board clcd_data = {
537 .name = "Integrator/CP", 412 .name = "Integrator/CP",
413 .caps = CLCD_CAP_5551 | CLCD_CAP_RGB565 | CLCD_CAP_888,
538 .check = clcdfb_check, 414 .check = clcdfb_check,
539 .decode = clcdfb_decode, 415 .decode = clcdfb_decode,
540 .enable = cp_clcd_enable, 416 .enable = cp_clcd_enable,
541 .setup = cp_clcd_setup, 417 .setup = cp_clcd_setup,
542 .mmap = cp_clcd_mmap, 418 .mmap = versatile_clcd_mmap_dma,
543 .remove = cp_clcd_remove, 419 .remove = versatile_clcd_remove_dma,
544}; 420};
545 421
546static struct amba_device clcd_device = { 422static struct amba_device clcd_device = {
@@ -565,11 +441,23 @@ static struct amba_device *amba_devs[] __initdata = {
565 &clcd_device, 441 &clcd_device,
566}; 442};
567 443
444#define REFCOUNTER (__io_address(INTEGRATOR_HDR_BASE) + 0x28)
445
446static void __init intcp_init_early(void)
447{
448 clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups));
449
450 integrator_init_early();
451
452#ifdef CONFIG_PLAT_VERSATILE_SCHED_CLOCK
453 versatile_sched_clock_init(REFCOUNTER, 24000000);
454#endif
455}
456
568static void __init intcp_init(void) 457static void __init intcp_init(void)
569{ 458{
570 int i; 459 int i;
571 460
572 clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups));
573 platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); 461 platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
574 462
575 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { 463 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
@@ -599,8 +487,9 @@ static struct sys_timer cp_timer = {
599MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") 487MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
600 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ 488 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
601 .boot_params = 0x00000100, 489 .boot_params = 0x00000100,
602 .map_io = intcp_map_io,
603 .reserve = integrator_reserve, 490 .reserve = integrator_reserve,
491 .map_io = intcp_map_io,
492 .init_early = intcp_init_early,
604 .init_irq = intcp_init_irq, 493 .init_irq = intcp_init_irq,
605 .timer = &cp_timer, 494 .timer = &cp_timer,
606 .init_machine = intcp_init, 495 .init_machine = intcp_init,
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index c105d28b53e..ae85aa95180 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -255,7 +255,7 @@ static void __init msm_timer_init(void)
255} 255}
256 256
257#ifdef CONFIG_SMP 257#ifdef CONFIG_SMP
258void __cpuinit local_timer_setup(struct clock_event_device *evt) 258int __cpuinit local_timer_setup(struct clock_event_device *evt)
259{ 259{
260 struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER]; 260 struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER];
261 261
@@ -287,6 +287,7 @@ void __cpuinit local_timer_setup(struct clock_event_device *evt)
287 gic_enable_ppi(clock->irq.irq); 287 gic_enable_ppi(clock->irq.irq);
288 288
289 clockevents_register_device(evt); 289 clockevents_register_device(evt);
290 return 0;
290} 291}
291 292
292inline int local_timer_ack(void) 293inline int local_timer_ack(void)
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index b69fa0a0299..6819c64594e 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -44,6 +44,7 @@ config ARCH_OMAP4
44 depends on ARCH_OMAP2PLUS 44 depends on ARCH_OMAP2PLUS
45 select CPU_V7 45 select CPU_V7
46 select ARM_GIC 46 select ARM_GIC
47 select LOCAL_TIMERS if SMP
47 select PL310_ERRATA_588369 48 select PL310_ERRATA_588369
48 select PL310_ERRATA_727915 49 select PL310_ERRATA_727915
49 select ARM_ERRATA_720789 50 select ARM_ERRATA_720789
diff --git a/arch/arm/mach-omap2/timer-mpu.c b/arch/arm/mach-omap2/timer-mpu.c
index 954682e6439..31c0ac4cd66 100644
--- a/arch/arm/mach-omap2/timer-mpu.c
+++ b/arch/arm/mach-omap2/timer-mpu.c
@@ -26,9 +26,14 @@
26/* 26/*
27 * Setup the local clock events for a CPU. 27 * Setup the local clock events for a CPU.
28 */ 28 */
29void __cpuinit local_timer_setup(struct clock_event_device *evt) 29int __cpuinit local_timer_setup(struct clock_event_device *evt)
30{ 30{
31 /* Local timers are not supprted on OMAP4430 ES1.0 */
32 if (omap_rev() == OMAP4430_REV_ES1_0)
33 return -ENXIO;
34
31 evt->irq = OMAP44XX_IRQ_LOCALTIMER; 35 evt->irq = OMAP44XX_IRQ_LOCALTIMER;
32 twd_timer_setup(evt); 36 twd_timer_setup(evt);
37 return 0;
33} 38}
34 39
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
index a01b76b7c95..541fa4c109e 100644
--- a/arch/arm/mach-realview/Makefile
+++ b/arch/arm/mach-realview/Makefile
@@ -8,6 +8,5 @@ obj-$(CONFIG_MACH_REALVIEW_PB11MP) += realview_pb11mp.o
8obj-$(CONFIG_MACH_REALVIEW_PB1176) += realview_pb1176.o 8obj-$(CONFIG_MACH_REALVIEW_PB1176) += realview_pb1176.o
9obj-$(CONFIG_MACH_REALVIEW_PBA8) += realview_pba8.o 9obj-$(CONFIG_MACH_REALVIEW_PBA8) += realview_pba8.o
10obj-$(CONFIG_MACH_REALVIEW_PBX) += realview_pbx.o 10obj-$(CONFIG_MACH_REALVIEW_PBX) += realview_pbx.o
11obj-$(CONFIG_SMP) += platsmp.o headsmp.o 11obj-$(CONFIG_SMP) += platsmp.o
12obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 12obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
13obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 1c6602cf50e..75dbc8791d0 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -51,6 +51,7 @@
51#include <mach/irqs.h> 51#include <mach/irqs.h>
52#include <asm/hardware/timer-sp.h> 52#include <asm/hardware/timer-sp.h>
53 53
54#include <plat/clcd.h>
54#include <plat/sched_clock.h> 55#include <plat/sched_clock.h>
55 56
56#include "core.h" 57#include "core.h"
@@ -359,18 +360,19 @@ static struct clk_lookup lookups[] = {
359 } 360 }
360}; 361};
361 362
362static int __init clk_init(void) 363void __init realview_init_early(void)
363{ 364{
365 void __iomem *sys = __io_address(REALVIEW_SYS_BASE);
366
364 if (machine_is_realview_pb1176()) 367 if (machine_is_realview_pb1176())
365 oscvco_clk.vcoreg = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC0_OFFSET; 368 oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC0_OFFSET;
366 else 369 else
367 oscvco_clk.vcoreg = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET; 370 oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC4_OFFSET;
368 371
369 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 372 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
370 373
371 return 0; 374 versatile_sched_clock_init(sys + REALVIEW_SYS_24MHz_OFFSET, 24000000);
372} 375}
373core_initcall(clk_init);
374 376
375/* 377/*
376 * CLCD support. 378 * CLCD support.
@@ -385,157 +387,6 @@ core_initcall(clk_init);
385#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8) 387#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8)
386#define SYS_CLCD_ID_VGA (0x1f << 8) 388#define SYS_CLCD_ID_VGA (0x1f << 8)
387 389
388static struct clcd_panel vga = {
389 .mode = {
390 .name = "VGA",
391 .refresh = 60,
392 .xres = 640,
393 .yres = 480,
394 .pixclock = 39721,
395 .left_margin = 40,
396 .right_margin = 24,
397 .upper_margin = 32,
398 .lower_margin = 11,
399 .hsync_len = 96,
400 .vsync_len = 2,
401 .sync = 0,
402 .vmode = FB_VMODE_NONINTERLACED,
403 },
404 .width = -1,
405 .height = -1,
406 .tim2 = TIM2_BCD | TIM2_IPC,
407 .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
408 .bpp = 16,
409};
410
411static struct clcd_panel xvga = {
412 .mode = {
413 .name = "XVGA",
414 .refresh = 60,
415 .xres = 1024,
416 .yres = 768,
417 .pixclock = 15748,
418 .left_margin = 152,
419 .right_margin = 48,
420 .upper_margin = 23,
421 .lower_margin = 3,
422 .hsync_len = 104,
423 .vsync_len = 4,
424 .sync = 0,
425 .vmode = FB_VMODE_NONINTERLACED,
426 },
427 .width = -1,
428 .height = -1,
429 .tim2 = TIM2_BCD | TIM2_IPC,
430 .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
431 .bpp = 16,
432};
433
434static struct clcd_panel sanyo_3_8_in = {
435 .mode = {
436 .name = "Sanyo QVGA",
437 .refresh = 116,
438 .xres = 320,
439 .yres = 240,
440 .pixclock = 100000,
441 .left_margin = 6,
442 .right_margin = 6,
443 .upper_margin = 5,
444 .lower_margin = 5,
445 .hsync_len = 6,
446 .vsync_len = 6,
447 .sync = 0,
448 .vmode = FB_VMODE_NONINTERLACED,
449 },
450 .width = -1,
451 .height = -1,
452 .tim2 = TIM2_BCD,
453 .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
454 .bpp = 16,
455};
456
457static struct clcd_panel sanyo_2_5_in = {
458 .mode = {
459 .name = "Sanyo QVGA Portrait",
460 .refresh = 116,
461 .xres = 240,
462 .yres = 320,
463 .pixclock = 100000,
464 .left_margin = 20,
465 .right_margin = 10,
466 .upper_margin = 2,
467 .lower_margin = 2,
468 .hsync_len = 10,
469 .vsync_len = 2,
470 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
471 .vmode = FB_VMODE_NONINTERLACED,
472 },
473 .width = -1,
474 .height = -1,
475 .tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC,
476 .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
477 .bpp = 16,
478};
479
480static struct clcd_panel epson_2_2_in = {
481 .mode = {
482 .name = "Epson QCIF",
483 .refresh = 390,
484 .xres = 176,
485 .yres = 220,
486 .pixclock = 62500,
487 .left_margin = 3,
488 .right_margin = 2,
489 .upper_margin = 1,
490 .lower_margin = 0,
491 .hsync_len = 3,
492 .vsync_len = 2,
493 .sync = 0,
494 .vmode = FB_VMODE_NONINTERLACED,
495 },
496 .width = -1,
497 .height = -1,
498 .tim2 = TIM2_BCD | TIM2_IPC,
499 .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
500 .bpp = 16,
501};
502
503/*
504 * Detect which LCD panel is connected, and return the appropriate
505 * clcd_panel structure. Note: we do not have any information on
506 * the required timings for the 8.4in panel, so we presently assume
507 * VGA timings.
508 */
509static struct clcd_panel *realview_clcd_panel(void)
510{
511 void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
512 struct clcd_panel *vga_panel;
513 struct clcd_panel *panel;
514 u32 val;
515
516 if (machine_is_realview_eb())
517 vga_panel = &vga;
518 else
519 vga_panel = &xvga;
520
521 val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
522 if (val == SYS_CLCD_ID_SANYO_3_8)
523 panel = &sanyo_3_8_in;
524 else if (val == SYS_CLCD_ID_SANYO_2_5)
525 panel = &sanyo_2_5_in;
526 else if (val == SYS_CLCD_ID_EPSON_2_2)
527 panel = &epson_2_2_in;
528 else if (val == SYS_CLCD_ID_VGA)
529 panel = vga_panel;
530 else {
531 printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
532 val);
533 panel = vga_panel;
534 }
535
536 return panel;
537}
538
539/* 390/*
540 * Disable all display connectors on the interface module. 391 * Disable all display connectors on the interface module.
541 */ 392 */
@@ -565,56 +416,60 @@ static void realview_clcd_enable(struct clcd_fb *fb)
565 writel(val, sys_clcd); 416 writel(val, sys_clcd);
566} 417}
567 418
419/*
420 * Detect which LCD panel is connected, and return the appropriate
421 * clcd_panel structure. Note: we do not have any information on
422 * the required timings for the 8.4in panel, so we presently assume
423 * VGA timings.
424 */
568static int realview_clcd_setup(struct clcd_fb *fb) 425static int realview_clcd_setup(struct clcd_fb *fb)
569{ 426{
427 void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
428 const char *panel_name, *vga_panel_name;
570 unsigned long framesize; 429 unsigned long framesize;
571 dma_addr_t dma; 430 u32 val;
572 431
573 if (machine_is_realview_eb()) 432 if (machine_is_realview_eb()) {
574 /* VGA, 16bpp */ 433 /* VGA, 16bpp */
575 framesize = 640 * 480 * 2; 434 framesize = 640 * 480 * 2;
576 else 435 vga_panel_name = "VGA";
436 } else {
577 /* XVGA, 16bpp */ 437 /* XVGA, 16bpp */
578 framesize = 1024 * 768 * 2; 438 framesize = 1024 * 768 * 2;
579 439 vga_panel_name = "XVGA";
580 fb->panel = realview_clcd_panel();
581
582 fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
583 &dma, GFP_KERNEL | GFP_DMA);
584 if (!fb->fb.screen_base) {
585 printk(KERN_ERR "CLCD: unable to map framebuffer\n");
586 return -ENOMEM;
587 } 440 }
588 441
589 fb->fb.fix.smem_start = dma; 442 val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
590 fb->fb.fix.smem_len = framesize; 443 if (val == SYS_CLCD_ID_SANYO_3_8)
591 444 panel_name = "Sanyo TM38QV67A02A";
592 return 0; 445 else if (val == SYS_CLCD_ID_SANYO_2_5)
593} 446 panel_name = "Sanyo QVGA Portrait";
447 else if (val == SYS_CLCD_ID_EPSON_2_2)
448 panel_name = "Epson L2F50113T00";
449 else if (val == SYS_CLCD_ID_VGA)
450 panel_name = vga_panel_name;
451 else {
452 pr_err("CLCD: unknown LCD panel ID 0x%08x, using VGA\n", val);
453 panel_name = vga_panel_name;
454 }
594 455
595static int realview_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) 456 fb->panel = versatile_clcd_get_panel(panel_name);
596{ 457 if (!fb->panel)
597 return dma_mmap_writecombine(&fb->dev->dev, vma, 458 return -EINVAL;
598 fb->fb.screen_base,
599 fb->fb.fix.smem_start,
600 fb->fb.fix.smem_len);
601}
602 459
603static void realview_clcd_remove(struct clcd_fb *fb) 460 return versatile_clcd_setup_dma(fb, framesize);
604{
605 dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
606 fb->fb.screen_base, fb->fb.fix.smem_start);
607} 461}
608 462
609struct clcd_board clcd_plat_data = { 463struct clcd_board clcd_plat_data = {
610 .name = "RealView", 464 .name = "RealView",
465 .caps = CLCD_CAP_ALL,
611 .check = clcdfb_check, 466 .check = clcdfb_check,
612 .decode = clcdfb_decode, 467 .decode = clcdfb_decode,
613 .disable = realview_clcd_disable, 468 .disable = realview_clcd_disable,
614 .enable = realview_clcd_enable, 469 .enable = realview_clcd_enable,
615 .setup = realview_clcd_setup, 470 .setup = realview_clcd_setup,
616 .mmap = realview_clcd_mmap, 471 .mmap = versatile_clcd_mmap_dma,
617 .remove = realview_clcd_remove, 472 .remove = versatile_clcd_remove_dma,
618}; 473};
619 474
620#ifdef CONFIG_LEDS 475#ifdef CONFIG_LEDS
@@ -656,12 +511,6 @@ void realview_leds_event(led_event_t ledevt)
656#endif /* CONFIG_LEDS */ 511#endif /* CONFIG_LEDS */
657 512
658/* 513/*
659 * The sched_clock counter
660 */
661#define REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + \
662 REALVIEW_SYS_24MHz_OFFSET)
663
664/*
665 * Where is the timer (VA)? 514 * Where is the timer (VA)?
666 */ 515 */
667void __iomem *timer0_va_base; 516void __iomem *timer0_va_base;
@@ -676,8 +525,6 @@ void __init realview_timer_init(unsigned int timer_irq)
676{ 525{
677 u32 val; 526 u32 val;
678 527
679 versatile_sched_clock_init(REFCOUNTER, 24000000);
680
681 /* 528 /*
682 * set clock frequency: 529 * set clock frequency:
683 * REALVIEW_REFCLK is 32KHz 530 * REALVIEW_REFCLK is 32KHz
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
index 693239ddc39..5c83d1e87a0 100644
--- a/arch/arm/mach-realview/core.h
+++ b/arch/arm/mach-realview/core.h
@@ -42,7 +42,6 @@ static struct amba_device name##_device = { \
42 }, \ 42 }, \
43 .dma_mask = ~0, \ 43 .dma_mask = ~0, \
44 .irq = base##_IRQ, \ 44 .irq = base##_IRQ, \
45 /* .dma = base##_DMA,*/ \
46} 45}
47 46
48struct machine_desc; 47struct machine_desc;
@@ -63,6 +62,7 @@ extern void realview_timer_init(unsigned int timer_irq);
63extern int realview_flash_register(struct resource *res, u32 num); 62extern int realview_flash_register(struct resource *res, u32 num);
64extern int realview_eth_register(const char *name, struct resource *res); 63extern int realview_eth_register(const char *name, struct resource *res);
65extern int realview_usb_register(struct resource *res); 64extern int realview_usb_register(struct resource *res);
65extern void realview_init_early(void);
66extern void realview_fixup(struct machine_desc *mdesc, struct tag *tags, 66extern void realview_fixup(struct machine_desc *mdesc, struct tag *tags,
67 char **from, struct meminfo *meminfo); 67 char **from, struct meminfo *meminfo);
68extern void (*realview_reset)(char); 68extern void (*realview_reset)(char);
diff --git a/arch/arm/mach-realview/headsmp.S b/arch/arm/mach-realview/headsmp.S
deleted file mode 100644
index b34be4554d4..00000000000
--- a/arch/arm/mach-realview/headsmp.S
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * linux/arch/arm/mach-realview/headsmp.S
3 *
4 * Copyright (c) 2003 ARM Limited
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/linkage.h>
12#include <linux/init.h>
13
14 __INIT
15
16/*
17 * Realview specific entry point for secondary CPUs. This provides
18 * a "holding pen" into which all secondary cores are held until we're
19 * ready for them to initialise.
20 */
21ENTRY(realview_secondary_startup)
22 mrc p15, 0, r0, c0, c0, 5
23 and r0, r0, #15
24 adr r4, 1f
25 ldmia r4, {r5, r6}
26 sub r4, r4, r5
27 add r6, r6, r4
28pen: ldr r7, [r6]
29 cmp r7, r0
30 bne pen
31
32 /*
33 * we've been released from the holding pen: secondary_stack
34 * should now contain the SVC stack for this core
35 */
36 b secondary_startup
37
38 .align
391: .long .
40 .long pen_release
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c
deleted file mode 100644
index 60b4e111f45..00000000000
--- a/arch/arm/mach-realview/localtimer.c
+++ /dev/null
@@ -1,26 +0,0 @@
1/*
2 * linux/arch/arm/mach-realview/localtimer.c
3 *
4 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/init.h>
12#include <linux/smp.h>
13#include <linux/clockchips.h>
14
15#include <asm/irq.h>
16#include <asm/smp_twd.h>
17#include <asm/localtimer.h>
18
19/*
20 * Setup the local clock events for a CPU.
21 */
22void __cpuinit local_timer_setup(struct clock_event_device *evt)
23{
24 evt->irq = IRQ_LOCALTIMER;
25 twd_timer_setup(evt);
26}
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index 6959d13d908..23919229e12 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -10,44 +10,21 @@
10 */ 10 */
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/jiffies.h>
16#include <linux/smp.h> 13#include <linux/smp.h>
17#include <linux/io.h> 14#include <linux/io.h>
18 15
19#include <asm/cacheflush.h>
20#include <mach/hardware.h> 16#include <mach/hardware.h>
21#include <asm/mach-types.h> 17#include <asm/mach-types.h>
18#include <asm/smp_scu.h>
22#include <asm/unified.h> 19#include <asm/unified.h>
23 20
24#include <mach/board-eb.h> 21#include <mach/board-eb.h>
25#include <mach/board-pb11mp.h> 22#include <mach/board-pb11mp.h>
26#include <mach/board-pbx.h> 23#include <mach/board-pbx.h>
27#include <asm/smp_scu.h>
28 24
29#include "core.h" 25#include "core.h"
30 26
31extern void realview_secondary_startup(void); 27extern void versatile_secondary_startup(void);
32
33/*
34 * control for which core is the next to come out of the secondary
35 * boot "holding pen"
36 */
37volatile int __cpuinitdata pen_release = -1;
38
39/*
40 * Write pen_release in a way that is guaranteed to be visible to all
41 * observers, irrespective of whether they're taking part in coherency
42 * or not. This is necessary for the hotplug code to work reliably.
43 */
44static void __cpuinit write_pen_release(int val)
45{
46 pen_release = val;
47 smp_wmb();
48 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
49 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
50}
51 28
52static void __iomem *scu_base_addr(void) 29static void __iomem *scu_base_addr(void)
53{ 30{
@@ -62,75 +39,6 @@ static void __iomem *scu_base_addr(void)
62 return (void __iomem *)0; 39 return (void __iomem *)0;
63} 40}
64 41
65static DEFINE_SPINLOCK(boot_lock);
66
67void __cpuinit platform_secondary_init(unsigned int cpu)
68{
69 /*
70 * if any interrupts are already enabled for the primary
71 * core (e.g. timer irq), then they will not have been enabled
72 * for us: do so
73 */
74 gic_secondary_init(0);
75
76 /*
77 * let the primary processor know we're out of the
78 * pen, then head off into the C entry point
79 */
80 write_pen_release(-1);
81
82 /*
83 * Synchronise with the boot thread.
84 */
85 spin_lock(&boot_lock);
86 spin_unlock(&boot_lock);
87}
88
89int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
90{
91 unsigned long timeout;
92
93 /*
94 * set synchronisation state between this boot processor
95 * and the secondary one
96 */
97 spin_lock(&boot_lock);
98
99 /*
100 * The secondary processor is waiting to be released from
101 * the holding pen - release it, then wait for it to flag
102 * that it has been released by resetting pen_release.
103 *
104 * Note that "pen_release" is the hardware CPU ID, whereas
105 * "cpu" is Linux's internal ID.
106 */
107 write_pen_release(cpu);
108
109 /*
110 * Send the secondary CPU a soft interrupt, thereby causing
111 * the boot monitor to read the system wide flags register,
112 * and branch to the address found there.
113 */
114 smp_cross_call(cpumask_of(cpu), 1);
115
116 timeout = jiffies + (1 * HZ);
117 while (time_before(jiffies, timeout)) {
118 smp_rmb();
119 if (pen_release == -1)
120 break;
121
122 udelay(10);
123 }
124
125 /*
126 * now the secondary core is starting up let it run its
127 * calibrations, then wait for it to finish
128 */
129 spin_unlock(&boot_lock);
130
131 return pen_release != -1 ? -ENOSYS : 0;
132}
133
134/* 42/*
135 * Initialise the CPU possible map early - this describes the CPUs 43 * Initialise the CPU possible map early - this describes the CPUs
136 * which may be present or become present in the system. 44 * which may be present or become present in the system.
@@ -174,6 +82,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
174 * until it receives a soft interrupt, and then the 82 * until it receives a soft interrupt, and then the
175 * secondary CPU branches to this address. 83 * secondary CPU branches to this address.
176 */ 84 */
177 __raw_writel(BSYM(virt_to_phys(realview_secondary_startup)), 85 __raw_writel(BSYM(virt_to_phys(versatile_secondary_startup)),
178 __io_address(REALVIEW_SYS_FLAGSSET)); 86 __io_address(REALVIEW_SYS_FLAGSSET));
179} 87}
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 8ede983b861..2ecc1d94284 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -144,60 +144,39 @@ static struct pl022_ssp_controller ssp0_plat_data = {
144 * These devices are connected via the core APB bridge 144 * These devices are connected via the core APB bridge
145 */ 145 */
146#define GPIO2_IRQ { IRQ_EB_GPIO2, NO_IRQ } 146#define GPIO2_IRQ { IRQ_EB_GPIO2, NO_IRQ }
147#define GPIO2_DMA { 0, 0 }
148#define GPIO3_IRQ { IRQ_EB_GPIO3, NO_IRQ } 147#define GPIO3_IRQ { IRQ_EB_GPIO3, NO_IRQ }
149#define GPIO3_DMA { 0, 0 }
150 148
151#define AACI_IRQ { IRQ_EB_AACI, NO_IRQ } 149#define AACI_IRQ { IRQ_EB_AACI, NO_IRQ }
152#define AACI_DMA { 0x80, 0x81 }
153#define MMCI0_IRQ { IRQ_EB_MMCI0A, IRQ_EB_MMCI0B } 150#define MMCI0_IRQ { IRQ_EB_MMCI0A, IRQ_EB_MMCI0B }
154#define MMCI0_DMA { 0x84, 0 }
155#define KMI0_IRQ { IRQ_EB_KMI0, NO_IRQ } 151#define KMI0_IRQ { IRQ_EB_KMI0, NO_IRQ }
156#define KMI0_DMA { 0, 0 }
157#define KMI1_IRQ { IRQ_EB_KMI1, NO_IRQ } 152#define KMI1_IRQ { IRQ_EB_KMI1, NO_IRQ }
158#define KMI1_DMA { 0, 0 }
159 153
160/* 154/*
161 * These devices are connected directly to the multi-layer AHB switch 155 * These devices are connected directly to the multi-layer AHB switch
162 */ 156 */
163#define EB_SMC_IRQ { NO_IRQ, NO_IRQ } 157#define EB_SMC_IRQ { NO_IRQ, NO_IRQ }
164#define EB_SMC_DMA { 0, 0 }
165#define MPMC_IRQ { NO_IRQ, NO_IRQ } 158#define MPMC_IRQ { NO_IRQ, NO_IRQ }
166#define MPMC_DMA { 0, 0 }
167#define EB_CLCD_IRQ { IRQ_EB_CLCD, NO_IRQ } 159#define EB_CLCD_IRQ { IRQ_EB_CLCD, NO_IRQ }
168#define EB_CLCD_DMA { 0, 0 }
169#define DMAC_IRQ { IRQ_EB_DMA, NO_IRQ } 160#define DMAC_IRQ { IRQ_EB_DMA, NO_IRQ }
170#define DMAC_DMA { 0, 0 }
171 161
172/* 162/*
173 * These devices are connected via the core APB bridge 163 * These devices are connected via the core APB bridge
174 */ 164 */
175#define SCTL_IRQ { NO_IRQ, NO_IRQ } 165#define SCTL_IRQ { NO_IRQ, NO_IRQ }
176#define SCTL_DMA { 0, 0 }
177#define EB_WATCHDOG_IRQ { IRQ_EB_WDOG, NO_IRQ } 166#define EB_WATCHDOG_IRQ { IRQ_EB_WDOG, NO_IRQ }
178#define EB_WATCHDOG_DMA { 0, 0 }
179#define EB_GPIO0_IRQ { IRQ_EB_GPIO0, NO_IRQ } 167#define EB_GPIO0_IRQ { IRQ_EB_GPIO0, NO_IRQ }
180#define EB_GPIO0_DMA { 0, 0 }
181#define GPIO1_IRQ { IRQ_EB_GPIO1, NO_IRQ } 168#define GPIO1_IRQ { IRQ_EB_GPIO1, NO_IRQ }
182#define GPIO1_DMA { 0, 0 }
183#define EB_RTC_IRQ { IRQ_EB_RTC, NO_IRQ } 169#define EB_RTC_IRQ { IRQ_EB_RTC, NO_IRQ }
184#define EB_RTC_DMA { 0, 0 }
185 170
186/* 171/*
187 * These devices are connected via the DMA APB bridge 172 * These devices are connected via the DMA APB bridge
188 */ 173 */
189#define SCI_IRQ { IRQ_EB_SCI, NO_IRQ } 174#define SCI_IRQ { IRQ_EB_SCI, NO_IRQ }
190#define SCI_DMA { 7, 6 }
191#define EB_UART0_IRQ { IRQ_EB_UART0, NO_IRQ } 175#define EB_UART0_IRQ { IRQ_EB_UART0, NO_IRQ }
192#define EB_UART0_DMA { 15, 14 }
193#define EB_UART1_IRQ { IRQ_EB_UART1, NO_IRQ } 176#define EB_UART1_IRQ { IRQ_EB_UART1, NO_IRQ }
194#define EB_UART1_DMA { 13, 12 }
195#define EB_UART2_IRQ { IRQ_EB_UART2, NO_IRQ } 177#define EB_UART2_IRQ { IRQ_EB_UART2, NO_IRQ }
196#define EB_UART2_DMA { 11, 10 }
197#define EB_UART3_IRQ { IRQ_EB_UART3, NO_IRQ } 178#define EB_UART3_IRQ { IRQ_EB_UART3, NO_IRQ }
198#define EB_UART3_DMA { 0x86, 0x87 }
199#define EB_SSP_IRQ { IRQ_EB_SSP, NO_IRQ } 179#define EB_SSP_IRQ { IRQ_EB_SSP, NO_IRQ }
200#define EB_SSP_DMA { 9, 8 }
201 180
202/* FPGA Primecells */ 181/* FPGA Primecells */
203AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); 182AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
@@ -487,6 +466,7 @@ MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
487 .boot_params = PLAT_PHYS_OFFSET + 0x00000100, 466 .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
488 .fixup = realview_fixup, 467 .fixup = realview_fixup,
489 .map_io = realview_eb_map_io, 468 .map_io = realview_eb_map_io,
469 .init_early = realview_init_early,
490 .init_irq = gic_init_irq, 470 .init_irq = gic_init_irq,
491 .timer = &realview_eb_timer, 471 .timer = &realview_eb_timer,
492 .init_machine = realview_eb_init, 472 .init_machine = realview_eb_init,
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index 9f26369555c..eab6070f66d 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -134,47 +134,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
134 * RealView PB1176 AMBA devices 134 * RealView PB1176 AMBA devices
135 */ 135 */
136#define GPIO2_IRQ { IRQ_PB1176_GPIO2, NO_IRQ } 136#define GPIO2_IRQ { IRQ_PB1176_GPIO2, NO_IRQ }
137#define GPIO2_DMA { 0, 0 }
138#define GPIO3_IRQ { IRQ_PB1176_GPIO3, NO_IRQ } 137#define GPIO3_IRQ { IRQ_PB1176_GPIO3, NO_IRQ }
139#define GPIO3_DMA { 0, 0 }
140#define AACI_IRQ { IRQ_PB1176_AACI, NO_IRQ } 138#define AACI_IRQ { IRQ_PB1176_AACI, NO_IRQ }
141#define AACI_DMA { 0x80, 0x81 }
142#define MMCI0_IRQ { IRQ_PB1176_MMCI0A, IRQ_PB1176_MMCI0B } 139#define MMCI0_IRQ { IRQ_PB1176_MMCI0A, IRQ_PB1176_MMCI0B }
143#define MMCI0_DMA { 0x84, 0 }
144#define KMI0_IRQ { IRQ_PB1176_KMI0, NO_IRQ } 140#define KMI0_IRQ { IRQ_PB1176_KMI0, NO_IRQ }
145#define KMI0_DMA { 0, 0 }
146#define KMI1_IRQ { IRQ_PB1176_KMI1, NO_IRQ } 141#define KMI1_IRQ { IRQ_PB1176_KMI1, NO_IRQ }
147#define KMI1_DMA { 0, 0 }
148#define PB1176_SMC_IRQ { NO_IRQ, NO_IRQ } 142#define PB1176_SMC_IRQ { NO_IRQ, NO_IRQ }
149#define PB1176_SMC_DMA { 0, 0 }
150#define MPMC_IRQ { NO_IRQ, NO_IRQ } 143#define MPMC_IRQ { NO_IRQ, NO_IRQ }
151#define MPMC_DMA { 0, 0 }
152#define PB1176_CLCD_IRQ { IRQ_DC1176_CLCD, NO_IRQ } 144#define PB1176_CLCD_IRQ { IRQ_DC1176_CLCD, NO_IRQ }
153#define PB1176_CLCD_DMA { 0, 0 }
154#define SCTL_IRQ { NO_IRQ, NO_IRQ } 145#define SCTL_IRQ { NO_IRQ, NO_IRQ }
155#define SCTL_DMA { 0, 0 }
156#define PB1176_WATCHDOG_IRQ { IRQ_DC1176_WATCHDOG, NO_IRQ } 146#define PB1176_WATCHDOG_IRQ { IRQ_DC1176_WATCHDOG, NO_IRQ }
157#define PB1176_WATCHDOG_DMA { 0, 0 }
158#define PB1176_GPIO0_IRQ { IRQ_PB1176_GPIO0, NO_IRQ } 147#define PB1176_GPIO0_IRQ { IRQ_PB1176_GPIO0, NO_IRQ }
159#define PB1176_GPIO0_DMA { 0, 0 }
160#define GPIO1_IRQ { IRQ_PB1176_GPIO1, NO_IRQ } 148#define GPIO1_IRQ { IRQ_PB1176_GPIO1, NO_IRQ }
161#define GPIO1_DMA { 0, 0 }
162#define PB1176_RTC_IRQ { IRQ_DC1176_RTC, NO_IRQ } 149#define PB1176_RTC_IRQ { IRQ_DC1176_RTC, NO_IRQ }
163#define PB1176_RTC_DMA { 0, 0 }
164#define SCI_IRQ { IRQ_PB1176_SCI, NO_IRQ } 150#define SCI_IRQ { IRQ_PB1176_SCI, NO_IRQ }
165#define SCI_DMA { 7, 6 }
166#define PB1176_UART0_IRQ { IRQ_DC1176_UART0, NO_IRQ } 151#define PB1176_UART0_IRQ { IRQ_DC1176_UART0, NO_IRQ }
167#define PB1176_UART0_DMA { 15, 14 }
168#define PB1176_UART1_IRQ { IRQ_DC1176_UART1, NO_IRQ } 152#define PB1176_UART1_IRQ { IRQ_DC1176_UART1, NO_IRQ }
169#define PB1176_UART1_DMA { 13, 12 }
170#define PB1176_UART2_IRQ { IRQ_DC1176_UART2, NO_IRQ } 153#define PB1176_UART2_IRQ { IRQ_DC1176_UART2, NO_IRQ }
171#define PB1176_UART2_DMA { 11, 10 }
172#define PB1176_UART3_IRQ { IRQ_DC1176_UART3, NO_IRQ } 154#define PB1176_UART3_IRQ { IRQ_DC1176_UART3, NO_IRQ }
173#define PB1176_UART3_DMA { 0x86, 0x87 }
174#define PB1176_UART4_IRQ { IRQ_PB1176_UART4, NO_IRQ } 155#define PB1176_UART4_IRQ { IRQ_PB1176_UART4, NO_IRQ }
175#define PB1176_UART4_DMA { 0, 0 }
176#define PB1176_SSP_IRQ { IRQ_DC1176_SSP, NO_IRQ } 156#define PB1176_SSP_IRQ { IRQ_DC1176_SSP, NO_IRQ }
177#define PB1176_SSP_DMA { 9, 8 }
178 157
179/* FPGA Primecells */ 158/* FPGA Primecells */
180AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); 159AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
@@ -382,6 +361,7 @@ MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
382 .boot_params = PLAT_PHYS_OFFSET + 0x00000100, 361 .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
383 .fixup = realview_pb1176_fixup, 362 .fixup = realview_pb1176_fixup,
384 .map_io = realview_pb1176_map_io, 363 .map_io = realview_pb1176_map_io,
364 .init_early = realview_init_early,
385 .init_irq = gic_init_irq, 365 .init_irq = gic_init_irq,
386 .timer = &realview_pb1176_timer, 366 .timer = &realview_pb1176_timer,
387 .init_machine = realview_pb1176_init, 367 .init_machine = realview_pb1176_init,
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index dea06b2da3a..b2985fc7cd4 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -136,47 +136,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
136 */ 136 */
137 137
138#define GPIO2_IRQ { IRQ_PB11MP_GPIO2, NO_IRQ } 138#define GPIO2_IRQ { IRQ_PB11MP_GPIO2, NO_IRQ }
139#define GPIO2_DMA { 0, 0 }
140#define GPIO3_IRQ { IRQ_PB11MP_GPIO3, NO_IRQ } 139#define GPIO3_IRQ { IRQ_PB11MP_GPIO3, NO_IRQ }
141#define GPIO3_DMA { 0, 0 }
142#define AACI_IRQ { IRQ_TC11MP_AACI, NO_IRQ } 140#define AACI_IRQ { IRQ_TC11MP_AACI, NO_IRQ }
143#define AACI_DMA { 0x80, 0x81 }
144#define MMCI0_IRQ { IRQ_TC11MP_MMCI0A, IRQ_TC11MP_MMCI0B } 141#define MMCI0_IRQ { IRQ_TC11MP_MMCI0A, IRQ_TC11MP_MMCI0B }
145#define MMCI0_DMA { 0x84, 0 }
146#define KMI0_IRQ { IRQ_TC11MP_KMI0, NO_IRQ } 142#define KMI0_IRQ { IRQ_TC11MP_KMI0, NO_IRQ }
147#define KMI0_DMA { 0, 0 }
148#define KMI1_IRQ { IRQ_TC11MP_KMI1, NO_IRQ } 143#define KMI1_IRQ { IRQ_TC11MP_KMI1, NO_IRQ }
149#define KMI1_DMA { 0, 0 }
150#define PB11MP_SMC_IRQ { NO_IRQ, NO_IRQ } 144#define PB11MP_SMC_IRQ { NO_IRQ, NO_IRQ }
151#define PB11MP_SMC_DMA { 0, 0 }
152#define MPMC_IRQ { NO_IRQ, NO_IRQ } 145#define MPMC_IRQ { NO_IRQ, NO_IRQ }
153#define MPMC_DMA { 0, 0 }
154#define PB11MP_CLCD_IRQ { IRQ_PB11MP_CLCD, NO_IRQ } 146#define PB11MP_CLCD_IRQ { IRQ_PB11MP_CLCD, NO_IRQ }
155#define PB11MP_CLCD_DMA { 0, 0 }
156#define DMAC_IRQ { IRQ_PB11MP_DMAC, NO_IRQ } 147#define DMAC_IRQ { IRQ_PB11MP_DMAC, NO_IRQ }
157#define DMAC_DMA { 0, 0 }
158#define SCTL_IRQ { NO_IRQ, NO_IRQ } 148#define SCTL_IRQ { NO_IRQ, NO_IRQ }
159#define SCTL_DMA { 0, 0 }
160#define PB11MP_WATCHDOG_IRQ { IRQ_PB11MP_WATCHDOG, NO_IRQ } 149#define PB11MP_WATCHDOG_IRQ { IRQ_PB11MP_WATCHDOG, NO_IRQ }
161#define PB11MP_WATCHDOG_DMA { 0, 0 }
162#define PB11MP_GPIO0_IRQ { IRQ_PB11MP_GPIO0, NO_IRQ } 150#define PB11MP_GPIO0_IRQ { IRQ_PB11MP_GPIO0, NO_IRQ }
163#define PB11MP_GPIO0_DMA { 0, 0 }
164#define GPIO1_IRQ { IRQ_PB11MP_GPIO1, NO_IRQ } 151#define GPIO1_IRQ { IRQ_PB11MP_GPIO1, NO_IRQ }
165#define GPIO1_DMA { 0, 0 }
166#define PB11MP_RTC_IRQ { IRQ_TC11MP_RTC, NO_IRQ } 152#define PB11MP_RTC_IRQ { IRQ_TC11MP_RTC, NO_IRQ }
167#define PB11MP_RTC_DMA { 0, 0 }
168#define SCI_IRQ { IRQ_PB11MP_SCI, NO_IRQ } 153#define SCI_IRQ { IRQ_PB11MP_SCI, NO_IRQ }
169#define SCI_DMA { 7, 6 }
170#define PB11MP_UART0_IRQ { IRQ_TC11MP_UART0, NO_IRQ } 154#define PB11MP_UART0_IRQ { IRQ_TC11MP_UART0, NO_IRQ }
171#define PB11MP_UART0_DMA { 15, 14 }
172#define PB11MP_UART1_IRQ { IRQ_TC11MP_UART1, NO_IRQ } 155#define PB11MP_UART1_IRQ { IRQ_TC11MP_UART1, NO_IRQ }
173#define PB11MP_UART1_DMA { 13, 12 }
174#define PB11MP_UART2_IRQ { IRQ_PB11MP_UART2, NO_IRQ } 156#define PB11MP_UART2_IRQ { IRQ_PB11MP_UART2, NO_IRQ }
175#define PB11MP_UART2_DMA { 11, 10 }
176#define PB11MP_UART3_IRQ { IRQ_PB11MP_UART3, NO_IRQ } 157#define PB11MP_UART3_IRQ { IRQ_PB11MP_UART3, NO_IRQ }
177#define PB11MP_UART3_DMA { 0x86, 0x87 }
178#define PB11MP_SSP_IRQ { IRQ_PB11MP_SSP, NO_IRQ } 158#define PB11MP_SSP_IRQ { IRQ_PB11MP_SSP, NO_IRQ }
179#define PB11MP_SSP_DMA { 9, 8 }
180 159
181/* FPGA Primecells */ 160/* FPGA Primecells */
182AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); 161AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
@@ -384,6 +363,7 @@ MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
384 .boot_params = PLAT_PHYS_OFFSET + 0x00000100, 363 .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
385 .fixup = realview_fixup, 364 .fixup = realview_fixup,
386 .map_io = realview_pb11mp_map_io, 365 .map_io = realview_pb11mp_map_io,
366 .init_early = realview_init_early,
387 .init_irq = gic_init_irq, 367 .init_irq = gic_init_irq,
388 .timer = &realview_pb11mp_timer, 368 .timer = &realview_pb11mp_timer,
389 .init_machine = realview_pb11mp_init, 369 .init_machine = realview_pb11mp_init,
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 7d0f1734a21..fb686655876 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -126,47 +126,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
126 */ 126 */
127 127
128#define GPIO2_IRQ { IRQ_PBA8_GPIO2, NO_IRQ } 128#define GPIO2_IRQ { IRQ_PBA8_GPIO2, NO_IRQ }
129#define GPIO2_DMA { 0, 0 }
130#define GPIO3_IRQ { IRQ_PBA8_GPIO3, NO_IRQ } 129#define GPIO3_IRQ { IRQ_PBA8_GPIO3, NO_IRQ }
131#define GPIO3_DMA { 0, 0 }
132#define AACI_IRQ { IRQ_PBA8_AACI, NO_IRQ } 130#define AACI_IRQ { IRQ_PBA8_AACI, NO_IRQ }
133#define AACI_DMA { 0x80, 0x81 }
134#define MMCI0_IRQ { IRQ_PBA8_MMCI0A, IRQ_PBA8_MMCI0B } 131#define MMCI0_IRQ { IRQ_PBA8_MMCI0A, IRQ_PBA8_MMCI0B }
135#define MMCI0_DMA { 0x84, 0 }
136#define KMI0_IRQ { IRQ_PBA8_KMI0, NO_IRQ } 132#define KMI0_IRQ { IRQ_PBA8_KMI0, NO_IRQ }
137#define KMI0_DMA { 0, 0 }
138#define KMI1_IRQ { IRQ_PBA8_KMI1, NO_IRQ } 133#define KMI1_IRQ { IRQ_PBA8_KMI1, NO_IRQ }
139#define KMI1_DMA { 0, 0 }
140#define PBA8_SMC_IRQ { NO_IRQ, NO_IRQ } 134#define PBA8_SMC_IRQ { NO_IRQ, NO_IRQ }
141#define PBA8_SMC_DMA { 0, 0 }
142#define MPMC_IRQ { NO_IRQ, NO_IRQ } 135#define MPMC_IRQ { NO_IRQ, NO_IRQ }
143#define MPMC_DMA { 0, 0 }
144#define PBA8_CLCD_IRQ { IRQ_PBA8_CLCD, NO_IRQ } 136#define PBA8_CLCD_IRQ { IRQ_PBA8_CLCD, NO_IRQ }
145#define PBA8_CLCD_DMA { 0, 0 }
146#define DMAC_IRQ { IRQ_PBA8_DMAC, NO_IRQ } 137#define DMAC_IRQ { IRQ_PBA8_DMAC, NO_IRQ }
147#define DMAC_DMA { 0, 0 }
148#define SCTL_IRQ { NO_IRQ, NO_IRQ } 138#define SCTL_IRQ { NO_IRQ, NO_IRQ }
149#define SCTL_DMA { 0, 0 }
150#define PBA8_WATCHDOG_IRQ { IRQ_PBA8_WATCHDOG, NO_IRQ } 139#define PBA8_WATCHDOG_IRQ { IRQ_PBA8_WATCHDOG, NO_IRQ }
151#define PBA8_WATCHDOG_DMA { 0, 0 }
152#define PBA8_GPIO0_IRQ { IRQ_PBA8_GPIO0, NO_IRQ } 140#define PBA8_GPIO0_IRQ { IRQ_PBA8_GPIO0, NO_IRQ }
153#define PBA8_GPIO0_DMA { 0, 0 }
154#define GPIO1_IRQ { IRQ_PBA8_GPIO1, NO_IRQ } 141#define GPIO1_IRQ { IRQ_PBA8_GPIO1, NO_IRQ }
155#define GPIO1_DMA { 0, 0 }
156#define PBA8_RTC_IRQ { IRQ_PBA8_RTC, NO_IRQ } 142#define PBA8_RTC_IRQ { IRQ_PBA8_RTC, NO_IRQ }
157#define PBA8_RTC_DMA { 0, 0 }
158#define SCI_IRQ { IRQ_PBA8_SCI, NO_IRQ } 143#define SCI_IRQ { IRQ_PBA8_SCI, NO_IRQ }
159#define SCI_DMA { 7, 6 }
160#define PBA8_UART0_IRQ { IRQ_PBA8_UART0, NO_IRQ } 144#define PBA8_UART0_IRQ { IRQ_PBA8_UART0, NO_IRQ }
161#define PBA8_UART0_DMA { 15, 14 }
162#define PBA8_UART1_IRQ { IRQ_PBA8_UART1, NO_IRQ } 145#define PBA8_UART1_IRQ { IRQ_PBA8_UART1, NO_IRQ }
163#define PBA8_UART1_DMA { 13, 12 }
164#define PBA8_UART2_IRQ { IRQ_PBA8_UART2, NO_IRQ } 146#define PBA8_UART2_IRQ { IRQ_PBA8_UART2, NO_IRQ }
165#define PBA8_UART2_DMA { 11, 10 }
166#define PBA8_UART3_IRQ { IRQ_PBA8_UART3, NO_IRQ } 147#define PBA8_UART3_IRQ { IRQ_PBA8_UART3, NO_IRQ }
167#define PBA8_UART3_DMA { 0x86, 0x87 }
168#define PBA8_SSP_IRQ { IRQ_PBA8_SSP, NO_IRQ } 148#define PBA8_SSP_IRQ { IRQ_PBA8_SSP, NO_IRQ }
169#define PBA8_SSP_DMA { 9, 8 }
170 149
171/* FPGA Primecells */ 150/* FPGA Primecells */
172AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); 151AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
@@ -334,6 +313,7 @@ MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
334 .boot_params = PLAT_PHYS_OFFSET + 0x00000100, 313 .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
335 .fixup = realview_fixup, 314 .fixup = realview_fixup,
336 .map_io = realview_pba8_map_io, 315 .map_io = realview_pba8_map_io,
316 .init_early = realview_init_early,
337 .init_irq = gic_init_irq, 317 .init_irq = gic_init_irq,
338 .timer = &realview_pba8_timer, 318 .timer = &realview_pba8_timer,
339 .init_machine = realview_pba8_init, 319 .init_machine = realview_pba8_init,
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index b89e28f8853..92ace2cf2b2 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -148,47 +148,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
148 */ 148 */
149 149
150#define GPIO2_IRQ { IRQ_PBX_GPIO2, NO_IRQ } 150#define GPIO2_IRQ { IRQ_PBX_GPIO2, NO_IRQ }
151#define GPIO2_DMA { 0, 0 }
152#define GPIO3_IRQ { IRQ_PBX_GPIO3, NO_IRQ } 151#define GPIO3_IRQ { IRQ_PBX_GPIO3, NO_IRQ }
153#define GPIO3_DMA { 0, 0 }
154#define AACI_IRQ { IRQ_PBX_AACI, NO_IRQ } 152#define AACI_IRQ { IRQ_PBX_AACI, NO_IRQ }
155#define AACI_DMA { 0x80, 0x81 }
156#define MMCI0_IRQ { IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B } 153#define MMCI0_IRQ { IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B }
157#define MMCI0_DMA { 0x84, 0 }
158#define KMI0_IRQ { IRQ_PBX_KMI0, NO_IRQ } 154#define KMI0_IRQ { IRQ_PBX_KMI0, NO_IRQ }
159#define KMI0_DMA { 0, 0 }
160#define KMI1_IRQ { IRQ_PBX_KMI1, NO_IRQ } 155#define KMI1_IRQ { IRQ_PBX_KMI1, NO_IRQ }
161#define KMI1_DMA { 0, 0 }
162#define PBX_SMC_IRQ { NO_IRQ, NO_IRQ } 156#define PBX_SMC_IRQ { NO_IRQ, NO_IRQ }
163#define PBX_SMC_DMA { 0, 0 }
164#define MPMC_IRQ { NO_IRQ, NO_IRQ } 157#define MPMC_IRQ { NO_IRQ, NO_IRQ }
165#define MPMC_DMA { 0, 0 }
166#define PBX_CLCD_IRQ { IRQ_PBX_CLCD, NO_IRQ } 158#define PBX_CLCD_IRQ { IRQ_PBX_CLCD, NO_IRQ }
167#define PBX_CLCD_DMA { 0, 0 }
168#define DMAC_IRQ { IRQ_PBX_DMAC, NO_IRQ } 159#define DMAC_IRQ { IRQ_PBX_DMAC, NO_IRQ }
169#define DMAC_DMA { 0, 0 }
170#define SCTL_IRQ { NO_IRQ, NO_IRQ } 160#define SCTL_IRQ { NO_IRQ, NO_IRQ }
171#define SCTL_DMA { 0, 0 }
172#define PBX_WATCHDOG_IRQ { IRQ_PBX_WATCHDOG, NO_IRQ } 161#define PBX_WATCHDOG_IRQ { IRQ_PBX_WATCHDOG, NO_IRQ }
173#define PBX_WATCHDOG_DMA { 0, 0 }
174#define PBX_GPIO0_IRQ { IRQ_PBX_GPIO0, NO_IRQ } 162#define PBX_GPIO0_IRQ { IRQ_PBX_GPIO0, NO_IRQ }
175#define PBX_GPIO0_DMA { 0, 0 }
176#define GPIO1_IRQ { IRQ_PBX_GPIO1, NO_IRQ } 163#define GPIO1_IRQ { IRQ_PBX_GPIO1, NO_IRQ }
177#define GPIO1_DMA { 0, 0 }
178#define PBX_RTC_IRQ { IRQ_PBX_RTC, NO_IRQ } 164#define PBX_RTC_IRQ { IRQ_PBX_RTC, NO_IRQ }
179#define PBX_RTC_DMA { 0, 0 }
180#define SCI_IRQ { IRQ_PBX_SCI, NO_IRQ } 165#define SCI_IRQ { IRQ_PBX_SCI, NO_IRQ }
181#define SCI_DMA { 7, 6 }
182#define PBX_UART0_IRQ { IRQ_PBX_UART0, NO_IRQ } 166#define PBX_UART0_IRQ { IRQ_PBX_UART0, NO_IRQ }
183#define PBX_UART0_DMA { 15, 14 }
184#define PBX_UART1_IRQ { IRQ_PBX_UART1, NO_IRQ } 167#define PBX_UART1_IRQ { IRQ_PBX_UART1, NO_IRQ }
185#define PBX_UART1_DMA { 13, 12 }
186#define PBX_UART2_IRQ { IRQ_PBX_UART2, NO_IRQ } 168#define PBX_UART2_IRQ { IRQ_PBX_UART2, NO_IRQ }
187#define PBX_UART2_DMA { 11, 10 }
188#define PBX_UART3_IRQ { IRQ_PBX_UART3, NO_IRQ } 169#define PBX_UART3_IRQ { IRQ_PBX_UART3, NO_IRQ }
189#define PBX_UART3_DMA { 0x86, 0x87 }
190#define PBX_SSP_IRQ { IRQ_PBX_SSP, NO_IRQ } 170#define PBX_SSP_IRQ { IRQ_PBX_SSP, NO_IRQ }
191#define PBX_SSP_DMA { 9, 8 }
192 171
193/* FPGA Primecells */ 172/* FPGA Primecells */
194AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); 173AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
@@ -417,6 +396,7 @@ MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
417 .boot_params = PLAT_PHYS_OFFSET + 0x00000100, 396 .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
418 .fixup = realview_pbx_fixup, 397 .fixup = realview_pbx_fixup,
419 .map_io = realview_pbx_map_io, 398 .map_io = realview_pbx_map_io,
399 .init_early = realview_init_early,
420 .init_irq = gic_init_irq, 400 .init_irq = gic_init_irq,
421 .timer = &realview_pbx_timer, 401 .timer = &realview_pbx_timer,
422 .init_machine = realview_pbx_init, 402 .init_machine = realview_pbx_init,
diff --git a/arch/arm/mach-s5pv310/localtimer.c b/arch/arm/mach-s5pv310/localtimer.c
index 2784036cd8b..8239c6a684a 100644
--- a/arch/arm/mach-s5pv310/localtimer.c
+++ b/arch/arm/mach-s5pv310/localtimer.c
@@ -18,8 +18,9 @@
18/* 18/*
19 * Setup the local clock events for a CPU. 19 * Setup the local clock events for a CPU.
20 */ 20 */
21void __cpuinit local_timer_setup(struct clock_event_device *evt) 21int __cpuinit local_timer_setup(struct clock_event_device *evt)
22{ 22{
23 evt->irq = IRQ_LOCALTIMER; 23 evt->irq = IRQ_LOCALTIMER;
24 twd_timer_setup(evt); 24 twd_timer_setup(evt);
25 return 0;
25} 26}
diff --git a/arch/arm/mach-shmobile/localtimer.c b/arch/arm/mach-shmobile/localtimer.c
index 2111c28b724..ad9ccc9900c 100644
--- a/arch/arm/mach-shmobile/localtimer.c
+++ b/arch/arm/mach-shmobile/localtimer.c
@@ -18,8 +18,9 @@
18/* 18/*
19 * Setup the local clock events for a CPU. 19 * Setup the local clock events for a CPU.
20 */ 20 */
21void __cpuinit local_timer_setup(struct clock_event_device *evt) 21int __cpuinit local_timer_setup(struct clock_event_device *evt)
22{ 22{
23 evt->irq = 29; 23 evt->irq = 29;
24 twd_timer_setup(evt); 24 twd_timer_setup(evt);
25 return 0;
25} 26}
diff --git a/arch/arm/mach-tegra/localtimer.c b/arch/arm/mach-tegra/localtimer.c
index f81ca7cbbc1..e91d681d45a 100644
--- a/arch/arm/mach-tegra/localtimer.c
+++ b/arch/arm/mach-tegra/localtimer.c
@@ -18,8 +18,9 @@
18/* 18/*
19 * Setup the local clock events for a CPU. 19 * Setup the local clock events for a CPU.
20 */ 20 */
21void __cpuinit local_timer_setup(struct clock_event_device *evt) 21int __cpuinit local_timer_setup(struct clock_event_device *evt)
22{ 22{
23 evt->irq = IRQ_LOCALTIMER; 23 evt->irq = IRQ_LOCALTIMER;
24 twd_timer_setup(evt); 24 twd_timer_setup(evt);
25 return 0;
25} 26}
diff --git a/arch/arm/mach-ux500/localtimer.c b/arch/arm/mach-ux500/localtimer.c
index 2288f6a7c51..5ba113309a0 100644
--- a/arch/arm/mach-ux500/localtimer.c
+++ b/arch/arm/mach-ux500/localtimer.c
@@ -21,8 +21,9 @@
21/* 21/*
22 * Setup the local clock events for a CPU. 22 * Setup the local clock events for a CPU.
23 */ 23 */
24void __cpuinit local_timer_setup(struct clock_event_device *evt) 24int __cpuinit local_timer_setup(struct clock_event_device *evt)
25{ 25{
26 evt->irq = IRQ_LOCALTIMER; 26 evt->irq = IRQ_LOCALTIMER;
27 twd_timer_setup(evt); 27 twd_timer_setup(evt);
28 return 0;
28} 29}
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 136c32e7ed8..eb7ffa0ee8b 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -50,6 +50,8 @@
50#include <mach/platform.h> 50#include <mach/platform.h>
51#include <asm/hardware/timer-sp.h> 51#include <asm/hardware/timer-sp.h>
52 52
53#include <plat/clcd.h>
54#include <plat/fpga-irq.h>
53#include <plat/sched_clock.h> 55#include <plat/sched_clock.h>
54 56
55#include "core.h" 57#include "core.h"
@@ -63,47 +65,12 @@
63#define VA_VIC_BASE __io_address(VERSATILE_VIC_BASE) 65#define VA_VIC_BASE __io_address(VERSATILE_VIC_BASE)
64#define VA_SIC_BASE __io_address(VERSATILE_SIC_BASE) 66#define VA_SIC_BASE __io_address(VERSATILE_SIC_BASE)
65 67
66static void sic_mask_irq(struct irq_data *d) 68static struct fpga_irq_data sic_irq = {
67{ 69 .base = VA_SIC_BASE,
68 unsigned int irq = d->irq - IRQ_SIC_START; 70 .irq_start = IRQ_SIC_START,
69 71 .chip.name = "SIC",
70 writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
71}
72
73static void sic_unmask_irq(struct irq_data *d)
74{
75 unsigned int irq = d->irq - IRQ_SIC_START;
76
77 writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_SET);
78}
79
80static struct irq_chip sic_chip = {
81 .name = "SIC",
82 .irq_ack = sic_mask_irq,
83 .irq_mask = sic_mask_irq,
84 .irq_unmask = sic_unmask_irq,
85}; 72};
86 73
87static void
88sic_handle_irq(unsigned int irq, struct irq_desc *desc)
89{
90 unsigned long status = readl(VA_SIC_BASE + SIC_IRQ_STATUS);
91
92 if (status == 0) {
93 do_bad_IRQ(irq, desc);
94 return;
95 }
96
97 do {
98 irq = ffs(status) - 1;
99 status &= ~(1 << irq);
100
101 irq += IRQ_SIC_START;
102
103 generic_handle_irq(irq);
104 } while (status);
105}
106
107#if 1 74#if 1
108#define IRQ_MMCI0A IRQ_VICSOURCE22 75#define IRQ_MMCI0A IRQ_VICSOURCE22
109#define IRQ_AACI IRQ_VICSOURCE24 76#define IRQ_AACI IRQ_VICSOURCE24
@@ -118,22 +85,11 @@ sic_handle_irq(unsigned int irq, struct irq_desc *desc)
118 85
119void __init versatile_init_irq(void) 86void __init versatile_init_irq(void)
120{ 87{
121 unsigned int i;
122
123 vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0); 88 vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0);
124 89
125 set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq);
126
127 /* Do second interrupt controller */
128 writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); 90 writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
129 91
130 for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) { 92 fpga_irq_init(IRQ_VICSOURCE31, ~PIC_MASK, &sic_irq);
131 if ((PIC_MASK & (1 << (i - IRQ_SIC_START))) == 0) {
132 set_irq_chip(i, &sic_chip);
133 set_irq_handler(i, handle_level_irq);
134 set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
135 }
136 }
137 93
138 /* 94 /*
139 * Interrupts on secondary controller from 0 to 8 are routed to 95 * Interrupts on secondary controller from 0 to 8 are routed to
@@ -476,127 +432,7 @@ static struct clk_lookup lookups[] = {
476#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8) 432#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8)
477#define SYS_CLCD_ID_VGA (0x1f << 8) 433#define SYS_CLCD_ID_VGA (0x1f << 8)
478 434
479static struct clcd_panel vga = { 435static bool is_sanyo_2_5_lcd;
480 .mode = {
481 .name = "VGA",
482 .refresh = 60,
483 .xres = 640,
484 .yres = 480,
485 .pixclock = 39721,
486 .left_margin = 40,
487 .right_margin = 24,
488 .upper_margin = 32,
489 .lower_margin = 11,
490 .hsync_len = 96,
491 .vsync_len = 2,
492 .sync = 0,
493 .vmode = FB_VMODE_NONINTERLACED,
494 },
495 .width = -1,
496 .height = -1,
497 .tim2 = TIM2_BCD | TIM2_IPC,
498 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
499 .bpp = 16,
500};
501
502static struct clcd_panel sanyo_3_8_in = {
503 .mode = {
504 .name = "Sanyo QVGA",
505 .refresh = 116,
506 .xres = 320,
507 .yres = 240,
508 .pixclock = 100000,
509 .left_margin = 6,
510 .right_margin = 6,
511 .upper_margin = 5,
512 .lower_margin = 5,
513 .hsync_len = 6,
514 .vsync_len = 6,
515 .sync = 0,
516 .vmode = FB_VMODE_NONINTERLACED,
517 },
518 .width = -1,
519 .height = -1,
520 .tim2 = TIM2_BCD,
521 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
522 .bpp = 16,
523};
524
525static struct clcd_panel sanyo_2_5_in = {
526 .mode = {
527 .name = "Sanyo QVGA Portrait",
528 .refresh = 116,
529 .xres = 240,
530 .yres = 320,
531 .pixclock = 100000,
532 .left_margin = 20,
533 .right_margin = 10,
534 .upper_margin = 2,
535 .lower_margin = 2,
536 .hsync_len = 10,
537 .vsync_len = 2,
538 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
539 .vmode = FB_VMODE_NONINTERLACED,
540 },
541 .width = -1,
542 .height = -1,
543 .tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC,
544 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
545 .bpp = 16,
546};
547
548static struct clcd_panel epson_2_2_in = {
549 .mode = {
550 .name = "Epson QCIF",
551 .refresh = 390,
552 .xres = 176,
553 .yres = 220,
554 .pixclock = 62500,
555 .left_margin = 3,
556 .right_margin = 2,
557 .upper_margin = 1,
558 .lower_margin = 0,
559 .hsync_len = 3,
560 .vsync_len = 2,
561 .sync = 0,
562 .vmode = FB_VMODE_NONINTERLACED,
563 },
564 .width = -1,
565 .height = -1,
566 .tim2 = TIM2_BCD | TIM2_IPC,
567 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
568 .bpp = 16,
569};
570
571/*
572 * Detect which LCD panel is connected, and return the appropriate
573 * clcd_panel structure. Note: we do not have any information on
574 * the required timings for the 8.4in panel, so we presently assume
575 * VGA timings.
576 */
577static struct clcd_panel *versatile_clcd_panel(void)
578{
579 void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
580 struct clcd_panel *panel = &vga;
581 u32 val;
582
583 val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
584 if (val == SYS_CLCD_ID_SANYO_3_8)
585 panel = &sanyo_3_8_in;
586 else if (val == SYS_CLCD_ID_SANYO_2_5)
587 panel = &sanyo_2_5_in;
588 else if (val == SYS_CLCD_ID_EPSON_2_2)
589 panel = &epson_2_2_in;
590 else if (val == SYS_CLCD_ID_VGA)
591 panel = &vga;
592 else {
593 printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
594 val);
595 panel = &vga;
596 }
597
598 return panel;
599}
600 436
601/* 437/*
602 * Disable all display connectors on the interface module. 438 * Disable all display connectors on the interface module.
@@ -614,7 +450,7 @@ static void versatile_clcd_disable(struct clcd_fb *fb)
614 /* 450 /*
615 * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off 451 * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off
616 */ 452 */
617 if (machine_is_versatile_ab() && fb->panel == &sanyo_2_5_in) { 453 if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) {
618 void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL); 454 void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
619 unsigned long ctrl; 455 unsigned long ctrl;
620 456
@@ -630,18 +466,22 @@ static void versatile_clcd_disable(struct clcd_fb *fb)
630 */ 466 */
631static void versatile_clcd_enable(struct clcd_fb *fb) 467static void versatile_clcd_enable(struct clcd_fb *fb)
632{ 468{
469 struct fb_var_screeninfo *var = &fb->fb.var;
633 void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET; 470 void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
634 u32 val; 471 u32 val;
635 472
636 val = readl(sys_clcd); 473 val = readl(sys_clcd);
637 val &= ~SYS_CLCD_MODE_MASK; 474 val &= ~SYS_CLCD_MODE_MASK;
638 475
639 switch (fb->fb.var.green.length) { 476 switch (var->green.length) {
640 case 5: 477 case 5:
641 val |= SYS_CLCD_MODE_5551; 478 val |= SYS_CLCD_MODE_5551;
642 break; 479 break;
643 case 6: 480 case 6:
644 val |= SYS_CLCD_MODE_565_RLSB; 481 if (var->red.offset == 0)
482 val |= SYS_CLCD_MODE_565_RLSB;
483 else
484 val |= SYS_CLCD_MODE_565_BLSB;
645 break; 485 break;
646 case 8: 486 case 8:
647 val |= SYS_CLCD_MODE_888; 487 val |= SYS_CLCD_MODE_888;
@@ -663,7 +503,7 @@ static void versatile_clcd_enable(struct clcd_fb *fb)
663 /* 503 /*
664 * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on 504 * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on
665 */ 505 */
666 if (machine_is_versatile_ab() && fb->panel == &sanyo_2_5_in) { 506 if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) {
667 void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL); 507 void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
668 unsigned long ctrl; 508 unsigned long ctrl;
669 509
@@ -674,50 +514,62 @@ static void versatile_clcd_enable(struct clcd_fb *fb)
674#endif 514#endif
675} 515}
676 516
677static unsigned long framesize = SZ_1M; 517/*
678 518 * Detect which LCD panel is connected, and return the appropriate
519 * clcd_panel structure. Note: we do not have any information on
520 * the required timings for the 8.4in panel, so we presently assume
521 * VGA timings.
522 */
679static int versatile_clcd_setup(struct clcd_fb *fb) 523static int versatile_clcd_setup(struct clcd_fb *fb)
680{ 524{
681 dma_addr_t dma; 525 void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
526 const char *panel_name;
527 u32 val;
682 528
683 fb->panel = versatile_clcd_panel(); 529 is_sanyo_2_5_lcd = false;
684 530
685 fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize, 531 val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
686 &dma, GFP_KERNEL); 532 if (val == SYS_CLCD_ID_SANYO_3_8)
687 if (!fb->fb.screen_base) { 533 panel_name = "Sanyo TM38QV67A02A";
688 printk(KERN_ERR "CLCD: unable to map framebuffer\n"); 534 else if (val == SYS_CLCD_ID_SANYO_2_5) {
689 return -ENOMEM; 535 panel_name = "Sanyo QVGA Portrait";
536 is_sanyo_2_5_lcd = true;
537 } else if (val == SYS_CLCD_ID_EPSON_2_2)
538 panel_name = "Epson L2F50113T00";
539 else if (val == SYS_CLCD_ID_VGA)
540 panel_name = "VGA";
541 else {
542 printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
543 val);
544 panel_name = "VGA";
690 } 545 }
691 546
692 fb->fb.fix.smem_start = dma; 547 fb->panel = versatile_clcd_get_panel(panel_name);
693 fb->fb.fix.smem_len = framesize; 548 if (!fb->panel)
549 return -EINVAL;
694 550
695 return 0; 551 return versatile_clcd_setup_dma(fb, SZ_1M);
696} 552}
697 553
698static int versatile_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) 554static void versatile_clcd_decode(struct clcd_fb *fb, struct clcd_regs *regs)
699{ 555{
700 return dma_mmap_writecombine(&fb->dev->dev, vma, 556 clcdfb_decode(fb, regs);
701 fb->fb.screen_base,
702 fb->fb.fix.smem_start,
703 fb->fb.fix.smem_len);
704}
705 557
706static void versatile_clcd_remove(struct clcd_fb *fb) 558 /* Always clear BGR for RGB565: we do the routing externally */
707{ 559 if (fb->fb.var.green.length == 6)
708 dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, 560 regs->cntl &= ~CNTL_BGR;
709 fb->fb.screen_base, fb->fb.fix.smem_start);
710} 561}
711 562
712static struct clcd_board clcd_plat_data = { 563static struct clcd_board clcd_plat_data = {
713 .name = "Versatile", 564 .name = "Versatile",
565 .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
714 .check = clcdfb_check, 566 .check = clcdfb_check,
715 .decode = clcdfb_decode, 567 .decode = versatile_clcd_decode,
716 .disable = versatile_clcd_disable, 568 .disable = versatile_clcd_disable,
717 .enable = versatile_clcd_enable, 569 .enable = versatile_clcd_enable,
718 .setup = versatile_clcd_setup, 570 .setup = versatile_clcd_setup,
719 .mmap = versatile_clcd_mmap, 571 .mmap = versatile_clcd_mmap_dma,
720 .remove = versatile_clcd_remove, 572 .remove = versatile_clcd_remove_dma,
721}; 573};
722 574
723static struct pl061_platform_data gpio0_plat_data = { 575static struct pl061_platform_data gpio0_plat_data = {
@@ -737,53 +589,35 @@ static struct pl022_ssp_controller ssp0_plat_data = {
737}; 589};
738 590
739#define AACI_IRQ { IRQ_AACI, NO_IRQ } 591#define AACI_IRQ { IRQ_AACI, NO_IRQ }
740#define AACI_DMA { 0x80, 0x81 }
741#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B } 592#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B }
742#define MMCI0_DMA { 0x84, 0 }
743#define KMI0_IRQ { IRQ_SIC_KMI0, NO_IRQ } 593#define KMI0_IRQ { IRQ_SIC_KMI0, NO_IRQ }
744#define KMI0_DMA { 0, 0 }
745#define KMI1_IRQ { IRQ_SIC_KMI1, NO_IRQ } 594#define KMI1_IRQ { IRQ_SIC_KMI1, NO_IRQ }
746#define KMI1_DMA { 0, 0 }
747 595
748/* 596/*
749 * These devices are connected directly to the multi-layer AHB switch 597 * These devices are connected directly to the multi-layer AHB switch
750 */ 598 */
751#define SMC_IRQ { NO_IRQ, NO_IRQ } 599#define SMC_IRQ { NO_IRQ, NO_IRQ }
752#define SMC_DMA { 0, 0 }
753#define MPMC_IRQ { NO_IRQ, NO_IRQ } 600#define MPMC_IRQ { NO_IRQ, NO_IRQ }
754#define MPMC_DMA { 0, 0 }
755#define CLCD_IRQ { IRQ_CLCDINT, NO_IRQ } 601#define CLCD_IRQ { IRQ_CLCDINT, NO_IRQ }
756#define CLCD_DMA { 0, 0 }
757#define DMAC_IRQ { IRQ_DMAINT, NO_IRQ } 602#define DMAC_IRQ { IRQ_DMAINT, NO_IRQ }
758#define DMAC_DMA { 0, 0 }
759 603
760/* 604/*
761 * These devices are connected via the core APB bridge 605 * These devices are connected via the core APB bridge
762 */ 606 */
763#define SCTL_IRQ { NO_IRQ, NO_IRQ } 607#define SCTL_IRQ { NO_IRQ, NO_IRQ }
764#define SCTL_DMA { 0, 0 }
765#define WATCHDOG_IRQ { IRQ_WDOGINT, NO_IRQ } 608#define WATCHDOG_IRQ { IRQ_WDOGINT, NO_IRQ }
766#define WATCHDOG_DMA { 0, 0 }
767#define GPIO0_IRQ { IRQ_GPIOINT0, NO_IRQ } 609#define GPIO0_IRQ { IRQ_GPIOINT0, NO_IRQ }
768#define GPIO0_DMA { 0, 0 }
769#define GPIO1_IRQ { IRQ_GPIOINT1, NO_IRQ } 610#define GPIO1_IRQ { IRQ_GPIOINT1, NO_IRQ }
770#define GPIO1_DMA { 0, 0 }
771#define RTC_IRQ { IRQ_RTCINT, NO_IRQ } 611#define RTC_IRQ { IRQ_RTCINT, NO_IRQ }
772#define RTC_DMA { 0, 0 }
773 612
774/* 613/*
775 * These devices are connected via the DMA APB bridge 614 * These devices are connected via the DMA APB bridge
776 */ 615 */
777#define SCI_IRQ { IRQ_SCIINT, NO_IRQ } 616#define SCI_IRQ { IRQ_SCIINT, NO_IRQ }
778#define SCI_DMA { 7, 6 }
779#define UART0_IRQ { IRQ_UARTINT0, NO_IRQ } 617#define UART0_IRQ { IRQ_UARTINT0, NO_IRQ }
780#define UART0_DMA { 15, 14 }
781#define UART1_IRQ { IRQ_UARTINT1, NO_IRQ } 618#define UART1_IRQ { IRQ_UARTINT1, NO_IRQ }
782#define UART1_DMA { 13, 12 }
783#define UART2_IRQ { IRQ_UARTINT2, NO_IRQ } 619#define UART2_IRQ { IRQ_UARTINT2, NO_IRQ }
784#define UART2_DMA { 11, 10 }
785#define SSP_IRQ { IRQ_SSPINT, NO_IRQ } 620#define SSP_IRQ { IRQ_SSPINT, NO_IRQ }
786#define SSP_DMA { 9, 8 }
787 621
788/* FPGA Primecells */ 622/* FPGA Primecells */
789AMBA_DEVICE(aaci, "fpga:04", AACI, NULL); 623AMBA_DEVICE(aaci, "fpga:04", AACI, NULL);
@@ -865,14 +699,21 @@ static void versatile_leds_event(led_event_t ledevt)
865} 699}
866#endif /* CONFIG_LEDS */ 700#endif /* CONFIG_LEDS */
867 701
868void __init versatile_init(void) 702/* Early initializations */
703void __init versatile_init_early(void)
869{ 704{
870 int i; 705 void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
871
872 osc4_clk.vcoreg = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSCCLCD_OFFSET;
873 706
707 osc4_clk.vcoreg = sys + VERSATILE_SYS_OSCCLCD_OFFSET;
874 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 708 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
875 709
710 versatile_sched_clock_init(sys + VERSATILE_SYS_24MHz_OFFSET, 24000000);
711}
712
713void __init versatile_init(void)
714{
715 int i;
716
876 platform_device_register(&versatile_flash_device); 717 platform_device_register(&versatile_flash_device);
877 platform_device_register(&versatile_i2c_device); 718 platform_device_register(&versatile_i2c_device);
878 platform_device_register(&smc91x_device); 719 platform_device_register(&smc91x_device);
@@ -889,12 +730,6 @@ void __init versatile_init(void)
889} 730}
890 731
891/* 732/*
892 * The sched_clock counter
893 */
894#define REFCOUNTER (__io_address(VERSATILE_SYS_BASE) + \
895 VERSATILE_SYS_24MHz_OFFSET)
896
897/*
898 * Where is the timer (VA)? 733 * Where is the timer (VA)?
899 */ 734 */
900#define TIMER0_VA_BASE __io_address(VERSATILE_TIMER0_1_BASE) 735#define TIMER0_VA_BASE __io_address(VERSATILE_TIMER0_1_BASE)
@@ -909,8 +744,6 @@ static void __init versatile_timer_init(void)
909{ 744{
910 u32 val; 745 u32 val;
911 746
912 versatile_sched_clock_init(REFCOUNTER, 24000000);
913
914 /* 747 /*
915 * set clock frequency: 748 * set clock frequency:
916 * VERSATILE_REFCLK is 32KHz 749 * VERSATILE_REFCLK is 32KHz
diff --git a/arch/arm/mach-versatile/core.h b/arch/arm/mach-versatile/core.h
index 9d39886a835..fd6404e5d78 100644
--- a/arch/arm/mach-versatile/core.h
+++ b/arch/arm/mach-versatile/core.h
@@ -25,6 +25,7 @@
25#include <linux/amba/bus.h> 25#include <linux/amba/bus.h>
26 26
27extern void __init versatile_init(void); 27extern void __init versatile_init(void);
28extern void __init versatile_init_early(void);
28extern void __init versatile_init_irq(void); 29extern void __init versatile_init_irq(void);
29extern void __init versatile_map_io(void); 30extern void __init versatile_map_io(void);
30extern struct sys_timer versatile_timer; 31extern struct sys_timer versatile_timer;
@@ -44,7 +45,6 @@ static struct amba_device name##_device = { \
44 }, \ 45 }, \
45 .dma_mask = ~0, \ 46 .dma_mask = ~0, \
46 .irq = base##_IRQ, \ 47 .irq = base##_IRQ, \
47 /* .dma = base##_DMA,*/ \
48} 48}
49 49
50#endif 50#endif
diff --git a/arch/arm/mach-versatile/include/mach/hardware.h b/arch/arm/mach-versatile/include/mach/hardware.h
index b5e75bb4496..6911e1f5f15 100644
--- a/arch/arm/mach-versatile/include/mach/hardware.h
+++ b/arch/arm/mach-versatile/include/mach/hardware.h
@@ -39,6 +39,6 @@
39/* macro to get at IO space when running virtually */ 39/* macro to get at IO space when running virtually */
40#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000) 40#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
41 41
42#define __io_address(n) __io(IO_ADDRESS(n)) 42#define __io_address(n) ((void __iomem __force *)IO_ADDRESS(n))
43 43
44#endif 44#endif
diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c
index aa9730fb13b..f8ae64b3eed 100644
--- a/arch/arm/mach-versatile/versatile_ab.c
+++ b/arch/arm/mach-versatile/versatile_ab.c
@@ -37,6 +37,7 @@ MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
37 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ 37 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
38 .boot_params = 0x00000100, 38 .boot_params = 0x00000100,
39 .map_io = versatile_map_io, 39 .map_io = versatile_map_io,
40 .init_early = versatile_init_early,
40 .init_irq = versatile_init_irq, 41 .init_irq = versatile_init_irq,
41 .timer = &versatile_timer, 42 .timer = &versatile_timer,
42 .init_machine = versatile_init, 43 .init_machine = versatile_init,
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
index bf469642a3f..37c23dfeefb 100644
--- a/arch/arm/mach-versatile/versatile_pb.c
+++ b/arch/arm/mach-versatile/versatile_pb.c
@@ -59,19 +59,14 @@ static struct pl061_platform_data gpio3_plat_data = {
59}; 59};
60 60
61#define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ } 61#define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ }
62#define UART3_DMA { 0x86, 0x87 }
63#define SCI1_IRQ { IRQ_SIC_SCI3, NO_IRQ } 62#define SCI1_IRQ { IRQ_SIC_SCI3, NO_IRQ }
64#define SCI1_DMA { 0x88, 0x89 }
65#define MMCI1_IRQ { IRQ_MMCI1A, IRQ_SIC_MMCI1B } 63#define MMCI1_IRQ { IRQ_MMCI1A, IRQ_SIC_MMCI1B }
66#define MMCI1_DMA { 0x85, 0 }
67 64
68/* 65/*
69 * These devices are connected via the core APB bridge 66 * These devices are connected via the core APB bridge
70 */ 67 */
71#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ } 68#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ }
72#define GPIO2_DMA { 0, 0 }
73#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ } 69#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ }
74#define GPIO3_DMA { 0, 0 }
75 70
76/* 71/*
77 * These devices are connected via the DMA APB bridge 72 * These devices are connected via the DMA APB bridge
@@ -110,6 +105,7 @@ MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
110 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ 105 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
111 .boot_params = 0x00000100, 106 .boot_params = 0x00000100,
112 .map_io = versatile_map_io, 107 .map_io = versatile_map_io,
108 .init_early = versatile_init_early,
113 .init_irq = versatile_init_irq, 109 .init_irq = versatile_init_irq,
114 .timer = &versatile_timer, 110 .timer = &versatile_timer,
115 .init_machine = versatile_pb_init, 111 .init_machine = versatile_pb_init,
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index 3f19b660a16..931148487f0 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -5,5 +5,8 @@ config ARCH_VEXPRESS_CA9X4
5 bool "Versatile Express Cortex-A9x4 tile" 5 bool "Versatile Express Cortex-A9x4 tile"
6 select CPU_V7 6 select CPU_V7
7 select ARM_GIC 7 select ARM_GIC
8 select ARM_ERRATA_720789
9 select ARM_ERRATA_751472
10 select ARM_ERRATA_753970
8 11
9endmenu 12endmenu
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
index 2c0ac7de281..90551b9780a 100644
--- a/arch/arm/mach-vexpress/Makefile
+++ b/arch/arm/mach-vexpress/Makefile
@@ -4,6 +4,5 @@
4 4
5obj-y := v2m.o 5obj-y := v2m.o
6obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o 6obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o
7obj-$(CONFIG_SMP) += platsmp.o headsmp.o 7obj-$(CONFIG_SMP) += platsmp.o
8obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 8obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
9obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
index 362780d868d..e0312a1dce3 100644
--- a/arch/arm/mach-vexpress/core.h
+++ b/arch/arm/mach-vexpress/core.h
@@ -21,4 +21,5 @@ struct amba_device name##_device = { \
21struct map_desc; 21struct map_desc;
22 22
23void v2m_map_io(struct map_desc *tile, size_t num); 23void v2m_map_io(struct map_desc *tile, size_t num);
24void v2m_init_early(void);
24extern struct sys_timer v2m_timer; 25extern struct sys_timer v2m_timer;
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index e9bccc5230c..30d5a5b0ac2 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -30,6 +30,8 @@
30 30
31#include <mach/motherboard.h> 31#include <mach/motherboard.h>
32 32
33#include <plat/clcd.h>
34
33#define V2M_PA_CS7 0x10000000 35#define V2M_PA_CS7 0x10000000
34 36
35static struct map_desc ct_ca9x4_io_desc[] __initdata = { 37static struct map_desc ct_ca9x4_io_desc[] __initdata = {
@@ -80,29 +82,6 @@ static struct sys_timer ct_ca9x4_timer = {
80}; 82};
81#endif 83#endif
82 84
83static struct clcd_panel xvga_panel = {
84 .mode = {
85 .name = "XVGA",
86 .refresh = 60,
87 .xres = 1024,
88 .yres = 768,
89 .pixclock = 15384,
90 .left_margin = 168,
91 .right_margin = 8,
92 .upper_margin = 29,
93 .lower_margin = 3,
94 .hsync_len = 144,
95 .vsync_len = 6,
96 .sync = 0,
97 .vmode = FB_VMODE_NONINTERLACED,
98 },
99 .width = -1,
100 .height = -1,
101 .tim2 = TIM2_BCD | TIM2_IPC,
102 .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
103 .bpp = 16,
104};
105
106static void ct_ca9x4_clcd_enable(struct clcd_fb *fb) 85static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
107{ 86{
108 v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0); 87 v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0);
@@ -112,42 +91,23 @@ static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
112static int ct_ca9x4_clcd_setup(struct clcd_fb *fb) 91static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
113{ 92{
114 unsigned long framesize = 1024 * 768 * 2; 93 unsigned long framesize = 1024 * 768 * 2;
115 dma_addr_t dma;
116
117 fb->panel = &xvga_panel;
118 94
119 fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize, 95 fb->panel = versatile_clcd_get_panel("XVGA");
120 &dma, GFP_KERNEL); 96 if (!fb->panel)
121 if (!fb->fb.screen_base) { 97 return -EINVAL;
122 printk(KERN_ERR "CLCD: unable to map frame buffer\n");
123 return -ENOMEM;
124 }
125 fb->fb.fix.smem_start = dma;
126 fb->fb.fix.smem_len = framesize;
127
128 return 0;
129}
130
131static int ct_ca9x4_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
132{
133 return dma_mmap_writecombine(&fb->dev->dev, vma, fb->fb.screen_base,
134 fb->fb.fix.smem_start, fb->fb.fix.smem_len);
135}
136 98
137static void ct_ca9x4_clcd_remove(struct clcd_fb *fb) 99 return versatile_clcd_setup_dma(fb, framesize);
138{
139 dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
140 fb->fb.screen_base, fb->fb.fix.smem_start);
141} 100}
142 101
143static struct clcd_board ct_ca9x4_clcd_data = { 102static struct clcd_board ct_ca9x4_clcd_data = {
144 .name = "CT-CA9X4", 103 .name = "CT-CA9X4",
104 .caps = CLCD_CAP_5551 | CLCD_CAP_565,
145 .check = clcdfb_check, 105 .check = clcdfb_check,
146 .decode = clcdfb_decode, 106 .decode = clcdfb_decode,
147 .enable = ct_ca9x4_clcd_enable, 107 .enable = ct_ca9x4_clcd_enable,
148 .setup = ct_ca9x4_clcd_setup, 108 .setup = ct_ca9x4_clcd_setup,
149 .mmap = ct_ca9x4_clcd_mmap, 109 .mmap = versatile_clcd_mmap_dma,
150 .remove = ct_ca9x4_clcd_remove, 110 .remove = versatile_clcd_remove_dma,
151}; 111};
152 112
153static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data); 113static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
@@ -220,6 +180,13 @@ static struct platform_device pmu_device = {
220 .resource = pmu_resources, 180 .resource = pmu_resources,
221}; 181};
222 182
183static void __init ct_ca9x4_init_early(void)
184{
185 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
186
187 v2m_init_early();
188}
189
223static void __init ct_ca9x4_init(void) 190static void __init ct_ca9x4_init(void)
224{ 191{
225 int i; 192 int i;
@@ -234,8 +201,6 @@ static void __init ct_ca9x4_init(void)
234 l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff); 201 l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
235#endif 202#endif
236 203
237 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
238
239 for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++) 204 for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
240 amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource); 205 amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
241 206
@@ -246,6 +211,7 @@ MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4")
246 .boot_params = PLAT_PHYS_OFFSET + 0x00000100, 211 .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
247 .map_io = ct_ca9x4_map_io, 212 .map_io = ct_ca9x4_map_io,
248 .init_irq = ct_ca9x4_init_irq, 213 .init_irq = ct_ca9x4_init_irq,
214 .init_early = ct_ca9x4_init_early,
249#if 0 215#if 0
250 .timer = &ct_ca9x4_timer, 216 .timer = &ct_ca9x4_timer,
251#else 217#else
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index 634bf1d3a31..18927023c2c 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -10,13 +10,9 @@
10 */ 10 */
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/jiffies.h>
16#include <linux/smp.h> 13#include <linux/smp.h>
17#include <linux/io.h> 14#include <linux/io.h>
18 15
19#include <asm/cacheflush.h>
20#include <asm/smp_scu.h> 16#include <asm/smp_scu.h>
21#include <asm/unified.h> 17#include <asm/unified.h>
22 18
@@ -26,99 +22,13 @@
26 22
27#include "core.h" 23#include "core.h"
28 24
29extern void vexpress_secondary_startup(void); 25extern void versatile_secondary_startup(void);
30
31/*
32 * control for which core is the next to come out of the secondary
33 * boot "holding pen"
34 */
35volatile int __cpuinitdata pen_release = -1;
36
37/*
38 * Write pen_release in a way that is guaranteed to be visible to all
39 * observers, irrespective of whether they're taking part in coherency
40 * or not. This is necessary for the hotplug code to work reliably.
41 */
42static void __cpuinit write_pen_release(int val)
43{
44 pen_release = val;
45 smp_wmb();
46 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
47 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
48}
49 26
50static void __iomem *scu_base_addr(void) 27static void __iomem *scu_base_addr(void)
51{ 28{
52 return MMIO_P2V(A9_MPCORE_SCU); 29 return MMIO_P2V(A9_MPCORE_SCU);
53} 30}
54 31
55static DEFINE_SPINLOCK(boot_lock);
56
57void __cpuinit platform_secondary_init(unsigned int cpu)
58{
59 /*
60 * if any interrupts are already enabled for the primary
61 * core (e.g. timer irq), then they will not have been enabled
62 * for us: do so
63 */
64 gic_secondary_init(0);
65
66 /*
67 * let the primary processor know we're out of the
68 * pen, then head off into the C entry point
69 */
70 write_pen_release(-1);
71
72 /*
73 * Synchronise with the boot thread.
74 */
75 spin_lock(&boot_lock);
76 spin_unlock(&boot_lock);
77}
78
79int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
80{
81 unsigned long timeout;
82
83 /*
84 * Set synchronisation state between this boot processor
85 * and the secondary one
86 */
87 spin_lock(&boot_lock);
88
89 /*
90 * This is really belt and braces; we hold unintended secondary
91 * CPUs in the holding pen until we're ready for them. However,
92 * since we haven't sent them a soft interrupt, they shouldn't
93 * be there.
94 */
95 write_pen_release(cpu);
96
97 /*
98 * Send the secondary CPU a soft interrupt, thereby causing
99 * the boot monitor to read the system wide flags register,
100 * and branch to the address found there.
101 */
102 smp_cross_call(cpumask_of(cpu), 1);
103
104 timeout = jiffies + (1 * HZ);
105 while (time_before(jiffies, timeout)) {
106 smp_rmb();
107 if (pen_release == -1)
108 break;
109
110 udelay(10);
111 }
112
113 /*
114 * now the secondary core is starting up let it run its
115 * calibrations, then wait for it to finish
116 */
117 spin_unlock(&boot_lock);
118
119 return pen_release != -1 ? -ENOSYS : 0;
120}
121
122/* 32/*
123 * Initialise the CPU possible map early - this describes the CPUs 33 * Initialise the CPU possible map early - this describes the CPUs
124 * which may be present or become present in the system. 34 * which may be present or become present in the system.
@@ -163,6 +73,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
163 * secondary CPU branches to this address. 73 * secondary CPU branches to this address.
164 */ 74 */
165 writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR)); 75 writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
166 writel(BSYM(virt_to_phys(vexpress_secondary_startup)), 76 writel(BSYM(virt_to_phys(versatile_secondary_startup)),
167 MMIO_P2V(V2M_SYS_FLAGSSET)); 77 MMIO_P2V(V2M_SYS_FLAGSSET));
168} 78}
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 1edae65a0e7..63ef663fb0b 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -7,6 +7,7 @@
7#include <linux/io.h> 7#include <linux/io.h>
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/platform_device.h> 9#include <linux/platform_device.h>
10#include <linux/ata_platform.h>
10#include <linux/smsc911x.h> 11#include <linux/smsc911x.h>
11#include <linux/spinlock.h> 12#include <linux/spinlock.h>
12#include <linux/sysdev.h> 13#include <linux/sysdev.h>
@@ -48,13 +49,15 @@ void __init v2m_map_io(struct map_desc *tile, size_t num)
48 iotable_init(tile, num); 49 iotable_init(tile, num);
49} 50}
50 51
52void __init v2m_init_early(void)
53{
54 versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
55}
51 56
52static void __init v2m_timer_init(void) 57static void __init v2m_timer_init(void)
53{ 58{
54 u32 scctrl; 59 u32 scctrl;
55 60
56 versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
57
58 /* Select 1MHz TIMCLK as the reference clock for SP804 timers */ 61 /* Select 1MHz TIMCLK as the reference clock for SP804 timers */
59 scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL)); 62 scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL));
60 scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK; 63 scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
@@ -249,6 +252,29 @@ static struct platform_device v2m_flash_device = {
249 .dev.platform_data = &v2m_flash_data, 252 .dev.platform_data = &v2m_flash_data,
250}; 253};
251 254
255static struct pata_platform_info v2m_pata_data = {
256 .ioport_shift = 2,
257};
258
259static struct resource v2m_pata_resources[] = {
260 {
261 .start = V2M_CF,
262 .end = V2M_CF + 0xff,
263 .flags = IORESOURCE_MEM,
264 }, {
265 .start = V2M_CF + 0x100,
266 .end = V2M_CF + SZ_4K - 1,
267 .flags = IORESOURCE_MEM,
268 },
269};
270
271static struct platform_device v2m_cf_device = {
272 .name = "pata_platform",
273 .id = -1,
274 .resource = v2m_pata_resources,
275 .num_resources = ARRAY_SIZE(v2m_pata_resources),
276 .dev.platform_data = &v2m_pata_data,
277};
252 278
253static unsigned int v2m_mmci_status(struct device *dev) 279static unsigned int v2m_mmci_status(struct device *dev)
254{ 280{
@@ -363,6 +389,7 @@ static int __init v2m_init(void)
363 platform_device_register(&v2m_pcie_i2c_device); 389 platform_device_register(&v2m_pcie_i2c_device);
364 platform_device_register(&v2m_ddc_i2c_device); 390 platform_device_register(&v2m_ddc_i2c_device);
365 platform_device_register(&v2m_flash_device); 391 platform_device_register(&v2m_flash_device);
392 platform_device_register(&v2m_cf_device);
366 platform_device_register(&v2m_eth_device); 393 platform_device_register(&v2m_eth_device);
367 platform_device_register(&v2m_usb_device); 394 platform_device_register(&v2m_usb_device);
368 395
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 4771dba6144..82a093cee09 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -149,6 +149,7 @@ static int __init consistent_init(void)
149{ 149{
150 int ret = 0; 150 int ret = 0;
151 pgd_t *pgd; 151 pgd_t *pgd;
152 pud_t *pud;
152 pmd_t *pmd; 153 pmd_t *pmd;
153 pte_t *pte; 154 pte_t *pte;
154 int i = 0; 155 int i = 0;
@@ -156,7 +157,15 @@ static int __init consistent_init(void)
156 157
157 do { 158 do {
158 pgd = pgd_offset(&init_mm, base); 159 pgd = pgd_offset(&init_mm, base);
159 pmd = pmd_alloc(&init_mm, pgd, base); 160
161 pud = pud_alloc(&init_mm, pgd, base);
162 if (!pud) {
163 printk(KERN_ERR "%s: no pud tables\n", __func__);
164 ret = -ENOMEM;
165 break;
166 }
167
168 pmd = pmd_alloc(&init_mm, pud, base);
160 if (!pmd) { 169 if (!pmd) {
161 printk(KERN_ERR "%s: no pmd tables\n", __func__); 170 printk(KERN_ERR "%s: no pmd tables\n", __func__);
162 ret = -ENOMEM; 171 ret = -ENOMEM;
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 01210dba022..7cab7917942 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -95,6 +95,7 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
95{ 95{
96 spinlock_t *ptl; 96 spinlock_t *ptl;
97 pgd_t *pgd; 97 pgd_t *pgd;
98 pud_t *pud;
98 pmd_t *pmd; 99 pmd_t *pmd;
99 pte_t *pte; 100 pte_t *pte;
100 int ret; 101 int ret;
@@ -103,7 +104,11 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
103 if (pgd_none_or_clear_bad(pgd)) 104 if (pgd_none_or_clear_bad(pgd))
104 return 0; 105 return 0;
105 106
106 pmd = pmd_offset(pgd, address); 107 pud = pud_offset(pgd, address);
108 if (pud_none_or_clear_bad(pud))
109 return 0;
110
111 pmd = pmd_offset(pud, address);
107 if (pmd_none_or_clear_bad(pmd)) 112 if (pmd_none_or_clear_bad(pmd))
108 return 0; 113 return 0;
109 114
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index f10f9bac220..bc0e1d88fd3 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -76,9 +76,11 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
76 76
77 printk(KERN_ALERT "pgd = %p\n", mm->pgd); 77 printk(KERN_ALERT "pgd = %p\n", mm->pgd);
78 pgd = pgd_offset(mm, addr); 78 pgd = pgd_offset(mm, addr);
79 printk(KERN_ALERT "[%08lx] *pgd=%08lx", addr, pgd_val(*pgd)); 79 printk(KERN_ALERT "[%08lx] *pgd=%08llx",
80 addr, (long long)pgd_val(*pgd));
80 81
81 do { 82 do {
83 pud_t *pud;
82 pmd_t *pmd; 84 pmd_t *pmd;
83 pte_t *pte; 85 pte_t *pte;
84 86
@@ -90,9 +92,21 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
90 break; 92 break;
91 } 93 }
92 94
93 pmd = pmd_offset(pgd, addr); 95 pud = pud_offset(pgd, addr);
96 if (PTRS_PER_PUD != 1)
97 printk(", *pud=%08lx", pud_val(*pud));
98
99 if (pud_none(*pud))
100 break;
101
102 if (pud_bad(*pud)) {
103 printk("(bad)");
104 break;
105 }
106
107 pmd = pmd_offset(pud, addr);
94 if (PTRS_PER_PMD != 1) 108 if (PTRS_PER_PMD != 1)
95 printk(", *pmd=%08lx", pmd_val(*pmd)); 109 printk(", *pmd=%08llx", (long long)pmd_val(*pmd));
96 110
97 if (pmd_none(*pmd)) 111 if (pmd_none(*pmd))
98 break; 112 break;
@@ -107,8 +121,9 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
107 break; 121 break;
108 122
109 pte = pte_offset_map(pmd, addr); 123 pte = pte_offset_map(pmd, addr);
110 printk(", *pte=%08lx", pte_val(*pte)); 124 printk(", *pte=%08llx", (long long)pte_val(*pte));
111 printk(", *ppte=%08lx", pte_val(pte[PTE_HWTABLE_PTRS])); 125 printk(", *ppte=%08llx",
126 (long long)pte_val(pte[PTE_HWTABLE_PTRS]));
112 pte_unmap(pte); 127 pte_unmap(pte);
113 } while(0); 128 } while(0);
114 129
@@ -388,6 +403,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
388{ 403{
389 unsigned int index; 404 unsigned int index;
390 pgd_t *pgd, *pgd_k; 405 pgd_t *pgd, *pgd_k;
406 pud_t *pud, *pud_k;
391 pmd_t *pmd, *pmd_k; 407 pmd_t *pmd, *pmd_k;
392 408
393 if (addr < TASK_SIZE) 409 if (addr < TASK_SIZE)
@@ -406,12 +422,19 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
406 422
407 if (pgd_none(*pgd_k)) 423 if (pgd_none(*pgd_k))
408 goto bad_area; 424 goto bad_area;
409
410 if (!pgd_present(*pgd)) 425 if (!pgd_present(*pgd))
411 set_pgd(pgd, *pgd_k); 426 set_pgd(pgd, *pgd_k);
412 427
413 pmd_k = pmd_offset(pgd_k, addr); 428 pud = pud_offset(pgd, addr);
414 pmd = pmd_offset(pgd, addr); 429 pud_k = pud_offset(pgd_k, addr);
430
431 if (pud_none(*pud_k))
432 goto bad_area;
433 if (!pud_present(*pud))
434 set_pud(pud, *pud_k);
435
436 pmd = pmd_offset(pud, addr);
437 pmd_k = pmd_offset(pud_k, addr);
415 438
416 /* 439 /*
417 * On ARM one Linux PGD entry contains two hardware entries (see page 440 * On ARM one Linux PGD entry contains two hardware entries (see page
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index 57299446f78..2be9139a4ef 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -4,10 +4,10 @@
4#include <asm/pgalloc.h> 4#include <asm/pgalloc.h>
5#include <asm/pgtable.h> 5#include <asm/pgtable.h>
6 6
7static void idmap_add_pmd(pgd_t *pgd, unsigned long addr, unsigned long end, 7static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
8 unsigned long prot) 8 unsigned long prot)
9{ 9{
10 pmd_t *pmd = pmd_offset(pgd, addr); 10 pmd_t *pmd = pmd_offset(pud, addr);
11 11
12 addr = (addr & PMD_MASK) | prot; 12 addr = (addr & PMD_MASK) | prot;
13 pmd[0] = __pmd(addr); 13 pmd[0] = __pmd(addr);
@@ -16,6 +16,18 @@ static void idmap_add_pmd(pgd_t *pgd, unsigned long addr, unsigned long end,
16 flush_pmd_entry(pmd); 16 flush_pmd_entry(pmd);
17} 17}
18 18
19static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
20 unsigned long prot)
21{
22 pud_t *pud = pud_offset(pgd, addr);
23 unsigned long next;
24
25 do {
26 next = pud_addr_end(addr, end);
27 idmap_add_pmd(pud, addr, next, prot);
28 } while (pud++, addr = next, addr != end);
29}
30
19void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) 31void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
20{ 32{
21 unsigned long prot, next; 33 unsigned long prot, next;
@@ -27,17 +39,28 @@ void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
27 pgd += pgd_index(addr); 39 pgd += pgd_index(addr);
28 do { 40 do {
29 next = pgd_addr_end(addr, end); 41 next = pgd_addr_end(addr, end);
30 idmap_add_pmd(pgd, addr, next, prot); 42 idmap_add_pud(pgd, addr, next, prot);
31 } while (pgd++, addr = next, addr != end); 43 } while (pgd++, addr = next, addr != end);
32} 44}
33 45
34#ifdef CONFIG_SMP 46#ifdef CONFIG_SMP
35static void idmap_del_pmd(pgd_t *pgd, unsigned long addr, unsigned long end) 47static void idmap_del_pmd(pud_t *pud, unsigned long addr, unsigned long end)
36{ 48{
37 pmd_t *pmd = pmd_offset(pgd, addr); 49 pmd_t *pmd = pmd_offset(pud, addr);
38 pmd_clear(pmd); 50 pmd_clear(pmd);
39} 51}
40 52
53static void idmap_del_pud(pgd_t *pgd, unsigned long addr, unsigned long end)
54{
55 pud_t *pud = pud_offset(pgd, addr);
56 unsigned long next;
57
58 do {
59 next = pud_addr_end(addr, end);
60 idmap_del_pmd(pud, addr, next);
61 } while (pud++, addr = next, addr != end);
62}
63
41void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end) 64void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
42{ 65{
43 unsigned long next; 66 unsigned long next;
@@ -45,7 +68,7 @@ void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
45 pgd += pgd_index(addr); 68 pgd += pgd_index(addr);
46 do { 69 do {
47 next = pgd_addr_end(addr, end); 70 next = pgd_addr_end(addr, end);
48 idmap_del_pmd(pgd, addr, next); 71 idmap_del_pud(pgd, addr, next);
49 } while (pgd++, addr = next, addr != end); 72 } while (pgd++, addr = next, addr != end);
50} 73}
51#endif 74#endif
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index cddd684364d..b3b0f0f5053 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -350,7 +350,7 @@ void __init bootmem_init(void)
350 */ 350 */
351 arm_bootmem_free(min, max_low, max_high); 351 arm_bootmem_free(min, max_low, max_high);
352 352
353 high_memory = __va((max_low << PAGE_SHIFT) - 1) + 1; 353 high_memory = __va(((phys_addr_t)max_low << PAGE_SHIFT) - 1) + 1;
354 354
355 /* 355 /*
356 * This doesn't seem to be used by the Linux memory manager any 356 * 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)
398 * Convert to physical addresses, and 398 * Convert to physical addresses, and
399 * round start upwards and end downwards. 399 * round start upwards and end downwards.
400 */ 400 */
401 pg = PAGE_ALIGN(__pa(start_pg)); 401 pg = (unsigned long)PAGE_ALIGN(__pa(start_pg));
402 pgend = __pa(end_pg) & PAGE_MASK; 402 pgend = (unsigned long)__pa(end_pg) & PAGE_MASK;
403 403
404 /* 404 /*
405 * If there are free pages between these, 405 * If there are free pages between these,
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 36960df5fb7..d2384106af9 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -7,7 +7,7 @@ extern pmd_t *top_pmd;
7 7
8static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) 8static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
9{ 9{
10 return pmd_offset(pgd, virt); 10 return pmd_offset(pud_offset(pgd, virt), virt);
11} 11}
12 12
13static inline pmd_t *pmd_off_k(unsigned long virt) 13static inline pmd_t *pmd_off_k(unsigned long virt)
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index ff7b43b5885..6cf76b3b68d 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -533,7 +533,7 @@ static void __init *early_alloc(unsigned long sz)
533static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot) 533static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot)
534{ 534{
535 if (pmd_none(*pmd)) { 535 if (pmd_none(*pmd)) {
536 pte_t *pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t)); 536 pte_t *pte = early_alloc(PTE_HWTABLE_OFF + PTE_HWTABLE_SIZE);
537 __pmd_populate(pmd, __pa(pte), prot); 537 __pmd_populate(pmd, __pa(pte), prot);
538 } 538 }
539 BUG_ON(pmd_bad(*pmd)); 539 BUG_ON(pmd_bad(*pmd));
@@ -551,11 +551,11 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
551 } while (pte++, addr += PAGE_SIZE, addr != end); 551 } while (pte++, addr += PAGE_SIZE, addr != end);
552} 552}
553 553
554static void __init alloc_init_section(pgd_t *pgd, unsigned long addr, 554static void __init alloc_init_section(pud_t *pud, unsigned long addr,
555 unsigned long end, phys_addr_t phys, 555 unsigned long end, phys_addr_t phys,
556 const struct mem_type *type) 556 const struct mem_type *type)
557{ 557{
558 pmd_t *pmd = pmd_offset(pgd, addr); 558 pmd_t *pmd = pmd_offset(pud, addr);
559 559
560 /* 560 /*
561 * Try a section mapping - end, addr and phys must all be aligned 561 * 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,
584 } 584 }
585} 585}
586 586
587static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
588 unsigned long phys, const struct mem_type *type)
589{
590 pud_t *pud = pud_offset(pgd, addr);
591 unsigned long next;
592
593 do {
594 next = pud_addr_end(addr, end);
595 alloc_init_section(pud, addr, next, phys, type);
596 phys += next - addr;
597 } while (pud++, addr = next, addr != end);
598}
599
587static void __init create_36bit_mapping(struct map_desc *md, 600static void __init create_36bit_mapping(struct map_desc *md,
588 const struct mem_type *type) 601 const struct mem_type *type)
589{ 602{
@@ -592,13 +605,13 @@ static void __init create_36bit_mapping(struct map_desc *md,
592 pgd_t *pgd; 605 pgd_t *pgd;
593 606
594 addr = md->virtual; 607 addr = md->virtual;
595 phys = (unsigned long)__pfn_to_phys(md->pfn); 608 phys = __pfn_to_phys(md->pfn);
596 length = PAGE_ALIGN(md->length); 609 length = PAGE_ALIGN(md->length);
597 610
598 if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) { 611 if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) {
599 printk(KERN_ERR "MM: CPU does not support supersection " 612 printk(KERN_ERR "MM: CPU does not support supersection "
600 "mapping for 0x%08llx at 0x%08lx\n", 613 "mapping for 0x%08llx at 0x%08lx\n",
601 __pfn_to_phys((u64)md->pfn), addr); 614 (long long)__pfn_to_phys((u64)md->pfn), addr);
602 return; 615 return;
603 } 616 }
604 617
@@ -611,14 +624,14 @@ static void __init create_36bit_mapping(struct map_desc *md,
611 if (type->domain) { 624 if (type->domain) {
612 printk(KERN_ERR "MM: invalid domain in supersection " 625 printk(KERN_ERR "MM: invalid domain in supersection "
613 "mapping for 0x%08llx at 0x%08lx\n", 626 "mapping for 0x%08llx at 0x%08lx\n",
614 __pfn_to_phys((u64)md->pfn), addr); 627 (long long)__pfn_to_phys((u64)md->pfn), addr);
615 return; 628 return;
616 } 629 }
617 630
618 if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) { 631 if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) {
619 printk(KERN_ERR "MM: cannot create mapping for " 632 printk(KERN_ERR "MM: cannot create mapping for 0x%08llx"
620 "0x%08llx at 0x%08lx invalid alignment\n", 633 " at 0x%08lx invalid alignment\n",
621 __pfn_to_phys((u64)md->pfn), addr); 634 (long long)__pfn_to_phys((u64)md->pfn), addr);
622 return; 635 return;
623 } 636 }
624 637
@@ -631,7 +644,8 @@ static void __init create_36bit_mapping(struct map_desc *md,
631 pgd = pgd_offset_k(addr); 644 pgd = pgd_offset_k(addr);
632 end = addr + length; 645 end = addr + length;
633 do { 646 do {
634 pmd_t *pmd = pmd_offset(pgd, addr); 647 pud_t *pud = pud_offset(pgd, addr);
648 pmd_t *pmd = pmd_offset(pud, addr);
635 int i; 649 int i;
636 650
637 for (i = 0; i < 16; i++) 651 for (i = 0; i < 16; i++)
@@ -652,22 +666,23 @@ static void __init create_36bit_mapping(struct map_desc *md,
652 */ 666 */
653static void __init create_mapping(struct map_desc *md) 667static void __init create_mapping(struct map_desc *md)
654{ 668{
655 unsigned long phys, addr, length, end; 669 unsigned long addr, length, end;
670 phys_addr_t phys;
656 const struct mem_type *type; 671 const struct mem_type *type;
657 pgd_t *pgd; 672 pgd_t *pgd;
658 673
659 if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { 674 if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
660 printk(KERN_WARNING "BUG: not creating mapping for " 675 printk(KERN_WARNING "BUG: not creating mapping for 0x%08llx"
661 "0x%08llx at 0x%08lx in user region\n", 676 " at 0x%08lx in user region\n",
662 __pfn_to_phys((u64)md->pfn), md->virtual); 677 (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
663 return; 678 return;
664 } 679 }
665 680
666 if ((md->type == MT_DEVICE || md->type == MT_ROM) && 681 if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
667 md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { 682 md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
668 printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx " 683 printk(KERN_WARNING "BUG: mapping for 0x%08llx"
669 "overlaps vmalloc space\n", 684 " at 0x%08lx overlaps vmalloc space\n",
670 __pfn_to_phys((u64)md->pfn), md->virtual); 685 (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
671 } 686 }
672 687
673 type = &mem_types[md->type]; 688 type = &mem_types[md->type];
@@ -681,13 +696,13 @@ static void __init create_mapping(struct map_desc *md)
681 } 696 }
682 697
683 addr = md->virtual & PAGE_MASK; 698 addr = md->virtual & PAGE_MASK;
684 phys = (unsigned long)__pfn_to_phys(md->pfn); 699 phys = __pfn_to_phys(md->pfn);
685 length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK)); 700 length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
686 701
687 if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) { 702 if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) {
688 printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not " 703 printk(KERN_WARNING "BUG: map for 0x%08llx at 0x%08lx can not "
689 "be mapped using pages, ignoring.\n", 704 "be mapped using pages, ignoring.\n",
690 __pfn_to_phys(md->pfn), addr); 705 (long long)__pfn_to_phys(md->pfn), addr);
691 return; 706 return;
692 } 707 }
693 708
@@ -696,7 +711,7 @@ static void __init create_mapping(struct map_desc *md)
696 do { 711 do {
697 unsigned long next = pgd_addr_end(addr, end); 712 unsigned long next = pgd_addr_end(addr, end);
698 713
699 alloc_init_section(pgd, addr, next, phys, type); 714 alloc_init_pud(pgd, addr, next, phys, type);
700 715
701 phys += next - addr; 716 phys += next - addr;
702 addr = next; 717 addr = next;
@@ -794,9 +809,10 @@ static void __init sanity_check_meminfo(void)
794 */ 809 */
795 if (__va(bank->start) >= vmalloc_min || 810 if (__va(bank->start) >= vmalloc_min ||
796 __va(bank->start) < (void *)PAGE_OFFSET) { 811 __va(bank->start) < (void *)PAGE_OFFSET) {
797 printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx " 812 printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx "
798 "(vmalloc region overlap).\n", 813 "(vmalloc region overlap).\n",
799 bank->start, bank->start + bank->size - 1); 814 (unsigned long long)bank->start,
815 (unsigned long long)bank->start + bank->size - 1);
800 continue; 816 continue;
801 } 817 }
802 818
@@ -807,10 +823,11 @@ static void __init sanity_check_meminfo(void)
807 if (__va(bank->start + bank->size) > vmalloc_min || 823 if (__va(bank->start + bank->size) > vmalloc_min ||
808 __va(bank->start + bank->size) < __va(bank->start)) { 824 __va(bank->start + bank->size) < __va(bank->start)) {
809 unsigned long newsize = vmalloc_min - __va(bank->start); 825 unsigned long newsize = vmalloc_min - __va(bank->start);
810 printk(KERN_NOTICE "Truncating RAM at %.8lx-%.8lx " 826 printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
811 "to -%.8lx (vmalloc region overlap).\n", 827 "to -%.8llx (vmalloc region overlap).\n",
812 bank->start, bank->start + bank->size - 1, 828 (unsigned long long)bank->start,
813 bank->start + newsize - 1); 829 (unsigned long long)bank->start + bank->size - 1,
830 (unsigned long long)bank->start + newsize - 1);
814 bank->size = newsize; 831 bank->size = newsize;
815 } 832 }
816#endif 833#endif
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index 709244c66fa..b2027c154b2 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -23,6 +23,7 @@
23pgd_t *pgd_alloc(struct mm_struct *mm) 23pgd_t *pgd_alloc(struct mm_struct *mm)
24{ 24{
25 pgd_t *new_pgd, *init_pgd; 25 pgd_t *new_pgd, *init_pgd;
26 pud_t *new_pud, *init_pud;
26 pmd_t *new_pmd, *init_pmd; 27 pmd_t *new_pmd, *init_pmd;
27 pte_t *new_pte, *init_pte; 28 pte_t *new_pte, *init_pte;
28 29
@@ -46,7 +47,11 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
46 * On ARM, first page must always be allocated since it 47 * On ARM, first page must always be allocated since it
47 * contains the machine vectors. 48 * contains the machine vectors.
48 */ 49 */
49 new_pmd = pmd_alloc(mm, new_pgd, 0); 50 new_pud = pud_alloc(mm, new_pgd, 0);
51 if (!new_pud)
52 goto no_pud;
53
54 new_pmd = pmd_alloc(mm, new_pud, 0);
50 if (!new_pmd) 55 if (!new_pmd)
51 goto no_pmd; 56 goto no_pmd;
52 57
@@ -54,7 +59,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
54 if (!new_pte) 59 if (!new_pte)
55 goto no_pte; 60 goto no_pte;
56 61
57 init_pmd = pmd_offset(init_pgd, 0); 62 init_pud = pud_offset(init_pgd, 0);
63 init_pmd = pmd_offset(init_pud, 0);
58 init_pte = pte_offset_map(init_pmd, 0); 64 init_pte = pte_offset_map(init_pmd, 0);
59 set_pte_ext(new_pte, *init_pte, 0); 65 set_pte_ext(new_pte, *init_pte, 0);
60 pte_unmap(init_pte); 66 pte_unmap(init_pte);
@@ -66,6 +72,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
66no_pte: 72no_pte:
67 pmd_free(mm, new_pmd); 73 pmd_free(mm, new_pmd);
68no_pmd: 74no_pmd:
75 pud_free(mm, new_pud);
76no_pud:
69 free_pages((unsigned long)new_pgd, 2); 77 free_pages((unsigned long)new_pgd, 2);
70no_pgd: 78no_pgd:
71 return NULL; 79 return NULL;
@@ -74,6 +82,7 @@ no_pgd:
74void pgd_free(struct mm_struct *mm, pgd_t *pgd_base) 82void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
75{ 83{
76 pgd_t *pgd; 84 pgd_t *pgd;
85 pud_t *pud;
77 pmd_t *pmd; 86 pmd_t *pmd;
78 pgtable_t pte; 87 pgtable_t pte;
79 88
@@ -84,7 +93,11 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
84 if (pgd_none_or_clear_bad(pgd)) 93 if (pgd_none_or_clear_bad(pgd))
85 goto no_pgd; 94 goto no_pgd;
86 95
87 pmd = pmd_offset(pgd, 0); 96 pud = pud_offset(pgd, 0);
97 if (pud_none_or_clear_bad(pud))
98 goto no_pud;
99
100 pmd = pmd_offset(pud, 0);
88 if (pmd_none_or_clear_bad(pmd)) 101 if (pmd_none_or_clear_bad(pmd))
89 goto no_pmd; 102 goto no_pmd;
90 103
@@ -92,8 +105,11 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
92 pmd_clear(pmd); 105 pmd_clear(pmd);
93 pte_free(mm, pte); 106 pte_free(mm, pte);
94no_pmd: 107no_pmd:
95 pgd_clear(pgd); 108 pud_clear(pud);
96 pmd_free(mm, pmd); 109 pmd_free(mm, pmd);
110no_pud:
111 pgd_clear(pgd);
112 pud_free(mm, pud);
97no_pgd: 113no_pgd:
98 free_pages((unsigned long) pgd_base, 2); 114 free_pages((unsigned long) pgd_base, 2);
99} 115}
diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig
new file mode 100644
index 00000000000..52353beb369
--- /dev/null
+++ b/arch/arm/plat-versatile/Kconfig
@@ -0,0 +1,17 @@
1if PLAT_VERSATILE
2
3config PLAT_VERSATILE_CLCD
4 bool
5
6config PLAT_VERSATILE_FPGA_IRQ
7 bool
8
9config PLAT_VERSATILE_LEDS
10 def_bool y if LEDS_CLASS
11 depends on ARCH_REALVIEW || ARCH_VERSATILE
12
13config PLAT_VERSATILE_SCHED_CLOCK
14 def_bool y if !ARCH_INTEGRATOR_AP
15 select HAVE_SCHED_CLOCK
16
17endif
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile
index 16dde081993..69714db47c3 100644
--- a/arch/arm/plat-versatile/Makefile
+++ b/arch/arm/plat-versatile/Makefile
@@ -1,8 +1,7 @@
1obj-y := clock.o 1obj-y := clock.o
2ifneq ($(CONFIG_ARCH_INTEGRATOR),y) 2obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
3obj-y += sched-clock.o 3obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
4endif 4obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
5ifeq ($(CONFIG_LEDS_CLASS),y) 5obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
6obj-$(CONFIG_ARCH_REALVIEW) += leds.o 6obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o
7obj-$(CONFIG_ARCH_VERSATILE) += leds.o 7obj-$(CONFIG_SMP) += headsmp.o platsmp.o
8endif
diff --git a/arch/arm/plat-versatile/clcd.c b/arch/arm/plat-versatile/clcd.c
new file mode 100644
index 00000000000..6628cc27efc
--- /dev/null
+++ b/arch/arm/plat-versatile/clcd.c
@@ -0,0 +1,182 @@
1#include <linux/device.h>
2#include <linux/dma-mapping.h>
3#include <linux/amba/bus.h>
4#include <linux/amba/clcd.h>
5#include <plat/clcd.h>
6
7static struct clcd_panel vga = {
8 .mode = {
9 .name = "VGA",
10 .refresh = 60,
11 .xres = 640,
12 .yres = 480,
13 .pixclock = 39721,
14 .left_margin = 40,
15 .right_margin = 24,
16 .upper_margin = 32,
17 .lower_margin = 11,
18 .hsync_len = 96,
19 .vsync_len = 2,
20 .sync = 0,
21 .vmode = FB_VMODE_NONINTERLACED,
22 },
23 .width = -1,
24 .height = -1,
25 .tim2 = TIM2_BCD | TIM2_IPC,
26 .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
27 .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
28 .bpp = 16,
29};
30
31static struct clcd_panel xvga = {
32 .mode = {
33 .name = "XVGA",
34 .refresh = 60,
35 .xres = 1024,
36 .yres = 768,
37 .pixclock = 15748,
38 .left_margin = 152,
39 .right_margin = 48,
40 .upper_margin = 23,
41 .lower_margin = 3,
42 .hsync_len = 104,
43 .vsync_len = 4,
44 .sync = 0,
45 .vmode = FB_VMODE_NONINTERLACED,
46 },
47 .width = -1,
48 .height = -1,
49 .tim2 = TIM2_BCD | TIM2_IPC,
50 .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
51 .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
52 .bpp = 16,
53};
54
55/* Sanyo TM38QV67A02A - 3.8 inch QVGA (320x240) Color TFT */
56static struct clcd_panel sanyo_tm38qv67a02a = {
57 .mode = {
58 .name = "Sanyo TM38QV67A02A",
59 .refresh = 116,
60 .xres = 320,
61 .yres = 240,
62 .pixclock = 100000,
63 .left_margin = 6,
64 .right_margin = 6,
65 .upper_margin = 5,
66 .lower_margin = 5,
67 .hsync_len = 6,
68 .vsync_len = 6,
69 .sync = 0,
70 .vmode = FB_VMODE_NONINTERLACED,
71 },
72 .width = -1,
73 .height = -1,
74 .tim2 = TIM2_BCD,
75 .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
76 .caps = CLCD_CAP_5551,
77 .bpp = 16,
78};
79
80static struct clcd_panel sanyo_2_5_in = {
81 .mode = {
82 .name = "Sanyo QVGA Portrait",
83 .refresh = 116,
84 .xres = 240,
85 .yres = 320,
86 .pixclock = 100000,
87 .left_margin = 20,
88 .right_margin = 10,
89 .upper_margin = 2,
90 .lower_margin = 2,
91 .hsync_len = 10,
92 .vsync_len = 2,
93 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
94 .vmode = FB_VMODE_NONINTERLACED,
95 },
96 .width = -1,
97 .height = -1,
98 .tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC,
99 .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
100 .caps = CLCD_CAP_5551,
101 .bpp = 16,
102};
103
104/* Epson L2F50113T00 - 2.2 inch 176x220 Color TFT */
105static struct clcd_panel epson_l2f50113t00 = {
106 .mode = {
107 .name = "Epson L2F50113T00",
108 .refresh = 390,
109 .xres = 176,
110 .yres = 220,
111 .pixclock = 62500,
112 .left_margin = 3,
113 .right_margin = 2,
114 .upper_margin = 1,
115 .lower_margin = 0,
116 .hsync_len = 3,
117 .vsync_len = 2,
118 .sync = 0,
119 .vmode = FB_VMODE_NONINTERLACED,
120 },
121 .width = -1,
122 .height = -1,
123 .tim2 = TIM2_BCD | TIM2_IPC,
124 .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
125 .caps = CLCD_CAP_5551,
126 .bpp = 16,
127};
128
129static struct clcd_panel *panels[] = {
130 &vga,
131 &xvga,
132 &sanyo_tm38qv67a02a,
133 &sanyo_2_5_in,
134 &epson_l2f50113t00,
135};
136
137struct clcd_panel *versatile_clcd_get_panel(const char *name)
138{
139 int i;
140
141 for (i = 0; i < ARRAY_SIZE(panels); i++)
142 if (strcmp(panels[i]->mode.name, name) == 0)
143 break;
144
145 if (i < ARRAY_SIZE(panels))
146 return panels[i];
147
148 pr_err("CLCD: couldn't get parameters for panel %s\n", name);
149
150 return NULL;
151}
152
153int versatile_clcd_setup_dma(struct clcd_fb *fb, unsigned long framesize)
154{
155 dma_addr_t dma;
156
157 fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
158 &dma, GFP_KERNEL);
159 if (!fb->fb.screen_base) {
160 pr_err("CLCD: unable to map framebuffer\n");
161 return -ENOMEM;
162 }
163
164 fb->fb.fix.smem_start = dma;
165 fb->fb.fix.smem_len = framesize;
166
167 return 0;
168}
169
170int versatile_clcd_mmap_dma(struct clcd_fb *fb, struct vm_area_struct *vma)
171{
172 return dma_mmap_writecombine(&fb->dev->dev, vma,
173 fb->fb.screen_base,
174 fb->fb.fix.smem_start,
175 fb->fb.fix.smem_len);
176}
177
178void versatile_clcd_remove_dma(struct clcd_fb *fb)
179{
180 dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
181 fb->fb.screen_base, fb->fb.fix.smem_start);
182}
diff --git a/arch/arm/plat-versatile/fpga-irq.c b/arch/arm/plat-versatile/fpga-irq.c
new file mode 100644
index 00000000000..31d945d37e4
--- /dev/null
+++ b/arch/arm/plat-versatile/fpga-irq.c
@@ -0,0 +1,72 @@
1/*
2 * Support for Versatile FPGA-based IRQ controllers
3 */
4#include <linux/irq.h>
5#include <linux/io.h>
6
7#include <asm/mach/irq.h>
8#include <plat/fpga-irq.h>
9
10#define IRQ_STATUS 0x00
11#define IRQ_RAW_STATUS 0x04
12#define IRQ_ENABLE_SET 0x08
13#define IRQ_ENABLE_CLEAR 0x0c
14
15static void fpga_irq_mask(struct irq_data *d)
16{
17 struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
18 u32 mask = 1 << (d->irq - f->irq_start);
19
20 writel(mask, f->base + IRQ_ENABLE_CLEAR);
21}
22
23static void fpga_irq_unmask(struct irq_data *d)
24{
25 struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
26 u32 mask = 1 << (d->irq - f->irq_start);
27
28 writel(mask, f->base + IRQ_ENABLE_SET);
29}
30
31static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc)
32{
33 struct fpga_irq_data *f = get_irq_desc_data(desc);
34 u32 status = readl(f->base + IRQ_STATUS);
35
36 if (status == 0) {
37 do_bad_IRQ(irq, desc);
38 return;
39 }
40
41 do {
42 irq = ffs(status) - 1;
43 status &= ~(1 << irq);
44
45 generic_handle_irq(irq + f->irq_start);
46 } while (status);
47}
48
49void __init fpga_irq_init(int parent_irq, u32 valid, struct fpga_irq_data *f)
50{
51 unsigned int i;
52
53 f->chip.irq_ack = fpga_irq_mask;
54 f->chip.irq_mask = fpga_irq_mask;
55 f->chip.irq_unmask = fpga_irq_unmask;
56
57 if (parent_irq != -1) {
58 set_irq_data(parent_irq, f);
59 set_irq_chained_handler(parent_irq, fpga_irq_handle);
60 }
61
62 for (i = 0; i < 32; i++) {
63 if (valid & (1 << i)) {
64 unsigned int irq = f->irq_start + i;
65
66 set_irq_chip_data(irq, f);
67 set_irq_chip(irq, &f->chip);
68 set_irq_handler(irq, handle_level_irq);
69 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
70 }
71 }
72}
diff --git a/arch/arm/mach-vexpress/headsmp.S b/arch/arm/plat-versatile/headsmp.S
index 7a3f0632947..d397a1fb2f5 100644
--- a/arch/arm/mach-vexpress/headsmp.S
+++ b/arch/arm/plat-versatile/headsmp.S
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-vexpress/headsmp.S 2 * linux/arch/arm/plat-versatile/headsmp.S
3 * 3 *
4 * Copyright (c) 2003 ARM Limited 4 * Copyright (c) 2003 ARM Limited
5 * All Rights Reserved 5 * All Rights Reserved
@@ -14,11 +14,11 @@
14 __INIT 14 __INIT
15 15
16/* 16/*
17 * Versatile Express specific entry point for secondary CPUs. This 17 * Realview/Versatile Express specific entry point for secondary CPUs.
18 * provides a "holding pen" into which all secondary cores are held 18 * This provides a "holding pen" into which all secondary cores are held
19 * until we're ready for them to initialise. 19 * until we're ready for them to initialise.
20 */ 20 */
21ENTRY(vexpress_secondary_startup) 21ENTRY(versatile_secondary_startup)
22 mrc p15, 0, r0, c0, c0, 5 22 mrc p15, 0, r0, c0, c0, 5
23 and r0, r0, #15 23 and r0, r0, #15
24 adr r4, 1f 24 adr r4, 1f
diff --git a/arch/arm/plat-versatile/include/plat/clcd.h b/arch/arm/plat-versatile/include/plat/clcd.h
new file mode 100644
index 00000000000..6bb6a1d2019
--- /dev/null
+++ b/arch/arm/plat-versatile/include/plat/clcd.h
@@ -0,0 +1,9 @@
1#ifndef PLAT_CLCD_H
2#define PLAT_CLCD_H
3
4struct clcd_panel *versatile_clcd_get_panel(const char *);
5int versatile_clcd_setup_dma(struct clcd_fb *, unsigned long);
6int versatile_clcd_mmap_dma(struct clcd_fb *, struct vm_area_struct *);
7void versatile_clcd_remove_dma(struct clcd_fb *);
8
9#endif
diff --git a/arch/arm/plat-versatile/include/plat/fpga-irq.h b/arch/arm/plat-versatile/include/plat/fpga-irq.h
new file mode 100644
index 00000000000..627fafd1e59
--- /dev/null
+++ b/arch/arm/plat-versatile/include/plat/fpga-irq.h
@@ -0,0 +1,12 @@
1#ifndef PLAT_FPGA_IRQ_H
2#define PLAT_FPGA_IRQ_H
3
4struct fpga_irq_data {
5 void __iomem *base;
6 unsigned int irq_start;
7 struct irq_chip chip;
8};
9
10void fpga_irq_init(int, u32, struct fpga_irq_data *);
11
12#endif
diff --git a/arch/arm/mach-vexpress/localtimer.c b/arch/arm/plat-versatile/localtimer.c
index c0e3a59a0bf..0fb3961999b 100644
--- a/arch/arm/mach-vexpress/localtimer.c
+++ b/arch/arm/plat-versatile/localtimer.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-vexpress/localtimer.c 2 * linux/arch/arm/plat-versatile/localtimer.c
3 * 3 *
4 * Copyright (C) 2002 ARM Ltd. 4 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved 5 * All Rights Reserved
@@ -19,8 +19,9 @@
19/* 19/*
20 * Setup the local clock events for a CPU. 20 * Setup the local clock events for a CPU.
21 */ 21 */
22void __cpuinit local_timer_setup(struct clock_event_device *evt) 22int __cpuinit local_timer_setup(struct clock_event_device *evt)
23{ 23{
24 evt->irq = IRQ_LOCALTIMER; 24 evt->irq = IRQ_LOCALTIMER;
25 twd_timer_setup(evt); 25 twd_timer_setup(evt);
26 return 0;
26} 27}
diff --git a/arch/arm/plat-versatile/platsmp.c b/arch/arm/plat-versatile/platsmp.c
new file mode 100644
index 00000000000..ba3d471d4bc
--- /dev/null
+++ b/arch/arm/plat-versatile/platsmp.c
@@ -0,0 +1,104 @@
1/*
2 * linux/arch/arm/plat-versatile/platsmp.c
3 *
4 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/init.h>
12#include <linux/errno.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/jiffies.h>
16#include <linux/smp.h>
17
18#include <asm/cacheflush.h>
19
20/*
21 * control for which core is the next to come out of the secondary
22 * boot "holding pen"
23 */
24volatile int __cpuinitdata pen_release = -1;
25
26/*
27 * Write pen_release in a way that is guaranteed to be visible to all
28 * observers, irrespective of whether they're taking part in coherency
29 * or not. This is necessary for the hotplug code to work reliably.
30 */
31static void __cpuinit write_pen_release(int val)
32{
33 pen_release = val;
34 smp_wmb();
35 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
36 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
37}
38
39static DEFINE_SPINLOCK(boot_lock);
40
41void __cpuinit platform_secondary_init(unsigned int cpu)
42{
43 /*
44 * if any interrupts are already enabled for the primary
45 * core (e.g. timer irq), then they will not have been enabled
46 * for us: do so
47 */
48 gic_secondary_init(0);
49
50 /*
51 * let the primary processor know we're out of the
52 * pen, then head off into the C entry point
53 */
54 write_pen_release(-1);
55
56 /*
57 * Synchronise with the boot thread.
58 */
59 spin_lock(&boot_lock);
60 spin_unlock(&boot_lock);
61}
62
63int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
64{
65 unsigned long timeout;
66
67 /*
68 * Set synchronisation state between this boot processor
69 * and the secondary one
70 */
71 spin_lock(&boot_lock);
72
73 /*
74 * This is really belt and braces; we hold unintended secondary
75 * CPUs in the holding pen until we're ready for them. However,
76 * since we haven't sent them a soft interrupt, they shouldn't
77 * be there.
78 */
79 write_pen_release(cpu);
80
81 /*
82 * Send the secondary CPU a soft interrupt, thereby causing
83 * the boot monitor to read the system wide flags register,
84 * and branch to the address found there.
85 */
86 smp_cross_call(cpumask_of(cpu), 1);
87
88 timeout = jiffies + (1 * HZ);
89 while (time_before(jiffies, timeout)) {
90 smp_rmb();
91 if (pen_release == -1)
92 break;
93
94 udelay(10);
95 }
96
97 /*
98 * now the secondary core is starting up let it run its
99 * calibrations, then wait for it to finish
100 */
101 spin_unlock(&boot_lock);
102
103 return pen_release != -1 ? -ENOSYS : 0;
104}