aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/Makefile5
-rw-r--r--arch/arm/kernel/head-nommu.S2
-rw-r--r--arch/arm/kernel/head.S2
-rw-r--r--arch/arm/kernel/init_task.c2
-rw-r--r--arch/arm/kernel/module.c4
-rw-r--r--arch/arm/kernel/smp.c4
-rw-r--r--arch/arm/kernel/vmlinux.lds.S12
-rw-r--r--arch/arm/mach-omap1/Kconfig5
-rw-r--r--arch/arm/mach-omap1/Makefile1
-rw-r--r--arch/arm/mach-omap1/board-fsample.c2
-rw-r--r--arch/arm/mach-omap1/board-h3.c2
-rw-r--r--arch/arm/mach-omap1/board-innovator.c2
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c2
-rw-r--r--arch/arm/mach-omap1/devices.c71
-rw-r--r--arch/arm/mach-omap1/io.c4
-rw-r--r--arch/arm/mach-omap1/mailbox.c206
-rw-r--r--arch/arm/mach-omap2/Kconfig2
-rw-r--r--arch/arm/mach-omap2/board-h4.c14
-rw-r--r--arch/arm/mach-omap2/devices.c66
-rw-r--r--arch/arm/mach-omap2/gpmc.c12
-rw-r--r--arch/arm/mach-omap2/io.c21
-rw-r--r--arch/arm/mach-omap2/mailbox.c318
-rw-r--r--arch/arm/mm/Kconfig32
-rw-r--r--arch/arm/mm/Makefile3
-rw-r--r--arch/arm/mm/abort-ev7.S32
-rw-r--r--arch/arm/mm/cache-v7.S253
-rw-r--r--arch/arm/mm/context.c17
-rw-r--r--arch/arm/mm/proc-macros.S12
-rw-r--r--arch/arm/mm/proc-v7.S262
-rw-r--r--arch/arm/plat-omap/Kconfig13
-rw-r--r--arch/arm/plat-omap/Makefile5
-rw-r--r--arch/arm/plat-omap/clock.c37
-rw-r--r--arch/arm/plat-omap/common.c8
-rw-r--r--arch/arm/plat-omap/debug-leds.c314
-rw-r--r--arch/arm/plat-omap/devices.c74
-rw-r--r--arch/arm/plat-omap/dma.c25
-rw-r--r--arch/arm/plat-omap/dmtimer.c2
-rw-r--r--arch/arm/plat-omap/fb.c305
-rw-r--r--arch/arm/plat-omap/gpio.c3
-rw-r--r--arch/arm/plat-omap/mailbox.c509
-rw-r--r--arch/arm/plat-omap/mailbox.h100
-rw-r--r--arch/arm/plat-omap/sram.c56
-rw-r--r--arch/arm/plat-omap/usb.c199
44 files changed, 2835 insertions, 186 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0d8fac3b0371..d7c0984d4a86 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -354,6 +354,7 @@ config ARCH_SA1100
354config ARCH_S3C2410 354config ARCH_S3C2410
355 bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443" 355 bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
356 select GENERIC_GPIO 356 select GENERIC_GPIO
357 select GENERIC_TIME
357 help 358 help
358 Samsung S3C2410X CPU based systems, such as the Simtec Electronics 359 Samsung S3C2410X CPU based systems, such as the Simtec Electronics
359 BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or 360 BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index ab9f2d4bd04e..00ea4305ad5d 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -47,8 +47,13 @@ comma = ,
47# Note that GCC does not numerically define an architecture version 47# Note that GCC does not numerically define an architecture version
48# macro, but instead defines a whole series of macros which makes 48# macro, but instead defines a whole series of macros which makes
49# testing for a specific architecture or later rather impossible. 49# testing for a specific architecture or later rather impossible.
50arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7a,-march=armv5t -Wa$(comma)-march=armv7a)
50arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) 51arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
52# Only override the compiler option if ARMv6. The ARMv6K extensions are
53# always available in ARMv7
54ifeq ($(CONFIG_CPU_32v6),y)
51arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k) 55arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k)
56endif
52arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t) 57arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t)
53arch-$(CONFIG_CPU_32v4T) :=-D__LINUX_ARM_ARCH__=4 -march=armv4t 58arch-$(CONFIG_CPU_32v4T) :=-D__LINUX_ARM_ARCH__=4 -march=armv4t
54arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4 59arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index 0119c0d5f978..5d78ffb8a9a7 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -33,7 +33,7 @@
33 * numbers for r1. 33 * numbers for r1.
34 * 34 *
35 */ 35 */
36 __INIT 36 .section ".text.head", "ax"
37 .type stext, %function 37 .type stext, %function
38ENTRY(stext) 38ENTRY(stext)
39 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode 39 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 1d35edacc011..41f98b4ba2ee 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -73,7 +73,7 @@
73 * crap here - that's what the boot loader (or in extreme, well justified 73 * crap here - that's what the boot loader (or in extreme, well justified
74 * circumstances, zImage) is for. 74 * circumstances, zImage) is for.
75 */ 75 */
76 __INIT 76 .section ".text.head", "ax"
77 .type stext, %function 77 .type stext, %function
78ENTRY(stext) 78ENTRY(stext)
79 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode 79 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
diff --git a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c
index a00cca0000bd..bd4ef53bc6b9 100644
--- a/arch/arm/kernel/init_task.c
+++ b/arch/arm/kernel/init_task.c
@@ -31,7 +31,7 @@ EXPORT_SYMBOL(init_mm);
31 * The things we do for performance.. 31 * The things we do for performance..
32 */ 32 */
33union thread_union init_thread_union 33union thread_union init_thread_union
34 __attribute__((__section__(".init.task"))) = 34 __attribute__((__section__(".data.init_task"))) =
35 { INIT_THREAD_INFO(init_task) }; 35 { INIT_THREAD_INFO(init_task) };
36 36
37/* 37/*
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 1b061583408e..79b7e5cf5416 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -116,8 +116,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
116 116
117 offset += sym->st_value - loc; 117 offset += sym->st_value - loc;
118 if (offset & 3 || 118 if (offset & 3 ||
119 offset <= (s32)0xfc000000 || 119 offset <= (s32)0xfe000000 ||
120 offset >= (s32)0x04000000) { 120 offset >= (s32)0x02000000) {
121 printk(KERN_ERR 121 printk(KERN_ERR
122 "%s: relocation out of range, section " 122 "%s: relocation out of range, section "
123 "%d reloc %d sym '%s'\n", module->name, 123 "%d reloc %d sym '%s'\n", module->name,
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 070bcb7a6306..1b76d87fa335 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -486,7 +486,7 @@ static void ipi_timer(void)
486} 486}
487 487
488#ifdef CONFIG_LOCAL_TIMERS 488#ifdef CONFIG_LOCAL_TIMERS
489asmlinkage void do_local_timer(struct pt_regs *regs) 489asmlinkage void __exception do_local_timer(struct pt_regs *regs)
490{ 490{
491 struct pt_regs *old_regs = set_irq_regs(regs); 491 struct pt_regs *old_regs = set_irq_regs(regs);
492 int cpu = smp_processor_id(); 492 int cpu = smp_processor_id();
@@ -551,7 +551,7 @@ static void ipi_cpu_stop(unsigned int cpu)
551 * 551 *
552 * Bit 0 - Inter-processor function call 552 * Bit 0 - Inter-processor function call
553 */ 553 */
554asmlinkage void do_IPI(struct pt_regs *regs) 554asmlinkage void __exception do_IPI(struct pt_regs *regs)
555{ 555{
556 unsigned int cpu = smp_processor_id(); 556 unsigned int cpu = smp_processor_id();
557 struct ipi_data *ipi = &per_cpu(ipi_data, cpu); 557 struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 6be67296f333..e4156e7868ce 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -23,11 +23,15 @@ SECTIONS
23#else 23#else
24 . = PAGE_OFFSET + TEXT_OFFSET; 24 . = PAGE_OFFSET + TEXT_OFFSET;
25#endif 25#endif
26 .init : { /* Init code and data */ 26 .text.head : {
27 _stext = .; 27 _stext = .;
28 _sinittext = .; 28 _sinittext = .;
29 *(.text.head)
30 }
31
32 .init : { /* Init code and data */
29 *(.init.text) 33 *(.init.text)
30 _einittext = .; 34 _einittext = .;
31 __proc_info_begin = .; 35 __proc_info_begin = .;
32 *(.proc.info.init) 36 *(.proc.info.init)
33 __proc_info_end = .; 37 __proc_info_end = .;
@@ -119,7 +123,7 @@ SECTIONS
119 * first, the init task union, aligned 123 * first, the init task union, aligned
120 * to an 8192 byte boundary. 124 * to an 8192 byte boundary.
121 */ 125 */
122 *(.init.task) 126 *(.data.init_task)
123 127
124#ifdef CONFIG_XIP_KERNEL 128#ifdef CONFIG_XIP_KERNEL
125 . = ALIGN(4096); 129 . = ALIGN(4096);
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index c7e229b00f6e..856c681ebbbc 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -22,6 +22,7 @@ comment "OMAP Board Type"
22config MACH_OMAP_INNOVATOR 22config MACH_OMAP_INNOVATOR
23 bool "TI Innovator" 23 bool "TI Innovator"
24 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX) 24 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
25 select OMAP_MCBSP
25 help 26 help
26 TI OMAP 1510 or 1610 Innovator board support. Say Y here if you 27 TI OMAP 1510 or 1610 Innovator board support. Say Y here if you
27 have such a board. 28 have such a board.
@@ -29,6 +30,7 @@ config MACH_OMAP_INNOVATOR
29config MACH_OMAP_H2 30config MACH_OMAP_H2
30 bool "TI H2 Support" 31 bool "TI H2 Support"
31 depends on ARCH_OMAP1 && ARCH_OMAP16XX 32 depends on ARCH_OMAP1 && ARCH_OMAP16XX
33 select OMAP_MCBSP
32 help 34 help
33 TI OMAP 1610/1611B H2 board support. Say Y here if you have such 35 TI OMAP 1610/1611B H2 board support. Say Y here if you have such
34 a board. 36 a board.
@@ -36,6 +38,7 @@ config MACH_OMAP_H2
36config MACH_OMAP_H3 38config MACH_OMAP_H3
37 bool "TI H3 Support" 39 bool "TI H3 Support"
38 depends on ARCH_OMAP1 && ARCH_OMAP16XX 40 depends on ARCH_OMAP1 && ARCH_OMAP16XX
41 select GPIOEXPANDER_OMAP
39 help 42 help
40 TI OMAP 1710 H3 board support. Say Y here if you have such 43 TI OMAP 1710 H3 board support. Say Y here if you have such
41 a board. 44 a board.
@@ -43,7 +46,7 @@ config MACH_OMAP_H3
43config MACH_OMAP_OSK 46config MACH_OMAP_OSK
44 bool "TI OSK Support" 47 bool "TI OSK Support"
45 depends on ARCH_OMAP1 && ARCH_OMAP16XX 48 depends on ARCH_OMAP1 && ARCH_OMAP16XX
46 select TPS65010 49 select OMAP_MCBSP
47 help 50 help
48 TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here 51 TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here
49 if you have such a board. 52 if you have such a board.
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index 7165f74f78da..a8b9a00cea22 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -37,4 +37,3 @@ led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o
37led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o 37led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o
38led-$(CONFIG_MACH_OMAP_OSK) += leds-osk.o 38led-$(CONFIG_MACH_OMAP_OSK) += leds-osk.o
39obj-$(CONFIG_LEDS) += $(led-y) 39obj-$(CONFIG_LEDS) += $(led-y)
40
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index 62e42c7a628e..f65baa95986e 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -246,7 +246,7 @@ static void __init fsample_init_smc91x(void)
246 mdelay(50); 246 mdelay(50);
247} 247}
248 248
249void omap_fsample_init_irq(void) 249static void __init omap_fsample_init_irq(void)
250{ 250{
251 omap1_init_common_hw(); 251 omap1_init_common_hw();
252 omap_init_irq(); 252 omap_init_irq();
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 9d2346fb68f4..7b260b7c537b 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -455,7 +455,7 @@ static void __init h3_init_smc91x(void)
455 } 455 }
456} 456}
457 457
458void h3_init_irq(void) 458static void __init h3_init_irq(void)
459{ 459{
460 omap1_init_common_hw(); 460 omap1_init_common_hw();
461 omap_init_irq(); 461 omap_init_irq();
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index cb00530ad279..7e63a41e37c6 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -308,7 +308,7 @@ static void __init innovator_init_smc91x(void)
308 } 308 }
309} 309}
310 310
311void innovator_init_irq(void) 311static void __init innovator_init_irq(void)
312{ 312{
313 omap1_init_common_hw(); 313 omap1_init_common_hw();
314 omap_init_irq(); 314 omap_init_irq();
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index fa4be962df67..1d5c8d509722 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -246,7 +246,7 @@ static void __init perseus2_init_smc91x(void)
246 mdelay(50); 246 mdelay(50);
247} 247}
248 248
249void omap_perseus2_init_irq(void) 249static void __init omap_perseus2_init_irq(void)
250{ 250{
251 omap1_init_common_hw(); 251 omap1_init_common_hw();
252 omap_init_irq(); 252 omap_init_irq();
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 6dcd10ab4496..da8a3ac47e13 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -24,35 +24,6 @@
24#include <asm/arch/mux.h> 24#include <asm/arch/mux.h>
25#include <asm/arch/gpio.h> 25#include <asm/arch/gpio.h>
26 26
27#if defined(CONFIG_OMAP1610_IR) || defined(CONFIG_OMAP161O_IR_MODULE)
28
29static u64 irda_dmamask = 0xffffffff;
30
31static struct platform_device omap1610ir_device = {
32 .name = "omap1610-ir",
33 .id = -1,
34 .dev = {
35 .dma_mask = &irda_dmamask,
36 },
37};
38
39static void omap_init_irda(void)
40{
41 /* FIXME define and use a boot tag, members something like:
42 * u8 uart; // uart1, or uart3
43 * ... but driver only handles uart3 for now
44 * s16 fir_sel; // gpio for SIR vs FIR
45 * ... may prefer a callback for SIR/MIR/FIR mode select;
46 * while h2 uses a GPIO, H3 uses a gpio expander
47 */
48 if (machine_is_omap_h2()
49 || machine_is_omap_h3())
50 (void) platform_device_register(&omap1610ir_device);
51}
52#else
53static inline void omap_init_irda(void) {}
54#endif
55
56/*-------------------------------------------------------------------------*/ 27/*-------------------------------------------------------------------------*/
57 28
58#if defined(CONFIG_RTC_DRV_OMAP) || defined(CONFIG_RTC_DRV_OMAP_MODULE) 29#if defined(CONFIG_RTC_DRV_OMAP) || defined(CONFIG_RTC_DRV_OMAP_MODULE)
@@ -90,6 +61,45 @@ static void omap_init_rtc(void)
90static inline void omap_init_rtc(void) {} 61static inline void omap_init_rtc(void) {}
91#endif 62#endif
92 63
64#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
65
66#if defined(CONFIG_ARCH_OMAP15XX)
67# define OMAP1_MBOX_SIZE 0x23
68# define INT_DSP_MAILBOX1 INT_1510_DSP_MAILBOX1
69#elif defined(CONFIG_ARCH_OMAP16XX)
70# define OMAP1_MBOX_SIZE 0x2f
71# define INT_DSP_MAILBOX1 INT_1610_DSP_MAILBOX1
72#endif
73
74#define OMAP1_MBOX_BASE IO_ADDRESS(OMAP16XX_MAILBOX_BASE)
75
76static struct resource mbox_resources[] = {
77 {
78 .start = OMAP1_MBOX_BASE,
79 .end = OMAP1_MBOX_BASE + OMAP1_MBOX_SIZE,
80 .flags = IORESOURCE_MEM,
81 },
82 {
83 .start = INT_DSP_MAILBOX1,
84 .flags = IORESOURCE_IRQ,
85 },
86};
87
88static struct platform_device mbox_device = {
89 .name = "mailbox",
90 .id = -1,
91 .num_resources = ARRAY_SIZE(mbox_resources),
92 .resource = mbox_resources,
93};
94
95static inline void omap_init_mbox(void)
96{
97 platform_device_register(&mbox_device);
98}
99#else
100static inline void omap_init_mbox(void) { }
101#endif
102
93#if defined(CONFIG_OMAP_STI) 103#if defined(CONFIG_OMAP_STI)
94 104
95#define OMAP1_STI_BASE IO_ADDRESS(0xfffea000) 105#define OMAP1_STI_BASE IO_ADDRESS(0xfffea000)
@@ -154,7 +164,8 @@ static int __init omap1_init_devices(void)
154 /* please keep these calls, and their implementations above, 164 /* please keep these calls, and their implementations above,
155 * in alphabetical order so they're easier to sort through. 165 * in alphabetical order so they're easier to sort through.
156 */ 166 */
157 omap_init_irda(); 167
168 omap_init_mbox();
158 omap_init_rtc(); 169 omap_init_rtc();
159 omap_init_sti(); 170 omap_init_sti();
160 171
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index fab8b0b27cfb..81c4e738506c 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -17,11 +17,11 @@
17#include <asm/io.h> 17#include <asm/io.h>
18#include <asm/arch/mux.h> 18#include <asm/arch/mux.h>
19#include <asm/arch/tc.h> 19#include <asm/arch/tc.h>
20#include <asm/arch/omapfb.h>
21 20
22extern int omap1_clk_init(void); 21extern int omap1_clk_init(void);
23extern void omap_check_revision(void); 22extern void omap_check_revision(void);
24extern void omap_sram_init(void); 23extern void omap_sram_init(void);
24extern void omapfb_reserve_sdram(void);
25 25
26/* 26/*
27 * The machine specific code may provide the extra mapping besides the 27 * The machine specific code may provide the extra mapping besides the
@@ -121,7 +121,7 @@ void __init omap1_map_common_io(void)
121#endif 121#endif
122 122
123 omap_sram_init(); 123 omap_sram_init();
124 omapfb_reserve_mem(); 124 omapfb_reserve_sdram();
125} 125}
126 126
127/* 127/*
diff --git a/arch/arm/mach-omap1/mailbox.c b/arch/arm/mach-omap1/mailbox.c
new file mode 100644
index 000000000000..d3abf5609902
--- /dev/null
+++ b/arch/arm/mach-omap1/mailbox.c
@@ -0,0 +1,206 @@
1/*
2 * Mailbox reservation modules for DSP
3 *
4 * Copyright (C) 2006 Nokia Corporation
5 * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11
12#include <linux/kernel.h>
13#include <linux/resource.h>
14#include <linux/interrupt.h>
15#include <linux/platform_device.h>
16#include <asm/arch/mailbox.h>
17#include <asm/arch/irqs.h>
18#include <asm/io.h>
19
20#define MAILBOX_ARM2DSP1 0x00
21#define MAILBOX_ARM2DSP1b 0x04
22#define MAILBOX_DSP2ARM1 0x08
23#define MAILBOX_DSP2ARM1b 0x0c
24#define MAILBOX_DSP2ARM2 0x10
25#define MAILBOX_DSP2ARM2b 0x14
26#define MAILBOX_ARM2DSP1_Flag 0x18
27#define MAILBOX_DSP2ARM1_Flag 0x1c
28#define MAILBOX_DSP2ARM2_Flag 0x20
29
30unsigned long mbox_base;
31
32struct omap_mbox1_fifo {
33 unsigned long cmd;
34 unsigned long data;
35 unsigned long flag;
36};
37
38struct omap_mbox1_priv {
39 struct omap_mbox1_fifo tx_fifo;
40 struct omap_mbox1_fifo rx_fifo;
41};
42
43static inline int mbox_read_reg(unsigned int reg)
44{
45 return __raw_readw(mbox_base + reg);
46}
47
48static inline void mbox_write_reg(unsigned int val, unsigned int reg)
49{
50 __raw_writew(val, mbox_base + reg);
51}
52
53/* msg */
54static inline mbox_msg_t omap1_mbox_fifo_read(struct omap_mbox *mbox)
55{
56 struct omap_mbox1_fifo *fifo =
57 &((struct omap_mbox1_priv *)mbox->priv)->rx_fifo;
58 mbox_msg_t msg;
59
60 msg = mbox_read_reg(fifo->data);
61 msg |= ((mbox_msg_t) mbox_read_reg(fifo->cmd)) << 16;
62
63 return msg;
64}
65
66static inline void
67omap1_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
68{
69 struct omap_mbox1_fifo *fifo =
70 &((struct omap_mbox1_priv *)mbox->priv)->tx_fifo;
71
72 mbox_write_reg(msg & 0xffff, fifo->data);
73 mbox_write_reg(msg >> 16, fifo->cmd);
74}
75
76static inline int omap1_mbox_fifo_empty(struct omap_mbox *mbox)
77{
78 return 0;
79}
80
81static inline int omap1_mbox_fifo_full(struct omap_mbox *mbox)
82{
83 struct omap_mbox1_fifo *fifo =
84 &((struct omap_mbox1_priv *)mbox->priv)->rx_fifo;
85
86 return (mbox_read_reg(fifo->flag));
87}
88
89/* irq */
90static inline void
91omap1_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
92{
93 if (irq == IRQ_RX)
94 enable_irq(mbox->irq);
95}
96
97static inline void
98omap1_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
99{
100 if (irq == IRQ_RX)
101 disable_irq(mbox->irq);
102}
103
104static inline int
105omap1_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
106{
107 if (irq == IRQ_TX)
108 return 0;
109 return 1;
110}
111
112static struct omap_mbox_ops omap1_mbox_ops = {
113 .type = OMAP_MBOX_TYPE1,
114 .fifo_read = omap1_mbox_fifo_read,
115 .fifo_write = omap1_mbox_fifo_write,
116 .fifo_empty = omap1_mbox_fifo_empty,
117 .fifo_full = omap1_mbox_fifo_full,
118 .enable_irq = omap1_mbox_enable_irq,
119 .disable_irq = omap1_mbox_disable_irq,
120 .is_irq = omap1_mbox_is_irq,
121};
122
123/* FIXME: the following struct should be created automatically by the user id */
124
125/* DSP */
126static struct omap_mbox1_priv omap1_mbox_dsp_priv = {
127 .tx_fifo = {
128 .cmd = MAILBOX_ARM2DSP1b,
129 .data = MAILBOX_ARM2DSP1,
130 .flag = MAILBOX_ARM2DSP1_Flag,
131 },
132 .rx_fifo = {
133 .cmd = MAILBOX_DSP2ARM1b,
134 .data = MAILBOX_DSP2ARM1,
135 .flag = MAILBOX_DSP2ARM1_Flag,
136 },
137};
138
139struct omap_mbox mbox_dsp_info = {
140 .name = "dsp",
141 .ops = &omap1_mbox_ops,
142 .priv = &omap1_mbox_dsp_priv,
143};
144EXPORT_SYMBOL(mbox_dsp_info);
145
146static int __init omap1_mbox_probe(struct platform_device *pdev)
147{
148 struct resource *res;
149 int ret = 0;
150
151 if (pdev->num_resources != 2) {
152 dev_err(&pdev->dev, "invalid number of resources: %d\n",
153 pdev->num_resources);
154 return -ENODEV;
155 }
156
157 /* MBOX base */
158 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
159 if (unlikely(!res)) {
160 dev_err(&pdev->dev, "invalid mem resource\n");
161 return -ENODEV;
162 }
163 mbox_base = res->start;
164
165 /* DSP IRQ */
166 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
167 if (unlikely(!res)) {
168 dev_err(&pdev->dev, "invalid irq resource\n");
169 return -ENODEV;
170 }
171 mbox_dsp_info.irq = res->start;
172
173 ret = omap_mbox_register(&mbox_dsp_info);
174
175 return ret;
176}
177
178static int omap1_mbox_remove(struct platform_device *pdev)
179{
180 omap_mbox_unregister(&mbox_dsp_info);
181
182 return 0;
183}
184
185static struct platform_driver omap1_mbox_driver = {
186 .probe = omap1_mbox_probe,
187 .remove = omap1_mbox_remove,
188 .driver = {
189 .name = "mailbox",
190 },
191};
192
193static int __init omap1_mbox_init(void)
194{
195 return platform_driver_register(&omap1_mbox_driver);
196}
197
198static void __exit omap1_mbox_exit(void)
199{
200 platform_driver_unregister(&omap1_mbox_driver);
201}
202
203module_init(omap1_mbox_init);
204module_exit(omap1_mbox_exit);
205
206MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index aab97ccf1e63..7393109f5c30 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -9,6 +9,7 @@ config ARCH_OMAP2420
9 bool "OMAP2420 support" 9 bool "OMAP2420 support"
10 depends on ARCH_OMAP24XX 10 depends on ARCH_OMAP24XX
11 select OMAP_DM_TIMER 11 select OMAP_DM_TIMER
12 select ARCH_OMAP_OTG
12 13
13comment "OMAP Board Type" 14comment "OMAP Board Type"
14 depends on ARCH_OMAP2 15 depends on ARCH_OMAP2
@@ -20,6 +21,7 @@ config MACH_OMAP_GENERIC
20config MACH_OMAP_H4 21config MACH_OMAP_H4
21 bool "OMAP 2420 H4 board" 22 bool "OMAP 2420 H4 board"
22 depends on ARCH_OMAP2 && ARCH_OMAP24XX 23 depends on ARCH_OMAP2 && ARCH_OMAP24XX
24 select OMAP_DEBUG_LEDS if LEDS || LEDS_OMAP_DEBUG
23 25
24config MACH_OMAP_APOLLON 26config MACH_OMAP_APOLLON
25 bool "OMAP 2420 Apollon board" 27 bool "OMAP 2420 Apollon board"
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 1e7ed6d22ca9..452193f01531 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -266,12 +266,26 @@ static struct platform_device h4_lcd_device = {
266 .id = -1, 266 .id = -1,
267}; 267};
268 268
269static struct resource h4_led_resources[] = {
270 [0] = {
271 .flags = IORESOURCE_MEM,
272 },
273};
274
275static struct platform_device h4_led_device = {
276 .name = "omap_dbg_led",
277 .id = -1,
278 .num_resources = ARRAY_SIZE(h4_led_resources),
279 .resource = h4_led_resources,
280};
281
269static struct platform_device *h4_devices[] __initdata = { 282static struct platform_device *h4_devices[] __initdata = {
270 &h4_smc91x_device, 283 &h4_smc91x_device,
271 &h4_flash_device, 284 &h4_flash_device,
272 &h4_irda_device, 285 &h4_irda_device,
273 &h4_kp_device, 286 &h4_kp_device,
274 &h4_lcd_device, 287 &h4_lcd_device,
288 &h4_led_device,
275}; 289};
276 290
277static inline void __init h4_init_smc91x(void) 291static inline void __init h4_init_smc91x(void)
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index aa4322451e8b..52ec2f2d6360 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -24,7 +24,7 @@
24#include <asm/arch/mux.h> 24#include <asm/arch/mux.h>
25#include <asm/arch/gpio.h> 25#include <asm/arch/gpio.h>
26 26
27#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) 27#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
28 28
29#define OMAP2_I2C_BASE2 0x48072000 29#define OMAP2_I2C_BASE2 0x48072000
30#define OMAP2_I2C_INT2 57 30#define OMAP2_I2C_INT2 57
@@ -42,8 +42,8 @@ static struct resource i2c_resources2[] = {
42}; 42};
43 43
44static struct platform_device omap_i2c_device2 = { 44static struct platform_device omap_i2c_device2 = {
45 .name = "i2c_omap", 45 .name = "i2c_omap",
46 .id = 2, 46 .id = 2,
47 .num_resources = ARRAY_SIZE(i2c_resources2), 47 .num_resources = ARRAY_SIZE(i2c_resources2),
48 .resource = i2c_resources2, 48 .resource = i2c_resources2,
49}; 49};
@@ -66,6 +66,40 @@ static void omap_init_i2c(void) {}
66 66
67#endif 67#endif
68 68
69#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
70#define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE)
71
72static struct resource mbox_resources[] = {
73 {
74 .start = OMAP2_MBOX_BASE,
75 .end = OMAP2_MBOX_BASE + 0x11f,
76 .flags = IORESOURCE_MEM,
77 },
78 {
79 .start = INT_24XX_MAIL_U0_MPU,
80 .flags = IORESOURCE_IRQ,
81 },
82 {
83 .start = INT_24XX_MAIL_U3_MPU,
84 .flags = IORESOURCE_IRQ,
85 },
86};
87
88static struct platform_device mbox_device = {
89 .name = "mailbox",
90 .id = -1,
91 .num_resources = ARRAY_SIZE(mbox_resources),
92 .resource = mbox_resources,
93};
94
95static inline void omap_init_mbox(void)
96{
97 platform_device_register(&mbox_device);
98}
99#else
100static inline void omap_init_mbox(void) { }
101#endif
102
69#if defined(CONFIG_OMAP_STI) 103#if defined(CONFIG_OMAP_STI)
70 104
71#define OMAP2_STI_BASE IO_ADDRESS(0x48068000) 105#define OMAP2_STI_BASE IO_ADDRESS(0x48068000)
@@ -111,29 +145,45 @@ static inline void omap_init_sti(void) {}
111#define OMAP2_MCSPI1_BASE 0x48098000 145#define OMAP2_MCSPI1_BASE 0x48098000
112#define OMAP2_MCSPI2_BASE 0x4809a000 146#define OMAP2_MCSPI2_BASE 0x4809a000
113 147
114/* FIXME: use resources instead */
115
116static struct omap2_mcspi_platform_config omap2_mcspi1_config = { 148static struct omap2_mcspi_platform_config omap2_mcspi1_config = {
117 .base = io_p2v(OMAP2_MCSPI1_BASE),
118 .num_cs = 4, 149 .num_cs = 4,
119}; 150};
120 151
152static struct resource omap2_mcspi1_resources[] = {
153 {
154 .start = OMAP2_MCSPI1_BASE,
155 .end = OMAP2_MCSPI1_BASE + 0xff,
156 .flags = IORESOURCE_MEM,
157 },
158};
159
121struct platform_device omap2_mcspi1 = { 160struct platform_device omap2_mcspi1 = {
122 .name = "omap2_mcspi", 161 .name = "omap2_mcspi",
123 .id = 1, 162 .id = 1,
163 .num_resources = ARRAY_SIZE(omap2_mcspi1_resources),
164 .resource = omap2_mcspi1_resources,
124 .dev = { 165 .dev = {
125 .platform_data = &omap2_mcspi1_config, 166 .platform_data = &omap2_mcspi1_config,
126 }, 167 },
127}; 168};
128 169
129static struct omap2_mcspi_platform_config omap2_mcspi2_config = { 170static struct omap2_mcspi_platform_config omap2_mcspi2_config = {
130 .base = io_p2v(OMAP2_MCSPI2_BASE),
131 .num_cs = 2, 171 .num_cs = 2,
132}; 172};
133 173
174static struct resource omap2_mcspi2_resources[] = {
175 {
176 .start = OMAP2_MCSPI2_BASE,
177 .end = OMAP2_MCSPI2_BASE + 0xff,
178 .flags = IORESOURCE_MEM,
179 },
180};
181
134struct platform_device omap2_mcspi2 = { 182struct platform_device omap2_mcspi2 = {
135 .name = "omap2_mcspi", 183 .name = "omap2_mcspi",
136 .id = 2, 184 .id = 2,
185 .num_resources = ARRAY_SIZE(omap2_mcspi2_resources),
186 .resource = omap2_mcspi2_resources,
137 .dev = { 187 .dev = {
138 .platform_data = &omap2_mcspi2_config, 188 .platform_data = &omap2_mcspi2_config,
139 }, 189 },
@@ -157,10 +207,10 @@ static int __init omap2_init_devices(void)
157 * in alphabetical order so they're easier to sort through. 207 * in alphabetical order so they're easier to sort through.
158 */ 208 */
159 omap_init_i2c(); 209 omap_init_i2c();
210 omap_init_mbox();
160 omap_init_mcspi(); 211 omap_init_mcspi();
161 omap_init_sti(); 212 omap_init_sti();
162 213
163 return 0; 214 return 0;
164} 215}
165arch_initcall(omap2_init_devices); 216arch_initcall(omap2_init_devices);
166
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index d8f57824423f..54c836a98456 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -246,14 +246,22 @@ static int gpmc_cs_mem_enabled(int cs)
246 return l & (1 << 6); 246 return l & (1 << 6);
247} 247}
248 248
249static void gpmc_cs_set_reserved(int cs, int reserved) 249int gpmc_cs_set_reserved(int cs, int reserved)
250{ 250{
251 if (cs > GPMC_CS_NUM)
252 return -ENODEV;
253
251 gpmc_cs_map &= ~(1 << cs); 254 gpmc_cs_map &= ~(1 << cs);
252 gpmc_cs_map |= (reserved ? 1 : 0) << cs; 255 gpmc_cs_map |= (reserved ? 1 : 0) << cs;
256
257 return 0;
253} 258}
254 259
255static int gpmc_cs_reserved(int cs) 260int gpmc_cs_reserved(int cs)
256{ 261{
262 if (cs > GPMC_CS_NUM)
263 return -ENODEV;
264
257 return gpmc_cs_map & (1 << cs); 265 return gpmc_cs_map & (1 << cs);
258} 266}
259 267
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index a0728c33e5d9..82dc70f6b779 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -27,6 +27,7 @@ extern void omap_sram_init(void);
27extern int omap2_clk_init(void); 27extern int omap2_clk_init(void);
28extern void omap2_check_revision(void); 28extern void omap2_check_revision(void);
29extern void gpmc_init(void); 29extern void gpmc_init(void);
30extern void omapfb_reserve_sdram(void);
30 31
31/* 32/*
32 * The machine specific code may provide the extra mapping besides the 33 * The machine specific code may provide the extra mapping besides the
@@ -40,9 +41,21 @@ static struct map_desc omap2_io_desc[] __initdata = {
40 .type = MT_DEVICE 41 .type = MT_DEVICE
41 }, 42 },
42 { 43 {
43 .virtual = L4_24XX_VIRT, 44 .virtual = DSP_MEM_24XX_VIRT,
44 .pfn = __phys_to_pfn(L4_24XX_PHYS), 45 .pfn = __phys_to_pfn(DSP_MEM_24XX_PHYS),
45 .length = L4_24XX_SIZE, 46 .length = DSP_MEM_24XX_SIZE,
47 .type = MT_DEVICE
48 },
49 {
50 .virtual = DSP_IPI_24XX_VIRT,
51 .pfn = __phys_to_pfn(DSP_IPI_24XX_PHYS),
52 .length = DSP_IPI_24XX_SIZE,
53 .type = MT_DEVICE
54 },
55 {
56 .virtual = DSP_MMU_24XX_VIRT,
57 .pfn = __phys_to_pfn(DSP_MMU_24XX_PHYS),
58 .length = DSP_MMU_24XX_SIZE,
46 .type = MT_DEVICE 59 .type = MT_DEVICE
47 } 60 }
48}; 61};
@@ -60,7 +73,7 @@ void __init omap2_map_common_io(void)
60 73
61 omap2_check_revision(); 74 omap2_check_revision();
62 omap_sram_init(); 75 omap_sram_init();
63 omapfb_reserve_mem(); 76 omapfb_reserve_sdram();
64} 77}
65 78
66void __init omap2_init_common_hw(void) 79void __init omap2_init_common_hw(void)
diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c
new file mode 100644
index 000000000000..b03cd06e055b
--- /dev/null
+++ b/arch/arm/mach-omap2/mailbox.c
@@ -0,0 +1,318 @@
1/*
2 * Mailbox reservation modules for OMAP2
3 *
4 * Copyright (C) 2006 Nokia Corporation
5 * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
6 * and Paul Mundt <paul.mundt@nokia.com>
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12
13#include <linux/kernel.h>
14#include <linux/clk.h>
15#include <linux/err.h>
16#include <linux/platform_device.h>
17#include <asm/arch/mailbox.h>
18#include <asm/arch/irqs.h>
19#include <asm/io.h>
20
21#define MAILBOX_REVISION 0x00
22#define MAILBOX_SYSCONFIG 0x10
23#define MAILBOX_SYSSTATUS 0x14
24#define MAILBOX_MESSAGE_0 0x40
25#define MAILBOX_MESSAGE_1 0x44
26#define MAILBOX_MESSAGE_2 0x48
27#define MAILBOX_MESSAGE_3 0x4c
28#define MAILBOX_MESSAGE_4 0x50
29#define MAILBOX_MESSAGE_5 0x54
30#define MAILBOX_FIFOSTATUS_0 0x80
31#define MAILBOX_FIFOSTATUS_1 0x84
32#define MAILBOX_FIFOSTATUS_2 0x88
33#define MAILBOX_FIFOSTATUS_3 0x8c
34#define MAILBOX_FIFOSTATUS_4 0x90
35#define MAILBOX_FIFOSTATUS_5 0x94
36#define MAILBOX_MSGSTATUS_0 0xc0
37#define MAILBOX_MSGSTATUS_1 0xc4
38#define MAILBOX_MSGSTATUS_2 0xc8
39#define MAILBOX_MSGSTATUS_3 0xcc
40#define MAILBOX_MSGSTATUS_4 0xd0
41#define MAILBOX_MSGSTATUS_5 0xd4
42#define MAILBOX_IRQSTATUS_0 0x100
43#define MAILBOX_IRQENABLE_0 0x104
44#define MAILBOX_IRQSTATUS_1 0x108
45#define MAILBOX_IRQENABLE_1 0x10c
46#define MAILBOX_IRQSTATUS_2 0x110
47#define MAILBOX_IRQENABLE_2 0x114
48#define MAILBOX_IRQSTATUS_3 0x118
49#define MAILBOX_IRQENABLE_3 0x11c
50
51static unsigned long mbox_base;
52
53#define MAILBOX_IRQ_NOTFULL(n) (1 << (2 * (n) + 1))
54#define MAILBOX_IRQ_NEWMSG(n) (1 << (2 * (n)))
55
56struct omap_mbox2_fifo {
57 unsigned long msg;
58 unsigned long fifo_stat;
59 unsigned long msg_stat;
60};
61
62struct omap_mbox2_priv {
63 struct omap_mbox2_fifo tx_fifo;
64 struct omap_mbox2_fifo rx_fifo;
65 unsigned long irqenable;
66 unsigned long irqstatus;
67 u32 newmsg_bit;
68 u32 notfull_bit;
69};
70
71static struct clk *mbox_ick_handle;
72
73static inline unsigned int mbox_read_reg(unsigned int reg)
74{
75 return __raw_readl(mbox_base + reg);
76}
77
78static inline void mbox_write_reg(unsigned int val, unsigned int reg)
79{
80 __raw_writel(val, mbox_base + reg);
81}
82
83/* Mailbox H/W preparations */
84static inline int omap2_mbox_startup(struct omap_mbox *mbox)
85{
86 unsigned int l;
87
88 mbox_ick_handle = clk_get(NULL, "mailboxes_ick");
89 if (IS_ERR(mbox_ick_handle)) {
90 printk("Could not get mailboxes_ick\n");
91 return -ENODEV;
92 }
93 clk_enable(mbox_ick_handle);
94
95 /* set smart-idle & autoidle */
96 l = mbox_read_reg(MAILBOX_SYSCONFIG);
97 l |= 0x00000011;
98 mbox_write_reg(l, MAILBOX_SYSCONFIG);
99
100 return 0;
101}
102
103static inline void omap2_mbox_shutdown(struct omap_mbox *mbox)
104{
105 clk_disable(mbox_ick_handle);
106 clk_put(mbox_ick_handle);
107}
108
109/* Mailbox FIFO handle functions */
110static inline mbox_msg_t omap2_mbox_fifo_read(struct omap_mbox *mbox)
111{
112 struct omap_mbox2_fifo *fifo =
113 &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
114 return (mbox_msg_t) mbox_read_reg(fifo->msg);
115}
116
117static inline void omap2_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
118{
119 struct omap_mbox2_fifo *fifo =
120 &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
121 mbox_write_reg(msg, fifo->msg);
122}
123
124static inline int omap2_mbox_fifo_empty(struct omap_mbox *mbox)
125{
126 struct omap_mbox2_fifo *fifo =
127 &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
128 return (mbox_read_reg(fifo->msg_stat) == 0);
129}
130
131static inline int omap2_mbox_fifo_full(struct omap_mbox *mbox)
132{
133 struct omap_mbox2_fifo *fifo =
134 &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
135 return (mbox_read_reg(fifo->fifo_stat));
136}
137
138/* Mailbox IRQ handle functions */
139static inline void omap2_mbox_enable_irq(struct omap_mbox *mbox,
140 omap_mbox_type_t irq)
141{
142 struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
143 u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
144
145 l = mbox_read_reg(p->irqenable);
146 l |= bit;
147 mbox_write_reg(l, p->irqenable);
148}
149
150static inline void omap2_mbox_disable_irq(struct omap_mbox *mbox,
151 omap_mbox_type_t irq)
152{
153 struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
154 u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
155
156 l = mbox_read_reg(p->irqenable);
157 l &= ~bit;
158 mbox_write_reg(l, p->irqenable);
159}
160
161static inline void omap2_mbox_ack_irq(struct omap_mbox *mbox,
162 omap_mbox_type_t irq)
163{
164 struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
165 u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
166
167 mbox_write_reg(bit, p->irqstatus);
168}
169
170static inline int omap2_mbox_is_irq(struct omap_mbox *mbox,
171 omap_mbox_type_t irq)
172{
173 struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
174 u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
175 u32 enable = mbox_read_reg(p->irqenable);
176 u32 status = mbox_read_reg(p->irqstatus);
177
178 return (enable & status & bit);
179}
180
181static struct omap_mbox_ops omap2_mbox_ops = {
182 .type = OMAP_MBOX_TYPE2,
183 .startup = omap2_mbox_startup,
184 .shutdown = omap2_mbox_shutdown,
185 .fifo_read = omap2_mbox_fifo_read,
186 .fifo_write = omap2_mbox_fifo_write,
187 .fifo_empty = omap2_mbox_fifo_empty,
188 .fifo_full = omap2_mbox_fifo_full,
189 .enable_irq = omap2_mbox_enable_irq,
190 .disable_irq = omap2_mbox_disable_irq,
191 .ack_irq = omap2_mbox_ack_irq,
192 .is_irq = omap2_mbox_is_irq,
193};
194
195/*
196 * MAILBOX 0: ARM -> DSP,
197 * MAILBOX 1: ARM <- DSP.
198 * MAILBOX 2: ARM -> IVA,
199 * MAILBOX 3: ARM <- IVA.
200 */
201
202/* FIXME: the following structs should be filled automatically by the user id */
203
204/* DSP */
205static struct omap_mbox2_priv omap2_mbox_dsp_priv = {
206 .tx_fifo = {
207 .msg = MAILBOX_MESSAGE_0,
208 .fifo_stat = MAILBOX_FIFOSTATUS_0,
209 },
210 .rx_fifo = {
211 .msg = MAILBOX_MESSAGE_1,
212 .msg_stat = MAILBOX_MSGSTATUS_1,
213 },
214 .irqenable = MAILBOX_IRQENABLE_0,
215 .irqstatus = MAILBOX_IRQSTATUS_0,
216 .notfull_bit = MAILBOX_IRQ_NOTFULL(0),
217 .newmsg_bit = MAILBOX_IRQ_NEWMSG(1),
218};
219
220struct omap_mbox mbox_dsp_info = {
221 .name = "dsp",
222 .ops = &omap2_mbox_ops,
223 .priv = &omap2_mbox_dsp_priv,
224};
225EXPORT_SYMBOL(mbox_dsp_info);
226
227/* IVA */
228static struct omap_mbox2_priv omap2_mbox_iva_priv = {
229 .tx_fifo = {
230 .msg = MAILBOX_MESSAGE_2,
231 .fifo_stat = MAILBOX_FIFOSTATUS_2,
232 },
233 .rx_fifo = {
234 .msg = MAILBOX_MESSAGE_3,
235 .msg_stat = MAILBOX_MSGSTATUS_3,
236 },
237 .irqenable = MAILBOX_IRQENABLE_3,
238 .irqstatus = MAILBOX_IRQSTATUS_3,
239 .notfull_bit = MAILBOX_IRQ_NOTFULL(2),
240 .newmsg_bit = MAILBOX_IRQ_NEWMSG(3),
241};
242
243static struct omap_mbox mbox_iva_info = {
244 .name = "iva",
245 .ops = &omap2_mbox_ops,
246 .priv = &omap2_mbox_iva_priv,
247};
248
249static int __init omap2_mbox_probe(struct platform_device *pdev)
250{
251 struct resource *res;
252 int ret = 0;
253
254 if (pdev->num_resources != 3) {
255 dev_err(&pdev->dev, "invalid number of resources: %d\n",
256 pdev->num_resources);
257 return -ENODEV;
258 }
259
260 /* MBOX base */
261 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
262 if (unlikely(!res)) {
263 dev_err(&pdev->dev, "invalid mem resource\n");
264 return -ENODEV;
265 }
266 mbox_base = res->start;
267
268 /* DSP IRQ */
269 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
270 if (unlikely(!res)) {
271 dev_err(&pdev->dev, "invalid irq resource\n");
272 return -ENODEV;
273 }
274 mbox_dsp_info.irq = res->start;
275
276 ret = omap_mbox_register(&mbox_dsp_info);
277
278 /* IVA IRQ */
279 res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
280 if (unlikely(!res)) {
281 dev_err(&pdev->dev, "invalid irq resource\n");
282 return -ENODEV;
283 }
284 mbox_iva_info.irq = res->start;
285
286 ret = omap_mbox_register(&mbox_iva_info);
287
288 return ret;
289}
290
291static int omap2_mbox_remove(struct platform_device *pdev)
292{
293 omap_mbox_unregister(&mbox_dsp_info);
294 return 0;
295}
296
297static struct platform_driver omap2_mbox_driver = {
298 .probe = omap2_mbox_probe,
299 .remove = omap2_mbox_remove,
300 .driver = {
301 .name = "mailbox",
302 },
303};
304
305static int __init omap2_mbox_init(void)
306{
307 return platform_driver_register(&omap2_mbox_driver);
308}
309
310static void __exit omap2_mbox_exit(void)
311{
312 platform_driver_unregister(&omap2_mbox_driver);
313}
314
315module_init(omap2_mbox_init);
316module_exit(omap2_mbox_exit);
317
318MODULE_LICENSE("GPL");
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index e684e9b38216..b81391a4e374 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -366,6 +366,19 @@ config CPU_32v6K
366 enabled will not boot on processors with do not support these 366 enabled will not boot on processors with do not support these
367 instructions. 367 instructions.
368 368
369# ARMv7
370config CPU_V7
371 bool "Support ARM V7 processor"
372 depends on ARCH_INTEGRATOR
373 select CPU_32v6K
374 select CPU_32v7
375 select CPU_ABRT_EV7
376 select CPU_CACHE_V7
377 select CPU_CACHE_VIPT
378 select CPU_CP15_MMU
379 select CPU_COPY_V6 if MMU
380 select CPU_TLB_V6 if MMU
381
369# Figure out what processor architecture version we should be using. 382# Figure out what processor architecture version we should be using.
370# This defines the compiler instruction set which depends on the machine type. 383# This defines the compiler instruction set which depends on the machine type.
371config CPU_32v3 384config CPU_32v3
@@ -391,6 +404,9 @@ config CPU_32v5
391config CPU_32v6 404config CPU_32v6
392 bool 405 bool
393 406
407config CPU_32v7
408 bool
409
394# The abort model 410# The abort model
395config CPU_ABRT_NOMMU 411config CPU_ABRT_NOMMU
396 bool 412 bool
@@ -413,6 +429,9 @@ config CPU_ABRT_EV5TJ
413config CPU_ABRT_EV6 429config CPU_ABRT_EV6
414 bool 430 bool
415 431
432config CPU_ABRT_EV7
433 bool
434
416# The cache model 435# The cache model
417config CPU_CACHE_V3 436config CPU_CACHE_V3
418 bool 437 bool
@@ -429,6 +448,9 @@ config CPU_CACHE_V4WB
429config CPU_CACHE_V6 448config CPU_CACHE_V6
430 bool 449 bool
431 450
451config CPU_CACHE_V7
452 bool
453
432config CPU_CACHE_VIVT 454config CPU_CACHE_VIVT
433 bool 455 bool
434 456
@@ -503,7 +525,7 @@ comment "Processor Features"
503 525
504config ARM_THUMB 526config ARM_THUMB
505 bool "Support Thumb user binaries" 527 bool "Support Thumb user binaries"
506 depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 528 depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 || CPU_V7
507 default y 529 default y
508 help 530 help
509 Say Y if you want to include kernel support for running user space 531 Say Y if you want to include kernel support for running user space
@@ -578,9 +600,15 @@ config CPU_CACHE_ROUND_ROBIN
578 Say Y here to use the predictable round-robin cache replacement 600 Say Y here to use the predictable round-robin cache replacement
579 policy. Unless you specifically require this or are unsure, say N. 601 policy. Unless you specifically require this or are unsure, say N.
580 602
603config CPU_L2CACHE_DISABLE
604 bool "Disable level 2 cache"
605 depends on CPU_V7
606 help
607 Say Y here to disable the level 2 cache. If unsure, say N.
608
581config CPU_BPREDICT_DISABLE 609config CPU_BPREDICT_DISABLE
582 bool "Disable branch prediction" 610 bool "Disable branch prediction"
583 depends on CPU_ARM1020 || CPU_V6 || CPU_XSC3 611 depends on CPU_ARM1020 || CPU_V6 || CPU_XSC3 || CPU_V7
584 help 612 help
585 Say Y here to disable branch prediction. If unsure, say N. 613 Say Y here to disable branch prediction. If unsure, say N.
586 614
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 2f8b95947774..b5bd335ff14a 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -24,12 +24,14 @@ obj-$(CONFIG_CPU_ABRT_LV4T) += abort-lv4t.o
24obj-$(CONFIG_CPU_ABRT_EV5T) += abort-ev5t.o 24obj-$(CONFIG_CPU_ABRT_EV5T) += abort-ev5t.o
25obj-$(CONFIG_CPU_ABRT_EV5TJ) += abort-ev5tj.o 25obj-$(CONFIG_CPU_ABRT_EV5TJ) += abort-ev5tj.o
26obj-$(CONFIG_CPU_ABRT_EV6) += abort-ev6.o 26obj-$(CONFIG_CPU_ABRT_EV6) += abort-ev6.o
27obj-$(CONFIG_CPU_ABRT_EV7) += abort-ev7.o
27 28
28obj-$(CONFIG_CPU_CACHE_V3) += cache-v3.o 29obj-$(CONFIG_CPU_CACHE_V3) += cache-v3.o
29obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o 30obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o
30obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o 31obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o
31obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o 32obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o
32obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o 33obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o
34obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o
33 35
34obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o 36obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o
35obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o 37obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o
@@ -66,5 +68,6 @@ obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o
66obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o 68obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o
67obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o 69obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o
68obj-$(CONFIG_CPU_V6) += proc-v6.o 70obj-$(CONFIG_CPU_V6) += proc-v6.o
71obj-$(CONFIG_CPU_V7) += proc-v7.o
69 72
70obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o 73obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
diff --git a/arch/arm/mm/abort-ev7.S b/arch/arm/mm/abort-ev7.S
new file mode 100644
index 000000000000..eb90bce38e14
--- /dev/null
+++ b/arch/arm/mm/abort-ev7.S
@@ -0,0 +1,32 @@
1#include <linux/linkage.h>
2#include <asm/assembler.h>
3/*
4 * Function: v7_early_abort
5 *
6 * Params : r2 = address of aborted instruction
7 * : r3 = saved SPSR
8 *
9 * Returns : r0 = address of abort
10 * : r1 = FSR, bit 11 = write
11 * : r2-r8 = corrupted
12 * : r9 = preserved
13 * : sp = pointer to registers
14 *
15 * Purpose : obtain information about current aborted instruction.
16 */
17 .align 5
18ENTRY(v7_early_abort)
19 /*
20 * The effect of data aborts on on the exclusive access monitor are
21 * UNPREDICTABLE. Do a CLREX to clear the state
22 */
23 clrex
24
25 mrc p15, 0, r1, c5, c0, 0 @ get FSR
26 mrc p15, 0, r0, c6, c0, 0 @ get FAR
27
28 /*
29 * V6 code adjusts the returned DFSR.
30 * New designs should not need to patch up faults.
31 */
32 mov pc, lr
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
new file mode 100644
index 000000000000..35ffc4d95997
--- /dev/null
+++ b/arch/arm/mm/cache-v7.S
@@ -0,0 +1,253 @@
1/*
2 * linux/arch/arm/mm/cache-v7.S
3 *
4 * Copyright (C) 2001 Deep Blue Solutions Ltd.
5 * Copyright (C) 2005 ARM Ltd.
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 * This is the "shell" of the ARMv7 processor support.
12 */
13#include <linux/linkage.h>
14#include <linux/init.h>
15#include <asm/assembler.h>
16
17#include "proc-macros.S"
18
19/*
20 * v7_flush_dcache_all()
21 *
22 * Flush the whole D-cache.
23 *
24 * Corrupted registers: r0-r5, r7, r9-r11
25 *
26 * - mm - mm_struct describing address space
27 */
28ENTRY(v7_flush_dcache_all)
29 mrc p15, 1, r0, c0, c0, 1 @ read clidr
30 ands r3, r0, #0x7000000 @ extract loc from clidr
31 mov r3, r3, lsr #23 @ left align loc bit field
32 beq finished @ if loc is 0, then no need to clean
33 mov r10, #0 @ start clean at cache level 0
34loop1:
35 add r2, r10, r10, lsr #1 @ work out 3x current cache level
36 mov r1, r0, lsr r2 @ extract cache type bits from clidr
37 and r1, r1, #7 @ mask of the bits for current cache only
38 cmp r1, #2 @ see what cache we have at this level
39 blt skip @ skip if no cache, or just i-cache
40 mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
41 isb @ isb to sych the new cssr&csidr
42 mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
43 and r2, r1, #7 @ extract the length of the cache lines
44 add r2, r2, #4 @ add 4 (line length offset)
45 ldr r4, =0x3ff
46 ands r4, r4, r1, lsr #3 @ find maximum number on the way size
47 clz r5, r4 @ find bit position of way size increment
48 ldr r7, =0x7fff
49 ands r7, r7, r1, lsr #13 @ extract max number of the index size
50loop2:
51 mov r9, r4 @ create working copy of max way size
52loop3:
53 orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
54 orr r11, r11, r7, lsl r2 @ factor index number into r11
55 mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
56 subs r9, r9, #1 @ decrement the way
57 bge loop3
58 subs r7, r7, #1 @ decrement the index
59 bge loop2
60skip:
61 add r10, r10, #2 @ increment cache number
62 cmp r3, r10
63 bgt loop1
64finished:
65 mov r10, #0 @ swith back to cache level 0
66 mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
67 isb
68 mov pc, lr
69
70/*
71 * v7_flush_cache_all()
72 *
73 * Flush the entire cache system.
74 * The data cache flush is now achieved using atomic clean / invalidates
75 * working outwards from L1 cache. This is done using Set/Way based cache
76 * maintainance instructions.
77 * The instruction cache can still be invalidated back to the point of
78 * unification in a single instruction.
79 *
80 */
81ENTRY(v7_flush_kern_cache_all)
82 stmfd sp!, {r4-r5, r7, r9-r11, lr}
83 bl v7_flush_dcache_all
84 mov r0, #0
85 mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate
86 ldmfd sp!, {r4-r5, r7, r9-r11, lr}
87 mov pc, lr
88
89/*
90 * v7_flush_cache_all()
91 *
92 * Flush all TLB entries in a particular address space
93 *
94 * - mm - mm_struct describing address space
95 */
96ENTRY(v7_flush_user_cache_all)
97 /*FALLTHROUGH*/
98
99/*
100 * v7_flush_cache_range(start, end, flags)
101 *
102 * Flush a range of TLB entries in the specified address space.
103 *
104 * - start - start address (may not be aligned)
105 * - end - end address (exclusive, may not be aligned)
106 * - flags - vm_area_struct flags describing address space
107 *
108 * It is assumed that:
109 * - we have a VIPT cache.
110 */
111ENTRY(v7_flush_user_cache_range)
112 mov pc, lr
113
114/*
115 * v7_coherent_kern_range(start,end)
116 *
117 * Ensure that the I and D caches are coherent within specified
118 * region. This is typically used when code has been written to
119 * a memory region, and will be executed.
120 *
121 * - start - virtual start address of region
122 * - end - virtual end address of region
123 *
124 * It is assumed that:
125 * - the Icache does not read data from the write buffer
126 */
127ENTRY(v7_coherent_kern_range)
128 /* FALLTHROUGH */
129
130/*
131 * v7_coherent_user_range(start,end)
132 *
133 * Ensure that the I and D caches are coherent within specified
134 * region. This is typically used when code has been written to
135 * a memory region, and will be executed.
136 *
137 * - start - virtual start address of region
138 * - end - virtual end address of region
139 *
140 * It is assumed that:
141 * - the Icache does not read data from the write buffer
142 */
143ENTRY(v7_coherent_user_range)
144 dcache_line_size r2, r3
145 sub r3, r2, #1
146 bic r0, r0, r3
1471: mcr p15, 0, r0, c7, c11, 1 @ clean D line to the point of unification
148 dsb
149 mcr p15, 0, r0, c7, c5, 1 @ invalidate I line
150 add r0, r0, r2
151 cmp r0, r1
152 blo 1b
153 mov r0, #0
154 mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB
155 dsb
156 isb
157 mov pc, lr
158
159/*
160 * v7_flush_kern_dcache_page(kaddr)
161 *
162 * Ensure that the data held in the page kaddr is written back
163 * to the page in question.
164 *
165 * - kaddr - kernel address (guaranteed to be page aligned)
166 */
167ENTRY(v7_flush_kern_dcache_page)
168 dcache_line_size r2, r3
169 add r1, r0, #PAGE_SZ
1701:
171 mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line
172 add r0, r0, r2
173 cmp r0, r1
174 blo 1b
175 dsb
176 mov pc, lr
177
178/*
179 * v7_dma_inv_range(start,end)
180 *
181 * Invalidate the data cache within the specified region; we will
182 * be performing a DMA operation in this region and we want to
183 * purge old data in the cache.
184 *
185 * - start - virtual start address of region
186 * - end - virtual end address of region
187 */
188ENTRY(v7_dma_inv_range)
189 dcache_line_size r2, r3
190 sub r3, r2, #1
191 tst r0, r3
192 bic r0, r0, r3
193 mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line
194
195 tst r1, r3
196 bic r1, r1, r3
197 mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D / U line
1981:
199 mcr p15, 0, r0, c7, c6, 1 @ invalidate D / U line
200 add r0, r0, r2
201 cmp r0, r1
202 blo 1b
203 dsb
204 mov pc, lr
205
206/*
207 * v7_dma_clean_range(start,end)
208 * - start - virtual start address of region
209 * - end - virtual end address of region
210 */
211ENTRY(v7_dma_clean_range)
212 dcache_line_size r2, r3
213 sub r3, r2, #1
214 bic r0, r0, r3
2151:
216 mcr p15, 0, r0, c7, c10, 1 @ clean D / U line
217 add r0, r0, r2
218 cmp r0, r1
219 blo 1b
220 dsb
221 mov pc, lr
222
223/*
224 * v7_dma_flush_range(start,end)
225 * - start - virtual start address of region
226 * - end - virtual end address of region
227 */
228ENTRY(v7_dma_flush_range)
229 dcache_line_size r2, r3
230 sub r3, r2, #1
231 bic r0, r0, r3
2321:
233 mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line
234 add r0, r0, r2
235 cmp r0, r1
236 blo 1b
237 dsb
238 mov pc, lr
239
240 __INITDATA
241
242 .type v7_cache_fns, #object
243ENTRY(v7_cache_fns)
244 .long v7_flush_kern_cache_all
245 .long v7_flush_user_cache_all
246 .long v7_flush_user_cache_range
247 .long v7_coherent_kern_range
248 .long v7_coherent_user_range
249 .long v7_flush_kern_dcache_page
250 .long v7_dma_inv_range
251 .long v7_dma_clean_range
252 .long v7_dma_flush_range
253 .size v7_cache_fns, . - v7_cache_fns
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 9da43a0fdcdf..fc84fcc74380 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -14,7 +14,8 @@
14#include <asm/mmu_context.h> 14#include <asm/mmu_context.h>
15#include <asm/tlbflush.h> 15#include <asm/tlbflush.h>
16 16
17unsigned int cpu_last_asid = { 1 << ASID_BITS }; 17static DEFINE_SPINLOCK(cpu_asid_lock);
18unsigned int cpu_last_asid = ASID_FIRST_VERSION;
18 19
19/* 20/*
20 * We fork()ed a process, and we need a new context for the child 21 * We fork()ed a process, and we need a new context for the child
@@ -31,15 +32,16 @@ void __new_context(struct mm_struct *mm)
31{ 32{
32 unsigned int asid; 33 unsigned int asid;
33 34
35 spin_lock(&cpu_asid_lock);
34 asid = ++cpu_last_asid; 36 asid = ++cpu_last_asid;
35 if (asid == 0) 37 if (asid == 0)
36 asid = cpu_last_asid = 1 << ASID_BITS; 38 asid = cpu_last_asid = ASID_FIRST_VERSION;
37 39
38 /* 40 /*
39 * If we've used up all our ASIDs, we need 41 * If we've used up all our ASIDs, we need
40 * to start a new version and flush the TLB. 42 * to start a new version and flush the TLB.
41 */ 43 */
42 if ((asid & ~ASID_MASK) == 0) { 44 if (unlikely((asid & ~ASID_MASK) == 0)) {
43 asid = ++cpu_last_asid; 45 asid = ++cpu_last_asid;
44 /* set the reserved ASID before flushing the TLB */ 46 /* set the reserved ASID before flushing the TLB */
45 asm("mcr p15, 0, %0, c13, c0, 1 @ set reserved context ID\n" 47 asm("mcr p15, 0, %0, c13, c0, 1 @ set reserved context ID\n"
@@ -47,7 +49,16 @@ void __new_context(struct mm_struct *mm)
47 : "r" (0)); 49 : "r" (0));
48 isb(); 50 isb();
49 flush_tlb_all(); 51 flush_tlb_all();
52 if (icache_is_vivt_asid_tagged()) {
53 asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n"
54 "mcr p15, 0, %0, c7, c5, 6 @ flush BTAC/BTB\n"
55 :
56 : "r" (0));
57 dsb();
58 }
50 } 59 }
60 spin_unlock(&cpu_asid_lock);
51 61
62 mm->cpu_vm_mask = cpumask_of_cpu(smp_processor_id());
52 mm->context.id = asid; 63 mm->context.id = asid;
53} 64}
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 9e2c89eb2115..b13150052a76 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -59,3 +59,15 @@
59 .word \ucset 59 .word \ucset
60#endif 60#endif
61 .endm 61 .endm
62
63/*
64 * cache_line_size - get the cache line size from the CSIDR register
65 * (available on ARMv7+). It assumes that the CSSR register was configured
66 * to access the L1 data cache CSIDR.
67 */
68 .macro dcache_line_size, reg, tmp
69 mrc p15, 1, \tmp, c0, c0, 0 @ read CSIDR
70 and \tmp, \tmp, #7 @ cache line size encoding
71 mov \reg, #16 @ size offset
72 mov \reg, \reg, lsl \tmp @ actual cache line size
73 .endm
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
new file mode 100644
index 000000000000..dd823dd4a374
--- /dev/null
+++ b/arch/arm/mm/proc-v7.S
@@ -0,0 +1,262 @@
1/*
2 * linux/arch/arm/mm/proc-v7.S
3 *
4 * Copyright (C) 2001 Deep Blue Solutions Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This is the "shell" of the ARMv7 processor support.
11 */
12#include <linux/linkage.h>
13#include <asm/assembler.h>
14#include <asm/asm-offsets.h>
15#include <asm/elf.h>
16#include <asm/pgtable-hwdef.h>
17#include <asm/pgtable.h>
18
19#include "proc-macros.S"
20
21#define TTB_C (1 << 0)
22#define TTB_S (1 << 1)
23#define TTB_RGN_OC_WT (2 << 3)
24#define TTB_RGN_OC_WB (3 << 3)
25
26ENTRY(cpu_v7_proc_init)
27 mov pc, lr
28
29ENTRY(cpu_v7_proc_fin)
30 mov pc, lr
31
32/*
33 * cpu_v7_reset(loc)
34 *
35 * Perform a soft reset of the system. Put the CPU into the
36 * same state as it would be if it had been reset, and branch
37 * to what would be the reset vector.
38 *
39 * - loc - location to jump to for soft reset
40 *
41 * It is assumed that:
42 */
43 .align 5
44ENTRY(cpu_v7_reset)
45 mov pc, r0
46
47/*
48 * cpu_v7_do_idle()
49 *
50 * Idle the processor (eg, wait for interrupt).
51 *
52 * IRQs are already disabled.
53 */
54ENTRY(cpu_v7_do_idle)
55 .long 0xe320f003 @ ARM V7 WFI instruction
56 mov pc, lr
57
58ENTRY(cpu_v7_dcache_clean_area)
59#ifndef TLB_CAN_READ_FROM_L1_CACHE
60 dcache_line_size r2, r3
611: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
62 add r0, r0, r2
63 subs r1, r1, r2
64 bhi 1b
65 dsb
66#endif
67 mov pc, lr
68
69/*
70 * cpu_v7_switch_mm(pgd_phys, tsk)
71 *
72 * Set the translation table base pointer to be pgd_phys
73 *
74 * - pgd_phys - physical address of new TTB
75 *
76 * It is assumed that:
77 * - we are not using split page tables
78 */
79ENTRY(cpu_v7_switch_mm)
80 mov r2, #0
81 ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id
82 orr r0, r0, #TTB_RGN_OC_WB @ mark PTWs outer cacheable, WB
83 mcr p15, 0, r2, c13, c0, 1 @ set reserved context ID
84 isb
851: mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
86 isb
87 mcr p15, 0, r1, c13, c0, 1 @ set context ID
88 isb
89 mov pc, lr
90
91/*
92 * cpu_v7_set_pte_ext(ptep, pte)
93 *
94 * Set a level 2 translation table entry.
95 *
96 * - ptep - pointer to level 2 translation table entry
97 * (hardware version is stored at -1024 bytes)
98 * - pte - PTE value to store
99 * - ext - value for extended PTE bits
100 *
101 * Permissions:
102 * YUWD APX AP1 AP0 SVC User
103 * 0xxx 0 0 0 no acc no acc
104 * 100x 1 0 1 r/o no acc
105 * 10x0 1 0 1 r/o no acc
106 * 1011 0 0 1 r/w no acc
107 * 110x 0 1 0 r/w r/o
108 * 11x0 0 1 0 r/w r/o
109 * 1111 0 1 1 r/w r/w
110 */
111ENTRY(cpu_v7_set_pte_ext)
112 str r1, [r0], #-2048 @ linux version
113
114 bic r3, r1, #0x000003f0
115 bic r3, r3, #0x00000003
116 orr r3, r3, r2
117 orr r3, r3, #PTE_EXT_AP0 | 2
118
119 tst r1, #L_PTE_WRITE
120 tstne r1, #L_PTE_DIRTY
121 orreq r3, r3, #PTE_EXT_APX
122
123 tst r1, #L_PTE_USER
124 orrne r3, r3, #PTE_EXT_AP1
125 tstne r3, #PTE_EXT_APX
126 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
127
128 tst r1, #L_PTE_YOUNG
129 biceq r3, r3, #PTE_EXT_APX | PTE_EXT_AP_MASK
130
131 tst r1, #L_PTE_EXEC
132 orreq r3, r3, #PTE_EXT_XN
133
134 tst r1, #L_PTE_PRESENT
135 moveq r3, #0
136
137 str r3, [r0]
138 mcr p15, 0, r0, c7, c10, 1 @ flush_pte
139 mov pc, lr
140
141cpu_v7_name:
142 .ascii "ARMv7 Processor"
143 .align
144
145 .section ".text.init", #alloc, #execinstr
146
147/*
148 * __v7_setup
149 *
150 * Initialise TLB, Caches, and MMU state ready to switch the MMU
151 * on. Return in r0 the new CP15 C1 control register setting.
152 *
153 * We automatically detect if we have a Harvard cache, and use the
154 * Harvard cache control instructions insead of the unified cache
155 * control instructions.
156 *
157 * This should be able to cover all ARMv7 cores.
158 *
159 * It is assumed that:
160 * - cache type register is implemented
161 */
162__v7_setup:
163 adr r12, __v7_setup_stack @ the local stack
164 stmia r12, {r0-r5, r7, r9, r11, lr}
165 bl v7_flush_dcache_all
166 ldmia r12, {r0-r5, r7, r9, r11, lr}
167 mov r10, #0
168#ifdef HARVARD_CACHE
169 mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate
170#endif
171 dsb
172 mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs
173 mcr p15, 0, r10, c2, c0, 2 @ TTB control register
174 orr r4, r4, #TTB_RGN_OC_WB @ mark PTWs outer cacheable, WB
175 mcr p15, 0, r4, c2, c0, 0 @ load TTB0
176 mcr p15, 0, r4, c2, c0, 1 @ load TTB1
177 mov r10, #0x1f @ domains 0, 1 = manager
178 mcr p15, 0, r10, c3, c0, 0 @ load domain access register
179#ifndef CONFIG_CPU_L2CACHE_DISABLE
180 @ L2 cache configuration in the L2 aux control register
181 mrc p15, 1, r10, c9, c0, 2
182 bic r10, r10, #(1 << 16) @ L2 outer cache
183 mcr p15, 1, r10, c9, c0, 2
184 @ L2 cache is enabled in the aux control register
185 mrc p15, 0, r10, c1, c0, 1
186 orr r10, r10, #2
187 mcr p15, 0, r10, c1, c0, 1
188#endif
189 mrc p15, 0, r0, c1, c0, 0 @ read control register
190 ldr r10, cr1_clear @ get mask for bits to clear
191 bic r0, r0, r10 @ clear bits them
192 ldr r10, cr1_set @ get mask for bits to set
193 orr r0, r0, r10 @ set them
194 mov pc, lr @ return to head.S:__ret
195
196 /*
197 * V X F I D LR
198 * .... ...E PUI. .T.T 4RVI ZFRS BLDP WCAM
199 * rrrr rrrx xxx0 0101 xxxx xxxx x111 xxxx < forced
200 * 0 110 0011 1.00 .111 1101 < we want
201 */
202 .type cr1_clear, #object
203 .type cr1_set, #object
204cr1_clear:
205 .word 0x0120c302
206cr1_set:
207 .word 0x00c0387d
208
209__v7_setup_stack:
210 .space 4 * 11 @ 11 registers
211
212 .type v7_processor_functions, #object
213ENTRY(v7_processor_functions)
214 .word v7_early_abort
215 .word cpu_v7_proc_init
216 .word cpu_v7_proc_fin
217 .word cpu_v7_reset
218 .word cpu_v7_do_idle
219 .word cpu_v7_dcache_clean_area
220 .word cpu_v7_switch_mm
221 .word cpu_v7_set_pte_ext
222 .size v7_processor_functions, . - v7_processor_functions
223
224 .type cpu_arch_name, #object
225cpu_arch_name:
226 .asciz "armv7"
227 .size cpu_arch_name, . - cpu_arch_name
228
229 .type cpu_elf_name, #object
230cpu_elf_name:
231 .asciz "v7"
232 .size cpu_elf_name, . - cpu_elf_name
233 .align
234
235 .section ".proc.info.init", #alloc, #execinstr
236
237 /*
238 * Match any ARMv7 processor core.
239 */
240 .type __v7_proc_info, #object
241__v7_proc_info:
242 .long 0x000f0000 @ Required ID value
243 .long 0x000f0000 @ Mask for ID
244 .long PMD_TYPE_SECT | \
245 PMD_SECT_BUFFERABLE | \
246 PMD_SECT_CACHEABLE | \
247 PMD_SECT_AP_WRITE | \
248 PMD_SECT_AP_READ
249 .long PMD_TYPE_SECT | \
250 PMD_SECT_XN | \
251 PMD_SECT_AP_WRITE | \
252 PMD_SECT_AP_READ
253 b __v7_setup
254 .long cpu_arch_name
255 .long cpu_elf_name
256 .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
257 .long cpu_v7_name
258 .long v7_processor_functions
259 .long v6wbi_tlb_fns
260 .long v6_user_fns
261 .long v7_cache_fns
262 .size __v7_proc_info, . - __v7_proc_info
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 9e8d21eca4ec..cfc69f3842fd 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -20,6 +20,11 @@ endchoice
20 20
21comment "OMAP Feature Selections" 21comment "OMAP Feature Selections"
22 22
23config OMAP_DEBUG_LEDS
24 bool
25 help
26 For debug card leds on TI reference boards.
27
23config OMAP_RESET_CLOCKS 28config OMAP_RESET_CLOCKS
24 bool "Reset unused clocks during boot" 29 bool "Reset unused clocks during boot"
25 depends on ARCH_OMAP 30 depends on ARCH_OMAP
@@ -58,6 +63,14 @@ config OMAP_MUX_WARNINGS
58 to change the pin multiplexing setup. When there are no warnings 63 to change the pin multiplexing setup. When there are no warnings
59 printed, it's safe to deselect OMAP_MUX for your product. 64 printed, it's safe to deselect OMAP_MUX for your product.
60 65
66config OMAP_MCBSP
67 bool "McBSP support"
68 depends on ARCH_OMAP
69 default y
70 help
71 Say Y here if you want support for the OMAP Multichannel
72 Buffered Serial Port.
73
61choice 74choice
62 prompt "System timer" 75 prompt "System timer"
63 default OMAP_MPU_TIMER 76 default OMAP_MPU_TIMER
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 2896b4546411..41a3c1cf3bd4 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -3,7 +3,8 @@
3# 3#
4 4
5# Common support 5# Common support
6obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o fb.o 6obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o \
7 usb.o fb.o
7obj-m := 8obj-m :=
8obj-n := 9obj-n :=
9obj- := 10obj- :=
@@ -16,4 +17,4 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
16 17
17obj-$(CONFIG_CPU_FREQ) += cpu-omap.o 18obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
18obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o 19obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
19 20obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index f1179ad4be1b..0a603242f367 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -33,6 +33,41 @@ static DEFINE_SPINLOCK(clockfw_lock);
33 33
34static struct clk_functions *arch_clock; 34static struct clk_functions *arch_clock;
35 35
36#ifdef CONFIG_PM_DEBUG
37
38static void print_parents(struct clk *clk)
39{
40 struct clk *p;
41 int printed = 0;
42
43 list_for_each_entry(p, &clocks, node) {
44 if (p->parent == clk && p->usecount) {
45 if (!clk->usecount && !printed) {
46 printk("MISMATCH: %s\n", clk->name);
47 printed = 1;
48 }
49 printk("\t%-15s\n", p->name);
50 }
51 }
52}
53
54void clk_print_usecounts(void)
55{
56 unsigned long flags;
57 struct clk *p;
58
59 spin_lock_irqsave(&clockfw_lock, flags);
60 list_for_each_entry(p, &clocks, node) {
61 if (p->usecount)
62 printk("%-15s: %d\n", p->name, p->usecount);
63 print_parents(p);
64
65 }
66 spin_unlock_irqrestore(&clockfw_lock, flags);
67}
68
69#endif
70
36/*------------------------------------------------------------------------- 71/*-------------------------------------------------------------------------
37 * Standard clock functions defined in include/linux/clk.h 72 * Standard clock functions defined in include/linux/clk.h
38 *-------------------------------------------------------------------------*/ 73 *-------------------------------------------------------------------------*/
@@ -249,6 +284,8 @@ void followparent_recalc(struct clk *clk)
249 return; 284 return;
250 285
251 clk->rate = clk->parent->rate; 286 clk->rate = clk->parent->rate;
287 if (unlikely(clk->flags & RATE_PROPAGATES))
288 propagate_rate(clk);
252} 289}
253 290
254/* Propagate rate to children */ 291/* Propagate rate to children */
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index fecd3d625995..dd8708ad0a71 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -93,8 +93,12 @@ static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out)
93 * in the kernel. */ 93 * in the kernel. */
94 for (i = 0; i < omap_board_config_size; i++) { 94 for (i = 0; i < omap_board_config_size; i++) {
95 if (omap_board_config[i].tag == tag) { 95 if (omap_board_config[i].tag == tag) {
96 kinfo = &omap_board_config[i]; 96 if (skip == 0) {
97 break; 97 kinfo = &omap_board_config[i];
98 break;
99 } else {
100 skip--;
101 }
98 } 102 }
99 } 103 }
100 if (kinfo == NULL) 104 if (kinfo == NULL)
diff --git a/arch/arm/plat-omap/debug-leds.c b/arch/arm/plat-omap/debug-leds.c
new file mode 100644
index 000000000000..9128a80d228f
--- /dev/null
+++ b/arch/arm/plat-omap/debug-leds.c
@@ -0,0 +1,314 @@
1/*
2 * linux/arch/arm/plat-omap/debug-leds.c
3 *
4 * Copyright 2003 by Texas Instruments Incorporated
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/init.h>
12#include <linux/platform_device.h>
13#include <linux/leds.h>
14
15#include <asm/io.h>
16#include <asm/hardware.h>
17#include <asm/leds.h>
18#include <asm/system.h>
19#include <asm/mach-types.h>
20
21#include <asm/arch/fpga.h>
22#include <asm/arch/gpio.h>
23
24
25/* Many OMAP development platforms reuse the same "debug board"; these
26 * platforms include H2, H3, H4, and Perseus2. There are 16 LEDs on the
27 * debug board (all green), accessed through FPGA registers.
28 *
29 * The "surfer" expansion board and H2 sample board also have two-color
30 * green+red LEDs (in parallel), used here for timer and idle indicators
31 * in preference to the ones on the debug board, for a "Disco LED" effect.
32 *
33 * This driver exports either the original ARM LED API, the new generic
34 * one, or both.
35 */
36
37static spinlock_t lock;
38static struct h2p2_dbg_fpga __iomem *fpga;
39static u16 led_state, hw_led_state;
40
41
42#ifdef CONFIG_LEDS_OMAP_DEBUG
43#define new_led_api() 1
44#else
45#define new_led_api() 0
46#endif
47
48
49/*-------------------------------------------------------------------------*/
50
51/* original ARM debug LED API:
52 * - timer and idle leds (some boards use non-FPGA leds here);
53 * - up to 4 generic leds, easily accessed in-kernel (any context)
54 */
55
56#define GPIO_LED_RED 3
57#define GPIO_LED_GREEN OMAP_MPUIO(4)
58
59#define LED_STATE_ENABLED 0x01
60#define LED_STATE_CLAIMED 0x02
61#define LED_TIMER_ON 0x04
62
63#define GPIO_IDLE GPIO_LED_GREEN
64#define GPIO_TIMER GPIO_LED_RED
65
66static void h2p2_dbg_leds_event(led_event_t evt)
67{
68 unsigned long flags;
69
70 spin_lock_irqsave(&lock, flags);
71
72 if (!(led_state & LED_STATE_ENABLED) && evt != led_start)
73 goto done;
74
75 switch (evt) {
76 case led_start:
77 if (fpga)
78 led_state |= LED_STATE_ENABLED;
79 break;
80
81 case led_stop:
82 case led_halted:
83 /* all leds off during suspend or shutdown */
84
85 if (!(machine_is_omap_perseus2() || machine_is_omap_h4())) {
86 omap_set_gpio_dataout(GPIO_TIMER, 0);
87 omap_set_gpio_dataout(GPIO_IDLE, 0);
88 }
89
90 __raw_writew(~0, &fpga->leds);
91 led_state &= ~LED_STATE_ENABLED;
92 goto done;
93
94 case led_claim:
95 led_state |= LED_STATE_CLAIMED;
96 hw_led_state = 0;
97 break;
98
99 case led_release:
100 led_state &= ~LED_STATE_CLAIMED;
101 break;
102
103#ifdef CONFIG_LEDS_TIMER
104 case led_timer:
105 led_state ^= LED_TIMER_ON;
106
107 if (machine_is_omap_perseus2() || machine_is_omap_h4())
108 hw_led_state ^= H2P2_DBG_FPGA_P2_LED_TIMER;
109 else {
110 omap_set_gpio_dataout(GPIO_TIMER,
111 led_state & LED_TIMER_ON);
112 goto done;
113 }
114
115 break;
116#endif
117
118#ifdef CONFIG_LEDS_CPU
119 /* LED lit iff busy */
120 case led_idle_start:
121 if (machine_is_omap_perseus2() || machine_is_omap_h4())
122 hw_led_state &= ~H2P2_DBG_FPGA_P2_LED_IDLE;
123 else {
124 omap_set_gpio_dataout(GPIO_IDLE, 1);
125 goto done;
126 }
127
128 break;
129
130 case led_idle_end:
131 if (machine_is_omap_perseus2() || machine_is_omap_h4())
132 hw_led_state |= H2P2_DBG_FPGA_P2_LED_IDLE;
133 else {
134 omap_set_gpio_dataout(GPIO_IDLE, 0);
135 goto done;
136 }
137
138 break;
139#endif
140
141 case led_green_on:
142 hw_led_state |= H2P2_DBG_FPGA_LED_GREEN;
143 break;
144 case led_green_off:
145 hw_led_state &= ~H2P2_DBG_FPGA_LED_GREEN;
146 break;
147
148 case led_amber_on:
149 hw_led_state |= H2P2_DBG_FPGA_LED_AMBER;
150 break;
151 case led_amber_off:
152 hw_led_state &= ~H2P2_DBG_FPGA_LED_AMBER;
153 break;
154
155 case led_red_on:
156 hw_led_state |= H2P2_DBG_FPGA_LED_RED;
157 break;
158 case led_red_off:
159 hw_led_state &= ~H2P2_DBG_FPGA_LED_RED;
160 break;
161
162 case led_blue_on:
163 hw_led_state |= H2P2_DBG_FPGA_LED_BLUE;
164 break;
165 case led_blue_off:
166 hw_led_state &= ~H2P2_DBG_FPGA_LED_BLUE;
167 break;
168
169 default:
170 break;
171 }
172
173
174 /*
175 * Actually burn the LEDs
176 */
177 if (led_state & LED_STATE_ENABLED)
178 __raw_writew(~hw_led_state, &fpga->leds);
179
180done:
181 spin_unlock_irqrestore(&lock, flags);
182}
183
184/*-------------------------------------------------------------------------*/
185
186/* "new" LED API
187 * - with syfs access and generic triggering
188 * - not readily accessible to in-kernel drivers
189 */
190
191struct dbg_led {
192 struct led_classdev cdev;
193 u16 mask;
194};
195
196static struct dbg_led dbg_leds[] = {
197 /* REVISIT at least H2 uses different timer & cpu leds... */
198#ifndef CONFIG_LEDS_TIMER
199 { .mask = 1 << 0, .cdev.name = "d4:green",
200 .cdev.default_trigger = "heartbeat", },
201#endif
202#ifndef CONFIG_LEDS_CPU
203 { .mask = 1 << 1, .cdev.name = "d5:green", }, /* !idle */
204#endif
205 { .mask = 1 << 2, .cdev.name = "d6:green", },
206 { .mask = 1 << 3, .cdev.name = "d7:green", },
207
208 { .mask = 1 << 4, .cdev.name = "d8:green", },
209 { .mask = 1 << 5, .cdev.name = "d9:green", },
210 { .mask = 1 << 6, .cdev.name = "d10:green", },
211 { .mask = 1 << 7, .cdev.name = "d11:green", },
212
213 { .mask = 1 << 8, .cdev.name = "d12:green", },
214 { .mask = 1 << 9, .cdev.name = "d13:green", },
215 { .mask = 1 << 10, .cdev.name = "d14:green", },
216 { .mask = 1 << 11, .cdev.name = "d15:green", },
217
218#ifndef CONFIG_LEDS
219 { .mask = 1 << 12, .cdev.name = "d16:green", },
220 { .mask = 1 << 13, .cdev.name = "d17:green", },
221 { .mask = 1 << 14, .cdev.name = "d18:green", },
222 { .mask = 1 << 15, .cdev.name = "d19:green", },
223#endif
224};
225
226static void
227fpga_led_set(struct led_classdev *cdev, enum led_brightness value)
228{
229 struct dbg_led *led = container_of(cdev, struct dbg_led, cdev);
230 unsigned long flags;
231
232 spin_lock_irqsave(&lock, flags);
233 if (value == LED_OFF)
234 hw_led_state &= ~led->mask;
235 else
236 hw_led_state |= led->mask;
237 __raw_writew(~hw_led_state, &fpga->leds);
238 spin_unlock_irqrestore(&lock, flags);
239}
240
241static void __init newled_init(struct device *dev)
242{
243 unsigned i;
244 struct dbg_led *led;
245 int status;
246
247 for (i = 0, led = dbg_leds; i < ARRAY_SIZE(dbg_leds); i++, led++) {
248 led->cdev.brightness_set = fpga_led_set;
249 status = led_classdev_register(dev, &led->cdev);
250 if (status < 0)
251 break;
252 }
253 return;
254}
255
256
257/*-------------------------------------------------------------------------*/
258
259static int /* __init */ fpga_probe(struct platform_device *pdev)
260{
261 struct resource *iomem;
262
263 spin_lock_init(&lock);
264
265 iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
266 if (!iomem)
267 return -ENODEV;
268
269 fpga = ioremap(iomem->start, H2P2_DBG_FPGA_SIZE);
270 __raw_writew(~0, &fpga->leds);
271
272#ifdef CONFIG_LEDS
273 leds_event = h2p2_dbg_leds_event;
274 leds_event(led_start);
275#endif
276
277 if (new_led_api()) {
278 newled_init(&pdev->dev);
279 }
280
281 return 0;
282}
283
284static int fpga_suspend_late(struct platform_device *pdev, pm_message_t mesg)
285{
286 __raw_writew(~0, &fpga->leds);
287 return 0;
288}
289
290static int fpga_resume_early(struct platform_device *pdev)
291{
292 __raw_writew(~hw_led_state, &fpga->leds);
293 return 0;
294}
295
296
297static struct platform_driver led_driver = {
298 .driver.name = "omap_dbg_led",
299 .probe = fpga_probe,
300 .suspend_late = fpga_suspend_late,
301 .resume_early = fpga_resume_early,
302};
303
304static int __init fpga_init(void)
305{
306 if (machine_is_omap_h4()
307 || machine_is_omap_h3()
308 || machine_is_omap_h2()
309 || machine_is_omap_perseus2()
310 )
311 return platform_driver_register(&led_driver);
312 return 0;
313}
314fs_initcall(fpga_init);
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index eeb33fed6f7c..c5dab1d6417e 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -25,7 +25,71 @@
25#include <asm/arch/gpio.h> 25#include <asm/arch/gpio.h>
26#include <asm/arch/menelaus.h> 26#include <asm/arch/menelaus.h>
27 27
28#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) 28#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
29
30#include "../plat-omap/dsp/dsp_common.h"
31
32static struct dsp_platform_data dsp_pdata = {
33 .kdev_list = LIST_HEAD_INIT(dsp_pdata.kdev_list),
34};
35
36static struct resource omap_dsp_resources[] = {
37 {
38 .name = "dsp_mmu",
39 .start = -1,
40 .flags = IORESOURCE_IRQ,
41 },
42};
43
44static struct platform_device omap_dsp_device = {
45 .name = "dsp",
46 .id = -1,
47 .num_resources = ARRAY_SIZE(omap_dsp_resources),
48 .resource = omap_dsp_resources,
49 .dev = {
50 .platform_data = &dsp_pdata,
51 },
52};
53
54static inline void omap_init_dsp(void)
55{
56 struct resource *res;
57 int irq;
58
59 if (cpu_is_omap15xx())
60 irq = INT_1510_DSP_MMU;
61 else if (cpu_is_omap16xx())
62 irq = INT_1610_DSP_MMU;
63 else if (cpu_is_omap24xx())
64 irq = INT_24XX_DSP_MMU;
65
66 res = platform_get_resource_byname(&omap_dsp_device,
67 IORESOURCE_IRQ, "dsp_mmu");
68 res->start = irq;
69
70 platform_device_register(&omap_dsp_device);
71}
72
73int dsp_kfunc_device_register(struct dsp_kfunc_device *kdev)
74{
75 static DEFINE_MUTEX(dsp_pdata_lock);
76
77 mutex_init(&kdev->lock);
78
79 mutex_lock(&dsp_pdata_lock);
80 list_add_tail(&kdev->entry, &dsp_pdata.kdev_list);
81 mutex_unlock(&dsp_pdata_lock);
82
83 return 0;
84}
85EXPORT_SYMBOL(dsp_kfunc_device_register);
86
87#else
88static inline void omap_init_dsp(void) { }
89#endif /* CONFIG_OMAP_DSP */
90
91/*-------------------------------------------------------------------------*/
92#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
29 93
30#define OMAP1_I2C_BASE 0xfffb3800 94#define OMAP1_I2C_BASE 0xfffb3800
31#define OMAP2_I2C_BASE1 0x48070000 95#define OMAP2_I2C_BASE1 0x48070000
@@ -48,8 +112,8 @@ static struct resource i2c_resources1[] = {
48/* DMA not used; works around erratum writing to non-empty i2c fifo */ 112/* DMA not used; works around erratum writing to non-empty i2c fifo */
49 113
50static struct platform_device omap_i2c_device1 = { 114static struct platform_device omap_i2c_device1 = {
51 .name = "i2c_omap", 115 .name = "i2c_omap",
52 .id = 1, 116 .id = 1,
53 .num_resources = ARRAY_SIZE(i2c_resources1), 117 .num_resources = ARRAY_SIZE(i2c_resources1),
54 .resource = i2c_resources1, 118 .resource = i2c_resources1,
55}; 119};
@@ -376,7 +440,7 @@ static inline void omap_init_wdt(void) {}
376 440
377/*-------------------------------------------------------------------------*/ 441/*-------------------------------------------------------------------------*/
378 442
379#if defined(CONFIG_OMAP_RNG) || defined(CONFIG_OMAP_RNG_MODULE) 443#if defined(CONFIG_HW_RANDOM_OMAP) || defined(CONFIG_HW_RANDOM_OMAP_MODULE)
380 444
381#ifdef CONFIG_ARCH_OMAP24XX 445#ifdef CONFIG_ARCH_OMAP24XX
382#define OMAP_RNG_BASE 0x480A0000 446#define OMAP_RNG_BASE 0x480A0000
@@ -436,6 +500,7 @@ static int __init omap_init_devices(void)
436 /* please keep these calls, and their implementations above, 500 /* please keep these calls, and their implementations above,
437 * in alphabetical order so they're easier to sort through. 501 * in alphabetical order so they're easier to sort through.
438 */ 502 */
503 omap_init_dsp();
439 omap_init_i2c(); 504 omap_init_i2c();
440 omap_init_kp(); 505 omap_init_kp();
441 omap_init_mmc(); 506 omap_init_mmc();
@@ -446,4 +511,3 @@ static int __init omap_init_devices(void)
446 return 0; 511 return 0;
447} 512}
448arch_initcall(omap_init_devices); 513arch_initcall(omap_init_devices);
449
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index f3f84fbf8b87..2d86b106ff3e 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -925,10 +925,17 @@ static int omap2_dma_handle_ch(int ch)
925{ 925{
926 u32 status = OMAP_DMA_CSR_REG(ch); 926 u32 status = OMAP_DMA_CSR_REG(ch);
927 927
928 if (!status) 928 if (!status) {
929 if (printk_ratelimit())
930 printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n", ch);
929 return 0; 931 return 0;
930 if (unlikely(dma_chan[ch].dev_id == -1)) 932 }
933 if (unlikely(dma_chan[ch].dev_id == -1)) {
934 if (printk_ratelimit())
935 printk(KERN_WARNING "IRQ %04x for non-allocated DMA"
936 "channel %d\n", status, ch);
931 return 0; 937 return 0;
938 }
932 if (unlikely(status & OMAP_DMA_DROP_IRQ)) 939 if (unlikely(status & OMAP_DMA_DROP_IRQ))
933 printk(KERN_INFO 940 printk(KERN_INFO
934 "DMA synchronization event drop occurred with device " 941 "DMA synchronization event drop occurred with device "
@@ -959,11 +966,15 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
959 int i; 966 int i;
960 967
961 val = omap_readl(OMAP_DMA4_IRQSTATUS_L0); 968 val = omap_readl(OMAP_DMA4_IRQSTATUS_L0);
962 969 if (val == 0) {
963 for (i = 1; i <= OMAP_LOGICAL_DMA_CH_COUNT; i++) { 970 if (printk_ratelimit())
964 int active = val & (1 << (i - 1)); 971 printk(KERN_WARNING "Spurious DMA IRQ\n");
965 if (active) 972 return IRQ_HANDLED;
966 omap2_dma_handle_ch(i - 1); 973 }
974 for (i = 0; i < OMAP_LOGICAL_DMA_CH_COUNT && val != 0; i++) {
975 if (val & 1)
976 omap2_dma_handle_ch(i);
977 val >>= 1;
967 } 978 }
968 979
969 return IRQ_HANDLED; 980 return IRQ_HANDLED;
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 659619f235ca..36073dfaa4db 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -372,7 +372,7 @@ void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
372 372
373 /* When the functional clock disappears, too quick writes seem to 373 /* When the functional clock disappears, too quick writes seem to
374 * cause an abort. */ 374 * cause an abort. */
375 __delay(15000); 375 __delay(150000);
376} 376}
377 377
378#endif 378#endif
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index 56acb8720f78..4493bcff5172 100644
--- a/arch/arm/plat-omap/fb.c
+++ b/arch/arm/plat-omap/fb.c
@@ -1,3 +1,26 @@
1/*
2 * File: arch/arm/plat-omap/fb.c
3 *
4 * Framebuffer device registration for TI OMAP platforms
5 *
6 * Copyright (C) 2006 Nokia Corporation
7 * Author: Imre Deak <imre.deak@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
1#include <linux/module.h> 24#include <linux/module.h>
2#include <linux/kernel.h> 25#include <linux/kernel.h>
3#include <linux/init.h> 26#include <linux/init.h>
@@ -16,6 +39,8 @@
16#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE) 39#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
17 40
18static struct omapfb_platform_data omapfb_config; 41static struct omapfb_platform_data omapfb_config;
42static int config_invalid;
43static int configured_regions;
19 44
20static u64 omap_fb_dma_mask = ~(u32)0; 45static u64 omap_fb_dma_mask = ~(u32)0;
21 46
@@ -30,39 +55,270 @@ static struct platform_device omap_fb_device = {
30 .num_resources = 0, 55 .num_resources = 0,
31}; 56};
32 57
33/* called from map_io */ 58static inline int ranges_overlap(unsigned long start1, unsigned long size1,
34void omapfb_reserve_mem(void) 59 unsigned long start2, unsigned long size2)
35{ 60{
36 const struct omap_fbmem_config *fbmem_conf; 61 return (start1 >= start2 && start1 < start2 + size2) ||
62 (start2 >= start1 && start2 < start1 + size1);
63}
37 64
38 omapfb_config.fbmem.fb_sram_start = omap_fb_sram_start; 65static inline int range_included(unsigned long start1, unsigned long size1,
39 omapfb_config.fbmem.fb_sram_size = omap_fb_sram_size; 66 unsigned long start2, unsigned long size2)
67{
68 return start1 >= start2 && start1 + size1 <= start2 + size2;
69}
40 70
41 fbmem_conf = omap_get_config(OMAP_TAG_FBMEM, struct omap_fbmem_config);
42 71
43 if (fbmem_conf != NULL) { 72/* Check if there is an overlapping region. */
44 /* indicate that the bootloader already initialized the 73static int fbmem_region_reserved(unsigned long start, size_t size)
45 * fb device, so we'll skip that part in the fb driver 74{
46 */ 75 struct omapfb_mem_region *rg;
47 omapfb_config.fbmem.fb_sdram_start = fbmem_conf->fb_sdram_start; 76 int i;
48 omapfb_config.fbmem.fb_sdram_size = fbmem_conf->fb_sdram_size; 77
49 if (fbmem_conf->fb_sdram_size) { 78 rg = &omapfb_config.mem_desc.region[0];
50 pr_info("Reserving %u bytes SDRAM for frame buffer\n", 79 for (i = 0; i < OMAPFB_PLANE_NUM; i++, rg++) {
51 fbmem_conf->fb_sdram_size); 80 if (!rg->paddr)
52 reserve_bootmem(fbmem_conf->fb_sdram_start, 81 /* Empty slot. */
53 fbmem_conf->fb_sdram_size); 82 continue;
83 if (ranges_overlap(start, size, rg->paddr, rg->size))
84 return 1;
85 }
86 return 0;
87}
88
89/*
90 * Get the region_idx`th region from board config/ATAG and convert it to
91 * our internal format.
92 */
93static int get_fbmem_region(int region_idx, struct omapfb_mem_region *rg)
94{
95 const struct omap_fbmem_config *conf;
96 u32 paddr;
97
98 conf = omap_get_nr_config(OMAP_TAG_FBMEM,
99 struct omap_fbmem_config, region_idx);
100 if (conf == NULL)
101 return -ENOENT;
102
103 paddr = conf->start;
104 /*
105 * Low bits encode the page allocation mode, if high bits
106 * are zero. Otherwise we need a page aligned fixed
107 * address.
108 */
109 memset(rg, 0, sizeof(*rg));
110 rg->type = paddr & ~PAGE_MASK;
111 rg->paddr = paddr & PAGE_MASK;
112 rg->size = PAGE_ALIGN(conf->size);
113 return 0;
114}
115
116static int set_fbmem_region_type(struct omapfb_mem_region *rg, int mem_type,
117 unsigned long mem_start,
118 unsigned long mem_size)
119{
120 /*
121 * Check if the configuration specifies the type explicitly.
122 * type = 0 && paddr = 0, a default don't care case maps to
123 * the SDRAM type.
124 */
125 if (rg->type || (!rg->type && !rg->paddr))
126 return 0;
127 if (ranges_overlap(rg->paddr, rg->size, mem_start, mem_size)) {
128 rg->type = mem_type;
129 return 0;
130 }
131 /* Can't determine it. */
132 return -1;
133}
134
135static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg,
136 unsigned long start_avail, unsigned size_avail)
137{
138 unsigned long paddr = rg->paddr;
139 size_t size = rg->size;
140
141 if (rg->type > OMAPFB_MEMTYPE_MAX) {
142 printk(KERN_ERR
143 "Invalid start address for FB region %d\n", region_idx);
144 return -EINVAL;
145 }
146
147 if (!rg->size) {
148 printk(KERN_ERR "Zero size for FB region %d\n", region_idx);
149 return -EINVAL;
150 }
151
152 if (!paddr)
153 /* Allocate this dynamically, leave paddr 0 for now. */
154 return 0;
155
156 /*
157 * Fixed region for the given RAM range. Check if it's already
158 * reserved by the FB code or someone else.
159 */
160 if (fbmem_region_reserved(paddr, size) ||
161 !range_included(paddr, size, start_avail, size_avail)) {
162 printk(KERN_ERR "Trying to use reserved memory "
163 "for FB region %d\n", region_idx);
164 return -EINVAL;
165 }
166
167 return 0;
168}
169
170/*
171 * Called from map_io. We need to call to this early enough so that we
172 * can reserve the fixed SDRAM regions before VM could get hold of them.
173 */
174void omapfb_reserve_sdram(void)
175{
176 struct bootmem_data *bdata;
177 unsigned long sdram_start, sdram_size;
178 unsigned long reserved;
179 int i;
180
181 if (config_invalid)
182 return;
183
184 bdata = NODE_DATA(0)->bdata;
185 sdram_start = bdata->node_boot_start;
186 sdram_size = (bdata->node_low_pfn << PAGE_SHIFT) - sdram_start;
187 reserved = 0;
188 for (i = 0; ; i++) {
189 struct omapfb_mem_region rg;
190
191 if (get_fbmem_region(i, &rg) < 0)
192 break;
193 if (i == OMAPFB_PLANE_NUM) {
194 printk(KERN_ERR
195 "Extraneous FB mem configuration entries\n");
196 config_invalid = 1;
197 return;
54 } 198 }
199 /* Check if it's our memory type. */
200 if (set_fbmem_region_type(&rg, OMAPFB_MEMTYPE_SDRAM,
201 sdram_start, sdram_size) < 0 ||
202 (rg.type != OMAPFB_MEMTYPE_SDRAM))
203 continue;
204 BUG_ON(omapfb_config.mem_desc.region[i].size);
205 if (check_fbmem_region(i, &rg, sdram_start, sdram_size) < 0) {
206 config_invalid = 1;
207 return;
208 }
209 if (rg.paddr)
210 reserve_bootmem(rg.paddr, rg.size);
211 reserved += rg.size;
212 omapfb_config.mem_desc.region[i] = rg;
213 configured_regions++;
55 } 214 }
215 omapfb_config.mem_desc.region_cnt = i;
216 if (reserved)
217 pr_info("Reserving %lu bytes SDRAM for frame buffer\n",
218 reserved);
219}
220
221/*
222 * Called at sram init time, before anything is pushed to the SRAM stack.
223 * Because of the stack scheme, we will allocate everything from the
224 * start of the lowest address region to the end of SRAM. This will also
225 * include padding for page alignment and possible holes between regions.
226 *
227 * As opposed to the SDRAM case, we'll also do any dynamic allocations at
228 * this point, since the driver built as a module would have problem with
229 * freeing / reallocating the regions.
230 */
231unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
232 unsigned long sram_vstart,
233 unsigned long sram_size,
234 unsigned long pstart_avail,
235 unsigned long size_avail)
236{
237 struct omapfb_mem_region rg;
238 unsigned long pend_avail;
239 unsigned long reserved;
240 int i;
241
242 if (config_invalid)
243 return 0;
244
245 reserved = 0;
246 pend_avail = pstart_avail + size_avail;
247 for (i = 0; ; i++) {
248 if (get_fbmem_region(i, &rg) < 0)
249 break;
250 if (i == OMAPFB_PLANE_NUM) {
251 printk(KERN_ERR
252 "Extraneous FB mem configuration entries\n");
253 config_invalid = 1;
254 return 0;
255 }
256
257 /* Check if it's our memory type. */
258 if (set_fbmem_region_type(&rg, OMAPFB_MEMTYPE_SRAM,
259 sram_pstart, sram_size) < 0 ||
260 (rg.type != OMAPFB_MEMTYPE_SRAM))
261 continue;
262 BUG_ON(omapfb_config.mem_desc.region[i].size);
263
264 if (check_fbmem_region(i, &rg, pstart_avail, size_avail) < 0) {
265 config_invalid = 1;
266 return 0;
267 }
268
269 if (!rg.paddr) {
270 /* Dynamic allocation */
271 if ((size_avail & PAGE_MASK) < rg.size) {
272 printk("Not enough SRAM for FB region %d\n",
273 i);
274 config_invalid = 1;
275 return 0;
276 }
277 size_avail = (size_avail - rg.size) & PAGE_MASK;
278 rg.paddr = pstart_avail + size_avail;
279 }
280 /* Reserve everything above the start of the region. */
281 if (pend_avail - rg.paddr > reserved)
282 reserved = pend_avail - rg.paddr;
283 size_avail = pend_avail - reserved - pstart_avail;
284
285 /*
286 * We have a kernel mapping for this already, so the
287 * driver won't have to make one.
288 */
289 rg.vaddr = (void *)(sram_vstart + rg.paddr - sram_pstart);
290 omapfb_config.mem_desc.region[i] = rg;
291 configured_regions++;
292 }
293 omapfb_config.mem_desc.region_cnt = i;
294 if (reserved)
295 pr_info("Reserving %lu bytes SRAM for frame buffer\n",
296 reserved);
297 return reserved;
298}
299
300void omapfb_set_ctrl_platform_data(void *data)
301{
302 omapfb_config.ctrl_platform_data = data;
56} 303}
57 304
58static inline int omap_init_fb(void) 305static inline int omap_init_fb(void)
59{ 306{
60 const struct omap_lcd_config *conf; 307 const struct omap_lcd_config *conf;
61 308
309 if (config_invalid)
310 return 0;
311 if (configured_regions != omapfb_config.mem_desc.region_cnt) {
312 printk(KERN_ERR "Invalid FB mem configuration entries\n");
313 return 0;
314 }
62 conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config); 315 conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
63 if (conf == NULL) 316 if (conf == NULL) {
317 if (configured_regions)
318 /* FB mem config, but no LCD config? */
319 printk(KERN_ERR "Missing LCD configuration\n");
64 return 0; 320 return 0;
65 321 }
66 omapfb_config.lcd = *conf; 322 omapfb_config.lcd = *conf;
67 323
68 return platform_device_register(&omap_fb_device); 324 return platform_device_register(&omap_fb_device);
@@ -72,7 +328,16 @@ arch_initcall(omap_init_fb);
72 328
73#else 329#else
74 330
75void omapfb_reserve_mem(void) {} 331void omapfb_reserve_sdram(void) {}
332unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
333 unsigned long sram_vstart,
334 unsigned long sram_size,
335 unsigned long start_avail,
336 unsigned long size_avail)
337{
338 return 0;
339}
340
76 341
77#endif 342#endif
78 343
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 9dc6d3617bdb..337455dfe64d 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -13,7 +13,6 @@
13 13
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/sched.h>
17#include <linux/interrupt.h> 16#include <linux/interrupt.h>
18#include <linux/sysdev.h> 17#include <linux/sysdev.h>
19#include <linux/err.h> 18#include <linux/err.h>
@@ -1545,7 +1544,7 @@ void omap2_gpio_resume_after_retention(void)
1545 * This may get called early from board specific init 1544 * This may get called early from board specific init
1546 * for boards that have interrupts routed via FPGA. 1545 * for boards that have interrupts routed via FPGA.
1547 */ 1546 */
1548int omap_gpio_init(void) 1547int __init omap_gpio_init(void)
1549{ 1548{
1550 if (!initialized) 1549 if (!initialized)
1551 return _omap_gpio_init(); 1550 return _omap_gpio_init();
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
new file mode 100644
index 000000000000..de7e6ef48bd0
--- /dev/null
+++ b/arch/arm/plat-omap/mailbox.c
@@ -0,0 +1,509 @@
1/*
2 * OMAP mailbox driver
3 *
4 * Copyright (C) 2006 Nokia Corporation. All rights reserved.
5 *
6 * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
7 * Restructured by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#include <linux/init.h>
26#include <linux/module.h>
27#include <linux/sched.h>
28#include <linux/interrupt.h>
29#include <linux/device.h>
30#include <linux/blkdev.h>
31#include <linux/err.h>
32#include <linux/delay.h>
33#include <asm/io.h>
34#include <asm/arch/mailbox.h>
35#include "mailbox.h"
36
37static struct omap_mbox *mboxes;
38static DEFINE_RWLOCK(mboxes_lock);
39
40/* Mailbox Sequence Bit function */
41void omap_mbox_init_seq(struct omap_mbox *mbox)
42{
43 mbox_seq_init(mbox);
44}
45EXPORT_SYMBOL(omap_mbox_init_seq);
46
47/*
48 * message sender
49 */
50static int __mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void *arg)
51{
52 int ret = 0, i = 1000;
53
54 while (mbox_fifo_full(mbox)) {
55 if (mbox->ops->type == OMAP_MBOX_TYPE2)
56 return -1;
57 if (--i == 0)
58 return -1;
59 udelay(1);
60 }
61
62 if (arg && mbox->txq->callback) {
63 ret = mbox->txq->callback(arg);
64 if (ret)
65 goto out;
66 }
67
68 mbox_seq_toggle(mbox, &msg);
69 mbox_fifo_write(mbox, msg);
70 out:
71 return ret;
72}
73
74int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void* arg)
75{
76 struct request *rq;
77 struct request_queue *q = mbox->txq->queue;
78 int ret = 0;
79
80 rq = blk_get_request(q, WRITE, GFP_ATOMIC);
81 if (unlikely(!rq)) {
82 ret = -ENOMEM;
83 goto fail;
84 }
85
86 rq->data = (void *)msg;
87 blk_insert_request(q, rq, 0, arg);
88
89 schedule_work(&mbox->txq->work);
90 fail:
91 return ret;
92}
93EXPORT_SYMBOL(omap_mbox_msg_send);
94
95static void mbox_tx_work(struct work_struct *work)
96{
97 int ret;
98 struct request *rq;
99 struct omap_mbox_queue *mq = container_of(work,
100 struct omap_mbox_queue, work);
101 struct omap_mbox *mbox = mq->queue->queuedata;
102 struct request_queue *q = mbox->txq->queue;
103
104 while (1) {
105 spin_lock(q->queue_lock);
106 rq = elv_next_request(q);
107 spin_unlock(q->queue_lock);
108
109 if (!rq)
110 break;
111
112 ret = __mbox_msg_send(mbox, (mbox_msg_t) rq->data, rq->special);
113 if (ret) {
114 enable_mbox_irq(mbox, IRQ_TX);
115 return;
116 }
117
118 spin_lock(q->queue_lock);
119 blkdev_dequeue_request(rq);
120 end_that_request_last(rq, 0);
121 spin_unlock(q->queue_lock);
122 }
123}
124
125/*
126 * Message receiver(workqueue)
127 */
128static void mbox_rx_work(struct work_struct *work)
129{
130 struct omap_mbox_queue *mq =
131 container_of(work, struct omap_mbox_queue, work);
132 struct omap_mbox *mbox = mq->queue->queuedata;
133 struct request_queue *q = mbox->rxq->queue;
134 struct request *rq;
135 mbox_msg_t msg;
136 unsigned long flags;
137
138 if (mbox->rxq->callback == NULL) {
139 sysfs_notify(&mbox->dev.kobj, NULL, "mbox");
140 return;
141 }
142
143 while (1) {
144 spin_lock_irqsave(q->queue_lock, flags);
145 rq = elv_next_request(q);
146 spin_unlock_irqrestore(q->queue_lock, flags);
147 if (!rq)
148 break;
149
150 msg = (mbox_msg_t) rq->data;
151
152 spin_lock_irqsave(q->queue_lock, flags);
153 blkdev_dequeue_request(rq);
154 end_that_request_last(rq, 0);
155 spin_unlock_irqrestore(q->queue_lock, flags);
156
157 mbox->rxq->callback((void *)msg);
158 }
159}
160
161/*
162 * Mailbox interrupt handler
163 */
164static void mbox_txq_fn(request_queue_t * q)
165{
166}
167
168static void mbox_rxq_fn(request_queue_t * q)
169{
170}
171
172static void __mbox_tx_interrupt(struct omap_mbox *mbox)
173{
174 disable_mbox_irq(mbox, IRQ_TX);
175 ack_mbox_irq(mbox, IRQ_TX);
176 schedule_work(&mbox->txq->work);
177}
178
179static void __mbox_rx_interrupt(struct omap_mbox *mbox)
180{
181 struct request *rq;
182 mbox_msg_t msg;
183 request_queue_t *q = mbox->rxq->queue;
184
185 disable_mbox_irq(mbox, IRQ_RX);
186
187 while (!mbox_fifo_empty(mbox)) {
188 rq = blk_get_request(q, WRITE, GFP_ATOMIC);
189 if (unlikely(!rq))
190 goto nomem;
191
192 msg = mbox_fifo_read(mbox);
193 rq->data = (void *)msg;
194
195 if (unlikely(mbox_seq_test(mbox, msg))) {
196 pr_info("mbox: Illegal seq bit!(%08x)\n", msg);
197 if (mbox->err_notify)
198 mbox->err_notify();
199 }
200
201 blk_insert_request(q, rq, 0, NULL);
202 if (mbox->ops->type == OMAP_MBOX_TYPE1)
203 break;
204 }
205
206 /* no more messages in the fifo. clear IRQ source. */
207 ack_mbox_irq(mbox, IRQ_RX);
208 enable_mbox_irq(mbox, IRQ_RX);
209 nomem:
210 schedule_work(&mbox->rxq->work);
211}
212
213static irqreturn_t mbox_interrupt(int irq, void *p)
214{
215 struct omap_mbox *mbox = (struct omap_mbox *)p;
216
217 if (is_mbox_irq(mbox, IRQ_TX))
218 __mbox_tx_interrupt(mbox);
219
220 if (is_mbox_irq(mbox, IRQ_RX))
221 __mbox_rx_interrupt(mbox);
222
223 return IRQ_HANDLED;
224}
225
226/*
227 * sysfs files
228 */
229static ssize_t
230omap_mbox_write(struct device *dev, struct device_attribute *attr,
231 const char * buf, size_t count)
232{
233 int ret;
234 mbox_msg_t *p = (mbox_msg_t *)buf;
235 struct omap_mbox *mbox = dev_get_drvdata(dev);
236
237 for (; count >= sizeof(mbox_msg_t); count -= sizeof(mbox_msg_t)) {
238 ret = omap_mbox_msg_send(mbox, be32_to_cpu(*p), NULL);
239 if (ret)
240 return -EAGAIN;
241 p++;
242 }
243
244 return (size_t)((char *)p - buf);
245}
246
247static ssize_t
248omap_mbox_read(struct device *dev, struct device_attribute *attr, char *buf)
249{
250 unsigned long flags;
251 struct request *rq;
252 mbox_msg_t *p = (mbox_msg_t *) buf;
253 struct omap_mbox *mbox = dev_get_drvdata(dev);
254 struct request_queue *q = mbox->rxq->queue;
255
256 while (1) {
257 spin_lock_irqsave(q->queue_lock, flags);
258 rq = elv_next_request(q);
259 spin_unlock_irqrestore(q->queue_lock, flags);
260
261 if (!rq)
262 break;
263
264 *p = (mbox_msg_t) rq->data;
265
266 spin_lock_irqsave(q->queue_lock, flags);
267 blkdev_dequeue_request(rq);
268 end_that_request_last(rq, 0);
269 spin_unlock_irqrestore(q->queue_lock, flags);
270
271 if (unlikely(mbox_seq_test(mbox, *p))) {
272 pr_info("mbox: Illegal seq bit!(%08x) ignored\n", *p);
273 continue;
274 }
275 p++;
276 }
277
278 pr_debug("%02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]);
279
280 return (size_t) ((char *)p - buf);
281}
282
283static DEVICE_ATTR(mbox, S_IRUGO | S_IWUSR, omap_mbox_read, omap_mbox_write);
284
285static ssize_t mbox_show(struct class *class, char *buf)
286{
287 return sprintf(buf, "mbox");
288}
289
290static CLASS_ATTR(mbox, S_IRUGO, mbox_show, NULL);
291
292static struct class omap_mbox_class = {
293 .name = "omap_mbox",
294};
295
296static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
297 request_fn_proc * proc,
298 void (*work) (struct work_struct *))
299{
300 request_queue_t *q;
301 struct omap_mbox_queue *mq;
302
303 mq = kzalloc(sizeof(struct omap_mbox_queue), GFP_KERNEL);
304 if (!mq)
305 return NULL;
306
307 spin_lock_init(&mq->lock);
308
309 q = blk_init_queue(proc, &mq->lock);
310 if (!q)
311 goto error;
312 q->queuedata = mbox;
313 mq->queue = q;
314
315 INIT_WORK(&mq->work, work);
316
317 return mq;
318error:
319 kfree(mq);
320 return NULL;
321}
322
323static void mbox_queue_free(struct omap_mbox_queue *q)
324{
325 blk_cleanup_queue(q->queue);
326 kfree(q);
327}
328
329static int omap_mbox_init(struct omap_mbox *mbox)
330{
331 int ret;
332 struct omap_mbox_queue *mq;
333
334 if (likely(mbox->ops->startup)) {
335 ret = mbox->ops->startup(mbox);
336 if (unlikely(ret))
337 return ret;
338 }
339
340 mbox->dev.class = &omap_mbox_class;
341 strlcpy(mbox->dev.bus_id, mbox->name, KOBJ_NAME_LEN);
342 dev_set_drvdata(&mbox->dev, mbox);
343
344 ret = device_register(&mbox->dev);
345 if (unlikely(ret))
346 goto fail_device_reg;
347
348 ret = device_create_file(&mbox->dev, &dev_attr_mbox);
349 if (unlikely(ret)) {
350 printk(KERN_ERR
351 "device_create_file failed: %d\n", ret);
352 goto fail_create_mbox;
353 }
354
355 ret = request_irq(mbox->irq, mbox_interrupt, IRQF_DISABLED,
356 mbox->name, mbox);
357 if (unlikely(ret)) {
358 printk(KERN_ERR
359 "failed to register mailbox interrupt:%d\n", ret);
360 goto fail_request_irq;
361 }
362 enable_mbox_irq(mbox, IRQ_RX);
363
364 mq = mbox_queue_alloc(mbox, mbox_txq_fn, mbox_tx_work);
365 if (!mq) {
366 ret = -ENOMEM;
367 goto fail_alloc_txq;
368 }
369 mbox->txq = mq;
370
371 mq = mbox_queue_alloc(mbox, mbox_rxq_fn, mbox_rx_work);
372 if (!mq) {
373 ret = -ENOMEM;
374 goto fail_alloc_rxq;
375 }
376 mbox->rxq = mq;
377
378 return 0;
379
380 fail_alloc_rxq:
381 mbox_queue_free(mbox->txq);
382 fail_alloc_txq:
383 free_irq(mbox->irq, mbox);
384 fail_request_irq:
385 device_remove_file(&mbox->dev, &dev_attr_mbox);
386 fail_create_mbox:
387 device_unregister(&mbox->dev);
388 fail_device_reg:
389 if (unlikely(mbox->ops->shutdown))
390 mbox->ops->shutdown(mbox);
391
392 return ret;
393}
394
395static void omap_mbox_fini(struct omap_mbox *mbox)
396{
397 mbox_queue_free(mbox->txq);
398 mbox_queue_free(mbox->rxq);
399
400 free_irq(mbox->irq, mbox);
401 device_remove_file(&mbox->dev, &dev_attr_mbox);
402 class_unregister(&omap_mbox_class);
403
404 if (unlikely(mbox->ops->shutdown))
405 mbox->ops->shutdown(mbox);
406}
407
408static struct omap_mbox **find_mboxes(const char *name)
409{
410 struct omap_mbox **p;
411
412 for (p = &mboxes; *p; p = &(*p)->next) {
413 if (strcmp((*p)->name, name) == 0)
414 break;
415 }
416
417 return p;
418}
419
420struct omap_mbox *omap_mbox_get(const char *name)
421{
422 struct omap_mbox *mbox;
423 int ret;
424
425 read_lock(&mboxes_lock);
426 mbox = *(find_mboxes(name));
427 if (mbox == NULL) {
428 read_unlock(&mboxes_lock);
429 return ERR_PTR(-ENOENT);
430 }
431
432 read_unlock(&mboxes_lock);
433
434 ret = omap_mbox_init(mbox);
435 if (ret)
436 return ERR_PTR(-ENODEV);
437
438 return mbox;
439}
440EXPORT_SYMBOL(omap_mbox_get);
441
442void omap_mbox_put(struct omap_mbox *mbox)
443{
444 omap_mbox_fini(mbox);
445}
446EXPORT_SYMBOL(omap_mbox_put);
447
448int omap_mbox_register(struct omap_mbox *mbox)
449{
450 int ret = 0;
451 struct omap_mbox **tmp;
452
453 if (!mbox)
454 return -EINVAL;
455 if (mbox->next)
456 return -EBUSY;
457
458 write_lock(&mboxes_lock);
459 tmp = find_mboxes(mbox->name);
460 if (*tmp)
461 ret = -EBUSY;
462 else
463 *tmp = mbox;
464 write_unlock(&mboxes_lock);
465
466 return ret;
467}
468EXPORT_SYMBOL(omap_mbox_register);
469
470int omap_mbox_unregister(struct omap_mbox *mbox)
471{
472 struct omap_mbox **tmp;
473
474 write_lock(&mboxes_lock);
475 tmp = &mboxes;
476 while (*tmp) {
477 if (mbox == *tmp) {
478 *tmp = mbox->next;
479 mbox->next = NULL;
480 write_unlock(&mboxes_lock);
481 return 0;
482 }
483 tmp = &(*tmp)->next;
484 }
485 write_unlock(&mboxes_lock);
486
487 return -EINVAL;
488}
489EXPORT_SYMBOL(omap_mbox_unregister);
490
491static int __init omap_mbox_class_init(void)
492{
493 int ret = class_register(&omap_mbox_class);
494 if (!ret)
495 ret = class_create_file(&omap_mbox_class, &class_attr_mbox);
496
497 return ret;
498}
499
500static void __exit omap_mbox_class_exit(void)
501{
502 class_remove_file(&omap_mbox_class, &class_attr_mbox);
503 class_unregister(&omap_mbox_class);
504}
505
506subsys_initcall(omap_mbox_class_init);
507module_exit(omap_mbox_class_exit);
508
509MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-omap/mailbox.h b/arch/arm/plat-omap/mailbox.h
new file mode 100644
index 000000000000..67c6740b8ad5
--- /dev/null
+++ b/arch/arm/plat-omap/mailbox.h
@@ -0,0 +1,100 @@
1/*
2 * Mailbox internal functions
3 *
4 * Copyright (C) 2006 Nokia Corporation
5 * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11
12#ifndef __ARCH_ARM_PLAT_MAILBOX_H
13#define __ARCH_ARM_PLAT_MAILBOX_H
14
15/*
16 * Mailbox sequence bit API
17 */
18#if defined(CONFIG_ARCH_OMAP1)
19# define MBOX_USE_SEQ_BIT
20#elif defined(CONFIG_ARCH_OMAP2)
21# define MBOX_USE_SEQ_BIT
22#endif
23
24#ifdef MBOX_USE_SEQ_BIT
25/* seq_rcv should be initialized with any value other than
26 * 0 and 1 << 31, to allow either value for the first
27 * message. */
28static inline void mbox_seq_init(struct omap_mbox *mbox)
29{
30 /* any value other than 0 and 1 << 31 */
31 mbox->seq_rcv = 0xffffffff;
32}
33
34static inline void mbox_seq_toggle(struct omap_mbox *mbox, mbox_msg_t * msg)
35{
36 /* add seq_snd to msg */
37 *msg = (*msg & 0x7fffffff) | mbox->seq_snd;
38 /* flip seq_snd */
39 mbox->seq_snd ^= 1 << 31;
40}
41
42static inline int mbox_seq_test(struct omap_mbox *mbox, mbox_msg_t msg)
43{
44 mbox_msg_t seq = msg & (1 << 31);
45 if (seq == mbox->seq_rcv)
46 return -1;
47 mbox->seq_rcv = seq;
48 return 0;
49}
50#else
51static inline void mbox_seq_init(struct omap_mbox *mbox)
52{
53}
54static inline void mbox_seq_toggle(struct omap_mbox *mbox, mbox_msg_t * msg)
55{
56}
57static inline int mbox_seq_test(struct omap_mbox *mbox, mbox_msg_t msg)
58{
59 return 0;
60}
61#endif
62
63/* Mailbox FIFO handle functions */
64static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
65{
66 return mbox->ops->fifo_read(mbox);
67}
68static inline void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
69{
70 mbox->ops->fifo_write(mbox, msg);
71}
72static inline int mbox_fifo_empty(struct omap_mbox *mbox)
73{
74 return mbox->ops->fifo_empty(mbox);
75}
76static inline int mbox_fifo_full(struct omap_mbox *mbox)
77{
78 return mbox->ops->fifo_full(mbox);
79}
80
81/* Mailbox IRQ handle functions */
82static inline void enable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
83{
84 mbox->ops->enable_irq(mbox, irq);
85}
86static inline void disable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
87{
88 mbox->ops->disable_irq(mbox, irq);
89}
90static inline void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
91{
92 if (mbox->ops->ack_irq)
93 mbox->ops->ack_irq(mbox, irq);
94}
95static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
96{
97 return mbox->ops->is_irq(mbox, irq);
98}
99
100#endif /* __ARCH_ARM_PLAT_MAILBOX_H */
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 19014b2ff4c6..bc46f33aede3 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -46,14 +46,19 @@
46 46
47#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) 47#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
48 48
49static unsigned long omap_sram_start;
49static unsigned long omap_sram_base; 50static unsigned long omap_sram_base;
50static unsigned long omap_sram_size; 51static unsigned long omap_sram_size;
51static unsigned long omap_sram_ceil; 52static unsigned long omap_sram_ceil;
52 53
53unsigned long omap_fb_sram_start; 54extern unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
54unsigned long omap_fb_sram_size; 55 unsigned long sram_vstart,
56 unsigned long sram_size,
57 unsigned long pstart_avail,
58 unsigned long size_avail);
55 59
56/* Depending on the target RAMFS firewall setup, the public usable amount of 60/*
61 * Depending on the target RAMFS firewall setup, the public usable amount of
57 * SRAM varies. The default accessable size for all device types is 2k. A GP 62 * SRAM varies. The default accessable size for all device types is 2k. A GP
58 * device allows ARM11 but not other initators for full size. This 63 * device allows ARM11 but not other initators for full size. This
59 * functionality seems ok until some nice security API happens. 64 * functionality seems ok until some nice security API happens.
@@ -77,32 +82,6 @@ static int is_sram_locked(void)
77 return 1; /* assume locked with no PPA or security driver */ 82 return 1; /* assume locked with no PPA or security driver */
78} 83}
79 84
80void get_fb_sram_conf(unsigned long start_avail, unsigned size_avail,
81 unsigned long *start, unsigned long *size)
82{
83 const struct omap_fbmem_config *fbmem_conf;
84
85 fbmem_conf = omap_get_config(OMAP_TAG_FBMEM, struct omap_fbmem_config);
86 if (fbmem_conf != NULL) {
87 *start = fbmem_conf->fb_sram_start;
88 *size = fbmem_conf->fb_sram_size;
89 } else {
90 *size = 0;
91 *start = 0;
92 }
93
94 if (*size && (
95 *start < start_avail ||
96 *start + *size > start_avail + size_avail)) {
97 printk(KERN_ERR "invalid FB SRAM configuration\n");
98 *start = start_avail;
99 *size = size_avail;
100 }
101
102 if (*size)
103 pr_info("Reserving %lu bytes SRAM for frame buffer\n", *size);
104}
105
106/* 85/*
107 * The amount of SRAM depends on the core type. 86 * The amount of SRAM depends on the core type.
108 * Note that we cannot try to test for SRAM here because writes 87 * Note that we cannot try to test for SRAM here because writes
@@ -111,16 +90,16 @@ void get_fb_sram_conf(unsigned long start_avail, unsigned size_avail,
111 */ 90 */
112void __init omap_detect_sram(void) 91void __init omap_detect_sram(void)
113{ 92{
114 unsigned long sram_start; 93 unsigned long reserved;
115 94
116 if (cpu_is_omap24xx()) { 95 if (cpu_is_omap24xx()) {
117 if (is_sram_locked()) { 96 if (is_sram_locked()) {
118 omap_sram_base = OMAP2_SRAM_PUB_VA; 97 omap_sram_base = OMAP2_SRAM_PUB_VA;
119 sram_start = OMAP2_SRAM_PUB_PA; 98 omap_sram_start = OMAP2_SRAM_PUB_PA;
120 omap_sram_size = 0x800; /* 2K */ 99 omap_sram_size = 0x800; /* 2K */
121 } else { 100 } else {
122 omap_sram_base = OMAP2_SRAM_VA; 101 omap_sram_base = OMAP2_SRAM_VA;
123 sram_start = OMAP2_SRAM_PA; 102 omap_sram_start = OMAP2_SRAM_PA;
124 if (cpu_is_omap242x()) 103 if (cpu_is_omap242x())
125 omap_sram_size = 0xa0000; /* 640K */ 104 omap_sram_size = 0xa0000; /* 640K */
126 else if (cpu_is_omap243x()) 105 else if (cpu_is_omap243x())
@@ -128,7 +107,7 @@ void __init omap_detect_sram(void)
128 } 107 }
129 } else { 108 } else {
130 omap_sram_base = OMAP1_SRAM_VA; 109 omap_sram_base = OMAP1_SRAM_VA;
131 sram_start = OMAP1_SRAM_PA; 110 omap_sram_start = OMAP1_SRAM_PA;
132 111
133 if (cpu_is_omap730()) 112 if (cpu_is_omap730())
134 omap_sram_size = 0x32000; /* 200K */ 113 omap_sram_size = 0x32000; /* 200K */
@@ -144,12 +123,11 @@ void __init omap_detect_sram(void)
144 omap_sram_size = 0x4000; 123 omap_sram_size = 0x4000;
145 } 124 }
146 } 125 }
147 get_fb_sram_conf(sram_start + SRAM_BOOTLOADER_SZ, 126 reserved = omapfb_reserve_sram(omap_sram_start, omap_sram_base,
148 omap_sram_size - SRAM_BOOTLOADER_SZ, 127 omap_sram_size,
149 &omap_fb_sram_start, &omap_fb_sram_size); 128 omap_sram_start + SRAM_BOOTLOADER_SZ,
150 if (omap_fb_sram_size) 129 omap_sram_size - SRAM_BOOTLOADER_SZ);
151 omap_sram_size -= sram_start + omap_sram_size - 130 omap_sram_size -= reserved;
152 omap_fb_sram_start;
153 omap_sram_ceil = omap_sram_base + omap_sram_size; 131 omap_sram_ceil = omap_sram_base + omap_sram_size;
154} 132}
155 133
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
index 7e8096809be2..25489aafb113 100644
--- a/arch/arm/plat-omap/usb.c
+++ b/arch/arm/plat-omap/usb.c
@@ -37,9 +37,27 @@
37#include <asm/arch/usb.h> 37#include <asm/arch/usb.h>
38#include <asm/arch/board.h> 38#include <asm/arch/board.h>
39 39
40#ifdef CONFIG_ARCH_OMAP1
41
42#define INT_USB_IRQ_GEN IH2_BASE + 20
43#define INT_USB_IRQ_NISO IH2_BASE + 30
44#define INT_USB_IRQ_ISO IH2_BASE + 29
45#define INT_USB_IRQ_HGEN INT_USB_HHC_1
46#define INT_USB_IRQ_OTG IH2_BASE + 8
47
48#else
49
50#define INT_USB_IRQ_GEN INT_24XX_USB_IRQ_GEN
51#define INT_USB_IRQ_NISO INT_24XX_USB_IRQ_NISO
52#define INT_USB_IRQ_ISO INT_24XX_USB_IRQ_ISO
53#define INT_USB_IRQ_HGEN INT_24XX_USB_IRQ_HGEN
54#define INT_USB_IRQ_OTG INT_24XX_USB_IRQ_OTG
55
56#endif
57
58
40/* These routines should handle the standard chip-specific modes 59/* These routines should handle the standard chip-specific modes
41 * for usb0/1/2 ports, covering basic mux and transceiver setup. 60 * for usb0/1/2 ports, covering basic mux and transceiver setup.
42 * Call omap_usb_init() once, from INIT_MACHINE().
43 * 61 *
44 * Some board-*.c files will need to set up additional mux options, 62 * Some board-*.c files will need to set up additional mux options,
45 * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup. 63 * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.
@@ -96,19 +114,26 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
96{ 114{
97 u32 syscon1 = 0; 115 u32 syscon1 = 0;
98 116
117 if (cpu_is_omap24xx())
118 CONTROL_DEVCONF_REG &= ~USBT0WRMODEI(USB_BIDIR_TLL);
119
99 if (nwires == 0) { 120 if (nwires == 0) {
100 if (!cpu_is_omap15xx()) { 121 if (cpu_class_is_omap1() && !cpu_is_omap15xx()) {
101 /* pulldown D+/D- */ 122 /* pulldown D+/D- */
102 USB_TRANSCEIVER_CTRL_REG &= ~(3 << 1); 123 USB_TRANSCEIVER_CTRL_REG &= ~(3 << 1);
103 } 124 }
104 return 0; 125 return 0;
105 } 126 }
106 127
107 if (is_device) 128 if (is_device) {
108 omap_cfg_reg(W4_USB_PUEN); 129 if (cpu_is_omap24xx())
130 omap_cfg_reg(J20_24XX_USB0_PUEN);
131 else
132 omap_cfg_reg(W4_USB_PUEN);
133 }
109 134
110 /* internal transceiver */ 135 /* internal transceiver (unavailable on 17xx, 24xx) */
111 if (nwires == 2) { 136 if (!cpu_class_is_omap2() && nwires == 2) {
112 // omap_cfg_reg(P9_USB_DP); 137 // omap_cfg_reg(P9_USB_DP);
113 // omap_cfg_reg(R8_USB_DM); 138 // omap_cfg_reg(R8_USB_DM);
114 139
@@ -136,29 +161,50 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
136 return 0; 161 return 0;
137 } 162 }
138 163
139 omap_cfg_reg(V6_USB0_TXD); 164 if (cpu_is_omap24xx()) {
140 omap_cfg_reg(W9_USB0_TXEN); 165 omap_cfg_reg(K18_24XX_USB0_DAT);
141 omap_cfg_reg(W5_USB0_SE0); 166 omap_cfg_reg(K19_24XX_USB0_TXEN);
167 omap_cfg_reg(J14_24XX_USB0_SE0);
168 if (nwires != 3)
169 omap_cfg_reg(J18_24XX_USB0_RCV);
170 } else {
171 omap_cfg_reg(V6_USB0_TXD);
172 omap_cfg_reg(W9_USB0_TXEN);
173 omap_cfg_reg(W5_USB0_SE0);
174 if (nwires != 3)
175 omap_cfg_reg(Y5_USB0_RCV);
176 }
142 177
143 /* NOTE: SPEED and SUSP aren't configured here */ 178 /* NOTE: SPEED and SUSP aren't configured here. OTG hosts
179 * may be able to use I2C requests to set those bits along
180 * with VBUS switching and overcurrent detction.
181 */
144 182
145 if (nwires != 3) 183 if (cpu_class_is_omap1() && nwires != 6)
146 omap_cfg_reg(Y5_USB0_RCV);
147 if (nwires != 6)
148 USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R; 184 USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
149 185
150 switch (nwires) { 186 switch (nwires) {
151 case 3: 187 case 3:
152 syscon1 = 2; 188 syscon1 = 2;
189 if (cpu_is_omap24xx())
190 CONTROL_DEVCONF_REG |= USBT0WRMODEI(USB_BIDIR);
153 break; 191 break;
154 case 4: 192 case 4:
155 syscon1 = 1; 193 syscon1 = 1;
194 if (cpu_is_omap24xx())
195 CONTROL_DEVCONF_REG |= USBT0WRMODEI(USB_BIDIR);
156 break; 196 break;
157 case 6: 197 case 6:
158 syscon1 = 3; 198 syscon1 = 3;
159 omap_cfg_reg(AA9_USB0_VP); 199 if (cpu_is_omap24xx()) {
160 omap_cfg_reg(R9_USB0_VM); 200 omap_cfg_reg(J19_24XX_USB0_VP);
161 USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R; 201 omap_cfg_reg(K20_24XX_USB0_VM);
202 CONTROL_DEVCONF_REG |= USBT0WRMODEI(USB_UNIDIR);
203 } else {
204 omap_cfg_reg(AA9_USB0_VP);
205 omap_cfg_reg(R9_USB0_VM);
206 USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
207 }
162 break; 208 break;
163 default: 209 default:
164 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", 210 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
@@ -171,14 +217,22 @@ static u32 __init omap_usb1_init(unsigned nwires)
171{ 217{
172 u32 syscon1 = 0; 218 u32 syscon1 = 0;
173 219
174 if (nwires != 6 && !cpu_is_omap15xx()) 220 if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6)
175 USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R; 221 USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R;
222 if (cpu_is_omap24xx())
223 CONTROL_DEVCONF_REG &= ~USBT1WRMODEI(USB_BIDIR_TLL);
224
176 if (nwires == 0) 225 if (nwires == 0)
177 return 0; 226 return 0;
178 227
179 /* external transceiver */ 228 /* external transceiver */
180 omap_cfg_reg(USB1_TXD); 229 if (cpu_class_is_omap1()) {
181 omap_cfg_reg(USB1_TXEN); 230 omap_cfg_reg(USB1_TXD);
231 omap_cfg_reg(USB1_TXEN);
232 if (nwires != 3)
233 omap_cfg_reg(USB1_RCV);
234 }
235
182 if (cpu_is_omap15xx()) { 236 if (cpu_is_omap15xx()) {
183 omap_cfg_reg(USB1_SEO); 237 omap_cfg_reg(USB1_SEO);
184 omap_cfg_reg(USB1_SPEED); 238 omap_cfg_reg(USB1_SPEED);
@@ -190,20 +244,38 @@ static u32 __init omap_usb1_init(unsigned nwires)
190 } else if (cpu_is_omap1710()) { 244 } else if (cpu_is_omap1710()) {
191 omap_cfg_reg(R13_1710_USB1_SE0); 245 omap_cfg_reg(R13_1710_USB1_SE0);
192 // SUSP 246 // SUSP
247 } else if (cpu_is_omap24xx()) {
248 /* NOTE: board-specific code must set up pin muxing for usb1,
249 * since each signal could come out on either of two balls.
250 */
193 } else { 251 } else {
194 pr_debug("usb unrecognized\n"); 252 pr_debug("usb%d cpu unrecognized\n", 1);
253 return 0;
195 } 254 }
196 if (nwires != 3)
197 omap_cfg_reg(USB1_RCV);
198 255
199 switch (nwires) { 256 switch (nwires) {
257 case 2:
258 if (!cpu_is_omap24xx())
259 goto bad;
260 /* NOTE: board-specific code must override this setting if
261 * this TLL link is not using DP/DM
262 */
263 syscon1 = 1;
264 CONTROL_DEVCONF_REG |= USBT1WRMODEI(USB_BIDIR_TLL);
265 break;
200 case 3: 266 case 3:
201 syscon1 = 2; 267 syscon1 = 2;
268 if (cpu_is_omap24xx())
269 CONTROL_DEVCONF_REG |= USBT1WRMODEI(USB_BIDIR);
202 break; 270 break;
203 case 4: 271 case 4:
204 syscon1 = 1; 272 syscon1 = 1;
273 if (cpu_is_omap24xx())
274 CONTROL_DEVCONF_REG |= USBT1WRMODEI(USB_BIDIR);
205 break; 275 break;
206 case 6: 276 case 6:
277 if (cpu_is_omap24xx())
278 goto bad;
207 syscon1 = 3; 279 syscon1 = 3;
208 omap_cfg_reg(USB1_VP); 280 omap_cfg_reg(USB1_VP);
209 omap_cfg_reg(USB1_VM); 281 omap_cfg_reg(USB1_VM);
@@ -211,6 +283,7 @@ static u32 __init omap_usb1_init(unsigned nwires)
211 USB_TRANSCEIVER_CTRL_REG |= CONF_USB1_UNI_R; 283 USB_TRANSCEIVER_CTRL_REG |= CONF_USB1_UNI_R;
212 break; 284 break;
213 default: 285 default:
286bad:
214 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", 287 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
215 1, nwires); 288 1, nwires);
216 } 289 }
@@ -221,10 +294,17 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
221{ 294{
222 u32 syscon1 = 0; 295 u32 syscon1 = 0;
223 296
224 /* NOTE erratum: must leave USB2_UNI_R set if usb0 in use */ 297 if (cpu_is_omap24xx()) {
298 CONTROL_DEVCONF_REG &= ~(USBT2WRMODEI(USB_BIDIR_TLL)
299 | USBT2TLL5PI);
300 alt_pingroup = 0;
301 }
302
303 /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */
225 if (alt_pingroup || nwires == 0) 304 if (alt_pingroup || nwires == 0)
226 return 0; 305 return 0;
227 if (nwires != 6 && !cpu_is_omap15xx()) 306
307 if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6)
228 USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R; 308 USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
229 309
230 /* external transceiver */ 310 /* external transceiver */
@@ -242,19 +322,54 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
242 if (nwires != 3) 322 if (nwires != 3)
243 omap_cfg_reg(Y5_USB2_RCV); 323 omap_cfg_reg(Y5_USB2_RCV);
244 // FIXME omap_cfg_reg(USB2_SPEED); 324 // FIXME omap_cfg_reg(USB2_SPEED);
325 } else if (cpu_is_omap24xx()) {
326 omap_cfg_reg(Y11_24XX_USB2_DAT);
327 omap_cfg_reg(AA10_24XX_USB2_SE0);
328 if (nwires > 2)
329 omap_cfg_reg(AA12_24XX_USB2_TXEN);
330 if (nwires > 3)
331 omap_cfg_reg(AA6_24XX_USB2_RCV);
245 } else { 332 } else {
246 pr_debug("usb unrecognized\n"); 333 pr_debug("usb%d cpu unrecognized\n", 1);
334 return 0;
247 } 335 }
248 // omap_cfg_reg(USB2_SUSP); 336 // if (cpu_class_is_omap1()) omap_cfg_reg(USB2_SUSP);
249 337
250 switch (nwires) { 338 switch (nwires) {
339 case 2:
340 if (!cpu_is_omap24xx())
341 goto bad;
342 /* NOTE: board-specific code must override this setting if
343 * this TLL link is not using DP/DM
344 */
345 syscon1 = 1;
346 CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_BIDIR_TLL);
347 break;
251 case 3: 348 case 3:
252 syscon1 = 2; 349 syscon1 = 2;
350 if (cpu_is_omap24xx())
351 CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_BIDIR);
253 break; 352 break;
254 case 4: 353 case 4:
255 syscon1 = 1; 354 syscon1 = 1;
355 if (cpu_is_omap24xx())
356 CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_BIDIR);
357 break;
358 case 5:
359 if (!cpu_is_omap24xx())
360 goto bad;
361 omap_cfg_reg(AA4_24XX_USB2_TLLSE0);
362 /* NOTE: board-specific code must override this setting if
363 * this TLL link is not using DP/DM. Something must also
364 * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED}
365 */
366 syscon1 = 3;
367 CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_UNIDIR_TLL)
368 | USBT2TLL5PI;
256 break; 369 break;
257 case 6: 370 case 6:
371 if (cpu_is_omap24xx())
372 goto bad;
258 syscon1 = 3; 373 syscon1 = 3;
259 if (cpu_is_omap15xx()) { 374 if (cpu_is_omap15xx()) {
260 omap_cfg_reg(USB2_VP); 375 omap_cfg_reg(USB2_VP);
@@ -266,6 +381,7 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
266 } 381 }
267 break; 382 break;
268 default: 383 default:
384bad:
269 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", 385 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
270 2, nwires); 386 2, nwires);
271 } 387 }
@@ -294,13 +410,13 @@ static struct resource udc_resources[] = {
294 .end = UDC_BASE + 0xff, 410 .end = UDC_BASE + 0xff,
295 .flags = IORESOURCE_MEM, 411 .flags = IORESOURCE_MEM,
296 }, { /* general IRQ */ 412 }, { /* general IRQ */
297 .start = IH2_BASE + 20, 413 .start = INT_USB_IRQ_GEN,
298 .flags = IORESOURCE_IRQ, 414 .flags = IORESOURCE_IRQ,
299 }, { /* PIO IRQ */ 415 }, { /* PIO IRQ */
300 .start = IH2_BASE + 30, 416 .start = INT_USB_IRQ_NISO,
301 .flags = IORESOURCE_IRQ, 417 .flags = IORESOURCE_IRQ,
302 }, { /* SOF IRQ */ 418 }, { /* SOF IRQ */
303 .start = IH2_BASE + 29, 419 .start = INT_USB_IRQ_ISO,
304 .flags = IORESOURCE_IRQ, 420 .flags = IORESOURCE_IRQ,
305 }, 421 },
306}; 422};
@@ -329,11 +445,11 @@ static u64 ohci_dmamask = ~(u32)0;
329static struct resource ohci_resources[] = { 445static struct resource ohci_resources[] = {
330 { 446 {
331 .start = OMAP_OHCI_BASE, 447 .start = OMAP_OHCI_BASE,
332 .end = OMAP_OHCI_BASE + 4096 - 1, 448 .end = OMAP_OHCI_BASE + 0xff,
333 .flags = IORESOURCE_MEM, 449 .flags = IORESOURCE_MEM,
334 }, 450 },
335 { 451 {
336 .start = INT_USB_HHC_1, 452 .start = INT_USB_IRQ_HGEN,
337 .flags = IORESOURCE_IRQ, 453 .flags = IORESOURCE_IRQ,
338 }, 454 },
339}; 455};
@@ -361,7 +477,7 @@ static struct resource otg_resources[] = {
361 .end = OTG_BASE + 0xff, 477 .end = OTG_BASE + 0xff,
362 .flags = IORESOURCE_MEM, 478 .flags = IORESOURCE_MEM,
363 }, { 479 }, {
364 .start = IH2_BASE + 8, 480 .start = INT_USB_IRQ_OTG,
365 .flags = IORESOURCE_IRQ, 481 .flags = IORESOURCE_IRQ,
366 }, 482 },
367}; 483};
@@ -385,7 +501,7 @@ static struct platform_device otg_device = {
385 501
386 502
387// FIXME correct answer depends on hmc_mode, 503// FIXME correct answer depends on hmc_mode,
388// as does any nonzero value for config->otg port number 504// as does (on omap1) any nonzero value for config->otg port number
389#ifdef CONFIG_USB_GADGET_OMAP 505#ifdef CONFIG_USB_GADGET_OMAP
390#define is_usb0_device(config) 1 506#define is_usb0_device(config) 1
391#else 507#else
@@ -426,12 +542,13 @@ omap_otg_init(struct omap_usb_config *config)
426 if (config->otg) 542 if (config->otg)
427 syscon |= OTG_EN; 543 syscon |= OTG_EN;
428#endif 544#endif
429 pr_debug("USB_TRANSCEIVER_CTRL_REG = %03x\n", USB_TRANSCEIVER_CTRL_REG); 545 if (cpu_class_is_omap1())
546 pr_debug("USB_TRANSCEIVER_CTRL_REG = %03x\n", USB_TRANSCEIVER_CTRL_REG);
430 pr_debug("OTG_SYSCON_2_REG = %08x\n", syscon); 547 pr_debug("OTG_SYSCON_2_REG = %08x\n", syscon);
431 OTG_SYSCON_2_REG = syscon; 548 OTG_SYSCON_2_REG = syscon;
432 549
433 printk("USB: hmc %d", config->hmc_mode); 550 printk("USB: hmc %d", config->hmc_mode);
434 if (alt_pingroup) 551 if (!alt_pingroup)
435 printk(", usb2 alt %d wires", config->pins[2]); 552 printk(", usb2 alt %d wires", config->pins[2]);
436 else if (config->pins[0]) 553 else if (config->pins[0])
437 printk(", usb0 %d wires%s", config->pins[0], 554 printk(", usb0 %d wires%s", config->pins[0],
@@ -444,10 +561,12 @@ omap_otg_init(struct omap_usb_config *config)
444 printk(", Mini-AB on usb%d", config->otg - 1); 561 printk(", Mini-AB on usb%d", config->otg - 1);
445 printk("\n"); 562 printk("\n");
446 563
447 /* leave USB clocks/controllers off until needed */ 564 if (cpu_class_is_omap1()) {
448 ULPD_SOFT_REQ_REG &= ~SOFT_USB_CLK_REQ; 565 /* leave USB clocks/controllers off until needed */
449 ULPD_CLOCK_CTRL_REG &= ~USB_MCLK_EN; 566 ULPD_SOFT_REQ_REG &= ~SOFT_USB_CLK_REQ;
450 ULPD_CLOCK_CTRL_REG |= DIS_USB_PVCI_CLK; 567 ULPD_CLOCK_CTRL_REG &= ~USB_MCLK_EN;
568 ULPD_CLOCK_CTRL_REG |= DIS_USB_PVCI_CLK;
569 }
451 syscon = OTG_SYSCON_1_REG; 570 syscon = OTG_SYSCON_1_REG;
452 syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN; 571 syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN;
453 572
@@ -585,7 +704,7 @@ omap_usb_init(void)
585 } 704 }
586 platform_data = *config; 705 platform_data = *config;
587 706
588 if (cpu_is_omap730() || cpu_is_omap16xx()) 707 if (cpu_is_omap730() || cpu_is_omap16xx() || cpu_is_omap24xx())
589 omap_otg_init(&platform_data); 708 omap_otg_init(&platform_data);
590 else if (cpu_is_omap15xx()) 709 else if (cpu_is_omap15xx())
591 omap_1510_usb_init(&platform_data); 710 omap_1510_usb_init(&platform_data);